command advance sweep
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user