You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Route reads/writes to mapped devices by address region
addressing
Decode addressing mode from opcode byte
opcodes
Decode opcode byte into instruction enum, categorize instruction type
cpu
Orchestrate fetch-decode-execute, resolve effective addresses, execute instructions, hold processor/register state
Memory interface
Behavioral Specifications
Function
Behavior
memory_read
Returns byte at address
memory_write
Stores byte at address
memory_reset
Fills memory with 0x00
memory_load
Copies data into memory starting at address
Bus Module
The bus sits between the CPU and devices, routing reads and writes by address region. Devices are mapped to non-overlapping address ranges; if regions overlap, the last-mapped region wins. Unmapped reads return $FF; unmapped writes are silently ignored.
Behavioral Specifications
Function
Behavior
bus_create()
Allocates bus with empty region table
bus_destroy(Bus* bus)
Destroys all mapped devices (calls each region's destroy callback), then frees the bus
Registers a device for the address range [start, end]
bus_read(Bus* bus, uint16_t addr)
Returns byte from the device mapped at addr, or $FF if unmapped
bus_write(Bus* bus, uint16_t addr, uint8_t val)
Writes byte to the device mapped at addr; no-op if unmapped
bus_load(Bus* bus, uint16_t addr, data, size)
Bulk-writes size bytes into bus starting at addr
bus_map_memory(Bus* bus, Memory* mem)
Convenience: maps a Memory device across the full $0000–$FFFF range
CPU Module
The CPU module manages processor state and implements the fetch-decode-execute cycle. It depends on the bus for all read/write operations, enabling testability via dependency injection.
Registers
Register
Size
Description
A
8-bit
Accumulator
X
8-bit
Index X - Loop counter, array indexing
Y
8-bit
Index Y - Loop counter, array indexing
SP
8-bit
Stack Pointer - Points within $0100-$01FF
PC
16-bit
Program Counter
P
8-bit
Status Register
Status Flags
7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
| N | V | - | B | D | I | Z | C |
+---+---+---+---+---+---+---+---+
Bit
Flag
Name
Set When
7
N
Negative
Result bit 7 is set
6
V
Overflow
Signed arithmetic overflow
5
-
Unused
Always 1
4
B
Break
BRK instruction executed
3
D
Decimal
BCD arithmetic mode
2
I
Interrupt Disable
IRQ disabled
1
Z
Zero
Result is zero
0
C
Carry
Unsigned overflow/borrow
Interrupts
Interrupt Vectors
Vector
Address
Trigger
NMI
$FFFA–$FFFB
Falling edge on NMI line
RESET
$FFFC–$FFFD
Power-on / cpu_reset
IRQ/BRK
$FFFE–$FFFF
IRQ line low (maskable) or BRK instruction
When an interrupt is serviced the CPU pushes PC (high then low) and the status register onto the stack, sets the I flag, then loads PC from the appropriate vector. The B flag is set in the pushed status for BRK, clear for hardware interrupts. The whole sequence takes 7 cycles.
NMI is edge-triggered and has the highest priority — it cannot be masked. IRQ is level-triggered and is ignored while the I flag is set.
Behavioral Specifications
Function
Behavior
cpu_create(Bus* bus)
Allocates CPU struct, stores reference to bus
cpu_destroy(CPU* cpu)
Frees CPU struct and destroys the bus (and all mapped devices)
cpu_reset(CPU* cpu)
Resets registers to power-on state, loads PC from RESET vector ($FFFC)
cpu_step(CPU* cpu)
Execute one instruction and return cycle count for that instruction
cpu_nmi(CPU* cpu)
Assert NMI line (edge-triggered, serviced on next step)
cpu_nmi_release(CPU* cpu)
Release NMI line
cpu_irq(CPU* cpu)
Assert IRQ line (level-triggered, masked by I flag)