Eprom emulation
This commit is contained in:
@@ -9,6 +9,8 @@ from ..rom import Rom
|
||||
from .constants import (
|
||||
ON_CHIP_RAM_END,
|
||||
ON_CHIP_RAM_START,
|
||||
P7DDR,
|
||||
P7DR,
|
||||
P9DDR,
|
||||
P9DR,
|
||||
REGISTER_FIELD_END,
|
||||
@@ -22,6 +24,7 @@ from .constants import (
|
||||
)
|
||||
from .peripherals.lcd import LCD, LCD_E_CLOCK_DATA, LCD_E_CLOCK_STATUS
|
||||
from .peripherals.p9_bus import P9Bus
|
||||
from .peripherals.x24164 import factory_default_words_from_rom
|
||||
from .sci import SCI1
|
||||
|
||||
|
||||
@@ -35,7 +38,7 @@ class MemoryAccess:
|
||||
|
||||
|
||||
class MemoryMap:
|
||||
def __init__(self, rom_bytes: bytes, sci1: SCI1 | None = None) -> None:
|
||||
def __init__(self, rom_bytes: bytes, sci1: SCI1 | None = None, *, p7_input: int = 0xFF) -> None:
|
||||
self.rom = Rom(rom_bytes, base=0)
|
||||
self.sci1 = sci1 if sci1 is not None else SCI1()
|
||||
self.lcd = LCD()
|
||||
@@ -43,6 +46,7 @@ class MemoryMap:
|
||||
self.ram = bytearray(ON_CHIP_RAM_END - ON_CHIP_RAM_START + 1)
|
||||
self.registers = bytearray(REGISTER_FIELD_END - REGISTER_FIELD_START + 1)
|
||||
self.external: dict[int, int] = {}
|
||||
self.port_inputs: dict[int, int] = {P7DR: p7_input & 0xFF}
|
||||
self.access_log: list[MemoryAccess] = []
|
||||
|
||||
self._set_register(SCI1_SMR, self.sci1.smr)
|
||||
@@ -64,6 +68,8 @@ class MemoryMap:
|
||||
value = self.lcd.read_status()
|
||||
elif address == LCD_E_CLOCK_DATA:
|
||||
value = self.lcd.read_data()
|
||||
elif address == P7DR:
|
||||
value = self._read_port_data(P7DDR, P7DR)
|
||||
elif address in self.external:
|
||||
value = self.external[address]
|
||||
elif ON_CHIP_RAM_START <= address <= ON_CHIP_RAM_END:
|
||||
@@ -101,6 +107,8 @@ class MemoryMap:
|
||||
self.external[address] = value
|
||||
elif ON_CHIP_RAM_START <= address <= ON_CHIP_RAM_END:
|
||||
self.ram[address - ON_CHIP_RAM_START] = value
|
||||
elif address in (P7DDR, P7DR):
|
||||
self._set_register(address, value)
|
||||
elif address == P9DDR:
|
||||
self._set_register(address, self.p9_bus.write_ddr(value))
|
||||
elif address == P9DR:
|
||||
@@ -140,9 +148,28 @@ class MemoryMap:
|
||||
self._set_register(address, (value >> 8) & 0xFF)
|
||||
self._set_register((address + 1) & 0xFFFF, value & 0xFF)
|
||||
|
||||
def set_port_input(self, data_register: int, value: int, *, mask: int = 0xFF) -> None:
|
||||
data_register &= 0xFFFF
|
||||
old = self.port_inputs.get(data_register, 0xFF)
|
||||
self.port_inputs[data_register] = ((old & ~mask) | (value & mask)) & 0xFF
|
||||
|
||||
def seed_factory_eeprom_and_shadow(self) -> None:
|
||||
for offset, word in factory_default_words_from_rom(self.rom.data):
|
||||
address = 0xF400 + offset
|
||||
self.external[address & 0xFFFF] = (word >> 8) & 0xFF
|
||||
self.external[(address + 1) & 0xFFFF] = word & 0xFF
|
||||
self.p9_bus.x24164_bus.seed_factory_defaults_from_rom(self.rom.data)
|
||||
self.p9_bus.clear_x24164_trace()
|
||||
|
||||
def _set_register(self, address: int, value: int) -> None:
|
||||
self.registers[address - REGISTER_FIELD_START] = value & 0xFF
|
||||
|
||||
def _read_port_data(self, direction_register: int, data_register: int) -> int:
|
||||
ddr = self.registers[direction_register - REGISTER_FIELD_START]
|
||||
latch = self.registers[data_register - REGISTER_FIELD_START]
|
||||
pins = self.port_inputs.get(data_register, 0xFF)
|
||||
return ((latch & ddr) | (pins & ~ddr)) & 0xFF
|
||||
|
||||
def _log(self, kind: str, address: int, size: int, value: int) -> None:
|
||||
self.access_log.append(MemoryAccess(address, size, value, kind, self.region(address).name))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user