6502

From CPCWiki - THE Amstrad CPC encyclopedia!
Revision as of 11:32, 3 September 2024 by Phi2x (Talk | contribs) (Memory Access)

Jump to: navigation, search
The 6502 CPU

The MOS Technology 6502 is an 8-bit microprocessor designed by Chuck Peddle for MOS Technology in 1975. When it was introduced it was the least expensive full featured CPU on the market by far, at about 1/6th the price, or less, of competing designs from larger companies such as Motorola and Intel. It was nevertheless faster than most of them, and, along with the Zilog Z80, sparked off a series of computer projects that would eventually result in the home computer revolution of the 1980s. The 6502 design was originally second-sourced by Rockwell and Synertek and later licensed to a number of companies; it is still made for embedded systems.

Originally the CPC was destined to be designed around the 6502 processor. But when Amstrad approached Locomotive Software to develop a Basic for it with a very tight deadline, Locomotive PLC, who already had a Z80 Basic in the works, urged and convinced Amstrad to switch to the Z80.


Description

The 6502 microprocessor is an 8-bit CPU with an 8-bit ALU and a 16-bit address bus capable of direct access to 64KB of memory space. Like the Z80, the 6502 is also a little-endian CPU, meaning it stores 16-bit values with the least significant byte first, followed by the most significant byte. The 6502 has 151 instructions, which are composed of 56 distinct opcodes across various addressing modes.

Although it lacks the raw processing power of processors like the Intel 80x86 or the Motorola 68000 series, the 6502 was known for its efficiency and affordability, making it a popular choice for embedded systems and early home computers. Its simple design contributed to lower manufacturing costs and simplified integration.

The 6502 chip is made up of 4528 transistors (3510 enhancement transistors and 1018 depletion pullup transistors). It comes in a 40-pin DIP package. It has been produced by various manufacturers and used in a wide range of applications, from early gaming consoles like the Atari VCS and Nintendo Entertainment System to personal computers like the Apple II and Commodore 64.


Registers

Register Size Description Notes
A (Accumulator) 8-bit Main register for arithmetic, logic, and data transfer Most operations use this register
X (Index Register X) 8-bit Used for indexing memory and loop counters Can be used for addressing modes like Indexed Indirect, Zero Page Indexed, and Absolute Indexed
Y (Index Register Y) 8-bit Used for indexing memory and loop counters Often used in Absolute and Zero Page Indexed addressing
P (Processor Status) 8-bit
  • bit7 - NF - Negative Flag
  • bit6 - VF - Overflow Flag
  • bit5 - Unused (always set to 1)
  • bit4 - BF - Break Command
  • bit3 - DF - Decimal Mode Flag
  • bit2 - IF - Interrupt Disable Flag
  • bit1 - ZF - Zero Flag
  • bit0 - CF - Carry Flag
The status register is modified by arithmetic and logic operations, as well as interrupts
S (Stack Pointer) 8-bit Points to the current location in the stack Stack is located in page 1 ($0100-$01FF), 8-bit S is offset to this base
PC (Program Counter) 16-bit Points to the next instruction to be executed Automatically increments as instructions are executed


Memory Access

The address space that the 6502 uses is split into pages. There are 256 pages and each page is 256 bytes in size, ranging from page 0 to page 255.

In order to make up for the lack of registers, the 6502 includes a zero page addressing mode ($0000-$00FF) that uses only 1 address byte in the instruction instead of the 2 that are needed to address the full 64 KB of memory. This provides fast access to the first 256 bytes of RAM by using shorter instructions.

The stack is permanently located in page 1 ($0100 to $01FF) and managed by the 8-bit stack pointer (S), with an initial value of $FF. It grows downward as data is pushed onto the stack.

Instructions PHA and PHP push the accumulator and processor status onto the stack, while PLA and PLP pull them back. Subroutine calls with JSR store the return address on the stack, and RTS retrieves it to continue execution. Similarly, interrupts (BRK) push the program counter and status, while RTI restores them. The stack has a 256-byte limit, and overflow occurs if not managed properly.

BRK/IRQ/NMI/RESET

On a RESET, the CPU loads the vector from $FFFC/$FFFD into the program counter and continues fetching instructions from there.

On an NMI, the CPU pushes the low byte and the high byte of the program counter as well as the processor status onto the stack, disables interrupts and loads the vector from $FFFA/$FFFB into the program counter and continues fetching instructions from there.

On an IRQ, the CPU does the same as in the NMI case, but uses the vector at $FFFE/$FFFF.

On a BRK instruction, the CPU does the same as in the IRQ case, but sets bit #4 (B flag) in the copy of the status register that is saved on the stack.


6502 Instruction set

Standard instructions

