feat(cpu): account for source fetches in branch and IRQ refills
This commit is contained in:
parent
0650b60908
commit
2d7eb6e4eb
27 changed files with 638 additions and 87 deletions
|
|
@ -55,8 +55,10 @@ The repository is a Cargo workspace with three crates:
|
|||
| `crates/gba-core/src/cpu/pipeline.rs` | CPU-owned ARM/Thumb instructions, PC/state tags, deferred fetch diagnostics, refill sampling, and explicit invalidation |
|
||||
| `crates/gba-core/src/cpu/arm_pipeline_tests.rs` | ARM self-modifying code, branches, target pairs, DMA isolation, exceptions, errors, and timing equivalence |
|
||||
| `crates/gba-core/src/cpu/thumb_pipeline_tests.rs` | Thumb retained halfwords, BL prefix/suffix, state-tagged refills, DMA isolation, rollback, and timing equivalence |
|
||||
| `crates/gba-core/src/cpu/timing.rs` | Fetch-address non-refill costs, nominal refill/DMA summaries, and data-access accounting |
|
||||
| `crates/gba-core/src/cpu/timing.rs` | Source-fetch/target-pair costs, IRQ fetch integration, nominal access kinds, and data accounting |
|
||||
| `crates/gba-core/src/cpu/fetch_timing_tests.rs` | Fetch-region/page/wait-window costs, DMA resume, WAITCNT stores, deferred errors, and timer/IRQ effects |
|
||||
| `crates/gba-core/src/cpu/refill_timing_tests.rs` | Refill source/target widths, wait settings, boundaries, DMA resume, and IRQ diagnostics |
|
||||
| `crates/gba-core/src/memory/irq_fetch_tests.rs` | Discarded IRQ fetch lanes, cold/retained entry, BIOS-history isolation, and deferred vector errors |
|
||||
| `crates/gba-core/src/cpu/dma_resume_tests.rs` | One-shot non-sequential DMA resume costs, wait settings, failures, idle, IRQs, and API isolation |
|
||||
| `crates/gba-core/src/cpu/timing_tests.rs` | Instruction timing and semantic-equivalence checks |
|
||||
| `crates/gba-demos/src/timer_demo.rs` | Original timer-configuration program and IRQ handler |
|
||||
|
|
|
|||
|
|
@ -92,7 +92,9 @@ The first target instruction samples T+2W before execution. State transitions re
|
|||
Thumb BL's prefix advances sequentially; only its suffix refills. Ordinary Thumb PC writes preserve Thumb state.
|
||||
The buffer records both expected PC and instruction state. A state mismatch cannot reinterpret retained ARM words as Thumb halfwords.
|
||||
|
||||
Machine IRQ entry captures the ARM vector pair before any handler instruction runs.
|
||||
Machine IRQ entry first samples and discards the old-state P+2W fetch, then captures the ARM vector pair.
|
||||
The discarded fetch drives actual IWRAM lanes but does not execute an instruction or commit a BIOS instruction snapshot.
|
||||
Missing source bytes cannot prevent IRQ entry. Missing vector bytes fail only when the handler instruction becomes current.
|
||||
`Cpu::enter_exception` and `Cpu::take_interrupt` have no memory parameter: they invalidate the buffer and leave vector sampling to the next step.
|
||||
An unexpected PC discontinuity starts from current mapped bytes rather than reusing a mismatched buffer.
|
||||
|
||||
|
|
@ -108,9 +110,10 @@ Use it after debugger code repair or when attaching different memory to a retain
|
|||
Do not call it for ordinary CPU/DMA stores: that would hide self-modifying-code behavior.
|
||||
|
||||
This is instruction buffering, not a complete timed fetch pipeline.
|
||||
Samples add no nominal data accesses or device cycles. Existing refill costs and one-shot DMA resume costs remain unchanged.
|
||||
Sampling adds no data accesses or independent device-clock updates.
|
||||
Code timing charges the source fetch and target pair once, with a DMA resume override on the source access.
|
||||
Instruction buffering and supported bus history now consume the same mapped fetch samples.
|
||||
Complete fetch-driven bus history, exact refill costs, per-access device updates, and DMA arbitration remain incomplete.
|
||||
Complete fetch-driven bus history, access-kind sequencing, per-access device updates, and DMA arbitration remain incomplete.
|
||||
See the [ARM evidence and diagnostic policy](../research/arm-instruction-buffer.md), [Thumb extension](../research/thumb-instruction-buffer.md),
|
||||
and [shared fetch samples](../research/shared-fetch-samples.md).
|
||||
|
||||
|
|
@ -234,11 +237,12 @@ Failed instructions do not sample a target or replace committed history.
|
|||
Target samples use strict mapped reads and add no nominal data or device cycles.
|
||||
The same captured target pair fills the CPU buffer and updates IWRAM history; no second target read occurs.
|
||||
A failed target fetch remains a later instruction diagnostic.
|
||||
IRQ entry samples its ARM BIOS vector pair without erasing IWRAM lanes.
|
||||
IRQ entry updates IWRAM lanes if its discarded old-state fetch addresses IWRAM.
|
||||
Its subsequent ARM BIOS vector pair does not erase those lanes.
|
||||
A BIOS handler can still change those lanes through actual IWRAM data accesses.
|
||||
|
||||
The [refill evidence and scope](../research/iwram-bus-history.md#thumb-iwram-refill-extension) distinguish these samples from a fully timed pipeline.
|
||||
Sub-instruction DMA ordering and exact refill timing remain incomplete.
|
||||
Sub-instruction DMA ordering and complete bus sequencing remain incomplete.
|
||||
|
||||
### DMA effects on Thumb IWRAM continuations
|
||||
|
||||
|
|
@ -317,17 +321,19 @@ An ordinary arithmetic instruction costs 1S. A register-specified shift adds 1I,
|
|||
Loads cost a code S access, a data N access, and 1I. Stores use N for code and data.
|
||||
Block transfers charge N for the first data word and S for each following word.
|
||||
Loads add 1I. Loading PC also adds the branch refill cost.
|
||||
Branches, PC writes, software interrupts, and exception entry use a nominal 1N+2S code refill.
|
||||
Branches, PC writes, software interrupts, and IRQ entry charge one source fetch plus a target N+S pair.
|
||||
The source fetch uses the incoming state at P+2W. The target pair uses the resulting state at T and T+W.
|
||||
The first target instruction charges T+2W when it executes; the refill does not charge it early.
|
||||
A skipped conditional instruction only pays its code S access.
|
||||
Thumb `BL` charges 1S for its prefix and 1N+2S for its suffix.
|
||||
Thumb `BL` charges one source fetch for each half; only its suffix adds the target N+S pair.
|
||||
Multiply costs vary with the incoming multiplier's upper bytes; accumulate and long forms add internal cycles.
|
||||
ARM uses Rs for this calculation. Thumb multiply uses the incoming destination register.
|
||||
|
||||
Non-refill code costs use the new instruction fetch address: P+8 for ARM and P+4 for Thumb.
|
||||
Source code costs use the new instruction fetch address: P+8 for ARM and P+4 for Thumb.
|
||||
The incoming instruction state selects the width. The sampled fetch address selects the memory region and ROM wait-state window.
|
||||
A 128 KiB ROM boundary therefore forces N timing when lookahead reaches it, not when execution reaches it later.
|
||||
This applies to cold and retained pipelines without adding separate startup-fill costs.
|
||||
See [fetch-address timing](../research/fetch-address-timing.md) for evidence, examples, and remaining limits.
|
||||
See [fetch-address timing](../research/fetch-address-timing.md) and [refill timing](../research/refill-fetch-timing.md) for evidence and limits.
|
||||
|
||||
Data costs use the addresses and widths of actual CPU bus calls, after alignment handling.
|
||||
BIOS, internal work RAM, OAM, and supported I/O accesses cost one cycle.
|
||||
|
|
@ -346,7 +352,8 @@ The new settings apply to subsequent code accesses.
|
|||
|
||||
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 actual lookahead address, incoming width, and current WAITCNT with N instead of S.
|
||||
The source fetch uses its actual lookahead address, incoming width, and current WAITCNT with N instead of S.
|
||||
This includes branches and accepted IRQ entry; target pairs still use N then 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.
|
||||
|
||||
|
|
@ -356,16 +363,15 @@ 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.
|
||||
A resumed refill can have two N accesses: the old-PC source fetch and the first target fetch.
|
||||
The resume changes the source access kind; it does not append another access.
|
||||
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.
|
||||
- Non-refill code costs follow actual lookahead addresses, but cold current/decode fills have no separate startup charge.
|
||||
- PC writes still use destination-region costs and the restored instruction width for nominal refill accesses.
|
||||
Their old-PC fetch and target pair are not yet charged individually; IRQ entry has the same remaining limit.
|
||||
- Source S/N kinds follow instruction-local summaries, not complete neighboring instruction/data-access sequencing.
|
||||
- Code costs follow actual source and target-pair addresses, but cold current/decode fills have no separate startup charge.
|
||||
- Refill cost calculation does not read target bytes. ARM/Thumb instruction-buffer and local IWRAM bus-history samples add no extra cycles.
|
||||
- Target-pair sampling cannot fail the branch early. An invalid branch target still fails on the following instruction fetch.
|
||||
- Game Pak prefetch is not implemented. WAITCNT bit 14 is stored but does not accelerate execution.
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@ Each successful step advances display and timer clocks by its nominal cost.
|
|||
`Machine::last_timing()` reports separate code, data, internal, and idle cycle totals for the last successful step.
|
||||
`StepTiming::idle_cycles` counts device-clock cycles during HALT; it does not count CPU work.
|
||||
IRQ entry is a separate step; the vector instruction runs on the following step.
|
||||
Entry charges the discarded incoming-state PC+8/PC+4 fetch and the ARM vector pair at `0x18` and `0x1c`.
|
||||
DMA resume can make the discarded fetch non-sequential. Missing discarded bytes do not prevent IRQ entry.
|
||||
See [refill timing](../research/refill-fetch-timing.md) for history effects and remaining limits.
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -180,6 +180,15 @@ Fetch-address timing research:
|
|||
|
||||
See [fetch-address timing](research/fetch-address-timing.md). This corrects non-refill address selection, not full bus sequencing or refill timing.
|
||||
|
||||
Refill and IRQ fetch-timing research:
|
||||
|
||||
- The ARM7TDMI branch sequence above, for the discarded source fetch before the destination pair.
|
||||
- [ARM7TDMI software-interrupt and exception entry](https://support.arm.com/documentation/ddi0029/g/instruction-cycle-timings/software-interrupt-and-exception-entry), for the incoming-state `pc+2L` access followed by the ARM vector pair.
|
||||
- The pinned NanoBoyAdvance `SignalIRQ`, `Run`, `ReloadPipeline16`, and `ReloadPipeline32` methods above, for discarded incoming-state fetches and N/S target pairs.
|
||||
|
||||
See [source-fetch and target-pair timing](research/refill-fetch-timing.md) for the implementation and public-report audit.
|
||||
Source review and comparisons between our own core versions are not physical-hardware timing validation.
|
||||
|
||||
Use [GBATEK](https://problemkaputt.de/gbatek.htm) and ARM7TDMI documentation for further hardware work.
|
||||
Only use game ROMs that you may lawfully use. Do not commit game ROMs, BIOS files, or game assets.
|
||||
The ignore file excludes `roms/`, common game ROM extensions, and save files.
|
||||
|
|
|
|||
|
|
@ -69,7 +69,8 @@ Failed-instruction tests continue to assert full-state preservation.
|
|||
|
||||
This implements persistent ARM instruction words, not a complete cycle-by-cycle pipeline.
|
||||
Cold fill and target-pair samples do not add nominal cycles or data accesses.
|
||||
The existing destination-based refill summaries and one-shot DMA resume timing remain unchanged.
|
||||
The later [refill timing extension](refill-fetch-timing.md) replaces destination-only costs with source-fetch and target-pair costs.
|
||||
IRQ entry also samples its discarded old-state fetch before the vector pair.
|
||||
The later [fetch-address timing extension](fetch-address-timing.md) selects non-refill code cost from the newly sampled address.
|
||||
Access kinds, cold-fill startup costs, and refill scheduling remain incomplete.
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ A failed unit cannot create or consume it. A blocked-source unit that successful
|
|||
Register configuration, host reads/writes, and clock-only advancement do not consume it.
|
||||
|
||||
Before instruction execution, `Cpu::step_timed` captures the pending state and WAITCNT.
|
||||
For a non-refill instruction, pending resume changes the nominal code-access kind to non-sequential.
|
||||
Pending resume changes the source code-access kind to non-sequential.
|
||||
The existing bus-cost function applies the code width and ROM-window wait settings.
|
||||
An ARM word still uses a non-sequential first halfword and a sequential second halfword.
|
||||
This is a change of access kind, not a fixed positive surcharge: some wait settings make N cheaper than S.
|
||||
|
|
@ -50,9 +50,9 @@ The [fetch-address timing extension](fetch-address-timing.md) now charges non-re
|
|||
A resumed access selects that fetch region's wait settings. It is still not a separately scheduled bus event.
|
||||
DMA still executes only between instructions, not between data accesses or during CPU internal cycles.
|
||||
|
||||
Existing refill summaries remain destination-based `1N+2S` costs.
|
||||
A resumed branch or exception consumes pending state without adding another nominal access.
|
||||
This prevents double-counting the existing N component, but does not model the discarded old-PC fetch separately.
|
||||
The later [refill timing extension](refill-fetch-timing.md) replaces destination-only summaries with source-fetch and target-pair costs.
|
||||
Resume changes the source access to N; the first target access independently remains N.
|
||||
No extra access is appended. A resumed ROM branch can therefore cost more than its non-resumed refill.
|
||||
Stores and fetches at 128 KiB ROM boundaries already use N and receive no duplicate cost.
|
||||
Game Pak prefetch remains unimplemented; WAITCNT bit 14 does not alter this nominal timing path.
|
||||
|
||||
|
|
|
|||
|
|
@ -63,18 +63,18 @@ Timer tests and the original timer demo now reflect this bounded rule.
|
|||
|
||||
## Deliberately retained limits
|
||||
|
||||
The later [refill timing extension](refill-fetch-timing.md) also charges source fetches and target pairs for branches and IRQ entry.
|
||||
|
||||
- Instruction-local S/N summaries remain in use, including the existing store rule.
|
||||
Neighboring instruction/data-access sequencing is not a complete chronological bus trace.
|
||||
- Branches, PC loads/writes, SWI, exception returns, and IRQ entry retain destination-based `1N+2S` summaries.
|
||||
The old-PC fetch and target pair are not yet charged individually.
|
||||
- The new lookahead cost is not added to those refill summaries; doing so would count an extra access.
|
||||
- Thumb BL prefixes use their lookahead address; suffixes retain the nominal refill summary.
|
||||
- Refills now charge one source fetch plus the target N+S pair, not an additional fetch beside the old destination-only summary.
|
||||
- Thumb BL prefixes use their lookahead address; suffixes add the target pair.
|
||||
- Cold fills have no separate startup charge, even though their samples update supported bus history.
|
||||
- Devices advance once after the whole successful instruction. No per-access timer/IRQ update is introduced.
|
||||
- Game Pak prefetch, display contention, configurable EWRAM timing, and sub-instruction DMA arbitration remain unimplemented.
|
||||
|
||||
This is a fetch-address correction within the existing timing model, not cycle-accurate emulation.
|
||||
The next timing step is verified source-fetch/target-pair accounting for refills and IRQ entry.
|
||||
The next timing step is verified access-kind sequencing between instructions and data accesses.
|
||||
|
||||
## Original regression coverage
|
||||
|
||||
|
|
|
|||
|
|
@ -77,7 +77,8 @@ A retry takes a new lookahead sample from current memory.
|
|||
- All data reads within an instruction still use one entry snapshot.
|
||||
|
||||
The later [fetch-address timing extension](fetch-address-timing.md) charges non-refill code at the actual lookahead address.
|
||||
Refill summaries remain destination-based; the instruction-local access kinds and cold-start costs are still nominal.
|
||||
The [refill timing extension](refill-fetch-timing.md) also charges source fetches and target pairs individually.
|
||||
Instruction-local access kinds and cold-start costs remain nominal.
|
||||
Per-access device updates, video-bus contention, general DMA handoff, and Game Pak prefetch remain incomplete.
|
||||
No boundary timing accuracy is claimed.
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,8 @@ Debugger invalidation clears only instruction retention, but the following cold
|
|||
A successful instruction commits its staged lanes regardless of its resulting state, PC, or region.
|
||||
A failed instruction discards every staged change, including cold-fill samples.
|
||||
Successful PC-writing instructions then apply target fetches after their data accesses.
|
||||
Other-region execution, BIOS IRQ entry, and unavailable targets do not erase known local lanes.
|
||||
Other-region execution, BIOS vector fetches, and unavailable targets do not erase known local lanes.
|
||||
The later [IRQ fetch extension](refill-fetch-timing.md) updates addressed IWRAM lanes through its discarded old-state source fetch.
|
||||
Host inspection and setup never drive the latch.
|
||||
|
||||
Initial lanes remain unknown until observed accesses establish them.
|
||||
|
|
|
|||
122
docs/research/refill-fetch-timing.md
Normal file
122
docs/research/refill-fetch-timing.md
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
# Source-fetch and target-pair refill timing
|
||||
|
||||
## Finding and evidence
|
||||
|
||||
The instruction buffer already sampled a branch's old-state lookahead and its two target instructions.
|
||||
However, timing charged three destination accesses: N(T), S(T+W), and S(T+2W).
|
||||
That omitted the source-region cost and charged the third target fetch before target execution.
|
||||
The totals often matched within one memory region, hiding cross-region and instruction-state errors.
|
||||
Machine IRQ entry also omitted the discarded source sample entirely.
|
||||
|
||||
The [ARM7TDMI branch timing description](https://support.arm.com/documentation/ddi0029/g/instruction-cycle-timings/branch-and-branch-with-link) specifies three accesses:
|
||||
|
||||
1. Prefetch from the current PC while calculating the destination. The decision cannot prevent this fetch.
|
||||
2. Fetch the branch destination.
|
||||
3. Fetch destination plus one instruction length to refill the pipeline.
|
||||
|
||||
The [software-interrupt and exception-entry description](https://support.arm.com/documentation/ddi0029/g/instruction-cycle-timings/software-interrupt-and-exception-entry) likewise describes a forced-address construction cycle followed by pipeline refill.
|
||||
Its first address is `pc+2L`, using the incoming instruction state.
|
||||
The vector pair uses ARM state.
|
||||
|
||||
[NanoBoyAdvance at 55b5cf0a](https://github.com/nba-emu/NanoBoyAdvance/blob/55b5cf0ae3d929582ac5bfd486558173502b8354/src/nba/src/arm/arm7tdmi.hh) provides a source cross-check:
|
||||
|
||||
- `Run` fetches the old-state lookahead before instruction execution.
|
||||
- `ReloadPipeline16` and `ReloadPipeline32` read the target N and the next instruction S.
|
||||
- `SignalIRQ` first performs a discarded halfword/word fetch using the incoming state and access kind.
|
||||
It then changes mode/state and reloads the ARM vector pair.
|
||||
|
||||
This supports source-address and target-pair accounting, not complete chronological bus sequencing in this emulator.
|
||||
The existing [DMA resume evidence](dma-resume-timing.md) supports changing the next source access to N.
|
||||
No physical-hardware measurement or external-emulator differential run was performed.
|
||||
Tests and tracing code are original. No external source code, ROM, or BIOS was added to the repository.
|
||||
|
||||
## Implemented subset
|
||||
|
||||
For an instruction executing at P, `Cpu::step_timed` charges its sampled lookahead once:
|
||||
|
||||
- ARM source: P+8, word width.
|
||||
- Thumb source: P+4, halfword width.
|
||||
- Access kind: the existing instruction-local summary, overridden to N after successful DMA.
|
||||
- WAITCNT: captured before instruction effects.
|
||||
|
||||
If the instruction refills, timing also charges N(T) and S(T+W) using the resulting state.
|
||||
The existing pipeline samples supply those instructions and update supported local history.
|
||||
T+2W is sampled and charged when the first target instruction executes, not during the refill.
|
||||
The same rule covers taken branches, BX, PC loads/writes, SWI, saved-state returns, and Thumb BL suffixes.
|
||||
Untaken conditions and BL prefixes do not add a target pair.
|
||||
|
||||
Accepted machine IRQ entry samples the discarded incoming-state P+2W fetch, then the ARM vector pair.
|
||||
It does not fetch or execute the interrupted current opcode, nor invent a cold current/decode fill.
|
||||
The discarded sample drives its addressed IWRAM lanes when mapped; other regions leave that local history unchanged.
|
||||
An unavailable discarded sample cannot prevent entry and is not retained as a current-slot diagnostic.
|
||||
Unavailable vector samples fail only when execution reaches them.
|
||||
IRQ sampling does not commit a BIOS instruction snapshot because no BIOS instruction executed.
|
||||
The separate successful-BIOS-instruction history policy remains unchanged.
|
||||
|
||||
Masked IRQ requests have no fetch, history, CPU, or resume-state effects.
|
||||
DMA still takes priority at machine-step boundaries.
|
||||
Successful IRQ entry consumes pending DMA resume through normal machine-step completion.
|
||||
Devices advance once by the total entry cost, not between its accesses.
|
||||
The public memory-free `Cpu::enter_exception` and `Cpu::take_interrupt` APIs remain unchanged.
|
||||
|
||||
## Examples with default WAITCNT
|
||||
|
||||
| Operation | Source | Target pair | Code cycles |
|
||||
| --- | --- | --- | --- |
|
||||
| IWRAM ARM BX to Thumb WS1 | 1 | 5 + 5 | 11 |
|
||||
| IWRAM Thumb BX to ARM WS0 | 1 | 8 + 6 | 15 |
|
||||
| ARM WS0 branch to IWRAM | 6 | 1 + 1 | 8 |
|
||||
| ARM WS0 branch within WS0 | 6 | 8 + 6 | 20 |
|
||||
| Same branch after DMA | 8 | 8 + 6 | 22 |
|
||||
| IRQ from ARM WS0 | 6 | 1 + 1 | 8 |
|
||||
| IRQ from ARM WS0 after DMA | 8 | 1 + 1 | 10 |
|
||||
|
||||
These examples exclude ROM page boundaries.
|
||||
Every access independently selects its actual region, wait window, and forced-N 128 KiB boundary cost.
|
||||
A target pair can cross a region or wait-window boundary.
|
||||
A boundary at T+2W is charged on target execution, not during the preceding branch.
|
||||
DMA can produce two N accesses: the source fetch and the first target fetch. No fourth fetch is added.
|
||||
|
||||
## Original regression coverage
|
||||
|
||||
Tests cover:
|
||||
|
||||
- Incoming/outgoing ARM and Thumb widths, all ROM wait settings, and the stored prefetch bit.
|
||||
- Boundaries in the first, second, and third target slots, plus split wait-window target pairs.
|
||||
- ROM source boundaries and DMA resume before a RAM refill, with no delayed resume penalty.
|
||||
- Cross-region source lookahead, data/internal costs for PC loads, and saved-state returns.
|
||||
- IRQ source widths, missing ROM, masked requests, LR/SPSR preservation, and device-clock totals.
|
||||
- IRQ IWRAM word and halfword lane updates, cold entry without invented fills, and retained Thumb entry.
|
||||
- Missing-vector rollback after accepted entry, BIOS-history isolation, and timed/untimed CPU equivalence.
|
||||
|
||||
## Validation and report changes
|
||||
|
||||
Workspace and core/demo tests pass in debug and release on Darwin arm64.
|
||||
Formatting, clippy, rustdoc, Python preparation tests, native ROM windows, and all graphics smoke modes pass.
|
||||
The release executable is native Mach-O arm64.
|
||||
Public ARM, Thumb, memory, and BIOS checkpoint assertions pass. Debug and release reports match.
|
||||
|
||||
Compared with the preceding fetch-address change, the ARM, Thumb, and memory reports each lose five nominal cycles.
|
||||
Their step counts and all other report fields remain unchanged.
|
||||
The BIOS report gains three instructions and 29 nominal cycles; all other fields remain unchanged.
|
||||
|
||||
A temporary original trace runner compared the preceding and updated cores against the pinned BIOS fixture.
|
||||
The changed VBlank arrival position causes one extra three-instruction polling loop, adding 34 cycles.
|
||||
Cross-region firmware transfers and IRQ entry together remove five cycles, giving the observed net increase of 29.
|
||||
The trace still reaches the same checkpoint with r12=0 and one IRQ entry.
|
||||
This trace comparison is a regression audit between our core versions, not external hardware validation.
|
||||
|
||||
The original timer demo retains its total nominal duration and IRQ step.
|
||||
IRQ entry gains five cycles before the handler stops the timer; the return loses five cycles afterward.
|
||||
The stopped counter therefore increases by five even though the final machine-cycle total is unchanged.
|
||||
|
||||
## Remaining limits
|
||||
|
||||
- Source access kinds still use instruction-local summaries, including the existing store rule.
|
||||
Neighboring instruction/data-access sequencing is not a complete chronological bus trace.
|
||||
- Cold current/decode fills have no separate startup timing charge.
|
||||
- BIOS retained history is not a complete refill/data-access bus latch.
|
||||
- Missing instruction bytes remain diagnostics, not hardware prefetch aborts.
|
||||
- Game Pak prefetch, per-access device updates, display contention, configurable EWRAM timing, and sub-instruction DMA arbitration remain unimplemented.
|
||||
|
||||
The next timing work is independently verified access-kind sequencing between instructions and data accesses.
|
||||
|
|
@ -39,6 +39,7 @@ It does not replay the bus observations of retained current/decode instructions.
|
|||
The consumer performs no mapped memory read.
|
||||
After successful control flow, the same target samples fill the instruction buffer and update local IWRAM history in either state.
|
||||
Machine IRQ entry uses this refill path; BIOS vector fetches leave IWRAM lanes unchanged.
|
||||
The later [refill timing extension](refill-fetch-timing.md) first samples the discarded source fetch, which can update IWRAM lanes.
|
||||
|
||||
Instruction buffers and BIOS/IWRAM latches remain separate retained state.
|
||||
Sampling alone changes no CPU access context, latch, device clock, DMA resume marker, or data-timing trace.
|
||||
|
|
@ -56,7 +57,7 @@ Strict instruction reads never use protected BIOS or unused-memory data fallback
|
|||
- All unused-memory data reads within an instruction still use its entry snapshot.
|
||||
- DMA remains scheduled between whole instructions. Sampling does not add an interleaving point.
|
||||
- Non-refill timing now consumes the sample's address in the [fetch-address extension](fetch-address-timing.md).
|
||||
- Destination-based refill summaries and instruction-local access kinds remain nominal.
|
||||
- Refills now charge the source fetch and target pair; instruction-local source access kinds remain nominal.
|
||||
- Per-access device updates, Game Pak prefetch, and exact refill/arbitration timing remain incomplete.
|
||||
|
||||
## Original tests
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ Refill bus history and instruction buffering now consume the same captured targe
|
|||
|
||||
Buffer samples add no nominal cycles or data accesses.
|
||||
Timed and untimed execution use the same buffer logic.
|
||||
Destination-based refill summaries remain unchanged.
|
||||
The later [refill timing extension](refill-fetch-timing.md) charges the incoming-state source fetch and outgoing-state target pair.
|
||||
The later [fetch-address timing extension](fetch-address-timing.md) selects non-refill and DMA-resume code costs from the new fetch address.
|
||||
Mapped boundary snapshots now follow the [actual fetch region](fetch-region-boundaries.md).
|
||||
Complete bus history, exact boundary timing, Game Pak prefetch, and sub-instruction DMA arbitration remain incomplete.
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@ Update this file when a feature lands or a limit is removed.
|
|||
- 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.
|
||||
- Non-refill code costs use actual ARM PC+8/Thumb PC+4 fetch addresses, including memory-region and ROM wait-window boundaries.
|
||||
- Code costs use actual ARM PC+8/Thumb PC+4 source fetches and branch/exception target pairs, including region and ROM boundaries.
|
||||
- IRQ entry samples its discarded incoming-state fetch before the ARM vector pair, with local IWRAM history updates.
|
||||
- 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, with CPU read protection based on retained ARM PC+8 or aligned Thumb PC+4 words.
|
||||
|
|
@ -79,7 +80,7 @@ Update this file when a feature lands or a limit is removed.
|
|||
- ARM unused-memory data reads return a PC+8 word snapshot, with normal byte lanes and load rotation.
|
||||
- Thumb unused-memory reads follow the actual PC+4 fetch region, including mapped boundaries, ROM windows, and IWRAM lane history.
|
||||
- Persistent IWRAM lanes track ARM/Thumb fetches, CPU data accesses, and successful DMA, with known-bit tracking and diagnostic rollback.
|
||||
- Cold fills and ARM/Thumb target pairs update local history; state changes and BIOS IRQ entry do not erase it.
|
||||
- Cold fills, ARM/Thumb target pairs, and discarded IRQ source fetches update addressed IWRAM lanes; state changes do not erase them.
|
||||
- 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.
|
||||
|
|
@ -141,7 +142,8 @@ ARM data reads from unused address ranges use a bounded [PC+8 open-bus snapshot]
|
|||
Thumb reads use [region-dependent snapshots](hardware/cpu.md#thumb-unused-memory-data-reads) and persistent local IWRAM lanes.
|
||||
Only actual IWRAM fetches and data accesses drive those lanes, independently of CPU state and executing region.
|
||||
Cold fills and target pairs establish both lanes when all required samples are mapped.
|
||||
State changes, other-region execution, and BIOS IRQ entry preserve local history; failed instructions discard staged updates.
|
||||
State changes and other-region accesses preserve local history; an IRQ source fetch updates lanes when it addresses IWRAM.
|
||||
Failed instructions discard staged updates.
|
||||
Successful DMA can establish lanes before CPU startup. Resumed fetches then update their addressed lanes.
|
||||
ARM/Thumb instruction buffering retains sequential instructions and refill target pairs.
|
||||
Instruction buffering and supported bus history now consume the same mapped fetch samples, without sharing retained storage.
|
||||
|
|
@ -162,8 +164,8 @@ Writes to cartridge addresses return errors instead of modeling cartridge hardwa
|
|||
Keep unknown history diagnostic until fetch ordering and latch ownership have independent coverage.
|
||||
Validate BIOS snapshots with independent hardware tests before claiming exact refill or data-access history.
|
||||
The desktop runner still uses only the original BIOS. Keep protected reads image-derived for all supplied images.
|
||||
2. Replace destination-only refill summaries with verified source-fetch/target-pair timing, including IRQ entry.
|
||||
Then extend access-kind sequencing, startup costs, Game Pak prefetch, per-access device updates, and timer/IRQ delays.
|
||||
2. Extend instruction-local source access kinds into verified neighboring instruction/data-access sequencing.
|
||||
Add startup costs, Game Pak prefetch, per-access device updates, and 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.
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ They check both target alignments, mirrors/wrap, captured target+2 versus later
|
|||
Original SWI/IRQ handlers verify return-time history. Failed returns, cold entry, region boundaries, DMA lane effects, and BIOS isolation retain checks.
|
||||
DMA tests compare source/destination lane updates against a byte-array reference, then apply the resumed PC+4 fetch.
|
||||
They cover channel preemption, blocked sources, failures, mirrors, pre-start lane establishment, cold fills, and other-region snapshot isolation.
|
||||
IRQ tests verify local-latch preservation; PC discontinuities verify new pipeline-fill samples.
|
||||
IRQ tests verify discarded-source lane updates and preservation across non-IWRAM fetches; PC discontinuities verify new pipeline-fill samples.
|
||||
Timed/untimed tests verify CPU results and nominal clock costs.
|
||||
Host/fetch isolation, separate BIOS history, unsupported stores/data regions, nominal device progression, and DMA diagnostics also have checks.
|
||||
ARM instruction-buffer tests verify retained P+4/P+8 words across CPU stores, DMA transfers, and host writes.
|
||||
|
|
@ -252,9 +252,13 @@ The bounded graphics frame runner is checked for instruction errors and timeouts
|
|||
Timing tests cover every ROM wait-state setting, access width, ROM window, and 128 KiB boundary handling.
|
||||
Fetch-address regressions place executing instructions before memory-region and ROM page/wait-window boundaries.
|
||||
They check ARM/Thumb widths, cold/retained pipelines, independent N/S tables, DMA resume, and pre-write WAITCNT settings.
|
||||
Other checks cover deferred fetch errors, unchanged nominal refill totals, timer advancement, and subsequent IRQ sampling.
|
||||
Other checks cover deferred fetch errors, source-plus-target refill totals, timer advancement, and subsequent IRQ sampling.
|
||||
Startup-ROM and timer expectations now use P+8/P+4 rather than the executing address; data and rollback assertions remain intact.
|
||||
See [fetch-address timing](research/fetch-address-timing.md) for the bounded scope.
|
||||
Refill timing tests cover incoming/outgoing widths, all ROM wait settings, and target first/second/third-slot page boundaries.
|
||||
They verify source DMA overrides, split wait-window pairs, missing source/target diagnostics, masked IRQ isolation, and device totals.
|
||||
IRQ history tests verify word/halfword lane updates without invented cold fills or BIOS instruction snapshots.
|
||||
See [refill timing](research/refill-fetch-timing.md) for source evidence and public-report changes.
|
||||
Instruction timing tests cover arithmetic, shifts, branches, transfers, block operations, multiply, and exception returns.
|
||||
Timed and untimed execution are compared across all 65,536 Thumb encodings with fixed initial registers.
|
||||
Timer/IRQ tests verify that changing WAITCNT changes when an interrupt is sampled.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue