Emualtor RX side
This commit is contained in:
@@ -16,11 +16,19 @@ from .constants import (
|
||||
IPRA,
|
||||
IPRC,
|
||||
IPRE,
|
||||
SCI_SCR_RE,
|
||||
SCI_SCR_RIE,
|
||||
SCI_SCR_TIE,
|
||||
SCI_SSR_FER,
|
||||
SCI_SSR_ORER,
|
||||
SCI_SSR_PER,
|
||||
SCI_SSR_RDRF,
|
||||
SCI_SSR_TDRE,
|
||||
VECTOR_FRT1_OCIA,
|
||||
VECTOR_FRT2_OCIA,
|
||||
VECTOR_INTERVAL_TIMER,
|
||||
VECTOR_SCI1_ERI,
|
||||
VECTOR_SCI1_RXI,
|
||||
VECTOR_SCI1_TXI,
|
||||
)
|
||||
from .cpu import CPUState, mask, s8, s16, sign_bit
|
||||
@@ -97,6 +105,9 @@ class H8536Emulator:
|
||||
return self.memory.rom.u16(0)
|
||||
raise DecodeError("ROM does not contain a reset vector at H'0000")
|
||||
|
||||
def inject_sci1_rx_byte(self, value: int) -> None:
|
||||
self.memory.inject_sci1_rx_byte(value)
|
||||
|
||||
def step(self) -> str:
|
||||
pc = self.cpu.pc
|
||||
if self.p9_fast_path.try_handle(self):
|
||||
@@ -116,6 +127,8 @@ class H8536Emulator:
|
||||
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:
|
||||
@@ -366,6 +379,20 @@ class H8536Emulator:
|
||||
return (next_pc + s16(int.from_bytes(raw[1:3], "big"))) & 0xFFFF
|
||||
return int.from_bytes(raw[1:3], "big")
|
||||
|
||||
def _indirect_jump_call(self, raw: bytes, pc: int, next_pc: int) -> int:
|
||||
op = raw[1]
|
||||
if 0xC0 <= op <= 0xDF:
|
||||
target = self.cpu.regs[op & 0x07] & 0xFFFF
|
||||
elif 0xE0 <= op <= 0xEF and len(raw) >= 3:
|
||||
target = (self.cpu.regs[op & 0x07] + s8(raw[2])) & 0xFFFF
|
||||
elif 0xF0 <= op <= 0xFF and len(raw) >= 4:
|
||||
target = (self.cpu.regs[op & 0x07] + s16(int.from_bytes(raw[2:4], "big"))) & 0xFFFF
|
||||
else:
|
||||
raise UnsupportedInstruction(pc, raw, H8536Decoder(self.memory.rom, br=self.cpu.br).decode(pc).text)
|
||||
if 0xC8 <= op <= 0xCF or 0xD8 <= op <= 0xDF or 0xE8 <= op <= 0xEF or 0xF8 <= op <= 0xFF:
|
||||
self._push16(next_pc)
|
||||
return target
|
||||
|
||||
def _scb(self, raw: bytes, pc: int, next_pc: int) -> int:
|
||||
reg = raw[1] & 0x07
|
||||
condition = {0x01: False, 0x06: not self.cpu.z, 0x07: self.cpu.z}[raw[0]]
|
||||
@@ -389,6 +416,15 @@ class H8536Emulator:
|
||||
if self.cpu.interrupt_depth:
|
||||
return
|
||||
candidates: list[tuple[int, int, str]] = []
|
||||
sci1_rx_interrupts_enabled = bool(self.sci1.scr & SCI_SCR_RIE and self.sci1.scr & SCI_SCR_RE)
|
||||
if sci1_rx_interrupts_enabled and self.sci1.ssr & (SCI_SSR_ORER | SCI_SSR_FER | SCI_SSR_PER):
|
||||
target = self._vector_target(VECTOR_SCI1_ERI)
|
||||
if target is not None:
|
||||
candidates.append((self._sci1_priority(), target, "sci1_eri"))
|
||||
if sci1_rx_interrupts_enabled and self.sci1.ssr & SCI_SSR_RDRF:
|
||||
target = self._vector_target(VECTOR_SCI1_RXI)
|
||||
if target is not None:
|
||||
candidates.append((self._sci1_priority(), target, "sci1_rxi"))
|
||||
if self.sci1.scr & SCI_SCR_TIE and self.sci1.ssr & SCI_SSR_TDRE:
|
||||
target = self._vector_target(VECTOR_SCI1_TXI)
|
||||
if target is not None:
|
||||
|
||||
Reference in New Issue
Block a user