Skip to content

Commit

Permalink
Move 'custom_loader' and 'tape_end_time' into LoadTracer's 'state' list
Browse files Browse the repository at this point in the history
  • Loading branch information
skoolkid committed Apr 5, 2024
1 parent 76ced63 commit 074943f
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 35 deletions.
19 changes: 5 additions & 14 deletions c/csimulator.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
48 changes: 27 additions & 21 deletions skoolkit/loadtracer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 074943f

Please sign in to comment.