feat(power): implement keypad-wake STOP and BIOS Stop service
Separate Running, Halt, and Stop states. Complete the entering instruction before freezing CPU, DMA, timers, display, and externally supplied clock advances. Wake STOP through the live enabled keypad condition without creating a clock-off IF request. Implement original ARM SWI 0x03, preserve caller state, and expose zero-cycle StopIdle plus stopped frame-runner results. Retain DMA state, timer phase, and captured frames across sleep. Document keypad-only wake and unverified oscillator/edge timing. Add core, BIOS, and demo regression tests; preserve BIOS-only access and failed-store isolation. Validated on Darwin arm64 with debug/release workspace and core/demo suites, Clippy, rustdoc, ten native window smoke tests, and terminal demos.
This commit is contained in:
parent
597b02881b
commit
c836944c2e
20 changed files with 748 additions and 105 deletions
|
|
@ -29,7 +29,7 @@ The repository is a Cargo workspace with three crates:
|
|||
| `crates/gba-core/src/cpu/tests.rs` | Condition truth tables and immediate arithmetic tests |
|
||||
| `crates/gba-core/src/cpu/instruction_tests.rs` | Register operations, transfers, branches, and edge cases |
|
||||
| `crates/gba-core/src/memory.rs` | Memory mapping, I/O routing, write validation, and device clock |
|
||||
| `crates/gba-core/src/io.rs` | I/O registers, timers, HALT wake-up, next-event bounds, and IRQ latches |
|
||||
| `crates/gba-core/src/io.rs` | I/O registers, timers, HALT/STOP wake-up, next-event bounds, and IRQ latches |
|
||||
| `crates/gba-core/src/display.rs` | Display clock, scanline status, comparison edges, and display IRQ events |
|
||||
| `crates/gba-core/src/dma.rs` | DMA registers, internal pointers, trigger state, priority, and completion IRQs |
|
||||
| `crates/gba-core/src/machine.rs` | Timed CPU/DMA/device stepping and IRQ delivery |
|
||||
|
|
@ -102,7 +102,9 @@ The repository is a Cargo workspace with three crates:
|
|||
| `crates/gba-core/tests/sprites/affine.rs` | Affine matrices, drawing areas, signed sampling, shared groups, and floating-point reference tests |
|
||||
| `crates/gba-core/tests/display.rs` | Display boundaries, register masks, IRQ handlers, and VBlank frame execution |
|
||||
| `crates/gba-core/tests/dma.rs` | DMA widths, latches, priority, triggers, IRQs, timing, errors, and CPU integration |
|
||||
| `crates/gba-core/tests/halt.rs` | HALT wake masks, idle timing, BIOS-only writes, DMA progress, and STOP diagnostics |
|
||||
| `crates/gba-core/tests/stop.rs` | STOP clock gating, live keypad wake, retained DMA/device phases, frame-runner results, and access rules |
|
||||
| `crates/gba-core/tests/bios/stop.rs` | ARM/Thumb Stop calls, caller preservation, keypad wake, and stopped frame running |
|
||||
| `crates/gba-core/tests/halt.rs` | HALT wake masks, idle timing, BIOS-only power writes, DMA progress, and validation |
|
||||
| `crates/gba-core/tests/bios.rs` | ARM/Thumb service calls, copy/fill boundaries, wait races, callback contracts, and boot |
|
||||
| `crates/gba-core/tests/bios/ram_reset.rs` | Selective RAM boundaries, flag combinations, I/O reset, display rendering, DMA/timer latches, and diagnostics |
|
||||
| `crates/gba-core/tests/bios/reset.rs` | All restart flags, exact RAM boundaries, CPU banks, restart execution, device continuity, and IRQ masking |
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ No Nintendo firmware bytes are included.
|
|||
A compile-time integer calculation generates the 512-byte sine table at `0x3e00..0x3fff`.
|
||||
The image builder checks that code and literal pools do not overlap this table.
|
||||
Literal pools follow unconditional branches and stay within each load instruction's address range.
|
||||
The CPU executes every instruction through the normal bus, timing, exception, HALT, and DMA paths.
|
||||
The CPU executes every instruction through the normal bus, timing, exception, HALT/STOP, and DMA paths.
|
||||
There is no host-side interception of SWIs.
|
||||
|
||||
Use `bios::boot(rom)` to create a machine at the reset vector with this image mapped.
|
||||
|
|
@ -35,6 +35,7 @@ Supported software interrupt services:
|
|||
| `0x00` | SoftReset | Clear BIOS work RAM and reset CPU registers/stacks; restart in ROM or RAM without returning |
|
||||
| `0x01` | RegisterRamReset | r0 selects RAM and supported I/O resets; force blank; reject serial/sound flags |
|
||||
| `0x02` | Halt | Wait for `IE & IF`; preserve IME and caller registers |
|
||||
| `0x03` | Stop | Freeze system clocks until an enabled live keypad condition wakes the system; preserve caller state |
|
||||
| `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 |
|
||||
| `0x06` | Div | Signed `r0 / r1`; return quotient in r0, remainder in r1, and quotient magnitude in r3 |
|
||||
|
|
@ -88,6 +89,21 @@ 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.
|
||||
|
||||
## Stop
|
||||
|
||||
`Stop` (`SWI 0x03`) executes an original ARM byte store of `0x80` to HALTCNT.
|
||||
It uses the common 28-byte Supervisor frame and restores caller registers/status after wake-up.
|
||||
It leaves IE, IME, KEYCNT, and DISPCNT unchanged.
|
||||
Configure KEYCNT and IE bit 12 before calling; no matching wake source means the system stays stopped.
|
||||
The caller can force blank separately before entering STOP.
|
||||
Both ARM and Thumb User/System callers are supported.
|
||||
|
||||
A keypad wake does not set IF in the stopped-clock model.
|
||||
The BIOS resumes its return sequence without requiring an IRQ callback or BIOS IRQ-flag update.
|
||||
Ready DMA and previously pending IRQs follow the ordinary machine scheduling rules after wake-up.
|
||||
See [STOP behavior and limits](timers-irq.md#stop-with-keypad-wake-up).
|
||||
Serial/Game Pak wake-up and exact oscillator restart timing are not implemented.
|
||||
|
||||
## SoftReset
|
||||
|
||||
`SoftReset` (`SWI 0x00`) does not return to its caller.
|
||||
|
|
@ -429,5 +445,5 @@ 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.
|
||||
RegisterRamReset serial/sound flags, HardReset, and STOP remain unimplemented.
|
||||
RegisterRamReset serial/sound flags, HardReset, and serial/Game Pak STOP wake-up remain unimplemented.
|
||||
This subset is not sufficient for Pokémon Emerald compatibility.
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ Hardware IRQ synchronization delays and display bus contention are not modeled.
|
|||
|
||||
`Machine::run_until_vblank(max_steps)` executes through the next line-160 entry, even if already in VBlank.
|
||||
It returns at the first instruction, DMA-unit, or HALT-idle boundary after that event and reports the number of machine steps.
|
||||
A stopped idle step returns `FrameRunError::Stopped` because STOP freezes the display clock.
|
||||
STOP retains the current display phase and captured frame; elapsed host time does not create emulated scanlines.
|
||||
DMA requested by that VBlank event can still be pending; this method does not wait for a redraw or DMA completion.
|
||||
A zero or exhausted step limit returns `FrameRunError::StepLimit`.
|
||||
CPU and DMA diagnostics return `FrameRunError::Cpu` and `FrameRunError::Dma`, respectively.
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ Clearing enable manually cancels a waiting or active transfer.
|
|||
|
||||
DMA0 has highest priority, followed by DMA1, DMA2, and DMA3.
|
||||
A higher-priority request can interrupt a lower-priority transfer between data units.
|
||||
The CPU remains paused while any channel is ready; display and timer clocks continue.
|
||||
While the system clock runs, the CPU remains paused while any channel is ready; display and timer clocks continue.
|
||||
STOP freezes DMA before transfer selection, including diagnostics, and retains pending transfer state until wake-up.
|
||||
Completion with local IRQ enable latches IF bits 8–11, independently of IE, IME, and CPSR.I.
|
||||
CPU delivery waits until no DMA is ready. IRQ entry does not acknowledge IF.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
# Timers, interrupts, and HALT
|
||||
# Timers, interrupts, HALT, and STOP
|
||||
|
||||
## Timers, interrupt registers, and the machine clock
|
||||
|
||||
`Machine::new(cpu, memory)` combines the CPU and memory bus.
|
||||
`Machine::step()` first services one ready DMA data unit, keeping the CPU paused.
|
||||
`Machine::step()` first checks STOP and returns `StopIdle` with zero timing if the system is still stopped.
|
||||
Otherwise it services one ready DMA data unit, keeping the CPU paused.
|
||||
If HALT is waiting and no DMA is ready, it advances device clocks to the next event without executing CPU code.
|
||||
Otherwise, it samples the IRQ line, including the CPU's interrupt mask, then enters IRQ mode or executes one instruction.
|
||||
Each successful step advances display and timer clocks by its nominal cost.
|
||||
|
|
@ -13,6 +14,7 @@ IRQ entry is a separate step; the vector instruction runs on the following step.
|
|||
A device event during a step can trigger IRQ entry once no DMA is ready and CPU masks allow delivery.
|
||||
Bus writes take effect before the step's device-clock update.
|
||||
`StepKind::Dma { channel }` identifies a DMA unit. `StepKind::HaltIdle` identifies one bounded HALT clock advance.
|
||||
`StepKind::StopIdle` identifies a stopped system with no clock progress.
|
||||
The other step kinds remain `Instruction` and `IrqEntry`.
|
||||
`MachineError::Cpu` and `MachineError::Dma` identify the source of a diagnostic.
|
||||
Failed steps do not advance the clock or partially change CPU or device state. Earlier successful steps remain committed.
|
||||
|
|
@ -23,14 +25,15 @@ Reads observe register state before that batch.
|
|||
Writes, including timer start/stop and IF acknowledgement, take effect before the entire batch.
|
||||
This does not reproduce bus-access timing within an instruction or IRQ synchronization delays.
|
||||
|
||||
`Cpu::step` remains a CPU-only API. It does not honor HALT, execute DMA, advance device clocks, or sample device IRQs.
|
||||
`Cpu::step` remains a CPU-only API. It does not honor HALT/STOP, execute DMA, advance device clocks, or sample device IRQs.
|
||||
`Cpu::step_timed` executes the same operation and returns `StepTiming`, without advancing devices.
|
||||
`Machine::step` uses that result to advance device clocks. Failed steps preserve the previous timing result.
|
||||
`Memory::advance_cycles(n)` advances device clocks, latches DMA requests, and updates HALT wake-up state.
|
||||
`Memory::advance_cycles(n)` advances device clocks, latches DMA requests, and updates HALT wake-up state while not stopped.
|
||||
In STOP, it ignores supplied cycles and leaves device phases and captured frames unchanged.
|
||||
It does not execute CPU instructions or DMA units.
|
||||
Multiple unserviced DMA requests coalesce; bulk clock advances do not replay every missed transfer.
|
||||
Reads and writes alone consume no cycles.
|
||||
`Memory::cycles()` and `Machine::cycles()` report the supplied cycle total as a wrapping 64-bit counter.
|
||||
`Memory::cycles()` and `Machine::cycles()` report elapsed emulated clocks as a wrapping 64-bit counter, excluding stopped time.
|
||||
|
||||
Mapped input/output (I/O) registers:
|
||||
|
||||
|
|
@ -45,7 +48,7 @@ Mapped input/output (I/O) registers:
|
|||
| `0x04000204` | WAITCNT | Configures first/second ROM access wait states; unused bits read as zero |
|
||||
| `0x04000208` | IME | Bit zero gates IRQ delivery; other bits read as zero |
|
||||
| `0x04000300` | POSTFLG | Bit-zero post-boot flag; CPU writes require BIOS execution |
|
||||
| `0x04000301` | HALTCNT | Write-only low-power control; HALT supported, STOP returns a diagnostic |
|
||||
| `0x04000301` | HALTCNT | Write-only low-power control; HALT and keypad-wake STOP supported |
|
||||
|
||||
Timers count at supplied clock rates divided by 1, 64, 256, or 1024.
|
||||
Timers 1–3 can instead count the preceding timer's overflows. Timer 0 ignores count-up selection.
|
||||
|
|
@ -63,7 +66,7 @@ Byte, halfword, and word accesses are supported for this register subset.
|
|||
|
||||
Timer startup delays and shared prescaler phase are not modeled.
|
||||
The provisional timer model resets its private prescaler phase on enable or clock-source changes.
|
||||
Audio events, STOP, and interrupt sources other than timers, display events, DMA completion, and keypad input are not implemented.
|
||||
Audio events and interrupt sources other than timers, display events, DMA completion, and keypad input are not implemented.
|
||||
|
||||
`--timer-demo` executes original ARM code that configures Timer 0, IE, and IME.
|
||||
The timer overflows after 16 supplied cycles and enters the original handler through vector `0x18`.
|
||||
|
|
@ -96,7 +99,7 @@ The original BIOS IntrWait can consume keypad events through the normal IRQ call
|
|||
|
||||
### Sampling policy and limits
|
||||
|
||||
The current functional model follows mGBA's polling behavior, not a verified hardware edge detector:
|
||||
While the system clock runs, the functional model follows mGBA's polling behavior, not a verified hardware edge detector:
|
||||
|
||||
- Each `Memory::set_buttons` call samples the input, including repeated identical values.
|
||||
- Each successful write touching KEYCNT samples after the complete register update.
|
||||
|
|
@ -113,7 +116,7 @@ Host input calls consume no emulated cycles and do not modify CPU registers.
|
|||
They can wake HALT immediately; `Machine::step` subsequently samples the IRQ line.
|
||||
The desktop demos currently supply frame-based input snapshots.
|
||||
Physical key-event timing, switch bounce, exact hardware retrigger rules, and synchronization delays remain unverified.
|
||||
STOP still returns a diagnostic; this change does not implement STOP wake-up.
|
||||
STOP uses a separate live-condition wake path described below, without latching IF or updating this polling history.
|
||||
|
||||
Byte writes merge with the untouched KEYCNT byte.
|
||||
Halfword writes, and word writes at KEYINPUT, evaluate the final KEYCNT value once.
|
||||
|
|
@ -156,10 +159,45 @@ HALTCNT reads return zero as a placeholder, not hardware open-bus behavior.
|
|||
The reserved bytes at `0x04000302..0x04000303` read zero and ignore writes.
|
||||
Byte, halfword, and word writes are supported; a halfword/word at POSTFLG also writes HALTCNT.
|
||||
|
||||
STOP requests from BIOS code or host setup return `MemoryError::UnsupportedStop` before any write commits.
|
||||
This prevents STOP from silently behaving like HALT while its clock-gating and wake sources are absent.
|
||||
Multi-byte and block-store diagnostics preserve POSTFLG, HALT state, CPU registers, and the current step's clock.
|
||||
CPU-only stepping can record a HALT request but does not enforce the pause. Use `Machine::step()` for device integration.
|
||||
Multi-byte and block-store diagnostics preserve POSTFLG, power state, CPU registers, and the current step's clock.
|
||||
CPU-only stepping can record HALT/STOP but does not enforce either pause. Use `Machine::step()` for device integration.
|
||||
|
||||
## STOP with keypad wake-up
|
||||
|
||||
Writing HALTCNT with bit 7 set requests STOP. Bits 0–6 are ignored.
|
||||
The instruction that writes STOP finishes and pays its full nominal cycle cost.
|
||||
Later machine steps perform no CPU fetch, DMA transfer, timer tick, or display update.
|
||||
`StepKind::StopIdle` reports zero timing; it does not represent elapsed host wall time.
|
||||
`Memory::stopped()` and `Machine::stopped()` report this state. The corresponding `halted()` methods return false in STOP.
|
||||
|
||||
A matching live keypad condition wakes STOP when KEYCNT bit 14 and IE bit 12 are enabled.
|
||||
The same selected-button OR/AND logic applies, including the empty-mask behavior.
|
||||
IME and CPSR.I do not gate wake-up in this functional model.
|
||||
A matching condition already present at entry prevents a sustained stop.
|
||||
Stale IF flags alone cannot wake STOP, including an old keypad request.
|
||||
Timer, display, and DMA requests cannot wake STOP.
|
||||
|
||||
An input sample supplied while stopped updates KEYINPUT and the wake condition without setting IF.
|
||||
It does not consume the normal running-state keypad polling history.
|
||||
This follows GBATEK's note that IF is not set while the system clock is stopped.
|
||||
Existing IF bits remain unchanged. After wake-up, an old pending enabled IRQ may still be delivered.
|
||||
A later running-state input sample follows the normal keypad IRQ policy.
|
||||
Host/debug writes to IE or KEYCNT can also satisfy the wake condition; stopped CPU code cannot execute such writes.
|
||||
|
||||
After wake-up, ready DMA again takes priority, then IRQ delivery or CPU execution resumes.
|
||||
Timer prescaler phases, display position, RAM, and completed captured frames are retained, not reset.
|
||||
STOP does not automatically set forced blank or clear DISPCNT.
|
||||
Software can force blank before STOP if it wants the displayed image disabled.
|
||||
|
||||
`Machine::run_until_vblank` returns `FrameRunError::Stopped` on a stopped idle step rather than exhausting the step limit.
|
||||
A zero step limit still returns `StepLimit(0)`.
|
||||
The demo frame runner maps this to `GraphicsError::Stopped`, including during startup, without changing its output image.
|
||||
A host can supply input and retry after wake-up.
|
||||
The current desktop demos do not enter STOP; the frontend does not yet provide a general game-sleep screen.
|
||||
|
||||
Only keypad wake-up is implemented. General-purpose serial and Game Pak wake sources require their missing external devices.
|
||||
Oscillator restart delays, exact entry/wake edges, and hardware-specific IF behavior remain unverified.
|
||||
There is no host-thread sleep, wall-clock accounting, or audio clock implementation.
|
||||
|
||||
The graphics demo now uses the optional original BIOS replacement's VBlankIntrWait service.
|
||||
Its IRQ callback acknowledges VBlank and updates the BIOS RAM flag before the service returns.
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ External sources consulted while implementing the emulator. Add new sources here
|
|||
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 GBA system control and WAITCNT](https://problemkaputt.de/gbatek-gba-system-control.htm), including HALTCNT power-mode selection.
|
||||
- [GBATEK BIOS reset functions](https://problemkaputt.de/gbatek-bios-reset-functions.htm), for SoftReset state and restart selection, plus RegisterRamReset flags, RAM bounds, and forced blank.
|
||||
- [GBATEK BIOS halt functions](https://problemkaputt.de/gbatek-bios-halt-functions.htm), for wait contracts and STOP differences.
|
||||
- [GBATEK BIOS halt functions](https://problemkaputt.de/gbatek-bios-halt-functions.htm), for wait contracts, STOP clock gating, allowed wake sources, and the clock-off IF note.
|
||||
- [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.
|
||||
|
|
|
|||
|
|
@ -37,7 +37,8 @@ Update this file when a feature lands or a limit is removed.
|
|||
- Four direct memory access (DMA) channels, with immediate, VBlank, and visible-line HBlank triggers.
|
||||
- Halfword/word DMA, address controls, repeat, channel priority, CPU pausing, and completion IRQs.
|
||||
- HALT with enabled-request wake-up, continued device clocks, and bounded idle steps.
|
||||
- BIOS-only CPU writes to POSTFLG/HALTCNT, with explicit errors for unsupported STOP mode.
|
||||
- BIOS-only CPU writes to POSTFLG/HALTCNT, with HALT and keypad-wake STOP.
|
||||
- STOP freezes CPU/DMA/device clocks, retains device phases, and reports a stopped frame runner without spinning.
|
||||
- Machine execution to the next VBlank event, with a configurable step limit.
|
||||
- CPU/device stepping with nominal ARM7 instruction costs and memory wait states.
|
||||
- Game Pak wait-state control (`WAITCNT`) for all three ROM windows.
|
||||
|
|
@ -98,6 +99,7 @@ Individual fetch timing, hardware-accurate work cutoffs, video-bus contention, a
|
|||
There is no sound or cartridge save support.
|
||||
Mapped I/O covers DMA, timers, interrupts, WAITCNT, display control/status, background control/scroll/affine registers, window/effect registers, KEYINPUT/KEYCNT, POSTFLG, and HALTCNT.
|
||||
Keypad IRQs use a documented polling model; hardware retrigger edges and asynchronous input timing remain unverified.
|
||||
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.
|
||||
|
|
@ -113,7 +115,7 @@ Writes to cartridge addresses return errors instead of modeling cartridge hardwa
|
|||
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. Validate keypad retrigger behavior with hardware tests and add remaining device registers; extend BIOS reset coverage as sound/serial support becomes available.
|
||||
Add STOP and remaining DMA device modes with verified timing and wake-up behavior.
|
||||
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.
|
||||
|
||||
|
|
|
|||
|
|
@ -135,7 +135,10 @@ Wait tests inject an IRQ at 100 different machine-step positions to check the fl
|
|||
Other wait tests cover discarded flags, unrelated IRQs, masked/User-mode callers, and callbacks that omit BIOS flag updates.
|
||||
HALT tests distinguish wake-up from IRQ delivery, including IME/CPSR masking and ARM/Thumb resume behavior.
|
||||
Idle batches are checked against a cycle-by-cycle reference with independent and cascaded timers.
|
||||
Tests cover display/DMA wake sources, DMA priority while halted, BIOS-only writes, STOP diagnostics, and frame limits.
|
||||
Tests cover display/DMA wake sources, DMA priority while halted, BIOS-only writes, power-state validation, and frame limits.
|
||||
STOP tests check zero-cycle idle steps, frozen DMA/timers/display, retained timer phases and captured frames, and live keypad wake.
|
||||
They distinguish wake-up from IF latching and test stale requests, interrupt masks, already-held keys, and normal resume ordering.
|
||||
ARM/Thumb BIOS Stop tests verify caller preservation. Frame-runner tests check prompt stopped results and unchanged output images.
|
||||
The graphics test verifies BIOS VBlank waiting, one IRQ callback per update, and status restoration before each redraw.
|
||||
DMA tests cover both widths, all supported address modes, count limits, register masks, enable latches, and repeated transfers.
|
||||
Tests verify channel priority/preemption, CPU pausing, display/timer progress, IRQ acknowledgement/return, and WAITCNT costs.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue