feat(timing): break CPU sequential access after DMA
Retain one pending non-sequential resume after successful DMA. Apply it to the next nominal non-refill code access and consume it only on successful CPU or IRQ progress. Preserve failed-step atomicity, host and idle isolation, existing refill costs, and WAITCNT ordering. Add 13 original regressions for ARM/Thumb widths, ROM wait settings, sources, preemption, retries, mixed APIs, idle states, and interrupt timing. Record pinned hardware-test source and emulator evidence without claiming physical-hardware or full-pipeline conformance. Validated on Darwin arm64: 952 workspace and 883 core/demo tests per debug/release profile, 39 Python tests, native ROM windows, ten window smoke modes, fmt, clippy, and rustdoc. Public ARM/Thumb/memory/BIOS reports remain unchanged.
This commit is contained in:
parent
663b25e5d1
commit
16286e0cbd
11 changed files with 437 additions and 4 deletions
|
|
@ -288,6 +288,24 @@ The writable mask is `0x5fff`; the Game Pak type flag reads as GBA, and the uppe
|
|||
A CPU write to WAITCNT does not retroactively change that instruction's code-access cost.
|
||||
The new settings apply to subsequent code accesses.
|
||||
|
||||
### Nominal CPU resume after DMA
|
||||
|
||||
A successful DMA unit marks the next CPU instruction's nominal code access non-sequential.
|
||||
This applies even when DMA only accesses RAM. Consecutive units retain one pending resume, not multiple penalties.
|
||||
A non-refill instruction uses its normal width and current WAITCNT with N instead of S.
|
||||
ARM word accesses retain an S cost for their second halfword.
|
||||
Stores and ROM boundaries that already use N do not receive an additional cost.
|
||||
|
||||
Successful timed or untimed CPU execution consumes pending resume, including skipped conditions and internal-memory instructions.
|
||||
Successful machine IRQ entry also consumes it. Failed CPU/DMA steps preserve it.
|
||||
Host access, clock-only advancement, and HALT/STOP idle do not consume it.
|
||||
A failed DMA unit cannot create pending resume.
|
||||
DMA WAITCNT writes apply before resume; CPU WAITCNT writes still use the previous code-access settings.
|
||||
|
||||
Branch and exception refill summaries retain their existing destination-based `1N+2S` costs, without an added resume access.
|
||||
The old-PC fetch is not modeled separately. This remains nominal timing, not a per-access pipeline.
|
||||
See [the evidence and limitations](../research/dma-resume-timing.md).
|
||||
|
||||
Important timing limits:
|
||||
|
||||
- Code S/N counts follow instruction summaries, not a simulated fetch pipeline.
|
||||
|
|
|
|||
|
|
@ -47,7 +47,10 @@ CPU delivery waits until no DMA is ready. IRQ entry does not acknowledge IF.
|
|||
Timing uses independent source and destination bus costs, including WAITCNT and 128 KiB ROM boundaries.
|
||||
The first unit uses non-sequential accesses plus two internal cycles. Later units use sequential accesses.
|
||||
Each step reports zero code cycles. Overlapping transfers read each unit after the preceding write; they are not bulk host copies.
|
||||
Startup scheduling delays, channel-resumption costs, CPU fetch-state effects, and display-bus contention remain unmodeled.
|
||||
A successful unit breaks the next nominal CPU code-access sequence, even if DMA accessed only RAM.
|
||||
The resumed non-refill instruction uses N code timing once; later instructions return to their normal summaries.
|
||||
See [CPU resume timing](cpu.md#nominal-cpu-resume-after-dma) for failure, idle, and refill rules.
|
||||
Startup scheduling delays, channel-resumption costs, a full CPU fetch pipeline, and display-bus contention remain unmodeled.
|
||||
|
||||
Special timing modes (sound FIFO/video capture), Game Pak DRQ, and prohibited source mode 3 return `DmaError::UnsupportedControl`.
|
||||
DMA reads below work RAM reuse known channel data as described below. They never expose BIOS bytes.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue