# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Commands
```bash
cargo build # Build the library
cargo test # Run all tests
cargo test <name> # Run a specific test
cargo clippy # Lint
cargo doc --open # Generate and open documentation
```
## Processor Documentation
Processor reference documentation is in the repo root — consult these when implementing instructions:
- `table_5_4_opcode_matrix.md` — opcode matrix with cycle counts, byte counts, and addressing modes
- `table_5_5_opcodes.md` — operation codes, flag effects, and operation descriptions
- `instruction_operation_addr_modes.md` — per-instruction bus cycle pseudocode (Table 5-7) !IMPORTANT!
## Architecture
This is a cycle-accurate, bus-accurate emulator library for the WDC W65C816S processor (16-bit 6502 derivative). It is `no_std` compatible with zero external dependencies.
### Core Design
**`src/lib.rs`** — CPU state machine and public API:
- `CPU` struct: holds all registers (A/B/C, X, Y, PC, S, D, PBR, DBR) and internal instruction state
- `Flags` struct: processor status flags (C, Z, I, D, X, M, V, N + emulation)
- `Signals` struct: CPU output signals (E, MLB, M/X, RDY)
- `AddressType` enum: classifies memory accesses (Invalid, Data, Program, Opcode, Vector)
- `AddressingMode` enum: 21 addressing mode variants
**`src/instructions.rs`** — Instruction implementations:
- 256-entry instruction dispatch table (one per opcode)
- Each instruction is a state machine executed one bus cycle at a time
- Missing instructions use `unimplemented!()` — expect panics if you hit them
**`src/util.rs`** — Internal helpers:
- `ByteRef<'a>`: reference to low or high byte of a 16-bit word
- `TaggedByte`, `Byte`: discriminants for byte-level access
**`src/tests.rs`** — Test suite with a `Sys` struct implementing `System` with 16MB RAM.
### The System Trait
Consumers must implement `System` to connect the CPU to memory and signals:
```rust
pub trait System {
fn read(&mut self, addr: u32, addr_type: AddressType, signals: &Signals) -> u8;
fn write(&mut self, addr: u32, data: u8, addr_type: AddressType, signals: &Signals);
fn irq(&mut self) -> bool { false }
fn nmi(&mut self) -> bool { false }
fn res(&mut self) -> bool { false }
fn rdy(&mut self) -> bool { true }
fn abort(&mut self) -> bool { false }
}
```
### Typical Usage
```rust
let mut cpu = CPU::new();
let mut sys = MySystem::new();
loop {
cpu.cycle(&mut sys); // one bus cycle
}
```
## WIP Status
Less than 60 instructions are missing; many addressing modes are also incomplete. See `src/instructions.rs` for the dispatch table to check what's implemented. Hitting an unimplemented instruction causes a panic.
## Tracking Progress
`UNIMPLEMENTED.md` contains a checkbox for every unimplemented opcode. When implementing an instruction, remove its entry from that file.