mirror of
https://github.com/andwati/mos-6502.git
synced 2026-10-18 03:02:51 +00:00
completed game
This commit is contained in:
@@ -1,45 +1,28 @@
|
||||
# CLAUDE.md
|
||||
# Contributor notes
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Build Commands
|
||||
## Commands
|
||||
|
||||
```sh
|
||||
make # build → bin/mos6502
|
||||
make clean # remove build/ and bin/
|
||||
make # build bin/mos6502
|
||||
make test # core checks
|
||||
make debug # strict warning build and checks
|
||||
make sanitize # ASan/UBSan build and checks
|
||||
make snake # assemble and run the SDL game (requires SDL2 + cc65)
|
||||
```
|
||||
|
||||
No test framework is wired up yet. Validation is planned via the **Klaus Dormann functional test suite** (see [docs/design.md](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.
|
||||
|
||||
## Architecture
|
||||
|
||||
This is a prototype MOS 6502 CPU emulator written in C. The design document at [docs/design.md](docs/design.md) is the authoritative reference — read it before making architectural changes.
|
||||
- `CPU6502` contains CPU-visible and interrupt-line state.
|
||||
- `Bus6502` owns RAM and Easy6502 MMIO; CPU code only uses bus accessors.
|
||||
- `cpu_step` executes one instruction or interrupt and returns status/opcode/cycles.
|
||||
- `src/opcode.c` has a 256-entry descriptor table for all 151 official encodings.
|
||||
- `src/frontend.c` is an optional SDL2 frontend with a dependency-free stub.
|
||||
- `tests/run_tests.c` is the in-tree test harness; `tests/run_suite.c` runs external ROMs.
|
||||
|
||||
### Module layout
|
||||
The target is the NMOS 6502. Preserve decimal-mode flag behavior, zero-page
|
||||
wrapping, the indirect-JMP page-wrap bug, stack push order, and page-cross cycle
|
||||
rules. Do not silently accept undocumented opcodes.
|
||||
|
||||
| Module | Header | Source | Responsibility |
|
||||
|---|---|---|---|
|
||||
| CPU | [include/cpu.h](include/cpu.h) | [src/cpu.c](src/cpu.c) | `CPU6502` struct (A, X, Y, SP, P, PC), reset, state dump |
|
||||
| Memory | [include/memory.h](include/memory.h) | [src/memory.c](src/memory.c) | Flat 64 KiB `uint8_t` array; `mem_read`/`mem_write`/`mem_reset` |
|
||||
| Addressing | [include/addressing.h](include/addressing.h) | [src/addressing.c](src/addressing.c) | `addr_ctx_t` — callback-based bus abstraction (stub) |
|
||||
| Opcode | [include/opcode.h](include/opcode.h) | [src/opcode.c](src/opcode.c) | Instruction decode/dispatch (stub) |
|
||||
| Entry point | — | [src/main.c](src/main.c) | Instantiates `CPU6502` + `Memory`, calls reset, prints state |
|
||||
|
||||
### Key design decisions (from the design doc)
|
||||
|
||||
- **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_t` uses function-pointer callbacks** (`read8`, `read16`) so the addressing layer is decoupled from the concrete `Memory` struct. Pass `userdata` to thread CPU + Memory through the callbacks.
|
||||
- **Opcode dispatch will use a giant `switch` statement** (256 cases). The design doc explicitly rejects function-pointer tables and computed gotos in favour of compiler-optimised switch.
|
||||
- **`PC` in `cpu.h` is currently typed `uint8_t`** — this is a known bug; it must be `uint16_t` to address the full 64 KiB space.
|
||||
- **Status flags** are individual bit masks (`FLAG_C` through `FLAG_N`) applied to `cpu->P`.
|
||||
- **Reset vector**: after `cpu_reset`, PC must be loaded from `$FFFC/$FFFD`; `cpu.c` currently leaves this for the caller.
|
||||
- **Stack** lives at `$0100–$01FF`; SP is a page-relative offset, so the absolute address is `0x0100 | cpu->SP`.
|
||||
- **Little-endian** 16-bit reads: LSB at lower address.
|
||||
|
||||
### Planned areas not yet implemented
|
||||
|
||||
- Addressing mode resolvers (`addressing.c` is empty)
|
||||
- Opcode decode/execute loop (`opcode.c` is empty)
|
||||
- Cycle counting
|
||||
- Interrupt handling (NMI / IRQ / RESET vectors)
|
||||
- BCD mode ADC/SBC
|
||||
The virtual machine exposes game state at `$00FB`, high/game score at `$00FC/$00FD`, random input
|
||||
at `$00FE`, keyboard input at `$00FF`, and a 32x32 framebuffer at
|
||||
`$0200-$05FF`.
|
||||
|
||||
Reference in New Issue
Block a user