Skip to content

Latest commit

 

History

History
50 lines (36 loc) · 3.16 KB

m6502.md

File metadata and controls

50 lines (36 loc) · 3.16 KB

m6502

MOS Technology 6502 series processor.

Compatible with:

  • 6502
  • 6510
  • 8502

Development Notes

Program Counter

The program counter on the 6502 increments before fetching the opcode, not after. To run code starting at address $400, the PC needs to be set to $3ff. This kept confusing me when switching between this processor and the Z80 which does not have this behavior. The solution is to obtain the address of the next instruction using cpu.PC() + cpu.Offset(). On the Z80, Offset returns 0 but on the 6502 returns 1.

BRK/PHP/PLP instructions

All these years I thought there was a break flag on the processor but apparently that is not true. The only time this is "seen" is during a brk instruction. When the status register is pushed to the stack in this case, bit 4, the so-called break flag, is set. I implemented the brk instruction wrong at least twice. The correct implementation, after decoding the opcode, appears to be:

  • fetch another byte which is discarded
  • push the value of the PC + 1 to the stack
  • push the value of the status register with bit 5 set.
  • disable interrupts
  • set the PC to the value found at 0xfffe - 1

When pushing the status register to the stack using the php instruction, ensure that both bits 4 and 5 are set. The plp instruction needs to make sure that bit 4, if set, is cleared when it is transfered to the status register.

In this implementation the status register is a variable. In other implementaitons I made it a getter and setter function. To ensure bit 5 is always set and that bit 4 is always clear, those operations are applied after each instruction is executed.

c.push(c.SR | FlagB | Flag5)

TXS/TSX Instructions

  • tsx modifies the N and Z flags.
  • txs does not modify any flags.

The reference I was using did not mention anything about the flags for these operations.

Testing

Unit tests were written when the 6502 emulator was developed to try and catch as many cases as possible but it has gaps in coverage. This provides a good quick first test to make sure the code is running as expected.

For full coverage, the tests written by Klaus Dormann from the 6502_65C02_functional_tests repository are used. The assembly code for running these tests are not found in the repository. Download bin_files/6502_functional_test.bin and place it in a ~/rcs/ext/m6502 directory. Run the tests by using the build tag ext.

References