This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
make # build → bin/mos6502
make clean # remove build/ and bin/No test framework is wired up yet. Validation is planned via the Klaus Dormann functional test suite (see docs/design.md): load 6502_functional_test.bin at $0000, set PC to $0400, and confirm the emulator reaches the success loop rather than a trap.
This is a prototype MOS 6502 CPU emulator written in C. The design document at docs/design.md is the authoritative reference — read it before making architectural changes.
| Module | Header | Source | Responsibility |
|---|---|---|---|
| CPU | include/cpu.h | src/cpu.c | CPU6502 struct (A, X, Y, SP, P, PC), reset, state dump |
| Memory | include/memory.h | src/memory.c | Flat 64 KiB uint8_t array; mem_read/mem_write/mem_reset |
| Addressing | include/addressing.h | src/addressing.c | addr_ctx_t — callback-based bus abstraction (stub) |
| Opcode | include/opcode.h | src/opcode.c | Instruction decode/dispatch (stub) |
| Entry point | — | src/main.c | Instantiates CPU6502 + Memory, calls reset, prints state |
- Memory access is always through
mem_read/mem_write, never direct array indexing from CPU logic. This keeps the door open for memory-mapped I/O and mirroring without touching the CPU. addr_ctx_tuses function-pointer callbacks (read8,read16) so the addressing layer is decoupled from the concreteMemorystruct. Passuserdatato thread CPU + Memory through the callbacks.- Opcode dispatch will use a giant
switchstatement (256 cases). The design doc explicitly rejects function-pointer tables and computed gotos in favour of compiler-optimised switch. PCincpu.his currently typeduint8_t— this is a known bug; it must beuint16_tto address the full 64 KiB space.- Status flags are individual bit masks (
FLAG_CthroughFLAG_N) applied tocpu->P. - Reset vector: after
cpu_reset, PC must be loaded from$FFFC/$FFFD;cpu.ccurrently leaves this for the caller. - Stack lives at
$0100–$01FF; SP is a page-relative offset, so the absolute address is0x0100 | cpu->SP. - Little-endian 16-bit reads: LSB at lower address.
- Addressing mode resolvers (
addressing.cis empty) - Opcode decode/execute loop (
opcode.cis empty) - Cycle counting
- Interrupt handling (NMI / IRQ / RESET vectors)
- BCD mode ADC/SBC