1
0

command advance sweep

This commit is contained in:
Aiden
2026-05-26 15:21:52 +10:00
parent 74a2e2fd2c
commit a48fa0ed18
14 changed files with 821 additions and 78 deletions

View File

@@ -41,6 +41,7 @@ from .fast_paths import P9FastPath, P9FastPathConfig
from .memory import MemoryMap
from .sci import SCI1
from .timers import FrtOciaScheduler, FrtRegisters
from .uart import UartTiming
@dataclass
@@ -94,6 +95,7 @@ class H8536Emulator:
p9_fast_default_wrapper_success: bool = False,
p7_input: int = 0xFF,
eeprom_seed: str = "blank",
sci1_tx_timing: UartTiming | None = None,
) -> None:
if not rom_bytes:
raise ValueError("ROM image is empty")
@@ -103,6 +105,7 @@ class H8536Emulator:
self.memory = MemoryMap(rom_bytes, self.sci1, p7_input=p7_input)
if eeprom_seed == "factory":
self.memory.seed_factory_eeprom_and_shadow()
self.sci1.configure_tx_timing(sci1_tx_timing, clock_hz=clock_hz)
self.memory.p9_bus.default_wrapper_success = bool(p9_fast_default_wrapper_success)
self.p9_fast_path = p9_fast_path or P9FastPath(
P9FastPathConfig(enabled=p9_fast_path_enabled, default_input_byte=p9_fast_default_input_byte)
@@ -134,66 +137,70 @@ class H8536Emulator:
def step(self) -> str:
pc = self.cpu.pc
cycles_before = self.cpu.cycles
if self.p9_fast_path.try_handle(self):
self._tick_peripherals(self.cpu.cycles - cycles_before)
return f"{h16(pc)}: {'<p9-fast-path>':<17} P9 fast-path"
self.memory.current_pc = pc
try:
if self.p9_fast_path.try_handle(self):
self._tick_peripherals(self.cpu.cycles - cycles_before)
return f"{h16(pc)}: {'<p9-fast-path>':<17} P9 fast-path"
decoder = H8536Decoder(self.memory.rom, br=self.cpu.br)
ins = decoder.decode(pc)
if not ins.valid:
raise UnsupportedInstruction(pc, ins.raw, ins.text)
decoder = H8536Decoder(self.memory.rom, br=self.cpu.br)
ins = decoder.decode(pc)
if not ins.valid:
raise UnsupportedInstruction(pc, ins.raw, ins.text)
next_pc = (pc + ins.size) & 0xFFFF
raw = ins.raw
text = ins.text
next_pc = (pc + ins.size) & 0xFFFF
raw = ins.raw
text = ins.text
if raw[0] == 0x00:
pass
elif raw[0] == 0x02 and len(raw) == 2:
self._pop_register_mask(raw[1])
elif raw[0] == 0x11 and len(raw) >= 2:
next_pc = self._indirect_jump_call(raw, pc, next_pc)
elif raw[0] == 0x12 and len(raw) == 2:
self._push_register_mask(raw[1])
elif raw[0] in (0x01, 0x06, 0x07) and len(raw) == 3 and 0xB8 <= raw[1] <= 0xBF:
next_pc = self._scb(raw, pc, next_pc)
elif raw[0] in (0x04, 0x0C):
next_pc = self._execute_general(pc, next_pc)
elif 0x40 <= raw[0] <= 0x47 and len(raw) == 2:
reg = raw[0] & 0x07
self._cmp(self._reg_read(reg, 1), raw[1], 1)
elif 0x48 <= raw[0] <= 0x4F and len(raw) == 3:
reg = raw[0] & 0x07
self._cmp(self.cpu.regs[reg], int.from_bytes(raw[1:3], "big"), 2)
elif 0x50 <= raw[0] <= 0x57 and len(raw) == 2:
self._reg_write(raw[0] & 0x07, raw[1], 1)
self._set_logic_flags(raw[1], 1)
elif 0x58 <= raw[0] <= 0x5F and len(raw) == 3:
self.cpu.regs[raw[0] & 0x07] = int.from_bytes(raw[1:3], "big")
self._set_logic_flags(self.cpu.regs[raw[0] & 0x07], 2)
elif raw[0] in (0x0E, 0x1E, 0x18):
next_pc = self._direct_call(raw, next_pc)
elif raw[0] == 0x19:
next_pc = self._pop16()
elif raw[0] == 0x0A:
next_pc = self._return_from_interrupt()
elif raw[0] in (0x15, 0x1D) and len(raw) >= 4:
next_pc = self._execute_general(pc, next_pc)
elif raw[0] in range(0xA0, 0x100):
next_pc = self._execute_general(pc, next_pc)
elif raw[0] in range(0x20, 0x30) and len(raw) == 2:
next_pc = self._branch8(raw, pc, next_pc)
elif raw[0] in range(0x30, 0x40) and len(raw) == 3:
next_pc = self._branch16(raw, pc, next_pc)
else:
raise UnsupportedInstruction(pc, raw, text)
if raw[0] == 0x00:
pass
elif raw[0] == 0x02 and len(raw) == 2:
self._pop_register_mask(raw[1])
elif raw[0] == 0x11 and len(raw) >= 2:
next_pc = self._indirect_jump_call(raw, pc, next_pc)
elif raw[0] == 0x12 and len(raw) == 2:
self._push_register_mask(raw[1])
elif raw[0] in (0x01, 0x06, 0x07) and len(raw) == 3 and 0xB8 <= raw[1] <= 0xBF:
next_pc = self._scb(raw, pc, next_pc)
elif raw[0] in (0x04, 0x0C):
next_pc = self._execute_general(pc, next_pc)
elif 0x40 <= raw[0] <= 0x47 and len(raw) == 2:
reg = raw[0] & 0x07
self._cmp(self._reg_read(reg, 1), raw[1], 1)
elif 0x48 <= raw[0] <= 0x4F and len(raw) == 3:
reg = raw[0] & 0x07
self._cmp(self.cpu.regs[reg], int.from_bytes(raw[1:3], "big"), 2)
elif 0x50 <= raw[0] <= 0x57 and len(raw) == 2:
self._reg_write(raw[0] & 0x07, raw[1], 1)
self._set_logic_flags(raw[1], 1)
elif 0x58 <= raw[0] <= 0x5F and len(raw) == 3:
self.cpu.regs[raw[0] & 0x07] = int.from_bytes(raw[1:3], "big")
self._set_logic_flags(self.cpu.regs[raw[0] & 0x07], 2)
elif raw[0] in (0x0E, 0x1E, 0x18):
next_pc = self._direct_call(raw, next_pc)
elif raw[0] == 0x19:
next_pc = self._pop16()
elif raw[0] == 0x0A:
next_pc = self._return_from_interrupt()
elif raw[0] in (0x15, 0x1D) and len(raw) >= 4:
next_pc = self._execute_general(pc, next_pc)
elif raw[0] in range(0xA0, 0x100):
next_pc = self._execute_general(pc, next_pc)
elif raw[0] in range(0x20, 0x30) and len(raw) == 2:
next_pc = self._branch8(raw, pc, next_pc)
elif raw[0] in range(0x30, 0x40) and len(raw) == 3:
next_pc = self._branch16(raw, pc, next_pc)
else:
raise UnsupportedInstruction(pc, raw, text)
self.cpu.pc = next_pc
self.cpu.steps += 1
cycle_delta = self._rough_cycles(raw)
self.cpu.cycles += cycle_delta
self._tick_peripherals(cycle_delta)
return f"{h16(pc)}: {' '.join(f'{byte:02X}' for byte in raw):<17} {text}"
self.cpu.pc = next_pc
self.cpu.steps += 1
cycle_delta = self._rough_cycles(raw)
self.cpu.cycles += cycle_delta
self._tick_peripherals(cycle_delta)
return f"{h16(pc)}: {' '.join(f'{byte:02X}' for byte in raw):<17} {text}"
finally:
self.memory.current_pc = None
def run(self, max_steps: int, trace: bool = False, stop_on_heartbeat: bool = False) -> RunReport:
trace_lines: list[str] = []
@@ -434,7 +441,7 @@ class H8536Emulator:
return next_pc
def _tick_peripherals(self, cycle_delta: int) -> None:
self.sci1.tick()
self.sci1.tick(cycle_delta)
self._interval_counter += 1
if self.frt1_ocia_steps is None:
self.frt1_ocia.tick(self.memory, cycle_delta)