The emulator requires Python 3.10 or later. The assembly written in this repository requires dasm because it's the easiest one I could find to install on my laptop when I started this project.
- The
uvPython package manager - Python 3.10 or later
dasmif you want to compile the assembly code contained in the repository
The dasm settings are pretty straightforward. The output needs to be written raw (-f3) which is why we need to change the default format (-f1) which adds a two-byte origin in little-endian order (as per the documentation). We set the origin manually in code, so this extra information isn't really needed. For more information, check out the dasm documentation.
$ dasm hello_world.asm -f3 -ohello_world.out
| Done | Tests | Addressing Mode | Comments |
|---|---|---|---|
| ✔️ | ✔️ | Implied | |
| ✔️ | ✔️ | Accumulator | Handled via direct access to A |
| ✔️ | ✔️ | Immediate | Implemented via _a_immediate() |
| ✔️ | ✔️ | Absolute | Implemented via _a_absolute() |
| ✔️ | ✔️ | X-Indexed Absolute | Implemented via _a_indexed_absolute('X') |
| ✔️ | ✔️ | Y-Indexed Absolute | Implemented via _a_indexed_absolute('Y') |
| ✔️ | Indirect | Implemented via _a_indirect() |
|
| ✔️ | ✔️ | Zero Page | Implemented via _a_zero_page() |
| ✔️ | ✔️ | X-Indexed Zero Page | Implemented via _a_zero_page_indexed('X') |
| ✔️ | ✔️ | Y-Indexed Zero Page | Implemented via _a_zero_page_indexed('Y') |
| ✔️ | ✔️ | X-Indexed Zero Page Indirect | Implemented via _a_x_indexed_zp_indirect() |
| ✔️ | ✔️ | Zero Page Indirect Y-Indexed | Implemented via _a_zp_indirect_y_indexed() |
The bus is built, but I need to clean it up a bit and document how you attach things to it. For now, you can create custom BusObjects and attach them to the main bus. There are also two pre-created BusObjects: RAM (BusRam) and ROM (BusRom). Also, you can attach the same object to the bus at a different location by setting the mirror option to True when attaching it to the bus.
| Done | Feature | Comment |
|---|---|---|
| ✔️ | Stack | Completed |
| ✔️ | Stack Pointer | Completed |
| Done | Method | Comment |
|---|---|---|
| ✔️ | _s_push_byte(value: int) |
Pushes a byte value onto the stack and increments the stack pointer. |
| ✔️ | _s_push_address(address: int) |
Pushes an address onto the stack and increments the stack pointer twice. |
| ✔️ | _s_pop_byte() |
Pulls a byte from the stack and decrements the stack pointer. |
| ✔️ | _s_pop_address() |
Pulls an address from the stack and decrements the stack pointer twice. |
| Done | Tests | Instruction | # of Opcodes | Comment |
|---|---|---|---|---|
| ✔️ | ✔️ | ADC |
8 | Completed (including decimal mode) |
| ✔️ | ✔️ | AND |
8 | Completed |
| ✔️ | ✔️ | ASL |
5 | Completed |
| ✔️ | ✔️ | BCC |
1 | Completed |
| ✔️ | ✔️ | BCS |
1 | Completed |
| ✔️ | ✔️ | BEQ |
1 | Completed |
| ✔️ | ✔️ | BMI |
1 | Completed |
| ✔️ | ✔️ | BNE |
1 | Completed |
| ✔️ | ✔️ | BPL |
1 | Completed |
| ✔️ | ✔️ | BVC |
1 | Completed |
| ✔️ | ✔️ | BVS |
1 | Completed |
| ✔️ | ✔️ | BIT |
2 | Completed |
| ✔️ | BRK |
1 | Completed | |
| ✔️ | ✔️ | CLC |
1 | Completed |
| ✔️ | ✔️ | CLD |
1 | Completed |
| ✔️ | ✔️ | CLI |
1 | Completed |
| ✔️ | ✔️ | CLV |
1 | Completed |
| ✔️ | ✔️ | CMP |
8 | Completed |
| ✔️ | ✔️ | CPX |
2 | Completed |
| ✔️ | ✔️ | CPY |
2 | Completed |
| ✔️ | ✔️ | DEC |
4 | Completed |
| ✔️ | ✔️ | DEX |
1 | Completed |
| ✔️ | ✔️ | DEY |
1 | Completed |
| ✔️ | ✔️ | EOR |
8 | Completed |
| ✔️ | ✔️ | INC |
4 | Completed |
| ✔️ | ✔️ | INX |
1 | Completed |
| ✔️ | ✔️ | INY |
1 | Completed |
| ✔️ | ✔️ | JMP |
2 | Completed |
| ✔️ | JSR |
1 | Completed | |
| ✔️ | ✔️ | LDA |
8 | Completed |
| ✔️ | ✔️ | LDX |
5 | Completed |
| ✔️ | ✔️ | LDY |
5 | Completed |
| ✔️ | ✔️ | LSR |
5 | Completed |
| ✔️ | ✔️ | NOP |
1 | Completed |
| ✔️ | ✔️ | ORA |
8 | Completed |
| ✔️ | ✔️ | PHA |
1 | Completed |
| ✔️ | ✔️ | PHP |
1 | Completed |
| ✔️ | ✔️ | PLA |
1 | Completed |
| ✔️ | ✔️ | PLP |
1 | Completed |
| ✔️ | ✔️ | ROL |
5 | Completed |
| ✔️ | ✔️ | ROR |
5 | Completed |
| ✔️ | RTI |
1 | Completed | |
| ✔️ | RTS |
1 | Completed | |
| ✔️ | ✔️ | SBC |
8 | Completed (including decimal mode) |
| ✔️ | ✔️ | SEC |
1 | Completed |
| ✔️ | ✔️ | SED |
1 | Completed |
| ✔️ | ✔️ | SEI |
1 | Completed |
| ✔️ | ✔️ | STA |
7 | Completed |
| ✔️ | ✔️ | STX |
3 | Completed |
| ✔️ | ✔️ | STY |
3 | Completed |
| ✔️ | ✔️ | TAX |
1 | Completed |
| ✔️ | ✔️ | TAY |
1 | Completed |
| ✔️ | ✔️ | TSX |
1 | Completed |
| ✔️ | ✔️ | TXA |
1 | Completed |
| ✔️ | ✔️ | TXS |
1 | Completed |
| ✔️ | ✔️ | TYA |
1 | Completed |
All of the undocumented/illegal opcodes have been implemented except for the unstable ones (ANE, LXA, SHA, SHX, SHY, TAS). These will likely stay unimplented due to the complexity of even trying to simulated some of the potential issues they cause. Testing for undocumented/illegal opcodes will have to wait until I have the ability to either find a very accurate emulator to test my results against or building an actual MOS6502 testbed.
| Done | Tests | Instruction | # of Opcodes | Comment |
|---|---|---|---|---|
| ✔️ | ANC |
7 | Completed | |
| ❌ | ANE |
1 | Unstable instruction, not implemented | |
| ✔️ | ARR |
1 | Completed (including decimal mode) |
|
| ✔️ | ASR |
1 | Completed | |
| ✔️ | DCP |
7 | Completed | |
| ✔️ | ISB |
7 | Completed (including decimal mode) |
|
| ❌ | JAM |
12 | Not implemented | |
| ✔️ | LAS |
1 | Completed | |
| ✔️ | LAX |
6 | Completed | |
| ❌ | LXA |
1 | Unstable instruction, not implemented | |
| ✔️ | NOP |
27 | Completed | |
| ✔️ | RLA |
7 | Completed | |
| ✔️ | RRA |
7 | Completed (including decimal mode) |
|
| ✔️ | SAX |
4 | Completed | |
| ✔️ | SBX |
1 | Completed | |
| ❌ | SHA |
2 | Unstable instruction, not implemented | |
| ❌ | SHX |
1 | Unstable instruction, not implemented | |
| ❌ | SHY |
1 | Unstable instruction, not implemented | |
| ✔️ | SLO |
7 | Completed | |
| ✔️ | SRE |
7 | Completed | |
| ❌ | TAS |
1 | Unstable instruction, not implemented |
The project uses pytest to run through all of the tests in the tests directory. This is currently the sole external dependency of the project, and can be installed uv sync.
To run all of the tests, simply run pytest at the root of the repository.