feat(memory): retain IWRAM lane effects across DMA
Update existing Thumb IWRAM continuation lanes from successful DMA reads and writes before the resumed PC+4 snapshot. Keep channel halfword duplication separate from actual lane accesses. Preserve atomic errors, cold-entry diagnostics, IRQ invalidation, and nominal timing. Add original DMA matrices and resume regressions; update prior invalidation expectations. Record pinned ares and jgenesis evidence and explicit limits for cross-state history, general open bus, and sub-instruction arbitration. Validated on Darwin arm64: 939 workspace and 870 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 identical to the previous results.
This commit is contained in:
parent
e72c643640
commit
663b25e5d1
15 changed files with 449 additions and 45 deletions
|
|
@ -30,7 +30,8 @@ The repository is a Cargo workspace with three crates:
|
|||
| `crates/gba-core/src/cpu/bios_access_tests.rs` | Original CPU BIOS protection regressions for retained history, modes, widths, exception returns, and diagnostics |
|
||||
| `crates/gba-core/src/cpu/thumb_bios_access_tests.rs` | Thumb BIOS aligned-word snapshots, transitions, load lanes, boundaries, diagnostics, and nominal timing |
|
||||
| `crates/gba-core/src/cpu/thumb_open_bus_tests.rs` | Region-dependent Thumb open bus, mirrors, widths, transfers, source boundaries, isolation, and nominal timing |
|
||||
| `crates/gba-core/src/cpu/iwram_open_bus_tests.rs` | Sequential IWRAM lane history, access widths, isolation, errors, refills, IRQ/DMA invalidation, and nominal timing |
|
||||
| `crates/gba-core/src/cpu/iwram_open_bus_tests.rs` | Sequential IWRAM lane history, access widths, isolation, errors, refills, IRQ invalidation, and nominal timing |
|
||||
| `crates/gba-core/src/cpu/iwram_dma_tests.rs` | Bounded DMA continuation lanes, access ordering, channel isolation, diagnostics, and resume snapshots |
|
||||
| `crates/gba-core/src/cpu/iwram_refill_tests.rs` | Thumb IWRAM target-pair refills, state changes, exception returns, boundaries, isolation, and nominal costs |
|
||||
| `crates/gba-core/src/memory/iwram_bus.rs` | Transactional known-lane history for Thumb IWRAM execution and target-pair refills |
|
||||
| `crates/gba-core/src/cpu/compare_psr_tests.rs` | Original Rd=15 test/compare status restoration, flags, bank, and timing regressions |
|
||||
|
|
|
|||
|
|
@ -128,7 +128,8 @@ See the [root-cause research](../research/bios-readback.md) for evidence and the
|
|||
|
||||
Host/debug reads and ROM-suite memory assertions still inspect raw mapped bytes and do not initialize or change the history.
|
||||
Instruction fetches remain strict mapped reads outside the CPU data-access context.
|
||||
BIOS writes remain read-only diagnostics. DMA BIOS sources retain their existing unsupported-source diagnostic.
|
||||
BIOS writes remain read-only diagnostics. DMA BIOS sources never read image bytes.
|
||||
They reuse known [channel data](dma.md#retained-channel-data), or report an unsupported-source diagnostic when channel data is unknown.
|
||||
Missing BIOS images remain unmapped. The unused-memory ARM open-bus snapshot is separate from this retained BIOS value.
|
||||
|
||||
The Thumb rule follows documented BIOS bus lanes and a source comparison with NanoBoyAdvance.
|
||||
|
|
|
|||
|
|
@ -99,11 +99,12 @@ Limits remain explicit:
|
|||
|
||||
- Thumb open bus uses the supported region rules below, including bounded sequential internal-RAM lane history.
|
||||
- [BIOS-protected reads](bios.md#cpu-bios-read-protection) use separate retained ARM PC+8 or aligned Thumb PC+4 word snapshots.
|
||||
- Unused/write-only I/O reads, DMA-to-CPU bus handoff, and disabled-RAM reads are not modeled here.
|
||||
- Unused/write-only I/O reads, general DMA-to-CPU bus handoff, and disabled-RAM reads are not modeled here.
|
||||
[DMA channel data](dma.md#retained-channel-data) is separate and never overrides a CPU snapshot.
|
||||
- Missing BIOS, truncated ROM, unsupported I/O, and save-memory accesses retain their existing diagnostics.
|
||||
- Unused-memory writes remain diagnostics rather than ignored hardware writes. Swaps cannot silently discard their write.
|
||||
- There is no persistent instruction pipeline. Thumb IWRAM refills sample their target pair, but DMA-to-CPU transitions remain unmodeled.
|
||||
- There is no persistent instruction pipeline. Thumb IWRAM refills sample their target pair.
|
||||
DMA updates existing IWRAM continuation lanes at instruction boundaries, not during CPU accesses.
|
||||
|
||||
This subset lets public ARM test 362 complete. That test does not assert the loaded data value.
|
||||
Original regressions check the values separately. See [the public ARM result](../public-arm-tests.md).
|
||||
|
|
@ -166,7 +167,8 @@ This preserves the existing atomic diagnostic policy without adding bus or devic
|
|||
Taken branches and PC-writing refills end the old continuation history, even when their target is the fallthrough address.
|
||||
A successful refill into Thumb IWRAM establishes new history from its target pair, as described below.
|
||||
Untaken conditional branches keep sequential history.
|
||||
Other execution states/regions, accepted machine IRQs, and successful DMA units invalidate continuation history.
|
||||
Other execution states/regions and accepted machine IRQs invalidate continuation history.
|
||||
Successful DMA units update existing continuation lanes as described below.
|
||||
A later exception return into Thumb IWRAM can establish new history through its refill.
|
||||
Failed DMA units leave history unchanged. Discontinuous entry without an executed refill starts unknown.
|
||||
|
||||
|
|
@ -186,10 +188,32 @@ Snapshots use strict mapped reads and add no nominal data or device cycles.
|
|||
They update bus history only; the interpreter does not cache these instructions for execution.
|
||||
Host inspection does not change captured lanes. A failed target fetch remains a later instruction diagnostic.
|
||||
Cold direct startup, unsupported target states/regions, and region-crossing lookahead still have no inferred refill history.
|
||||
DMA between refill and arrival still invalidates this history rather than supplying a guessed DMA value.
|
||||
DMA between refill and arrival updates this continuation's actual IWRAM access lanes before the target+4 sample.
|
||||
|
||||
The [refill evidence and scope](../research/iwram-bus-history.md#thumb-iwram-refill-extension) distinguish these samples from a full pipeline.
|
||||
ARM-target refill history, DMA ordering, self-modifying instruction execution, and exact refill timing remain incomplete.
|
||||
ARM-target refill history, sub-instruction DMA ordering, self-modifying instruction execution, and exact refill timing remain incomplete.
|
||||
|
||||
### DMA effects on Thumb IWRAM continuations
|
||||
|
||||
Within the instruction-boundary scheduler, DMA finishes before the next CPU PC+4 sample.
|
||||
For an existing sequential or refill continuation, each successful DMA unit updates IWRAM source lanes, then IWRAM destination lanes.
|
||||
Word accesses replace all lanes. Halfword accesses replace only the addressed halfword.
|
||||
Other memory regions do not replace the local IWRAM value, even when DMA's channel data changes.
|
||||
The resumed PC+4 fetch then replaces one halfword before the instruction's unused-memory snapshot is taken.
|
||||
|
||||
Channel halfword duplication is not a full-word IWRAM access.
|
||||
A blocked source below work RAM does not drive IWRAM; an IWRAM destination still drives the halfword or word actually written.
|
||||
Multiple units and channel preemption update lanes in access order, not channel-number order.
|
||||
Host inspection/setup cannot change them.
|
||||
|
||||
History changes commit only after a unit succeeds. A failed unit retains the previous successful unit's history.
|
||||
A failed resumed instruction discards its staged changes, not the completed DMA history.
|
||||
DMA does not establish an expected PC at cold direct entry. Existing partially known continuations can gain known lanes.
|
||||
PC discontinuities, unsupported state changes, IRQ entry, and region-crossing lookahead keep their existing conservative rules.
|
||||
|
||||
This implements local lane effects, not a general last-DMA-value override or a persistent pipeline.
|
||||
Sub-instruction arbitration, DMA during CPU internal cycles, cold/cross-state IWRAM history, and exact resume timing remain incomplete.
|
||||
See [the source evidence and limits](../research/iwram-bus-history.md#dma-continuation-extension).
|
||||
|
||||
## Processor status and exceptions
|
||||
|
||||
|
|
|
|||
|
|
@ -55,8 +55,10 @@ DMA writes to DMA registers return `DmaError::RegisterDestination`; self-modifyi
|
|||
Other accesses use the existing memory map, alignment checks, mirrors, and I/O write rules.
|
||||
Other unmapped reads and cartridge writes remain diagnostics, not general DMA open-bus behavior.
|
||||
A failed unit changes no memory, device state, or clock. Earlier units remain committed; the failed unit remains pending.
|
||||
Successful units invalidate bounded sequential Thumb IWRAM history because DMA-to-CPU latch ordering is not modeled.
|
||||
Failed units preserve that history. No DMA value is substituted for a CPU open-bus read.
|
||||
Successful units update existing Thumb IWRAM continuation lanes for their actual IWRAM reads and writes, in that order.
|
||||
Accesses elsewhere leave those local lanes unchanged. Failed units preserve history.
|
||||
The resumed CPU's PC+4 fetch then updates its addressed halfword. No universal DMA-value override is used.
|
||||
See [bounded IWRAM DMA history](cpu.md#dma-effects-on-thumb-iwram-continuations) for the scope.
|
||||
|
||||
## Retained channel data
|
||||
|
||||
|
|
@ -83,5 +85,5 @@ Earlier successful units remain committed. Normal destination validation, nomina
|
|||
This error policy is not a model of hardware data aborts.
|
||||
|
||||
See [the latch evidence and scope](../research/dma-data-latches.md).
|
||||
General DMA open-bus reads, IWRAM lane effects, and CPU bus ownership on resume remain unimplemented.
|
||||
General DMA open-bus reads, cross-state IWRAM history, and sub-instruction bus ownership remain unimplemented.
|
||||
In particular, the known channel value does not supply unused/write-only I/O reads or CPU open-bus snapshots.
|
||||
|
|
|
|||
|
|
@ -130,6 +130,15 @@ DMA data-latch research:
|
|||
|
||||
See [DMA data-latch findings](research/dma-data-latches.md). Source review is not a local hardware-test pass.
|
||||
|
||||
DMA IWRAM continuation research:
|
||||
|
||||
- [jgenesis bus at fab6e2cc](https://github.com/jsgroth/jgenesis/blob/fab6e2ccc60e492dd68b7f1e927b0829a6d80195/backend/gba-core/src/bus.rs), for DMA read/write dispatch through the same lane-retaining IWRAM helpers as CPU accesses.
|
||||
Its [DMA controller](https://github.com/jsgroth/jgenesis/blob/fab6e2ccc60e492dd68b7f1e927b0829a6d80195/backend/gba-core/src/dma.rs) and [memory storage](https://github.com/jsgroth/jgenesis/blob/fab6e2ccc60e492dd68b7f1e927b0829a6d80195/backend/gba-core/src/memory.rs) distinguish channel data from local bus lanes.
|
||||
- The pinned ares DMA, bus dispatch, and IWRAM helpers above independently use the same local lane ownership.
|
||||
|
||||
See [the bounded DMA continuation extension](research/iwram-bus-history.md#dma-continuation-extension).
|
||||
These source reviews do not establish sub-instruction arbitration, exact CPU resume timing, or hardware conformance.
|
||||
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -33,9 +33,10 @@ Its IWRAM bus and general data register are separate, and pending DMA runs befor
|
|||
GBATEK's possible DMA influence on IWRAM is not sufficient to choose CPU resume ordering here.
|
||||
Our instruction-boundary scheduler does not yet represent these per-access transitions.
|
||||
|
||||
Therefore, this change keeps successful-DMA invalidation of bounded Thumb IWRAM history.
|
||||
Failed DMA preserves that history. No channel value is injected into CPU or BIOS snapshots.
|
||||
The next CPU-bus work needs independent resume-ordering coverage rather than a universal last-transfer override.
|
||||
The initial channel-latch change kept successful-DMA invalidation of bounded Thumb IWRAM history.
|
||||
The later [DMA continuation extension](iwram-bus-history.md#dma-continuation-extension) models local IWRAM lanes at instruction boundaries.
|
||||
Failed DMA preserves that history. No universal channel-value override is injected into CPU or BIOS snapshots.
|
||||
General CPU-bus work still needs independent resume-ordering coverage rather than a universal last-transfer override.
|
||||
|
||||
## Implemented subset
|
||||
|
||||
|
|
@ -55,7 +56,8 @@ Other unmapped sources and unsupported controls remain diagnostics even with kno
|
|||
The existing atomic diagnostic policy commits no new latch value for a failed unit.
|
||||
Earlier successful units remain visible. A partial failed read cannot replace their retained value.
|
||||
Nominal source/destination costs, CPU pausing, trigger scheduling, and completion IRQs are unchanged.
|
||||
General DMA open-bus reads, write-only register readback, local IWRAM lane effects, and CPU resume ownership remain outside this subset.
|
||||
General DMA open-bus reads, write-only register readback, and general CPU resume ownership remain outside this subset.
|
||||
Local IWRAM lane effects are now covered by the separately bounded continuation extension linked above.
|
||||
|
||||
## Validation scope
|
||||
|
||||
|
|
|
|||
|
|
@ -52,8 +52,8 @@ The initial sequential-only implementation invalidated history after all refill
|
|||
The extension below now establishes target-pair history for successful refills into Thumb IWRAM.
|
||||
The existing ARM/Thumb timing classifiers identify these refills for both timed and untimed CPU stepping.
|
||||
Execution outside Thumb IWRAM still ends a sequential history sequence.
|
||||
An accepted machine IRQ and each successful DMA unit invalidate history. Failed DMA units preserve it.
|
||||
The implementation does not guess DMA latch contents.
|
||||
An accepted machine IRQ invalidates history. Failed DMA units preserve it.
|
||||
The DMA extension below updates existing continuation lanes from successful IWRAM accesses.
|
||||
|
||||
This is not a full IWRAM bus model across all CPU states. ARM-target history and DMA-to-CPU ordering remain incomplete.
|
||||
It is not a persistent instruction pipeline. Self-modifying instruction execution and exact per-access device timing remain unverified.
|
||||
|
|
@ -81,10 +81,41 @@ The interpreter still reads instructions when it executes them.
|
|||
Changing T+2 after the branch does not replace its captured bus value; changing T+4 before arrival affects the later sample.
|
||||
Those original tests verify sample ordering, not hardware-accurate self-modifying instruction execution.
|
||||
|
||||
Successful DMA still invalidates history, including between refill and arrival.
|
||||
ARM-target refill history, exact pipeline timing, and DMA-to-CPU ordering remain outside this extension.
|
||||
The refill-only implementation invalidated history on successful DMA, including between refill and arrival.
|
||||
The DMA extension below replaces that invalidation within existing continuations.
|
||||
ARM-target refill history, exact pipeline timing, and sub-instruction DMA ordering remain incomplete.
|
||||
No external emulator differential run or physical-hardware test was performed.
|
||||
|
||||
## DMA continuation extension
|
||||
|
||||
Two independent implementations route DMA through the same local IWRAM lane updates as CPU accesses:
|
||||
|
||||
- [ares bus dispatch](https://github.com/ares-emulator/ares/blob/6f6786e04f0822a3475463df284f313ab8518d51/ares/gba/cpu/bus.cpp) selects its IWRAM helpers for both CPU and DMA.
|
||||
[Its DMA controller](https://github.com/ares-emulator/ares/blob/6f6786e04f0822a3475463df284f313ab8518d51/ares/gba/cpu/dma.cpp) performs a source read before its destination write.
|
||||
- [jgenesis bus at fab6e2cc](https://github.com/jsgroth/jgenesis/blob/fab6e2ccc60e492dd68b7f1e927b0829a6d80195/backend/gba-core/src/bus.rs) routes `AccessCtx::DMA` through `read_iwram` and `write_iwram`.
|
||||
Both call `iwram_update_open_bus`, which changes only addressed lanes and drives the general bus from the local word.
|
||||
Its `try_progress_dma` performs source reads and destination writes in order.
|
||||
|
||||
Both run pending DMA before a CPU bus access. The access that resumes determines the subsequent bus value.
|
||||
These source reviews support local lane effects, not a universal first-instruction DMA override.
|
||||
They do not determine every hardware arbitration edge or validate our instruction-boundary scheduling.
|
||||
|
||||
Our bounded model applies those effects only when an existing Thumb IWRAM continuation has an expected next PC.
|
||||
After a successful unit, the source and destination independently update their addressed IWRAM lanes.
|
||||
DMA elsewhere leaves those lanes unchanged. A blocked source drives no IWRAM read lanes.
|
||||
The destination sees the actual selected halfword, not an assumed duplicated full word.
|
||||
The next PC+4 sample updates one halfword before the resumed instruction takes its snapshot.
|
||||
This also applies between a completed refill and its first target instruction.
|
||||
|
||||
Only complete successful units commit history, preserving the project's atomic diagnostic policy.
|
||||
Cold direct entry still has no expected continuation PC. DMA does not manufacture one, even after a word access.
|
||||
An existing partially known continuation can gain lanes. IRQ entry and CPU discontinuities retain their invalidation rules.
|
||||
General DMA open-bus reads, cross-state history, sub-instruction arbitration, and DMA during CPU internal cycles remain outside this subset.
|
||||
The interpreter still fetches instructions directly; this extension does not fix self-modifying instruction-buffer behavior.
|
||||
|
||||
No physical-hardware measurements or external emulator differential runs were performed.
|
||||
All regression programs are original, with a separate byte-array lane reference in the DMA matrix tests.
|
||||
|
||||
## Original regression coverage
|
||||
|
||||
- Both code alignments, IWRAM mirrors, and physical RAM wrap.
|
||||
|
|
@ -96,12 +127,15 @@ No external emulator differential run or physical-hardware test was performed.
|
|||
- Taken and untaken branches, PC writes to fallthrough, discontinuities, IRQ entry, and DMA success/failure.
|
||||
- ARM/Thumb source regions, both target alignments, refill sample ordering, stack/block returns, and saved User/System banks.
|
||||
- Actual SWI/IRQ return handlers, failed refills, unmapped targets, separate BIOS history, and DMA between refill and arrival.
|
||||
- DMA source/destination regions and alignments, word/halfword widths, mirrors, blocked-source lane selection, and other-region isolation.
|
||||
- Channel preemption, completed-unit order, DMA/instruction failure retention, partial/cold continuations, and unchanged other CPU snapshot rules.
|
||||
- Equal timed/untimed CPU results and unchanged nominal data/device costs.
|
||||
|
||||
## Validation result
|
||||
|
||||
The sequential-history regressions reproduced the old unsupported-read failures before implementation.
|
||||
The refill regressions also failed on the prior invalidation-only path, then passed with target-pair sampling.
|
||||
The DMA continuation regressions reproduced unsupported-read failures under unconditional DMA invalidation, then passed with local lane updates.
|
||||
Workspace and core/demo tests pass on Darwin arm64 in debug and release builds.
|
||||
Formatting, lint checks, rustdoc, preparation tests, native ROM windows, and graphics smoke modes also pass.
|
||||
Public ARM, Thumb, memory, and BIOS reports match their previous passing results exactly.
|
||||
|
|
|
|||
|
|
@ -137,8 +137,9 @@ 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 bounded sequential IWRAM lane history.
|
||||
Cold or invalidated IWRAM history remains diagnostic until all lanes are known.
|
||||
Refills into Thumb IWRAM establish new target-pair history after the instruction succeeds.
|
||||
Accepted machine IRQs, successful DMA, unsupported refills, and other execution states/regions invalidate continuation history.
|
||||
This is not a fetch pipeline. ARM-target refill history, region-crossing fetches, DMA-to-CPU handoff, and unused/write-only I/O open bus remain unsupported.
|
||||
Accepted machine IRQs, unsupported refills, and other execution states/regions invalidate continuation history.
|
||||
Successful DMA updates existing Thumb IWRAM continuation lanes for actual IWRAM accesses, before the resumed PC+4 sample.
|
||||
This is not a fetch pipeline. ARM-target history, region-crossing fetches, general DMA handoff, and unused/write-only I/O open bus remain unsupported.
|
||||
[DMA channel data latches](hardware/dma.md#retained-channel-data) support blocked-source reuse, but never replace CPU bus history.
|
||||
BIOS protection uses separate retained BIOS fetch snapshots as described in [BIOS behavior](hardware/bios.md#cpu-bios-read-protection).
|
||||
Host inspection and instruction fetches remain strict. Other unmapped reads return errors.
|
||||
|
|
@ -149,8 +150,8 @@ Writes to cartridge addresses return errors instead of modeling cartridge hardwa
|
|||
|
||||
## Next steps
|
||||
|
||||
1. Extend the DMA channel-latch foundation with validated DMA-to-CPU bus ownership and IWRAM effects.
|
||||
General DMA open-bus reads need separate evidence; blocked-source reuse does not establish their values.
|
||||
1. Extend bounded IWRAM DMA continuations toward general bus ownership with independent per-access resume tests.
|
||||
General DMA open-bus reads and sub-instruction arbitration remain separate from retained channel data and local IWRAM lanes.
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -75,8 +75,10 @@ Known-bit tests reject incomplete words. Transaction tests verify discarded part
|
|||
Control-flow tests distinguish taken/untaken branches and refill Thumb IWRAM targets even when the target equals fallthrough.
|
||||
Refill tests cover ARM/Thumb BX, Thumb branches and BL, high-register PC writes, stack/block PC loads, and saved-state returns.
|
||||
They check both target alignments, mirrors/wrap, captured target+2 versus later target+4, widths, sign extension, and rotation.
|
||||
Original SWI/IRQ handlers verify return-time history. Failed returns, cold entry, region boundaries, DMA invalidation, and BIOS isolation retain checks.
|
||||
DMA and IRQ tests check conservative invalidation; timed/untimed tests verify CPU results and nominal clock costs.
|
||||
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, partial/cold continuations, and other-region snapshot isolation.
|
||||
IRQ and PC-discontinuity tests retain conservative invalidation; 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.
|
||||
The pinned public ARM ROM now reaches its completion checkpoint with r12 = 0 in debug and release builds.
|
||||
The pinned public Thumb ROM also reaches its ARM-state checkpoint with r7 = 0 in both builds.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue