blob: 3d8f1318302ded7a02f682320e23ff77b36421c7 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
from getch import getche
from .emu import Machine
class Debugger:
def __init__(self):
self.rom_image = None
self.breakpoints: set[int] = set()
self.machine = Machine()
self.machine.reset()
self.machine.run()
def load_rom_image(self, rom_image: bytearray) -> None:
self.rom_image = rom_image
self.machine.load_rom_image(rom_image)
print("Loaded rom image.")
def print_pc_context(self):
print("=== Program context")
for i in range(-4, 5):
addr = self.machine.pc.value + i
if addr < 0 or addr >= 64 * 2 ** 16:
continue
if i == 0:
print(f"> 0x{addr:>04x}: 0x{self.machine.mem_read(addr):>04x}")
else:
print(f" 0x{addr:>04x}: 0x{self.machine.mem_read(addr):>04x}")
print()
def activate(self):
print("=== ATK16 debugger ===")
print("Press ? to show command help. Press q to quit.")
print()
while True:
self.print_pc_context()
print("dbg> ", end="", flush=True)
cmd = getche()
print()
if cmd == "q":
break
elif cmd == "?":
self.print_help()
elif cmd == "r":
while self.machine.running:
self.machine.step()
if self.machine.pc.value in self.breakpoints:
print(f"Breakpoint hit at 0x{self.machine.pc.value:>04x}")
break
if not self.machine.running:
print("Machine halted.")
elif cmd == "b":
print("Set breakpoints:")
for addr in self.breakpoints:
print(f" 0x{addr:>04x}")
if len(self.breakpoints) == 0:
print("<no breakpoints>")
print()
try:
addr = eval(input("Breakpoint address: "), {})
except:
print("Cancelled")
continue
if type(addr) != int or addr < 0 or addr >= 64 * 2 ** 16:
print("Invalid address")
if addr in self.breakpoints:
self.breakpoints.remove(addr)
print(f"Removed breakpoint at 0x{addr:>04x}")
else:
self.breakpoints.add(addr)
elif cmd == "n":
if not self.machine.running:
print("Machine halted.")
continue
self.machine.step()
if not self.machine.running:
print("Machine halted.")
elif cmd == "s":
self.machine.print_state_summary()
elif cmd == "0":
self.machine.reset()
self.machine.run()
print("Machine reset.")
else:
print(f"Unknown command: {cmd}")
def print_help(self):
print("Debugger commands:")
print(" r run until next breakpoint or until halted")
print(" n step forward")
print(" b step backward")
print(" b set or remove breakpoint")
print(" s show state summary")
print(" 0 reset the machine state")
print(" q quit")
print(" ? show this help")
print()
|