This project is a basic emulator of the Commodore 64 written in Python.
Its main purpose is to run simple BASIC programs stored in .prg
files and to show how an emulator is built, step by step. It covers the MOS 6510 CPU, memory map, a minimal VIC-II display, and input handling.
This screenshot shows a simple PRINT command executed in the BASIC interpreter, demonstrating text rendering and keyboard input handling in the emulated environment.
A lightweight diagnostic program that visualizes C64 RAM and sprite memory. Useful for verifying basic video memory access and display via the VIC-II module.
A more advanced diagnostic tool that tests multiple hardware components including CIA-driven memory mapping. Demonstrates support for dynamically remapped address spaces and I/O handling.
- The goal is not to reach 100 % hardware accuracy.
- It must be able to load and start small
.prg
files without extra loaders. - Extra chips such as SID and full CIA1/CIA2 support are still missing.
- Code should stay clear and short so it is easy to study.
I developed this project with strong help from AI tools. The AI supported me with:
- Code flow ideas and naming
- Quick research on C-64 internals and data-sheets
- Small assembler examples and bug hunting
However, the project also shows that AI alone cannot finish a full emulator. A human still has to design the structure, understand corner cases, and test the result. My background is software engineering with a focus on quality-process automation, which helped in planning and testing the codebase.
Status | Module | Notes |
---|---|---|
โ | MOS 6510 CPU | All documented 6502 instructions |
โ | Memory map | BASIC, KERNAL, CHAR ROM, RAM |
โ | Basic VIC-II | Text and bitmap modes, drawn with Pygame |
๐ก | CIA1 & CIA2 | Only timers A/B and IRQ mask; no TOD clock |
โ | SID sound | Not yet implemented |
๐ก | 1541 drive | Skeleton class; disabled by default |
Legend: โ ready ยท ๐ก partial ยท โ missing
Additional details:
- Drag-and-drop: Drop a
.prg
file on the window to auto-load it. - Pygame interface: Keyboard mapping and window output.
- Works without custom loaders; the emulator adjusts the BASIC pointers for you.
- No sound, because SID emulation is still on the to-do list.
- CIA1/CIA2 do not yet cover all registers, so some demos or games can fail.
- Cycle timing is approximate; programs that depend on exact raster timing may break.
- Finish CIA1/CIA2 (TOD clock, serial lines, full interrupts).
- Add a very rough SID channel so simple tones can play.
- Improve timing and add a โfast-loadโ option for large files.
- Optional: grow the 1541 module into a working drive with GCR decoding.
- Pythonย >=ย 3.12
- numpyย ==ย 2.2.1
- pygameย ==ย 2.6.1
git clone <REPO_URL>
cd c64
python3 -m venv .venv
source .venv/bin/activate # or .venv\Scripts\activate on Windows
pip install -r requirements.txt
Then place the original ROM images in the rom/
folder (see below).
mkdir -p rom
curl -L https://www.zimmers.net/anonftp/pub/cbm/firmware/computers/c64/basic.901226-01.bin -o rom/basic.bin
curl -L https://www.zimmers.net/anonftp/pub/cbm/firmware/computers/c64/kernal.901227-01.bin -o rom/kernel.bin
curl -L https://www.zimmers.net/anonftp/pub/cbm/firmware/computers/c64/characters.901225-01.bin -o rom/chargen.bin
curl -L https://www.zimmers.net/anonftp/pub/cbm/firmware/drives/new/1541/1540-c000.325302-01.bin -o rom/dos1541.bin
(Replace the URLs with mirrors of your choice.)
python main.py
- A C-64 screen appears.
- Drag a
.prg
file onto it. - Type
RUN
and press Enter.
Press Esc or close the window to quit.
Run the emulator with verbose debug logs:
python main.py --debug
classDiagram
class Emulator {
+run()
-init_pygame()
-main_loop()
}
class CPU6510 {
+reset()
+step()
-executeInstruction()
}
class VICII {
+renderFrame()
-drawTextMode()
-drawBitmapMode()
}
class SID {
+clock()
-updateRegisters()
}
class CIA {
+tick()
-handleIRQ()
}
class Bus {
+read(addr)
+write(addr, data)
}
class IOHandler {
+loadPrg(file)
+processInput()
}
Emulator --> CPU6510 : uses
Emulator --> VICII : uses
Emulator --> SID : uses
Emulator --> CIA : uses
Emulator --> Bus : uses
Emulator --> IOHandler : uses
CPU6510 --> Bus : accesses
VICII --> Bus : accesses
SID --> Bus : accesses
CIA --> Bus : accesses
IOHandler --> Bus : accesses
c64/
โโโ rom/ # ROM files and sample .prg files
โโโ src/ # Emulator source code
โ โโโ emulator/ # Emulator class and Pygame setup
โ โโโ bus/ # System bus and memory mapping
โ โโโ cpu/ # MOSย 6510 CPU emulation
โ โโโ vic/ # VIC-II graphics emulation
โ โโโ sid/ # SID sound chip emulation
โ โโโ cia/ # CIA1 and CIA2 timers/I/O emulation
โ โโโ io/ # Keyboard input, .prg loader, disk drive interface
โ โโโ utils/ # Logging and utility functions
โโโ tests/ # Unit and integration tests
โโโ main.py # Entry point
โโโ requirements.txt # Dependencies
โโโ LICENSE # MIT License
โโโ README.md # This file
Run all unit tests with:
pytest
Pull requests are very welcome, especially for missing chips or performance fixes. Feel free to open issues for discussion.
Interested in working together or adding new components? Write to jaroslawtrepkowski@gmail.com โ I am open to ideas and cooperation.
This project is released under the GNU GPL. See the LICENSE file for details.