6502
Introduction
The MOS Technology 6502 was first released in 1975 and was the dominant CPU in home computers for a decade, appearing in the Atari 2600, Apple II, NES, Commodore PET/VIC20/C64. It is an 8-bit processor with 16 bit address space. It included 3 registers (Accumulator and two general purpose X, Y registers) and a status register.
The instruction sets allowed for loading, storing, and transferring data between the A, X, and Y registers, arithmetic, shifting and rotating, logic AND and OR, comparison, branching, jumping and subroutines, interrupts, and stack operations.
Memory to the 6502 spans its entire 16-bit address space and allows for up to 64 KB of memory to be addressed. Though, this space may also be used for ROM, screen memory, or hardware peripherals via memory mapped IO. While the address space can be divided up in various ways depending on the hardware designer, the 6502 is hard coded to use the following memory mapping.
Address | Purpose |
---|---|
0000 - 00FF | First page is known as the Zero page and used for variables.
Instructions can reference a single-byte address which references the zero page. |
0100 - 01FF | Second page reserved for the stack. Initializes at 0x1FF.
The 8-bit stack location is stored in the S register. S initializes to FF and grows down as the stack is used. |
FFFA - FFFF | Typically a ROM address space containing the:
|
A ROM is typically required in order to tell the 6502 where to begin execution (the reset routine) and provide the instructions to execute.
A hardware designer can choose to divide the memory up, for example to have the upper half of the address space as ROM and the lower half as RAM while reserving a small address space for memory mapped IO. To implement this, some type of address decoding logic is needed to convert the raw address value asserted by the processor on the address bus into enable/disable signals that are sent to the ROM, RAM, or hardware peripheral. It's a good idea to have the mapping as simple as possible so that implementing the address decoding logic requires fewer parts since additional hardware increases propagation delay which can be problematic especially if the processor runs at a high clock rate.
Instruction Set
Description | Instructions | Examples and notes |
---|---|---|
Load from memory | LDA, LDX, LDY | LDA #$22 to load 0x22 to accumulator
|
Store to memory | STA, STX, STY | |
Transfer from Accumulator | TAX, TAY | |
Transfer to Accumulator | TXA, TYA | Note: No way to directly transfer between registers X and Y |
Arithmetic on accumulator | ADC add
SBC - subtract |
ADC #$02 add 2 to accumulator
|
Increment and Decrement | INC, INX, INY
DEC, DEX, DEY |
Note: May set carry, overflow, or zero flags. |
Rotate | ROL, ROR | Rotate left or right |
Shifting | ASL, ASR
LSL, LSR |
Arithmetic shift will set carry bit, Logical uses carry bit (?)
|
Set Flags | SEC, SED, SEI | Sets carry, decimal, interrupt |
Clear Flags | CLC, CLV, CLI, CLD | Clear carry, overflow, interrupt, decimal |
Jumping | JMP | |
Branching | BCC - carry clear
BCS - carry set BNE - zero clear BEQ - zero set BPL - negative clear BMI - negative set BVC - overflow clear BVS - overflow set |
|
Stack | PUSH, PULL
PHP, PLP - push/pull flags PHA, PLA - push/pull accumulator |
|
Subroutine | JSR - jump to subroutine
RTS - return |
JSR pushes the current address to the stack before jumping. RTS pops and jumps back to this location and adds one. |
Flags
- Carry set if add/inc >255 or sub/dec <0.
- Overflow if numbers >255
- Zero: operation results in 0
- Negative: bit 7 is set
- Break
- Interrupt
- Decimal
Other Notes
The processor is little endian. The least significant value is always first. In the case of a 16-bit value, the lower 8-bits are sent, then the higher 8-bits.
See Also
- A good tutorial and JS emulator - http://skilldrick.github.io/easy6502
- Explanation on the 6502 memory mappings - http://wilsonminesco.com/6502primer/MemMapReqs.html