feat(cartridge): add bounded terminal ROM loading
Load read-only raw ROM files with bounded size checks and original BIOS boot. Require a machine-step budget and report CPU state, STOP, and explicit diagnostics without opening a window. Keep file access in the desktop crate. Cover argument parsing, Darwin paths, file boundaries, ARM/Thumb execution, DMA/IRQ budgets, HALT/STOP, and error reports. Document limits and usage. Verified on native Darwin arm64: debug/release workspace tests, core-only tests, Clippy, rustdoc, all ten window smoke tests, and a release raw-ROM run.
This commit is contained in:
parent
c836944c2e
commit
c256bf8ccd
13 changed files with 837 additions and 13 deletions
|
|
@ -78,7 +78,10 @@ The repository is a Cargo workspace with three crates:
|
|||
| `crates/desktop/src/desktop/effects.rs` | Window/effects demo and independent smoke-test pixel checks |
|
||||
| `crates/desktop/src/desktop/mosaic.rs` | Mosaic window and 128-frame independent pixel checks |
|
||||
| `crates/desktop/src/desktop/raster.rs` | Raster window and scanline color-band smoke test |
|
||||
| `crates/desktop/src/main.rs` | Command-line modes and fixed-length CPU demo |
|
||||
| `crates/desktop/src/main.rs` | Command-line modes, error exit status, and fixed-length CPU demo |
|
||||
| `crates/desktop/src/cartridge.rs` | Read-only ROM files, argument checks, bounded machine execution, and terminal reports |
|
||||
| `crates/desktop/src/cartridge/tests.rs` | ROM options, bounded readers, instruction/DMA/IRQ budgets, HALT/STOP, and diagnostic reports |
|
||||
| `crates/desktop/tests/rom_cli.rs` | Process-level loading and exit-status checks using temporary original programs |
|
||||
| `crates/gba-core/tests/core.rs` | CPU integration tests and the complete demo |
|
||||
| `crates/gba-core/tests/memory.rs` | Memory widths, alignment, errors, and mirrors |
|
||||
| `crates/gba-core/tests/exceptions.rs` | Exception demo, BIOS mapping, and reset-vector execution |
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ Verified locally on macOS 15.7.3:
|
|||
- All ten native window smoke tests pass. The mosaic test submits 128 frames; the other nine submit 60 frames each.
|
||||
- The eight CPU-driven smoke tests check CPU state, every output pixel, and presentation at VBlank entry.
|
||||
- The terminal-only CPU and timer IRQ demos run successfully.
|
||||
- The bounded ROM runner loads original raw programs and reports state without opening a window.
|
||||
|
||||
These results cover the CPU core, memory, Mode 0–5 snapshots and row capture, input mapping, and desktop windows.
|
||||
They do not verify a complete GBA display controller or audio.
|
||||
|
|
|
|||
|
|
@ -26,7 +26,8 @@ Minimal boot initializes:
|
|||
|
||||
It then enters `0x08000000` in ARM System mode with IRQ/FIQ masks clear.
|
||||
It does not reproduce Nintendo's logo, cartridge-header checks, RAM clearing, boot delays, or full hardware initialization.
|
||||
The executable still does not load game files.
|
||||
The executable can load raw ROM files for [bounded terminal diagnostics](cartridge.md) using this boot sequence.
|
||||
This does not establish game compatibility or complete BIOS behavior.
|
||||
|
||||
Supported software interrupt services:
|
||||
|
||||
|
|
|
|||
64
docs/hardware/cartridge.md
Normal file
64
docs/hardware/cartridge.md
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
# Cartridge files and terminal execution
|
||||
|
||||
The desktop executable can load raw ROM bytes and run a bounded diagnostic session.
|
||||
This supports original test programs. It does not establish commercial-game compatibility.
|
||||
|
||||
```sh
|
||||
direnv exec . cargo run --locked --release -- --rom path/to/original.gba --steps 100000
|
||||
```
|
||||
|
||||
Both options are required. Their order does not matter.
|
||||
`COUNT` must contain decimal digits and be between 1 and 100,000,000 inclusive.
|
||||
Do not combine ROM mode with demo or help options. Bare file paths are not accepted.
|
||||
Quote paths that contain spaces. File extensions do not affect loading.
|
||||
|
||||
## Loading and boot
|
||||
|
||||
`crates/desktop/src/cartridge.rs` owns file access, argument checks, execution limits, and reports.
|
||||
The core remains independent of the filesystem and window library.
|
||||
The loader opens a regular file read-only and accepts 4 bytes through 32 MiB inclusive.
|
||||
It checks metadata before and after opening, then independently bounds the read to the limit plus one byte.
|
||||
This bounds file content reads even if the file grows. It is not a filesystem race protection mechanism.
|
||||
Directories and other non-regular files are rejected. Symlinks to regular files are accepted.
|
||||
Paths retain their operating-system representation and appear quoted in diagnostics.
|
||||
The host filesystem can reject filenames, including invalid UTF-8 on Darwin.
|
||||
|
||||
Bytes are not padded, patched, or written back.
|
||||
The loader does not validate a cartridge header, logo, or checksum.
|
||||
It does not decode archives or ELF executables. Supply a raw binary with an ARM instruction at offset zero.
|
||||
Headerless original programs are accepted.
|
||||
Reads past supplied cartridge bytes remain explicit memory errors, not open-bus values.
|
||||
All three Game Pak ROM windows use the same supplied bytes and existing wait-state rules.
|
||||
Cartridge writes, save devices, and cartridge peripherals remain unsupported.
|
||||
|
||||
The runner calls `bios::boot` with the loaded bytes.
|
||||
The [original BIOS replacement](bios.md) executes its minimal boot before entering `0x08000000` in ARM System mode.
|
||||
There is no command-line option for external BIOS files.
|
||||
Unsupported services remain diagnostics. In particular, RegisterRamReset sound/serial flags, including `r0=0xff`, still fail.
|
||||
|
||||
## Execution limits and results
|
||||
|
||||
The budget counts successful machine steps, including BIOS boot instructions.
|
||||
Each CPU instruction, IRQ entry, DMA unit, or HALT idle batch consumes one step.
|
||||
The budget is not an instruction-only, cycle, frame, or wall-clock limit.
|
||||
HALT continues advancing devices within the budget.
|
||||
STOP returns immediately because terminal mode has no input source to wake the machine.
|
||||
STOP on the final allowed step is reported as STOP, not as budget exhaustion.
|
||||
A failed CPU or DMA step consumes no budget and retains the machine state from earlier successful steps.
|
||||
|
||||
The report includes:
|
||||
|
||||
- Quoted path, byte count, and requested step limit.
|
||||
- Stop reason and successful-step counters by kind.
|
||||
- Nominal emulated cycles, PC, CPSR, CPU mode, and ARM/Thumb state.
|
||||
- HALT/STOP flags and all active registers r0–r15.
|
||||
|
||||
Exit status zero means the step limit was reached or STOP was entered.
|
||||
It does not mean the program completed or passed a hardware test.
|
||||
Invalid arguments, loading failures, output failures, and emulation diagnostics produce a nonzero exit status.
|
||||
For emulation diagnostics, stdout contains the final machine state and stderr contains the core error.
|
||||
|
||||
ROM mode has no window, keyboard input, audio, saves, per-step trace, or real-time pacing.
|
||||
It does not enable frame capture or validate rendered output.
|
||||
Use the existing demos for window and input tests.
|
||||
Only load files that you may lawfully use. Do not commit game ROMs or firmware.
|
||||
|
|
@ -62,6 +62,7 @@ Update this file when a feature lands or a limit is removed.
|
|||
- `SWP`/`SWPB`, including unaligned word rotation and register aliases.
|
||||
- 256 KiB external work RAM and 32 KiB internal work RAM, including mirrors.
|
||||
- Read-only cartridge bytes in the three GBA cartridge windows.
|
||||
- Raw ROM-file loading for bounded terminal diagnostics, with original BIOS boot and final CPU/step reports.
|
||||
- Little-endian byte, halfword, and word reads/writes.
|
||||
- ARM7TDMI word-load rotation, aligned stores, and odd-address halfword-load behavior.
|
||||
- Explicit errors for unsupported instructions when their condition passes, and for unsupported memory accesses.
|
||||
|
|
@ -102,7 +103,9 @@ Keypad IRQs use a documented polling model; hardware retrigger edges and asynchr
|
|||
STOP implements keypad wake only. Serial/Game Pak wake sources, oscillator restart delays, and exact wake timing remain unimplemented or unverified.
|
||||
The presentation framebuffer is separate from emulated video RAM.
|
||||
All named graphics demos connect desktop input and rendering to the emulated CPU. The default display test remains host-generated.
|
||||
The executable does not accept ROM files yet.
|
||||
ROM files can run in bounded terminal mode with the original BIOS replacement.
|
||||
This mode has no window, input, audio, saves, or external BIOS option. It does not establish commercial-game compatibility.
|
||||
See [cartridge loading](hardware/cartridge.md) for file limits, step budgets, and exit status.
|
||||
|
||||
Unmapped reads return errors instead of hardware open-bus values.
|
||||
Reads beyond the supplied cartridge bytes also return errors.
|
||||
|
|
@ -117,7 +120,7 @@ Writes to cartridge addresses return errors instead of modeling cartridge hardwa
|
|||
3. Validate keypad retrigger behavior with hardware tests and add remaining device registers; extend BIOS reset coverage as sound/serial support becomes available.
|
||||
Validate STOP entry/wake edges and add external wake sources and remaining DMA device modes.
|
||||
4. Replace nominal sprite work limits with verified individual fetch timing; add background fetch timing and per-pixel composition.
|
||||
5. Expand graphics, audio, cartridge loading, and saves before testing Emerald compatibility.
|
||||
5. Connect ROM execution to the window and input; expand audio, cartridge hardware, and saves before testing Emerald compatibility.
|
||||
|
||||
Keep the emulator core independent of window and audio libraries.
|
||||
Treat Nintendo DS support as a separate project phase.
|
||||
|
|
|
|||
|
|
@ -37,6 +37,13 @@ The core's integration tests use `gba-demos` as a development dependency.
|
|||
On Apple Silicon, `file` must report a Mach-O `arm64` executable.
|
||||
Do not set a Linux cross-compilation target for this validation.
|
||||
|
||||
ROM-runner tests use temporary files containing original instructions, without Nintendo assets or a desktop session.
|
||||
They check file-size boundaries, bounded reads, short reads, I/O errors, paths, symlinks, and read-only loading.
|
||||
CLI tests cover option order, missing/conflicting options, invalid step limits, process exit status, and reports.
|
||||
Execution tests cover original ARM/Thumb code, BIOS boot, DMA/IRQ step accounting, HALT budgets, and prompt STOP results.
|
||||
Unsupported instructions, truncated code, and DMA errors retain the failure state for inspection.
|
||||
See [cartridge execution](hardware/cartridge.md) for usage and limitations.
|
||||
|
||||
Angle-service tests compare results with wide-integer polynomial and signed-sector references, plus floating-point accuracy checks in supported ranges.
|
||||
They cover a dense ArcTan unit-interval grid, sampled full-domain and seeded inputs, axes, quadrant boundaries, signed extremes, and scale invariance.
|
||||
Other tests verify all caller flag combinations, User/System masks, non-result registers, stack bounds, repeated calls, diagnostics, and DMA/IRQ progress.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue