feat(bios): implement SoftReset restart service
Execute SWI 0x00 through original ARM code. Read the restart flag before clearing 512 bytes of BIOS work RAM, reset System/SVC/IRQ stacks and specified registers, then branch to ROM or EWRAM in ARM System mode. Keep device state and clocks active, preserve unrelated CPU banks, and document the deterministic IRQ-masked restart status. Add eleven tests for every flag byte, ARM/Thumb and User/System callers, exact memory bounds, bank state, restart execution, DMA/timers, and unsupported exception callers. Validated on Darwin arm64: 705 default and 694 core-only tests in debug and release; formatting, Clippy, rustdoc, ten native window smoke tests, and CPU/timer demos pass.
This commit is contained in:
parent
f60db7e43b
commit
2dfab137a6
5 changed files with 468 additions and 12 deletions
64
README.md
64
README.md
|
|
@ -253,7 +253,7 @@ Verified locally on macOS 15.7.3:
|
|||
- Nix system: `aarch64-darwin`.
|
||||
- Rust host: `aarch64-apple-darwin`.
|
||||
- Release executable: native Mach-O `arm64`, without Rosetta.
|
||||
- All 694 tests pass in debug and release builds.
|
||||
- All 705 tests pass in debug and release builds.
|
||||
- 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.
|
||||
|
|
@ -358,7 +358,7 @@ nix develop -c cargo test
|
|||
- Game Pak wait-state control (`WAITCNT`) for all three ROM windows.
|
||||
- Sequential/non-sequential data accesses, branch refill costs, and variable multiply timing.
|
||||
- Optional caller-supplied 16 KiB BIOS mapping for vector code, without CPU BIOS read protection.
|
||||
- Optional original BIOS replacement: minimal boot, IRQ dispatch, interrupt waits, memory copy/fill, integer/fixed-point arithmetic, affine matrices, bit unpacking, LZ77/run-length/Huffman decompression, and differential filters.
|
||||
- Optional original BIOS replacement: minimal boot, SoftReset, IRQ dispatch, interrupt waits, memory copy/fill, integer/fixed-point arithmetic, affine matrices, bit unpacking, LZ77/run-length/Huffman decompression, and differential filters.
|
||||
- All 16 ARM data-processing operations, with immediate and shifted-register operands.
|
||||
- Logical operations: `AND`, `EOR`, `TST`, `TEQ`, `ORR`, `MOV`, `BIC`, and `MVN`.
|
||||
- Arithmetic operations: `SUB`, `RSB`, `ADD`, `ADC`, `SBC`, `RSC`, `CMP`, and `CMN`.
|
||||
|
|
@ -507,6 +507,7 @@ Supported software interrupt services:
|
|||
|
||||
| Number | Service | Behavior |
|
||||
| --- | --- | --- |
|
||||
| `0x00` | SoftReset | Clear BIOS work RAM and reset CPU registers/stacks; restart in ROM or RAM without returning |
|
||||
| `0x02` | Halt | Wait for `IE & IF`; preserve IME and caller registers |
|
||||
| `0x04` | IntrWait | `r0`: discard old selected flags when nonzero; `r1`: flags to wait for |
|
||||
| `0x05` | VBlankIntrWait | IntrWait with discard enabled and the VBlank flag selected |
|
||||
|
|
@ -531,7 +532,8 @@ Supported software interrupt services:
|
|||
|
||||
ARM code uses `SWI service_number << 16`; Thumb code uses the service number directly.
|
||||
Only User/System callers are supported. Calls from exception modes return a diagnostic rather than risking nested stack corruption.
|
||||
Services preserve CPSR and every caller register except the documented arithmetic outputs.
|
||||
Returning services preserve CPSR and every caller register except the documented arithmetic outputs.
|
||||
SoftReset instead initializes CPU registers and status as described below.
|
||||
This is deterministic behavior, not a claim about undocumented firmware outputs.
|
||||
Supervisor stack use is 28 bytes normally, including ArcTan. Division and ArcTan2 use 40 bytes.
|
||||
CpuFastSet, affine-matrix services, BitUnPack, all three decompression formats, and differential filters use 60 bytes.
|
||||
|
|
@ -560,6 +562,45 @@ Other invalid accesses use normal memory diagnostics. Earlier successful writes
|
|||
These copy services keep CPU IRQ delivery masked until return; device clocks and DMA continue throughout.
|
||||
BIOS bus protection, exact firmware timing, undocumented side effects, and nested service calls remain incomplete.
|
||||
|
||||
#### SoftReset
|
||||
|
||||
`SoftReset` (`SWI 0x00`) does not return to its caller.
|
||||
It reads the byte at `0x03007ffa` before clearing the containing RAM:
|
||||
zero selects cartridge ROM at `0x08000000`; any nonzero value selects work RAM at `0x02000000`.
|
||||
Surrounding bytes do not affect this choice. Both destinations start in ARM state, even for Thumb callers.
|
||||
|
||||
The service clears exactly `0x03007e00..0x03007fff`, including BIOS IRQ flags, the callback pointer, and the restart flag.
|
||||
It resets r0–r12 to zero and initializes these CPU banks:
|
||||
|
||||
| Mode | Stack pointer | Link register | Saved status |
|
||||
| --- | --- | --- | --- |
|
||||
| System/User | `0x03007f00` | Selected restart address | Not present |
|
||||
| Supervisor | `0x03007fe0` | Zero | Zero |
|
||||
| IRQ | `0x03007fa0` | Zero | Zero |
|
||||
|
||||
Other banked registers and saved status registers remain unchanged.
|
||||
The service enters System mode with CPSR `0x9f`: IRQ masked, FIQ unmasked, condition flags clear.
|
||||
This is the subset's deterministic status policy, not independently verified hardware behavior.
|
||||
It jumps through the System link register and does not execute the cold-boot sequence.
|
||||
|
||||
SoftReset does not reset I/O registers or devices.
|
||||
IME, IE, pending IF bits, POSTFLG, display configuration, and timer configuration remain in place.
|
||||
Device clocks and DMA continue, so counters and pending requests can change during the service.
|
||||
IRQ delivery stays masked throughout the service and after restart.
|
||||
Restart code must install an IRQ callback and configure interrupts before unmasking IRQ.
|
||||
|
||||
The common SWI entry still requires an initialized, writable Supervisor stack and saves a 28-byte frame.
|
||||
SoftReset abandons that frame. It uses no further stack storage and never restores the old caller state.
|
||||
With default stacks, the frame lies inside the cleared RAM.
|
||||
If the Supervisor stack is outside this region, its entry writes remain there after reset.
|
||||
The clearing loop performs ordinary word stores; stopping execution partway leaves a partially cleared region.
|
||||
Active DMA can still modify memory. Software must stop conflicting transfers before requesting a restart.
|
||||
|
||||
Lower internal RAM, external RAM, palette RAM, video RAM, and sprite attribute memory are not cleared by SoftReset.
|
||||
Use separate initialization code for those regions. `RegisterRamReset` is not implemented yet.
|
||||
Calls from exception modes retain the existing unsupported-service diagnostic.
|
||||
Exact firmware timing, bus-protection behavior, and undocumented side effects remain incomplete.
|
||||
|
||||
#### Integer arithmetic
|
||||
|
||||
Div truncates the signed quotient toward zero. The remainder has the numerator's sign, or is zero.
|
||||
|
|
@ -808,7 +849,7 @@ Unsupported SWIs, unsupported exception vectors, and null/misaligned IRQ callbac
|
|||
The CPU reports `CpuError::UnsupportedInstruction` with `bios::UNSUPPORTED_TRAP`, rather than silently treating a service as a no-op.
|
||||
Invalid arithmetic/decompression arguments use the same CPU error type with the distinct `bios::INVALID_ARGUMENT_TRAP` instruction.
|
||||
Prior boot/service steps remain committed on failure.
|
||||
BIOS reset services and STOP remain unimplemented.
|
||||
RegisterRamReset, HardReset, and STOP remain unimplemented.
|
||||
This subset is not sufficient for Pokémon Emerald compatibility.
|
||||
|
||||
### Timers, interrupt registers, and the machine clock
|
||||
|
|
@ -1559,6 +1600,7 @@ Important timing limits:
|
|||
| `src/timer_demo.rs` | Original timer-configuration program and IRQ handler |
|
||||
| `src/lib.rs` | Core modules and original demo bytes |
|
||||
| `src/bios.rs` | Original ARM BIOS image builder, minimal boot, IRQ dispatch, waits, and memory services |
|
||||
| `src/bios/reset.rs` | Emitted ARM SoftReset, BIOS work RAM clearing, bank initialization, and ROM/RAM restart |
|
||||
| `src/bios/arithmetic.rs` | Emitted ARM division and integer-square-root routines |
|
||||
| `src/bios/affine.rs` | Emitted ARM background/sprite matrix services, range checks, and generated sine table |
|
||||
| `src/bios/angles.rs` | Emitted ARM ArcTan polynomial, ArcTan2 ratio/quadrant handling, and input validation |
|
||||
|
|
@ -1619,6 +1661,7 @@ Important timing limits:
|
|||
| `tests/dma.rs` | DMA widths, latches, priority, triggers, IRQs, timing, errors, and CPU integration |
|
||||
| `tests/halt.rs` | HALT wake masks, idle timing, BIOS-only writes, DMA progress, and STOP diagnostics |
|
||||
| `tests/bios.rs` | ARM/Thumb service calls, copy/fill boundaries, wait races, callback contracts, and boot |
|
||||
| `tests/bios/reset.rs` | All restart flags, exact RAM boundaries, CPU banks, restart execution, device continuity, and IRQ masking |
|
||||
| `tests/bios/arithmetic.rs` | Arithmetic boundaries, wide-integer references, status restoration, and zero-division diagnostics |
|
||||
| `tests/bios/affine.rs` | Matrix/origin references, all angle phases, strides, live rendering, register preservation, and diagnostics |
|
||||
| `tests/bios/angles.rs` | Fixed-point references, axes/quadrants, rounding, caller flags, stack bounds, DMA, and diagnostics |
|
||||
|
|
@ -1694,12 +1737,12 @@ To test the core without building the window dependency:
|
|||
direnv exec . cargo test --locked --no-default-features
|
||||
```
|
||||
|
||||
This runs 683 core and integration tests; the eleven desktop and command-line tests are excluded.
|
||||
This runs 694 core and integration tests; the eleven desktop and command-line tests are excluded.
|
||||
|
||||
On Apple Silicon, `file` must report a Mach-O `arm64` executable.
|
||||
Do not set a Linux cross-compilation target for this validation.
|
||||
|
||||
The default suite has 694 tests.
|
||||
The default suite has 705 tests.
|
||||
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.
|
||||
|
|
@ -1774,6 +1817,10 @@ The CPU demo test checks sprite controls, OAM attributes, disabled unused object
|
|||
Tile tests cover both color depths, palette banks, flips, all map sizes, scrolling, transparency, priorities, and register masks.
|
||||
They check errors for unsupported features and out-of-range fetches without changing the output image.
|
||||
The CPU tile demo test verifies asset copies, every pixel, wrapping, opposite directions, reset, and VBlank synchronization.
|
||||
SoftReset tests check every restart flag byte from ARM and Thumb, exact RAM clearing, and preserved memory.
|
||||
They seed CPU banks and verify stack pointers, link registers, saved status, caller modes, and restart status.
|
||||
Other tests execute RAM restart code, call BIOS services again, and restart from code inside the erased region.
|
||||
Device tests check retained I/O state, advancing timers/DMA, pending IRQs, and instruction-by-instruction RAM clearing.
|
||||
BIOS affine tests check all 256 angle phases against independent trigonometric and wide-integer references.
|
||||
They cover signed scales, origin wraparound, rounding, ignored angle bits, strides, alignment, and partial failures.
|
||||
Live rendering tests apply generated matrices to background registers and sprite attribute memory.
|
||||
|
|
@ -1835,7 +1882,7 @@ These tests do not replace validation against GBA hardware or public hardware te
|
|||
|
||||
1. Validate CPU behavior with public ARM7TDMI test programs before claiming instruction compatibility.
|
||||
2. Refine nominal timing with a fetch pipeline, Game Pak prefetch, per-access device updates, and verified timer/IRQ delays.
|
||||
3. Expand BIOS services with reset functions; add STOP and remaining DMA device modes.
|
||||
3. Add RegisterRamReset with explicit limits for unimplemented sound/serial registers; add STOP 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.
|
||||
|
||||
|
|
@ -1846,11 +1893,12 @@ Hardware references used for the core:
|
|||
|
||||
- [GBATEK ARM instruction cycle times](https://problemkaputt.de/gbatek-arm-cpu-instruction-cycle-times.htm).
|
||||
- [GBATEK GBA system control and WAITCNT](https://problemkaputt.de/gbatek-gba-system-control.htm).
|
||||
- [GBATEK BIOS reset functions](https://problemkaputt.de/gbatek-bios-reset-functions.htm), for SoftReset RAM bounds, CPU banks, stack pointers, and restart selection.
|
||||
- [GBATEK BIOS halt functions](https://problemkaputt.de/gbatek-bios-halt-functions.htm), for wait contracts and STOP differences.
|
||||
- [GBATEK BIOS function calling conventions](https://problemkaputt.de/gbatek-bios-functions.htm).
|
||||
- [GBATEK BIOS memory-copy services](https://problemkaputt.de/gbatek-bios-memory-copy.htm).
|
||||
- [GBATEK BIOS rotation/scaling services](https://problemkaputt.de/gbatek-bios-rotation-scaling-functions.htm), for record layouts, angle units, and output strides.
|
||||
- [VisualBoyAdvance-M BIOS services](https://github.com/visualboyadvance-m/visualboyadvance-m/blob/master/src/core/gba/internal/gbaBios.cpp), reviewed for integer affine rounding and signed matrix intermediates. Our sine table is generated mathematically.
|
||||
- [VisualBoyAdvance-M BIOS services](https://github.com/visualboyadvance-m/visualboyadvance-m/blob/master/src/core/gba/internal/gbaBios.cpp), reviewed for integer affine rounding, signed matrix intermediates, and SoftReset status handling. Our sine table is generated mathematically.
|
||||
- [GBATEK BIOS arithmetic services](https://problemkaputt.de/gbatek-bios-arithmetic-functions.htm).
|
||||
- [GBATEK BIOS decompression services](https://problemkaputt.de/gbatek-bios-decompression-functions.htm), including BitUnPack descriptor fields, differential-filter headers, Huffman tree layout, and width constraints.
|
||||
- [mGBA BIOS service implementation](https://github.com/mgba-emu/mgba/blob/master/src/gba/bios.c), reviewed for angle-polynomial coefficients and quadrant conventions, BitUnPack ordering/offsets, and Huffman tree layout and packing.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue