From 074943f34bb92f67a0cfdcdfc8a8f7694a843569 Mon Sep 17 00:00:00 2001 From: Richard Dymond Date: Fri, 5 Apr 2024 17:38:16 -0300 Subject: [PATCH] Move 'custom_loader' and 'tape_end_time' into LoadTracer's 'state' list --- c/csimulator.c | 19 +++++------------ skoolkit/loadtracer.py | 48 ++++++++++++++++++++++++------------------ 2 files changed, 32 insertions(+), 35 deletions(-) diff --git a/c/csimulator.c b/c/csimulator.c index 54e451a4..5b6abb7f 100644 --- a/c/csimulator.c +++ b/c/csimulator.c @@ -6157,27 +6157,18 @@ static PyObject* CSimulator_load(CSimulatorObject* self, PyObject* args, PyObjec } if (!did_fast_load) { if (end_of_tape && stop == 0x10000) { - PyObject* cl = PyObject_GetAttrString(self->tracer, "custom_loader"); - if (cl == NULL) { - break; - } - int custom_loader = PyObject_IsTrue(cl); - Py_DECREF(cl); - if (custom_loader) { + if (tracer_state[7]) { + /* Custom loader was detected */ rv = PyLong_FromLong(1); break; } if (pc > 0x3FFF) { + /* PC in RAM */ rv = PyLong_FromLong(2); break; } - PyObject* tet = PyObject_GetAttrString(self->tracer, "tape_end_time"); - if (tet == NULL) { - break; - } - unsigned tape_end_time = PyLong_AsLong(tet); - Py_DECREF(tet); - if (TIME - tape_end_time > 3500000) { + if (TIME - tracer_state[8] > 3500000) { + /* Tape ended 1 second ago */ rv = PyLong_FromLong(3); break; } diff --git a/skoolkit/loadtracer.py b/skoolkit/loadtracer.py index 286acb5b..d8f9e1f4 100644 --- a/skoolkit/loadtracer.py +++ b/skoolkit/loadtracer.py @@ -172,8 +172,6 @@ def __init__(self, simulator, blocks, accelerators, pause, first_edge, polarity, self.block_index = 0 self.block_data_index = self.indexes[0][0] self.max_index = len(self.edges) - 1 - self.tape_end_time = 0 - self.custom_loader = False self.border = border if len(simulator.memory) == 65536: self.out7ffd = 0x10 # Signal: 48K ROM always @@ -184,14 +182,20 @@ def __init__(self, simulator, blocks, accelerators, pause, first_edge, polarity, self.outfe = outfe self.text = TextReader() self.state = [ - 0, # state[0]: next_edge - 0, # state[1]: index - 0, # state[2]: end_of_tape - self.indexes[0][1], # state[3]: block_max_index - 0, # state[4]: tape_running + 0, # state[0]: next edge (timestamp) + 0, # state[1]: edge index + 0, # state[2]: end of tape reached + self.indexes[0][1], # state[3]: index of final edge in current block + 0, # state[4]: tape running accel_dec_a, # state[5] list_accelerators, # state[6] + 0, # state[7]: custom loader detected + 0, # state[8]: tape end time ] + if hasattr(simulator, 'load'): # pragma: no cover + self.edges = array.array('I', self.edges) + self.state = array.array('I', self.state) + self.read_port = partial(self._read_port, self.state) def run(self, stop, fast_load, finish_tape, timeout, tracefile, trace_line, prefix, byte_fmt, word_fmt): simulator = self.simulator @@ -207,8 +211,6 @@ def run(self, stop, fast_load, finish_tape, timeout, tracefile, trace_line, pref else: df = tf = None ppf = lambda p: write(f'[{p/10:5.1f}%]\x08\x08\x08\x08\x08\x08\x08\x08') - self.edges = array.array('I', self.edges) - self.state = array.array('I', self.state) stop_cond = simulator.load(stop, fast_load, finish_tape, timeout, ppf, df, tf) pc = registers[24] else: @@ -270,18 +272,22 @@ def run(self, stop, fast_load, finish_tape, timeout, tracefile, trace_line, pref else: # Otherwise continue to play the tape until this block's # 'pause' period (if any) has elapsed - state[4] = 1 + state[4] = 1 # Signal: tape is running registers[25] = state[0] = edges[state[1]] pc = registers[24] else: if state[2] and stop is None: - if self.custom_loader: + # The tape has ended and no stop address is set + if state[7]: + # Custom loader was detected stop_cond = 1 break if pc > 0x3FFF: + # PC in RAM stop_cond = 2 break - if tstates - self.tape_end_time > 3500000: # pragma: no cover + if tstates - self.state[8] > 3500000: # pragma: no cover + # Tape ended 1 second ago stop_cond = 3 break if tstates > timeout: # pragma: no cover @@ -500,15 +506,15 @@ def list_accelerators(self, registers, memory, accelerators, auto_method, opcode self.dec_b_misses += 1 auto_method(registers, memory, ()) - def read_port(self, registers, port): + def _read_port(self, state, registers, port): if port % 256 == 0xFE: pc = registers[24] if pc >= self.in_min_addr or (0x0562 <= pc <= 0x05F1 and self.out7ffd & 0x10): - self.custom_loader = True - index = self.state[1] - if self.announce_data and not self.state[2]: + state[7] = 1 # Signal: custom loader detected + index = state[1] + if self.announce_data and not state[2]: self.announce_data = False - self.state[4] = 1 + state[4] = 1 # Signal: tape is running registers[T] = self.edges[index] length = len(self.blocks[self.block_index]) if length: @@ -538,16 +544,16 @@ def next_block(self, tstates): self.state[1] = self.state[3] + 1 self.state[0] = self.edges[self.state[1]] self.block_data_index, self.state[3] = self.indexes[self.block_index] - self.state[4] = int(not self.pause) + self.state[4] = int(not self.pause) # Pause tape unless configured not to self.announce_data = True def stop_tape(self, tstates): self.block_index = len(self.blocks) - self.state[2] += 1 + self.state[2] += 1 # Signal: end of tape reached if self.state[2] == 1: write_line('Tape finished') - self.tape_end_time = tstates - self.state[4] = 0 + self.state[8] = tstates # Set tape end time + self.state[4] = 0 # Signal: tape is not running def fast_load(self, simulator): registers = simulator.registers