Mnemonic Addressing Modes Flags Operation Description
No arg A #$nn $nnnn $nnnn,X $nnnn,Y ($nnnn) $nn $nn,X $nn,Y ($nn,X) ($nn),Y rel N V - B D I Z C
ADC 69 6D 7D 79 65 75 61 71 N V - - - - Z C A + M + CF → A, CF Add Memory to Accumulator with Carry
AND 29 2D 3D 39 25 35 21 31 N - - - - - Z - A ∧ M → A "AND" Memory with Accumulator
ASL 0A 0E 1E 06 16 N - - - - - Z C CF ← /M7...M0/ ← 0 Arithmetic Shift Left
BCC 90 - - - - - - - - Branch on CF = 0 Branch on Carry Clear
BCS B0 - - - - - - - - Branch on CF = 1 Branch on Carry Set
BEQ F0 - - - - - - - - Branch on ZF = 1 Branch on Result Zero
BIT 2C 24 N V - - - - Z - A ∧ M, M7 → NF, M6 → VF Test Bits in Memory with Accumulator
BMI 30 - - - - - - - - Branch on NF = 1 Branch on Result Minus
BNE D0 - - - - - - - - Branch on ZF = 0 Branch on Result Not Zero
BPL 10 - - - - - - - - Branch on NF = 0 Branch on Result Plus
BRK 00 - - - - - 1 - - PC + 2↓, [FFFE] → PCL, [FFFF] → PCH Break Command
BVC 50 - - - - - - - - Branch on VF = 0 Branch on Overflow Clear
BVS 70 - - - - - - - - Branch on VF = 1 Branch on Overflow Set
CLC 18 - - - - - - - 0 0 → CF Clear Carry Flag
CLD D8 - - - - 0 - - - 0 → DF Clear Decimal Mode
CLI 58 - - - - - 0 - - 0 → IF Clear Interrupt Disable
CLV B8 - 0 - - - - - - 0 → VF Clear Overflow Flag
CMP C9 CD DD D9 C5 D5 C1 D1 N - - - - - Z C A - M Compare Memory and Accumulator
CPX E0 EC E4 N - - - - - Z C X - M Compare Index Register X To Memory
CPY C0 CC C4 N - - - - - Z C Y - M Compare Index Register Y To Memory
DEC CE DE C6 D6 N - - - - - Z - M - 1 → M Decrement Memory By One
DEX CA N - - - - - Z - X - 1 → X Decrement Index Register X By One
DEY 88 N - - - - - Z - Y - 1 → Y Decrement Index Register Y By One
EOR 49 4D 5D 59 45 55 41 51 N - - - - - Z - A ⊻ M → A "Exclusive OR" Memory with Accumulator
INC EE FE E6 F6 N - - - - - Z - M + 1 → M Increment Memory By One
INX E8 N - - - - - Z - X + 1 → X Increment Index Register X By One
INY C8 N - - - - - Z - Y + 1 → Y Increment Index Register Y By One
JMP 4C 6C - - - - - - - - [PC + 1] → PCL, [PC + 2] → PCH JMP Indirect
JSR 20 - - - - - - - - PC + 2↓, [PC + 1] → PCL, [PC + 2] → PCH Jump To Subroutine
LDA A9 AD BD B9 A5 B5 A1 B1 N - - - - - Z - M → A Load Accumulator with Memory
LDX A2 AE BE A6 B6 N - - - - - Z - M → X Load Index Register X From Memory
LDY A0 AC BC A4 B4 N - - - - - Z - M → Y Load Index Register Y From Memory
LSR 4A 4E 5E 46 56 0 - - - - - Z C 0 → /M7...M0/ → CF Logical Shift Right
NOP EA - - - - - - - - No operation No Operation
ORA 09 0D 1D 19 05 15 01 11 N - - - - - Z - A ∨ M → A "OR" Memory with Accumulator
PHA 48 - - - - - - - - A↓ Push Accumulator On Stack
PHP 08 - - - 1 - - - - P↓ Push Processor Status on Stack
PLA 68 N - - - - - Z - (S)↑ → A Pull Accumulator From Stack
PLP 28 N V - B D I Z C (S)↑ → P Pull Processor Status From Stack
ROL 2A 2E 3E 26 36 N - - - - - Z C CF ← /M7...M0/ ← CF Rotate One Bit Left (Memory or Accumulator)
ROR 6A 6E 7E 66 76 N - - - - - Z C CF → /M7...M0/ → CF Rotate One Bit Right (Memory or Accumulator)
RTI 40 N V - B D I Z C (S)↑ → P, (S)↑ → PCL, (S)↑ → PCH Return From Interrupt
RTS 60 - - - - - - - - (S)↑ → PCL, (S)↑ → PCH, PC + 1 → PC Return From Subroutine
SBC E9 ED FD F9 E5 F5 E1 F1 N V - - - - Z C A - M - (1 - CF) → A Subtract Memory from Accumulator with Borrow
SEC 38 - - - - - - - 1 1 → CF Set Carry Flag
SED F8 - - - - 1 - - - 1 → DF Set Decimal Mode
SEI 78 - - - - - 1 - - 1 → IF Set Interrupt Disable
STA 8D 9D 99 85 95 81 91 - - - - - - - - A → M Store Accumulator in Memory
STX 8E 86 96 - - - - - - - - X → M Store Index X in Memory
STY 8C 84 94 - - - - - - - - Y → M Store Index Y in Memory
TAX AA N - - - - - Z - A → X Transfer Accumulator to Index X
TAY A8 N - - - - - Z - A → Y Transfer Accumulator to Index Y
TSX BA N - - - - - Z - S → X Transfer Stack Pointer to Index X
TXA 8A N - - - - - Z - X → A Transfer Index X to Accumulator
TXS 9A - - - - - - - - X → S Transfer Index X to Stack Pointer
TYA 98 N - - - - - Z - Y → A Transfer Index Y to Accumulator

Illegal instructions

The opcodes in bold are unstable. Only 2 of those 7 opcodes (8B, AB) are actually unstable in the sense that they may produce a truly unpredictable result. The other 5 opcodes actually produce predictable results – but the conditions under which they do that and the produced results are a bit unexpected.

Mnemonic Addressing Modes Flags Operation Description
No arg #$nn $nnnn $nnnn,X $nnnn,Y $nn $nn,X $nn,Y ($nn,X) ($nn),Y N V - B D I Z C
ANC (ANC2) 0B, 2B N - - - - - Z C A ∧ M → A, NF → CF "AND" Memory with Accumulator then Move Negative Flag to Carry Flag
ARR 6B N V - - - - Z C (A ∧ M) / 2 → A "AND" Accumulator then Rotate Right
ASR (ALR) 4B 0 - - - - - Z C (A ∧ M) / 2 → A "AND" then Logical Shift Right
DCP (DCM) CF DF DB C7 D7 C3 D3 N - - - - - Z C M - 1 → M, A - M Decrement Memory By One then Compare with Accumulator
ISC (ISB, INS) EF FF FB E7 F7 E3 F3 N V - - - - Z C M + 1 → M, A - M → A Increment Memory By One then SBC then Subtract Memory from Accumulator with Borrow
JAM (KIL, HLT) 02, 12, 22,

32, 42, 52,

62, 72, 92,

B2, D2, F2

- - - - - - - - Stop execution Halt the CPU
LAS (LAR) BB N - - - - - Z - M ∧ S → A, X, S "AND" Memory with Stack Pointer
LAX (LXA) AB AF BF A7 B7 A3 B3 N - - - - - Z - M → A, X Load Accumulator and Index Register X From Memory
NOP (DOP, TOP) 1A, 3A, 5A,

7A, DA, FA

80, 82, 89,

C2, E2

0C 1C, 3C, 5C,

7C, DC, FC

04, 44, 64 14, 34, 54,

74, D4, F4

- - - - - - - - No operation No Operation
RLA 2F 3F 3B 27 37 23 33 N - - - - - Z C CF ← /M7...M0/ ← CF, A ∧ M → A Rotate Left then "AND" with Accumulator
RRA 6F 7F 7B 67 77 63 73 N V - - - - Z C CF → /M7...M0/ → CF, A + M + CF → A Rotate Right and Add Memory to Accumulator
SAX (AXS, AAX) 8F 87 97 83 - - - - - - - - A ∧ X → M Store Accumulator "AND" Index Register X in Memory
SBC (USBC) EB N V - - - - Z C A - M - ~CF → A Subtract Memory from Accumulator with Borrow
SBX (AXS, SAX) CB N - - - - - Z C (A ∧ X) - M → X Subtract Memory from Accumulator "AND" Index Register X
SHA (AHX, AXA) 9F 93 - - - - - - - - A ∧ X ∧ V → M Store Accumulator "AND" Index Register X "AND" Value
SHS (TAS, XAS) 9B - - - - - - - - A ∧ X → S, S ∧ (H + 1) → M Transfer Accumulator "AND" Index Register X to Stack Pointer then Store Stack Pointer "AND" Hi-Byte In Memory
SHX (SXA, XAS) 9E - - - - - - - - X ∧ (H + 1) → M Store Index Register X "AND" Value
SHY (SYA, SAY) 9C - - - - - - - - Y ∧ (H + 1) → M Store Index Register Y "AND" Value
SLO (ASO) 0F 1F 1B 07 17 03 13 N - - - - - Z C M * 2 → M, A ∨ M → A Arithmetic Shift Left then "OR" Memory with Accumulator
SRE (LSE) 4F 5F 5B 47 57 43 53 N - - - - - Z C M / 2 → M, A ⊻ M → A Logical Shift Right then "Exclusive OR" Memory with Accumulator
XAA (ANE) 8B N - - - - - Z - (A ∨ V) ∧ X ∧ M → A Non-deterministic Operation of Accumulator, Index Register X, Memory and Bus Contents


