6502 / 65C12 CPU
The BBC family uses three CPU variants. Knowing which you target matters because instructions, cycle counts, and BRK semantics differ.
| Machine | CPU | Clock | Cycle time | Notes |
|---|---|---|---|---|
| Model B, B+, Electron | NMOS 6502 (“6502A”) | 2 MHz | 0.5 µs | Original NMOS core. JMP (ind) page-boundary bug present. |
| Master 128, Master Compact | 65C12 | 2 MHz | 0.5 µs | CMOS, extra opcodes, fixed JMP (ind), +1c for decimal-mode ADC/SBC. |
| 6502 2nd processor | NMOS 6502 | 3 MHz | 0.33 µs | Via Tube. |
| Master Turbo | Rockwell R65C02 | 4 MHz | 0.25 µs | Adds BBR/BBS/RMB/SMB on top of 65C12. |
Cycle times are NAUG §5.0 p37.
Registers
- A — 8-bit accumulator.
- X, Y — 8-bit index registers.
- SP — 8-bit stack pointer. Stack lives in page 1 (
&0100-&01FF); SP holds the low byte of the next free location. - PC — 16-bit program counter.
- P — status register (see below).
Status flags (P)
| Bit | Name | Meaning |
|---|---|---|
| 0 | C | Carry — set on add overflow, cleared on subtract borrow; shift/rotate bit 9 |
| 1 | Z | Zero — result was 0 |
| 2 | I | Interrupt disable — set: IRQs masked. Set automatically on IRQ/BRK entry. |
| 3 | D | Decimal — ADC/SBC operate in BCD |
| 4 | B | Break — set in the P value pushed by BRK; not a real flag |
| 5 | — | Unused (reads as 1 on stack) |
| 6 | V | Overflow — signed-arithmetic overflow |
| 7 | N | Negative — bit 7 of result |
CPU variant differences
65C12 vs NMOS 6502
The 65C12 (Master series) adds and fixes:
- New opcodes:
BRA,STZ/CLR,DEC A/INC A(aliasDEA/INA),PHX/PHY/PLX/PLY,TRB,TSB. - New addressing modes:
(zp indirect)(no X/Y) for ADC/AND/CMP/EOR/LDA/ORA/SBC/STA;JMP (abs,X); immediateBIT;zp,Xandabs,Xfor BIT. - JMP (ind) page-boundary bug fixed — costs +1c (6c vs 5c on NMOS). NMOS bug: when the indirect operand low byte is
&FF(e.g.JMP (&19FF)), the high byte of the target is fetched from the same page (&1900), not the next page (&1A00). 65C12 fetches from the correct address. - CLD set automatically on entry to BRK/IRQ — guarantees handlers run in binary mode.
- +1c penalty for decimal-mode
ADC/SBC— opposite trade to NMOS where decimal mode is the same cost. - RMW
abs,X(ASL/LSR/ROL/ROR) is 6c (+1 page) rather than always 7c on NMOS.
R65C02 vs 65C12
Adds Rockwell-only opcodes: BBR0..7, BBS0..7, RMB0..7, SMB0..7, plus WAI and STP. The BBC BASIC assembler does not recognise these — hand-assemble with EQUB. Only present on Master Turbo and 6502 second processor.
Detecting NMOS vs CMOS at runtime
There is no clean MOS API for this. The idiomatic test (from Acorn’s Exmon II ROM) exploits the fact that PHX (&DA) and PLX (&FA) are CMOS-only — on NMOS those bytes are treated as NOPs and have no effect on X:
LDX #&FF ; X = &FF
EQUB &DA ; PHX on CMOS / NOP on NMOS
INX ; X = &00 (wraps from &FF)
EQUB &FA ; PLX on CMOS / NOP on NMOS
; result: X = &FF on CMOS (FF was pushed, X wrapped to 00, FF was pulled back)
; X = &00 on NMOS (both EQUBs no-op'd, only the INX took effect)Do not use OSBYTE &A4 for this — despite its short description as “check processor type” in the Master ARM OSBYTE table, it’s actually a paged-ROM image validity check that raises BRK on failure and returns undefined X/Y. See paged-roms for its real purpose, and detection for the broader model-detection picture.
For distinguishing 65C12 from R65C02 (i.e. detecting the Rockwell BBR/BBS/RMB/SMB opcodes), no clean stock-MOS idiom exists. The closest is to install a temporary BRKV handler that catches the BRK that the 65C12 raises on encountering an undocumented opcode, then try executing e.g. SMB0 zp. On R65C02 it executes; on 65C12 it traps.
Stack
Hard-wired to page 1. SP wraps within page 1 on overflow (no overflow trap). PHA/PHP/JSR/BRK push; PLA/PLP/RTS/RTI pull.
Reset / interrupt vectors
| Vector | Address | Pushed on stack | Notes |
|---|---|---|---|
| NMI | &FFFA/&FFFB | PC then P | edge-triggered, not maskable |
| RESET | &FFFC/&FFFD | nothing | clears nothing useful; firmware sets D=0, I=1 |
| IRQ/BRK | &FFFE/&FFFF | PC then P | shared vector; B flag in pushed P distinguishes |
Distinguishing IRQ from BRK in the handler: pull P from &0101,S (the pushed copy) and test bit 4 (B). On NMOS, also be aware that D may still be set on entry — clear it explicitly in the handler. On 65C12, D is auto-cleared.
Decimal flag (D) — discipline
Setting D=1 (via SED) enables BCD for ADC and SBC. Always CLD before calling MOS — the OS doesn’t clear D itself, and a stray BCD operation in an OS routine corrupts state silently.
- NMOS BRK / IRQ: D not cleared on entry. Handler must
CLDif any ADC/SBC is involved. - 65C12 BRK / IRQ: D auto-cleared on entry.
- 65C12 cost:
ADC/SBCin decimal mode take +1c (chip correctly updates N/V/Z flags; NMOS leaves them indeterminate after BCD).
See 6502-isa for the per-mnemonic cycle/opcode reference. See 6502-addressing-modes for mode mechanics. See interrupts for the IRQ chain and BRK/IRQ flag behaviour.
This wiki is curated by Claude following the LLM-Wiki methodology — a human curates source documents, the LLM compiles structured cross-linked markdown. Content may contain errors, omissions, or stale claims. For authoritative information refer to the original source documents in the bbc-documents GitHub archive.