Skip to content

Commit

Permalink
Fix how 'trace.py --max-tstates' counts T-states
Browse files Browse the repository at this point in the history
  • Loading branch information
skoolkid committed Mar 31, 2024
1 parent ce3f96a commit d1b8e3e
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 15 deletions.
6 changes: 3 additions & 3 deletions c/csimulator.c
Original file line number Diff line number Diff line change
Expand Up @@ -5359,12 +5359,12 @@ static PyObject* CSimulator_trace(CSimulatorObject* self, PyObject* args, PyObje
PyObject* start_obj;
PyObject* stop_obj;
unsigned long long max_operations;
unsigned long long max_tstates;
unsigned long long max_time;
int interrupts;
PyObject* disassemble;
PyObject* trace;

if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOKKiOO", kwlist, &start_obj, &stop_obj, &max_operations, &max_tstates, &interrupts, &disassemble, &trace)) {
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOKKiOO", kwlist, &start_obj, &stop_obj, &max_operations, &max_time, &interrupts, &disassemble, &trace)) {
return NULL;
}

Expand Down Expand Up @@ -5446,7 +5446,7 @@ static PyObject* CSimulator_trace(CSimulatorObject* self, PyObject* args, PyObje
if (max_operations > 0 && operations >= max_operations) {
return Py_BuildValue("(IL)", 1, operations);
}
if (max_tstates > 0 && REG(T) >= max_tstates) {
if (max_time > 0 && REG(T) >= max_time) {
return Py_BuildValue("(IL)", 2, operations);
}
if (REG(PC) == stop) {
Expand Down
17 changes: 10 additions & 7 deletions skoolkit/trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ def run(self, start, stop, max_operations, max_tstates, interrupts, trace_line,
simulator = self.simulator
memory = simulator.memory
registers = simulator.registers
start_time = registers[T]
if max_tstates > 0:
max_time = start_time + max_tstates
else:
max_time = 0
r = Registers(registers)

if hasattr(simulator, 'trace'): # pragma: no cover
Expand All @@ -52,9 +57,7 @@ def run(self, start, stop, max_operations, max_tstates, interrupts, trace_line,
tf = lambda pc, i, t0: print(trace_line.format(pc=pc, i=i, r=r, t=t0))
else:
df = tf = None
stop_cond, operations = simulator.trace(start, stop, max_operations, max_tstates, interrupts, df, tf)
pc = registers[24]
tstates = registers[25]
stop_cond, operations = simulator.trace(start, stop, max_operations, max_time, interrupts, df, tf)
else:
opcodes = simulator.opcodes
frame_duration = simulator.frame_duration
Expand Down Expand Up @@ -82,19 +85,19 @@ def run(self, start, stop, max_operations, max_tstates, interrupts, trace_line,
if operations >= max_operations > 0:
stop_cond = 1
break
if tstates >= max_tstates > 0:
if tstates >= max_time > 0:
stop_cond = 2
break
if pc == stop:
stop_cond = 3
break

if stop_cond == 1:
print(f'Stopped at {prefix}{pc:{word_fmt}}: {operations} operations')
print(f'Stopped at {prefix}{registers[PC]:{word_fmt}}: {operations} operations')
elif stop_cond == 2:
print(f'Stopped at {prefix}{pc:{word_fmt}}: {tstates} T-states')
print(f'Stopped at {prefix}{registers[PC]:{word_fmt}}: {registers[T] - start_time} T-states')
elif stop_cond == 3:
print(f'Stopped at {prefix}{pc:{word_fmt}}')
print(f'Stopped at {prefix}{registers[PC]:{word_fmt}}')
self.operations = operations

def read_port(self, registers, port):
Expand Down
2 changes: 2 additions & 0 deletions sphinx/source/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ Changelog
pure Python Z80 simulator even if the C version is available)
* Fixed the lazy evaluation bug that can make the :ref:`FONT`, :ref:`SCR` and
:ref:`UDG` macros create frames with incorrect graphic content
* Fixed the bug that can make :ref:`trace.py` stop too soon when the
``--max-tstates`` option is used
* Fixed the contention pattern for the OUTI/OUTD/OTIR/OTDR instructions

9.1 (2024-02-03)
Expand Down
15 changes: 10 additions & 5 deletions tests/test_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -1335,19 +1335,24 @@ def test_option_max_operations_disables_fast_ldir(self):
self.assertLessEqual({'BC=1', 'DE=49154', 'HL=49153', 'R=6'}, set(s_reg))

def test_option_max_tstates(self):
data = [
data = (
0xAF, # XOR A
0x3C, # INC A
]
binfile = self.write_bin_file(data, suffix='.bin')
start = 32768
)
start = 0x8000
stop = start + len(data)
ram = [0] * 0xC000
ram[start - 0x4000:stop - 0x4000] = data
start_time = 4
registers = {'PC': start, 'tstates': start_time}
z80file = self.write_z80_file(None, ram, registers=registers)
exp_output = """
$8000 XOR A
$8001 INC A
Stopped at $8002: 8 T-states
"""
for option in ('-M', '--max-tstates'):
output, error = self.run_trace(f'-n -o {start} -v {option} 8 {binfile}')
output, error = self.run_trace(f'-v {option} 8 {z80file}')
self.assertEqual(error, '')
self.assertEqual(dedent(exp_output).strip(), output.rstrip())

Expand Down

0 comments on commit d1b8e3e

Please sign in to comment.