jb302@29: #!/usr/bin/env python jb302@29: # cli.py - a command line to control the emulator using jb302@29: # the debug control class jb302@29: jb302@29: import struct jb302@40: import sys jb302@29: from StringIO import StringIO jb302@29: from io import BytesIO jb302@29: from subprocess import Popen, PIPE, STDOUT jb302@29: jb302@29: from asm import asm jb302@29: from dbg import dbg jb302@29: jb302@34: # start emu instance jb302@34: emu = dbg.controller() jb302@34: emu.Emu = Popen(['bin/emu'], stdout=PIPE, stdin=PIPE, stderr=PIPE) jb302@34: jb302@34: # symbol encodings jb302@29: syms = { jb302@29: 'R0_0':0, jb302@29: 'R1_0':1, jb302@29: 'R2_0':2, jb302@29: 'R3_0':3, jb302@29: 'DPH':4, jb302@29: 'SPH':5, jb302@29: 'PCH':6, jb302@29: 'TMPH':7, jb302@30: 'R0_1':8, jb302@29: 'R1_1':9, jb302@29: 'R2_1':10, jb302@29: 'R3_1':11, jb302@29: 'DPL':12, jb302@29: 'SPL':13, jb302@29: 'PCL':14, jb302@29: 'TMPL':15, jb302@29: 'BS':0, jb302@29: 'IE':1, jb302@29: 'OV':2, jb302@29: 'S':3, jb302@29: 'P':4, jb302@29: 'AC':5, jb302@29: 'Z':6, jb302@29: 'C':7 jb302@29: } jb302@29: jb302@34: # command line command strings jb302@34: cmds = { jb302@34: 'step':emu.step, jb302@40: 'frun':emu.free_run, jb302@34: 'run':emu.run, jb302@34: 'runl':emu.run_len, jb302@34: 'gr':emu.get_reg, jb302@34: 'sr':emu.set_reg, jb302@34: 'gf':emu.get_flag, jb302@34: 'sf':emu.set_flag, jb302@34: 'gb':emu.get_block, jb302@34: 'sb':emu.set_block, jb302@34: 'ga':emu.get_a, jb302@34: 'gfs':emu.get_flags, jb302@34: 'gi':emu.get_ir, jb302@34: 'sbp':emu.set_bp jb302@34: } jb302@29: jb302@29: # assemble and execute inline asm. jb302@29: # bytecode is copied to where ever the PC is and then executed jb302@29: def exc(): jb302@29: jb302@29: while True: jb302@29: # file like objects for source and byte code jb302@29: code = StringIO() jb302@29: bytecode = BytesIO() jb302@29: jb302@29: # get the PC jb302@29: pch = struct.unpack('>B', emu.get_reg(syms['PCH']))[0] jb302@29: pcl = struct.unpack('>B', emu.get_reg(syms['PCL']))[0] jb302@29: jb302@29: # get user input jb302@34: c = raw_input('>> ') jb302@34: if c == 'end': jb302@29: break jb302@29: code.write(c) jb302@29: jb302@29: try: jb302@29: # assemble and determine length bytes jb302@29: a, l = asm.first_pass(code) jb302@29: if l.keys() != []: jb302@29: print 'labels not yet supported in interpreter mode' jb302@29: continue jb302@34: bytecode, d = asm.second_pass(bytecode, a, l) jb302@29: bytecode.seek(0) jb302@29: byte_array = bytearray(bytecode.read()) jb302@29: except: jb302@29: print 'invalid instruction' jb302@29: continue jb302@29: jb302@34: print 'PC:', hex(pcl | (pch << 8)),'BC:', [hex(b) for b in byte_array] jb302@29: # write to emu memory and execute jb302@29: emu.set_block(pch, pcl, byte_array) jb302@29: emu.step() jb302@29: jb302@34: jb302@34: # request input and run command jb302@34: def req_run(): jb302@34: inp = raw_input('> ').split() jb302@34: if inp == []: jb302@34: return jb302@34: cmd = inp[0] jb302@34: args = [] jb302@34: jb302@34: try: jb302@34: if cmd == 'exit': jb302@34: emu.Emu.kill() jb302@34: exit() jb302@34: # deal with inline execution independently jb302@34: if cmd == 'exc': jb302@34: exc() jb302@34: return jb302@34: jb302@34: # set block has unique argument syntax jb302@34: if cmd == 'sb': jb302@34: args.append(int(inp[1], 0)) jb302@34: args.append(int(inp[2], 0)) jb302@34: args.append([int(x, 0) for x in inp[3:]]) jb302@34: cmds[cmd](*args) jb302@34: return jb302@34: jb302@34: # decode args jb302@34: i = 0 jb302@34: for word in inp[1:]: jb302@34: if word in syms.keys(): jb302@34: args.append(syms[word]) jb302@34: # only arguments after 3 will be data for set block jb302@34: # this needs to be in a list jb302@34: else: jb302@34: args.append(int(word, 0)) jb302@34: i = i + 1 jb302@34: jb302@34: resp = cmds[cmd](*args) jb302@34: if resp == None: jb302@34: return jb302@34: else: jb302@34: print [hex(struct.unpack('>B', x)[0]) for x in resp] jb302@34: jb302@34: except Exception, e: jb302@34: print e jb302@34: print 'invalid command or argument syntax' jb302@34: return jb302@34: jb302@29: jb302@29: if __name__ == '__main__': jb302@40: try: jb302@40: with open(sys.argv[1], 'rb') as f: jb302@40: prog = bytearray(f.read()) jb302@40: emu.set_block(0, 0, prog) jb302@40: except IndexError: jb302@40: pass jb302@40: jb302@29: while True: jb302@34: req_run() jb302@29: