From 80402f25a54743f9e234878a0804654cc0b01cf3 Mon Sep 17 00:00:00 2001 From: kris Date: Wed, 27 Feb 2019 22:46:53 +0000 Subject: [PATCH] - Allow HGR ROM entry point - Don't trap unexpected entrypoint when crossing between regions via RTS - Implement TICK handler - Improve status printing in CPU loop --- simulator/apple2.py | 18 +++++++++++++++--- simulator/machine.py | 6 ++++-- simulator/memory.py | 7 ++++--- simulator/uthernet.py | 2 +- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/simulator/apple2.py b/simulator/apple2.py index d058245..7ab06cd 100644 --- a/simulator/apple2.py +++ b/simulator/apple2.py @@ -33,6 +33,7 @@ class AppleII(machine.Machine): memory.MemoryRegion( "ROM", 0xd000, 0xffff, entrypoints={ + 0xf3e2: machine._Event("ROM", "HGR"), 0xfca8: self._Wait, 0xfded: machine._Event("ROM", "COUT"), 0xfe89: machine._Event("ROM", "Select the keyboard (IN#0)") @@ -71,9 +72,14 @@ class AppleII(machine.Machine): else: return self.uthernet.write_data(value) + def _tick(mode, value): + machine.Log("Tick", self.cpu.processorCycles) + # Set up interceptors for accessing various interesting parts of the # memory map self.io_map = { + 0xc030: ( + machine.AccessMode.RW, "TICK", _tick), 0xc094: ( machine.AccessMode.RW, "WMODE", _uther_wmode), 0xc095: ( @@ -181,16 +187,22 @@ class AppleII(machine.Machine): address)) def Run(self, pc, trace=False): + ctr = 0 self.cpu.pc = pc old_pc = self.cpu.pc while True: self.memory_manager.MaybeInterceptExecution(self.cpu, old_pc) old_pc = self.cpu.pc if trace: - print(self.cpu) - print(" $%04X: %s" % ( + cpu = str(self.cpu).split("\n") + if ctr % 20 == 0: + print(cpu[0]) + print(cpu[1], " $%04X: %-12s %d" % ( self.cpu.pc, - self.disassembler.instruction_at(self.cpu.pc)[1])) + self.disassembler.instruction_at(self.cpu.pc)[1], + self.cpu.processorCycles + )) self.cpu.step() if self.cpu.pc == old_pc: break + ctr += 1 diff --git a/simulator/machine.py b/simulator/machine.py index 9e79f64..bc6d076 100644 --- a/simulator/machine.py +++ b/simulator/machine.py @@ -61,12 +61,14 @@ class SoftSwitch: def set(self) -> Optional[int]: self.state = True Log(self.name, "Setting soft switch") - return self.callback(True) + if self.callback: + return self.callback(True) def clear(self) -> Optional[int]: self.state = False Log(self.name, "Clearing soft switch") - return self.callback(False) + if self.callback: + return self.callback(False) def get(self) -> int: Log(self.name, "Reading soft switch (%s)" % ( diff --git a/simulator/memory.py b/simulator/memory.py index f8049a8..524dfb0 100644 --- a/simulator/memory.py +++ b/simulator/memory.py @@ -71,7 +71,8 @@ class MemoryManager: if self.regions[old_pc] != self.regions[pc]: print("Entering region %s" % self.regions[pc].name) - if not handlers: + # Don't worry if last instruction was RTS + if self.memory[old_pc] != 0x60 and not handlers: raise UndefinedEntryPointException(self.regions[pc], old_pc, pc) for handler in handlers: @@ -87,8 +88,8 @@ class MemoryManager: self.memory.subscribe_to_write(addr_range, region.write_interceptor) if not region.writable: - self.memory.subscribe_to_write(addr_range, - self.DenyWritesToRegion(region)) + self.memory.subscribe_to_write( + addr_range, self.DenyWritesToRegion(region)) for addr in addr_range: self.regions[addr] = region diff --git a/simulator/uthernet.py b/simulator/uthernet.py index 4823e6a..5859a8e 100644 --- a/simulator/uthernet.py +++ b/simulator/uthernet.py @@ -3,7 +3,7 @@ import memory class Uthernet(machine.Machine): - """Uthernet device simulator.""" + """Uthernet/W5100 device simulator.""" def __init__(self, stream:bytes): memory_map = [