from __future__ import annotations
from typing import *
+import hexdump
+
# ------------------------------------------------------------------------------
self._return_stack = list()
self._regions = dict()
self._syms = list()
+ self._breakpoints = list()
def load_bin(self, data: bytes, offset: int = 0):
for i, b in enumerate(data):
addr = int(saddr, 0)
self._syms.append((addr, symbol.strip()))
+ def bp(self, address: int | str) -> None:
+ if isinstance(address, str):
+ address = self.symbol_to_addr(address)
+ self._breakpoints.append(address)
+
def addr_to_symbol(self, address: int) -> str:
# Assumes symbols are sorted
found_symbol = ''
while self.pc != addr:
self.step()
- def step(self) -> None:
+ def step(self) -> Optional[int]:
instr = self.ld8(self.pc)
self.pc += 1
if instr == 0x01: # #8
elif instr == 0x0f: # JP
addr = self.ld32(self.pc)
self.pc += 4
- if self.p_pop() > 0:
+ x = self.p_pop()
+ if x > 0 and x & 0x8000000 == 0:
self.pc = addr
elif instr == 0x10: # +
self.p_push(self.p_pop() + self.p_pop())
self.p_push(val << 1)
else: # NOP
pass
+ for i, addr in enumerate(self._breakpoints):
+ if self.pc == addr:
+ return i
+ return None
def dump(self) -> None:
print('-'*80)
print(f'0x{self.pc:08x} {self.addr_to_symbol(self.pc)}')
instr = self.ld8(self.pc)
sinstr = self.INSTRS[instr] if instr in self.INSTRS else '???'
- print(f' (0x{instr:02x} {sinstr})')
+ if sinstr == '#8':
+ imm = self.ld8(self.pc + 1)
+ sinstr += f' 0x{imm:02x}/{imm}'
+ elif sinstr in ['#32', 'JMP', 'JN', 'JZ', 'JP', 'CALL']:
+ imm = self.ld32(self.pc + 1)
+ sinstr += f' 0x{imm:08x}/{imm} - {self.addr_to_symbol(imm)}'
+ print(f' 0x{instr:02x} {sinstr}')
print()
print('Data stack:')
for x in reversed(self._param_stack):
emu.load_bin(data)
emu.load_map(mapfile)
+ emu.p_push(0)
+ emu.pc = 0
emu.dump()
- emu.r_push(0xdeadbeef)
- emu.p_push(0x1234)
- emu.p_push(0x41)
- emu.pc = 'div_uu'
- emu.dump()
-
- emu.run_until(0xdeadbeef)
+ emu.run_until('vga_console_putc')
emu.dump()
+ i = ''
+ while True:
+ p = i
+ i = input('> ')
+ if not i:
+ i = p
+ c = i.split()
+
+ if c[0] == 'q':
+ break
+ elif c[0] == 'b':
+ if len(c) == 1:
+ for i, addr in enumerate(emu._breakpoints):
+ print(f'{i}: 0x{addr:08x} ({emu.addr_to_symbol(addr)})')
+ print()
+ elif c[1][0].isdigit():
+ emu.bp(int(c[1], 0))
+ else:
+ emu.bp(c[1])
+ elif c[0] == 'c':
+ try:
+ while True:
+ bp = emu.step()
+ if bp is not None:
+ print(f'Halted at breakpoint {bp}')
+ break
+ except KeyboardInterrupt:
+ print('Halted')
+ emu.dump()
+ elif c[0] == 'd':
+ a = c[1]
+ l = c[2]
+ l = int(l, 0)
+ if a[0].isdigit():
+ a = int(a, 0)
+ else:
+ a = emu.symbol_to_addr(a)
+ d = bytes(emu.ld8(addr) for addr in range(a, a+l))
+ hexdump.hexdump(d)
+ elif c[0] == 's':
+ emu.step()
+ emu.dump()
return 0