feat(memory): sample Thumb IWRAM refill targets

After successful refill instructions, sample the Thumb IWRAM target and target+2 halfwords to establish bus history. Share ARM/Thumb refill classification with nominal timing. Respect restored instruction state, completed data accesses, region limits, and diagnostic rollback; keep instruction execution and nominal costs unchanged.

Add original regressions for ARM/Thumb BX, Thumb branches and BL, PC writes, stack/block PC loads, status-restoring returns, real SWI/IRQ returns, both target alignments, mirrors/wrap, captured sample ordering, load lanes, failure retention, BIOS isolation, and DMA invalidation. Document official ARM7TDMI refill evidence and the distinction from a full pipeline.

Darwin arm64 validation: 917 workspace tests and 848 core/demo tests per debug/release profile; 39 preparation tests; native ROM windows in both profiles; ten graphics/window smoke modes; fmt, clippy, and rustdoc. Public ARM, Thumb, memory, and BIOS reports remain identical to prior passing results and between profiles. Cold startup, ARM-target refill history, and DMA-to-CPU ordering remain incomplete; no hardware-conformance or commercial-game claim.
This commit is contained in:
0xrsydn 2026-10-06 02:04:07 +07:00
commit 8b0f1a5ead
12 changed files with 566 additions and 35 deletions

View file

@ -24,6 +24,8 @@ mod instruction_tests;
#[cfg(test)]
mod iwram_open_bus_tests;
#[cfg(test)]
mod iwram_refill_tests;
#[cfg(test)]
mod load_alias_tests;
#[cfg(test)]
mod open_bus_tests;
@ -211,14 +213,17 @@ impl Cpu {
// Record the executing instruction, not an operand's pipelined PC value.
// Always clear the access context, including on diagnostic errors.
let pc = self.pc();
let sequential_thumb =
self.instruction_set == InstructionSet::Thumb && !self.thumb_refills(instruction);
let refill = self.instruction_refills(instruction);
let sequential_thumb = self.instruction_set == InstructionSet::Thumb && !refill;
memory.begin_cpu_access(pc, self.instruction_set);
let result = self.execute_instruction(instruction, memory);
let sequential = sequential_thumb
&& self.instruction_set == InstructionSet::Thumb
&& self.pc() == pc.wrapping_add(2);
memory.end_cpu_access(result.is_ok(), sequential);
if result.is_ok() && refill {
memory.refill_cpu_bus_history(self.pc(), self.instruction_set);
}
result
}