non-volatile storage emulation
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user