Skip to content

Commit 2488486

Browse files
author
none
committed
refactor tracing out of Emulator, try to make it less insane
1 parent 166b6d2 commit 2488486

17 files changed

+347
-287
lines changed

TODO

+8-4
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ Things to investigate / fix:
1515
✔ suppress read traces for instruction fetches @done (20-02-02 18:24)
1616
✔ newlib sbrk is busted; make stack bigger (room for stack + heap) & grow up from _end @done (20-02-08 23:32)
1717
☐ exceptions in callbacks seem to trash the emulator state; probably better to hard-abort out of them
18-
decide between public attributes and property methods. Device._name, size, address - anything not computed.
18+
decide between public attributes and property methods. Device._name, size, address - anything not computed. @done (20-02-15 09:35)
1919
☐ lots of Emulator functionality needs an instance, but that's inconvenient; maybe classmethods? module-level functions?
20+
☐ symbolication for e.g. address zero is printing vector names
21+
☐ MAP operations should not symbolicate
2022

2123
Features:
2224
✔ need new memory model, support multiple disjoint memories (RAM, ROM), > 16MiB @done (20-01-28 15:54)
@@ -34,6 +36,9 @@ Features:
3436
✔ factor ROM loading into emu.add_memory rather than duplicating in the target @done (20-02-08 09:35)
3537

3638
Tracing:
39+
Needs a complete rethink
40+
☐ trace message via NatFeat
41+
☐ tracing on/off for-X-cycles via NatFeat
3742
☐ device read/write
3843
☐ memory read/write
3944
☐ register mapping
@@ -46,7 +51,6 @@ Tracing:
4651
☐ spurious interrupt
4752
☐ quantum start / end
4853
☐ emulator, device debug message
49-
5054
Devices:
5155
☐ root_device should signal bus error on failed register decode
5256
✔ always call device.tick after handling register access @done (20-02-04 22:48)
@@ -63,8 +67,8 @@ Devices:
6367
☐ migrate existing tick logic to callbacks @high
6468
✔ hash register/size/direction to handler rather than just address to read/write handlers @done (20-02-13 22:33)
6569
☐ support 'fallback' handlers (16-bit access to 8 or 32-bit registers, etc.)
66-
--trace-io is global, would be nice to have per-dev tracing effective here
67-
Device.__trace/__diagnostic is a mess, rethink -> use logging framework?
70+
--trace-io is global, would be nice to have per-dev tracing effective here @done (20-02-18 23:15)
71+
Device.__trace/__diagnostic is a mess, rethink -> use logging framework? @done (20-02-18 23:15)
6872
68681:
6973
✔ don't assume 'off-by-one' mapping, configure for low-byte, high-byte and packed @done (20-02-08 09:18)
7074
☐ implement echo & loopback modes @low

consoleserver.py

+4-9
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
# Console server application - listens on port 6809 and emulates a VT102
33
#
44

5-
import sys
6-
import os
75
import curses
8-
import vt102
9-
import socket
6+
import os
107
import selectors
118
import signal
9+
import socket
10+
import sys
1211
import time
12+
import vt102
1313

1414

1515
class ConsoleServer():
@@ -114,12 +114,9 @@ def _fmt(self, val):
114114
return str
115115

116116
def _handle_input(self, input):
117-
# self.trace('in ' + self._fmt(input))
118117
self._buffered_input += chr(input)
119118

120119
def _handle_output(self, output):
121-
# self.trace('out ' + self._fmt(output))
122-
123120
# vt102 is only 7-bit clean
124121
output &= 0x7f
125122
self._buffered_output += chr(output)
@@ -144,8 +141,6 @@ def _update(self):
144141
input = self._win.getch()
145142
if input != -1:
146143
if input in ConsoleServer.input_keymap:
147-
# self.trace('translate {} -> {}'.format(input,
148-
# ConsoleServer.input_keymap[input]))
149144
for c in ConsoleServer.input_keymap[input]:
150145
self._handle_input(ord(c))
151146
else:

device.py

+25-31
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
#
44

55
import sys
6+
67
from musashi import m68k
78
from register import Register
9+
from trace import Trace
810

911

1012
class Device(object):
@@ -17,13 +19,15 @@ class Device(object):
1719
__emu = None
1820
__root_device = None
1921
__debug = False
20-
__trace_io = False
22+
__trace = None
2123

2224
__console_output_handler = None
2325
__console_input_handler = None
2426

2527
def __init__(self, args, name, required_options=None, **options):
2628
self.name = name
29+
if Device.__trace is None:
30+
Device.__trace = Trace.get_tracer()
2731

2832
if required_options is not None:
2933
for optname in required_options:
@@ -56,11 +60,11 @@ def add_device(cls, args, dev, **options):
5660

5761
if Device.__root_device is None:
5862
# one-time init
63+
Register.init(args)
5964
m68k.set_int_ack_callback(Device.__cb_int)
6065
m68k.mem_set_device_handler(Device.__cb_access)
61-
Device.__debug = 'device' in args.debug_device
66+
Device.__debug = 'Device' in args.debug_device
6267
Device.__emu = options['emulator']
63-
Register.init(args, Device.__emu)
6468

6569
Device.__root_device = dev(args=args, **options)
6670
Device.__root_device.add_system_devices(args)
@@ -91,7 +95,7 @@ def add_register(self, name, offset, size, access, handler):
9195
self.size = implied_size
9296

9397
if self.debug or self.__class__.__debug:
94-
Device.__emu.trace('MAP_REG', address=reg.address, info=f'{repr(reg)}')
98+
Device.trace(action='MAP_REG', address=reg.address, info=f'{reg}')
9599

96100
def add_registers(self, registers):
97101
"""
@@ -106,32 +110,10 @@ def __cb_access(cls, operation, address, size, value):
106110
value = Register.access(address, size, operation, value)
107111
except KeyError:
108112
# XXX bus error?
109-
Device.__trace('DECODE', f'no register to handle {operation}:{address:#x}/{size}')
113+
Device.trace('DECODE', f'no register to handle {operation}:{address:#x}/{size}')
110114

111115
return value
112116

113-
########################################
114-
# Logging
115-
116-
def trace(self, address=None, info=''):
117-
"""
118-
Emit a debug trace message
119-
"""
120-
if self.debug:
121-
Device.__emu.trace(self.name, address=address, info=info)
122-
123-
def diagnostic(self, address=None, info=''):
124-
Device.__emu.trace(f'{self.name}!!', info=info)
125-
126-
@classmethod
127-
def __trace(cls, address=None, info=''):
128-
if Device.__debug:
129-
Device.__emu.trace('device', address=address, info=info)
130-
131-
@classmethod
132-
def __diagnostic(cls, address=None, info=''):
133-
Device.__emu.trace('device!!', address=address, info=info)
134-
135117
########################################
136118
# Device callbacks
137119

@@ -237,9 +219,9 @@ def __set_ipl(cls):
237219
# an unmasked interrupt we need to end the timeslice to get its
238220
# attention
239221
m68k.end_timeslice()
240-
Device.__trace(info=f'un-masked IPL {ipl} from {asserting_dev.name}')
222+
Device.trace(info=f'un-masked IPL {ipl} from {asserting_dev.name}')
241223
else:
242-
Device.__trace(info=f'masked IPL {ipl} from {asserting_dev.name}')
224+
Device.trace(info=f'masked IPL {ipl} from {asserting_dev.name}')
243225
m68k.set_irq(ipl)
244226

245227
@classmethod
@@ -251,9 +233,9 @@ def __cb_int(cls, interrupt):
251233
if dev._asserted_ipl == interrupt:
252234
vector = dev.get_vector(interrupt)
253235
if vector != m68k.IRQ_SPURIOUS:
254-
Device.__trace(info=f'INTERRUPT, vector {vector}')
236+
Device.trace(info=f'INTERRUPT, vector {vector}')
255237
return vector
256-
Device.__trace(info='SPURIOUS_INTERRUPT')
238+
Device.trace(info='SPURIOUS_INTERRUPT')
257239
return m68k.IRQ_SPURIOUS
258240

259241
########################################
@@ -328,6 +310,18 @@ def root_device(self):
328310
def devices(self):
329311
return self.__class__.__devices
330312

313+
########################################
314+
# Tracing
315+
316+
def trace(self, address=None, info=''):
317+
if self.debug:
318+
Device.__trace.trace(action=self.name, address=address, info=info)
319+
320+
@classmethod
321+
def trace(cls, action='', address=None, info=''):
322+
if cls.__debug:
323+
cls.__trace.trace(action=action, address=address, info=info)
324+
331325
########################################
332326
# Subclass protocol
333327

devices/CompactFlash.py

+9-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import sys
21
import io
32
import struct
3+
import sys
44

55
from device import Device
66
from musashi import m68k
@@ -248,16 +248,15 @@ def _write_command(self, value):
248248
else:
249249
self._r_status = STATUS_ERR
250250
self._r_error = ERROR_ABORT
251-
self._trace_io('IOERR', 'command {:02x} not supported'.format(value))
251+
self.trace(info=f'ERROR: command {value:02x} not supported')
252252

253253
def _trace_io(self, action):
254-
self.trace(action, 'count {} LBA {}'.format(
255-
self._r_sector_count, self._r_lba))
254+
self.trace(info=f'{action} count {self._r_sector_count} LBA {self._r_lba}')
256255

257256
def _do_io(self, mode):
258257
# if we're in the FAULT state (no file, eg.) all I/O fails
259258
if self._r_status & STATUS_DF:
260-
self.trace('IOERR', 'no device')
259+
self.trace(info=f'ERROR: no device')
261260
self._r_status |= STATUS_ERR
262261
self._r_error = ERROR_UNCORRECTABLE
263262
return
@@ -271,7 +270,7 @@ def _do_io(self, mode):
271270
self._bytes_remaining = 256 * SECTOR_SIZE
272271

273272
if (file_byte_offset + self._bytes_remaining) > self._file_size:
274-
self.trace('IOERR', 'access beyond end of device')
273+
self.trace(info=f'ERROR: access beyond end of device')
275274
self._r_status |= STATUS_ERR
276275
self._r_error = ERROR_UNCORRECTABLE
277276

@@ -291,15 +290,15 @@ def _io_read(self, width):
291290
elif self._current_mode == AMODE_READ:
292291
pass
293292
else:
294-
self.trace('IOERR', 'data read when not reading / identifying')
293+
self.trace(info=f'ERROR: data read when not reading / identifying')
295294
return 0
296295

297296
if width == m68k.MEM_SIZE_8:
298297
count = 1
299298
else:
300299
count = 2
301300
if self._bytes_remaining < count:
302-
self.trace('IOERR', 'read beyond sector buffer')
301+
self.trace(info=f'ERROR: read beyond sector buffer')
303302
return 0
304303

305304
if self._current_mode == AMODE_READ:
@@ -327,7 +326,7 @@ def _io_read(self, width):
327326

328327
def _io_write(self, width, value):
329328
if self._current_mode != AMODE_WRITE:
330-
self.trace('IOERR', 'data write when not writing')
329+
self.trace(info=f'ERROR: data write when not writing')
331330
return 0
332331

333332
data = bytearray()
@@ -336,7 +335,7 @@ def _io_write(self, width, value):
336335
data.append(value >> 8)
337336

338337
if self._bytes_remaining < len(data):
339-
self.trace('IOERR', 'write beyond sector buffer')
338+
self.trace(info=f'ERROR: write beyond sector buffer')
340339
return
341340

342341
self._file_handle.write(data)

devices/MC68681.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ def _update_isr(self):
115115
isr |= self.INT_TXRDY
116116
if self._rxEnable:
117117
if len(self._rxfifo) > (1 if self._mr1 & self.MR1_FFULL_EN else 0):
118-
isr |= self.INT_RXDRY_FFULL
118+
isr |= self.INT_RXRDY_FFULL
119119
self._parent.update_channel_isr(self._port, isr)
120120

121121
def _handle_console_input(self, input):

devices/p90ce201.py

+3-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1+
from collections import deque
12
import sys
3+
24
from device import Device
3-
from collections import deque
4-
from musashi.m68k import (
5-
M68K_IRQ_SPURIOUS,
6-
M68K_IRQ_AUTOVECTOR,
7-
MEM_SIZE_8,
8-
)
5+
from musashi.m68k import m68k
96

107
ADDR_P90Syscon = 0x80001000
118
ADDR_P90ICU = 0x80001020

devices/simple.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
from device import Device
21
from collections import deque
32

3+
from device import Device
44
from musashi import m68k
55

66

@@ -132,23 +132,23 @@ def _write_countdown(self, value):
132132
self.deassert_ipl()
133133
self._deadline = 0
134134
self.callback_cancel('count')
135-
self.trace('timer cancelled')
135+
self.trace(info='timer cancelled')
136136
else:
137137
self._deadline = self.current_cycle + value * self._scaler
138138
self.callback_at(self._deadline, 'count', self._callback)
139-
self.trace(f'timer set for {self._deadline}, now {self.current_cycle}')
139+
self.trace(info=f'timer set for {self._deadline}, now {self.current_cycle}')
140140

141141
def _write_vector(self, value):
142142
self._r_vector = value
143143

144144
def _callback(self):
145145
if (self._deadline > 0):
146146
if (self._deadline <= self.current_cycle):
147-
self.trace('timer expired')
147+
self.trace(info='timer expired')
148148
self.assert_ipl()
149149
self._deadline = 0
150150
else:
151-
self.trace('spurious callback')
151+
self.trace(info='spurious callback')
152152
self.callback_at(self._deadline, 'count', self._callback)
153153

154154
def reset(self):

0 commit comments

Comments
 (0)