1
0

non-volatile storage emulation

This commit is contained in:
Aiden
2026-05-25 23:16:41 +10:00
parent 0c241877eb
commit 0819701b22
12 changed files with 647 additions and 36 deletions

View File

@@ -10,19 +10,22 @@ LOC_BFE0_TRANSFER_WRAPPER = 0xBFE0
LOC_BFFE_TRANSFER_WRAPPER = 0xBFFE
LOC_C08B_P9_WRITE_BYTE = 0xC08B
LOC_C0DB_P9_READ_BYTE = 0xC0DB
LOC_C10C_P9_MASTER_ACK = 0xC10C
LOC_C10C_P9_MARKER = 0xC10C
LOC_C121_P9_MARKER = 0xC121
LOC_C142_P9_MARKER = 0xC142
LOC_C121_P9_START = 0xC121
LOC_C121_P9_MARKER = LOC_C121_P9_START
LOC_C142_P9_STOP = 0xC142
LOC_C142_P9_MARKER = LOC_C142_P9_STOP
@dataclass(frozen=True)
class P9FastPathConfig:
"""Configuration for optional ROM P9 transfer shortcuts.
The helper assumes the CPU PC is exactly at a known routine entry. It
models the routine as if it completed successfully and returned via RTS.
Integration should keep this disabled unless the runner intentionally opts
into skipping these ROM routines.
The helper assumes the CPU PC is exactly at a known routine entry. It feeds
those byte/marker/wrapper operations into the modeled P9/X24164 bus and
returns via RTS. Integration should keep this disabled unless the runner
intentionally opts into skipping these ROM routines.
"""
enabled: bool = False
@@ -100,8 +103,7 @@ class P9FastPath:
elif pc == (self.config.read_byte_pc & 0xFFFF):
self._handle_read_byte(emulator)
elif pc in self.config.marker_pcs:
self.events.append(P9FastPathEvent("marker", pc))
self._return_from_subroutine(emulator)
self._handle_marker(emulator, pc)
elif pc in self.config.wrapper_pcs:
self._handle_wrapper(emulator)
else:
@@ -116,10 +118,12 @@ class P9FastPath:
pc = emulator.cpu.pc & 0xFFFF
value = emulator.cpu.regs[0] & 0xFF
self.output_bytes.append(value)
self.events.append(P9FastPathEvent("write_byte", pc, value))
success = emulator.memory.p9_bus.fast_write_byte(value)
self.events.append(P9FastPathEvent("write_byte", pc, value, source="x24164", success=success))
emulator.cpu.regs[0] = 1
self._set_logic_flags(emulator.cpu, 1, 1)
result = 1 if success else 0
emulator.cpu.regs[0] = result
self._set_logic_flags(emulator.cpu, result, 1)
self._return_from_subroutine(emulator)
def _handle_read_byte(self, emulator: Any) -> None:
@@ -127,6 +131,9 @@ class P9FastPath:
if self.input_bytes:
value = self.input_bytes.pop(0)
source = self.input_sources.pop(0) if self.input_sources else "queued"
elif (x24164_value := emulator.memory.p9_bus.fast_read_byte()) is not None:
value = x24164_value
source = "x24164"
else:
value = self.config.default_input_byte
source = "default_input_byte"
@@ -141,7 +148,27 @@ class P9FastPath:
def _handle_wrapper(self, emulator: Any) -> None:
pc = emulator.cpu.pc & 0xFFFF
success, source, queue_depth = emulator.memory.p9_bus.consume_wrapper_result()
success: bool
source: str
queue_depth: int | None
if pc == (LOC_BFE0_TRANSFER_WRAPPER & 0xFFFF):
address = emulator.cpu.regs[4] & 0x0FFF
value = emulator.cpu.regs[5] & 0xFFFF
write_success = emulator.memory.p9_bus.fast_write_word(address, value)
read_success, readback = emulator.memory.p9_bus.fast_read_word(address)
success = write_success and read_success and readback == value
source = "x24164_write_verify"
queue_depth = None
elif pc == (LOC_BFFE_TRANSFER_WRAPPER & 0xFFFF):
address = emulator.cpu.regs[4] & 0x0FFF
read_success, value = emulator.memory.p9_bus.fast_read_word(address)
if read_success:
emulator.cpu.regs[5] = value & 0xFFFF
success = read_success
source = "x24164_read_word"
queue_depth = None
else:
success, source, queue_depth = emulator.memory.p9_bus.consume_wrapper_result()
value = 1 if success else 0
self.events.append(
P9FastPathEvent(
@@ -163,6 +190,20 @@ class P9FastPath:
emulator.cpu.pc = emulator.memory.read16(sp) & 0xFFFF
emulator.cpu.regs[7] = (sp + 2) & 0xFFFF
def _handle_marker(self, emulator: Any, pc: int) -> None:
if pc == (LOC_C121_P9_START & 0xFFFF):
emulator.memory.p9_bus.fast_start()
self.events.append(P9FastPathEvent("start", pc, source="x24164"))
elif pc == (LOC_C10C_P9_MASTER_ACK & 0xFFFF):
emulator.memory.p9_bus.fast_master_ack(True)
self.events.append(P9FastPathEvent("master_ack", pc, source="x24164"))
elif pc == (LOC_C142_P9_STOP & 0xFFFF):
emulator.memory.p9_bus.fast_stop()
self.events.append(P9FastPathEvent("stop", pc, source="x24164"))
else:
self.events.append(P9FastPathEvent("marker", pc))
self._return_from_subroutine(emulator)
def _set_logic_flags(self, cpu: Any, value: int, size: int) -> None:
value &= mask(size)
cpu.z = value == 0