Opcode matrix

Addressing modes: A - accumulator, # - immediate, zpg - zero page, abs - absolute, ind - indirect, rel - relative. Uncolored cells are illegal opcodes.
High nibble Low nibble
0 1 2 3 4 5 6 7 8 9 A B C D E F
0 BRK ORA (ind,X) JAM SLO (ind,X) NOP zpg ORA zpg ASL zpg SLO zpg PHP ORA # ASL A ANC # NOP abs ORA abs ASL abs SLO abs
1 BPL rel ORA (ind),Y JAM SLO (ind),Y NOP zpg,X ORA zpg,X ASL zpg,X SLO zpg,X CLC ORA abs,Y NOP SLO abs,Y NOP abs,X ORA abs,X ASL abs,X SLO abs,X
2 JSR abs AND (ind,X) JAM RLA (ind,X) BIT zpg AND zpg ROL zpg RLA zpg PLP AND # ROL A ANC # BIT abs AND abs ROL abs RLA abs
3 BMI rel AND (ind),Y JAM RLA (ind),Y NOP zpg,X AND zpg,X ROL zpg,X RLA zpg,X SEC AND abs,Y NOP RLA abs,Y NOP abs,X AND abs,X ROL abs,X RLA abs,X
4 RTI EOR (ind,X) JAM SRE (ind,X) NOP zpg EOR zpg LSR zpg SRE zpg PHA EOR # LSR A ALR # JMP abs EOR abs LSR abs SRE abs
5 BVC rel EOR (ind),Y JAM SRE (ind),Y NOP zpg,X EOR zpg,X LSR zpg,X SRE zpg,X CLI EOR abs,Y NOP SRE abs,Y NOP abs,X EOR abs,X LSR abs,X SRE abs,X
6 RTS ADC (ind,X) JAM RRA (ind,X) NOP zpg ADC zpg ROR zpg RRA zpg PLA ADC # ROR A ARR # JMP (ind) ADC abs ROR abs RRA abs
7 BVS rel ADC (ind),Y JAM RRA (ind),Y NOP zpg,X ADC zpg,X ROR zpg,X RRA zpg,X SEI ADC abs,Y NOP RRA abs,Y NOP abs,X ADC abs,X ROR abs,X RRA abs,X
8 NOP # STA (ind,X) NOP # SAX (ind,X) STY zpg STA zpg STX zpg SAX zpg DEY NOP # TXA ANE # STY abs STA abs STX abs SAX abs
9 BCC rel STA (ind),Y JAM SHA (ind),Y STY zpg,X STA zpg,X STX zpg,Y SAX zpg,Y TYA STA abs,Y TXS TAS abs,Y SHY abs,X STA abs,X SHX abs,Y SHA abs,Y
A LDY # LDA (ind,X) LDX # LAX (ind,X) LDY zpg LDA zpg LDX zpg LAX zpg TAY LDA # TAX LXA # LDY abs LDA abs LDX abs LAX abs
B BCS rel LDA (ind),Y JAM LAX (ind),Y LDY zpg,X LDA zpg,X LDX zpg,Y LAX zpg,Y CLV LDA abs,Y TSX LAS abs,Y LDY abs,X LDA abs,X LDX abs,Y LAX abs,Y
C CPY # CMP (ind,X) NOP # DCP (ind,X) CPY zpg CMP zpg DEC zpg DCP zpg INY CMP # DEX AXS # CPY abs CMP abs DEC abs DCP abs
D BNE rel CMP (ind),Y JAM DCP (ind),Y NOP zpg,X CMP zpg,X DEC zpg,X DCP zpg,X CLD CMP abs,Y NOP DCP abs,Y NOP abs,X CMP abs,X DEC abs,X DCP abs,X
E CPX # SBC (ind,X) NOP # ISC (ind,X) CPX zpg SBC zpg INC zpg ISC zpg INX SBC # NOP SBC # CPX abs SBC abs INC abs ISC abs
F BEQ rel SBC (ind),Y JAM ISC (ind),Y NOP zpg,X SBC zpg,X INC zpg,X ISC zpg,X SED SBC abs,Y NOP ISC abs,Y NOP abs,X SBC abs,X INC abs,X ISC abs,X


Block Diagram

Mcs6502-block-diagram.svg


Links