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@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@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@29: 'RO_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@29: emu = dbg.controller() jb302@29: emu.Emu = Popen(['bin/emu'], stdout=PIPE, stdin=PIPE, stderr=PIPE) jb302@29: 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@29: c = raw_input() jb302@29: if c == 'exit': 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@29: bytecode = 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@29: print hex(pcl | (pch << 8)), [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@29: cmds = { jb302@29: 'step':emu.step, jb302@29: 'run':emu.run, jb302@29: 'gr':emu.get_reg, jb302@29: 'sr':emu.set_reg, jb302@29: 'gf':emu.get_flag, jb302@29: 'sf':emu.set_flag, jb302@29: 'gb':emu.get_block, jb302@29: 'sb':emu.set_block, jb302@29: 'ga':emu.get_a, jb302@29: 'gfs':emu.get_flags, jb302@29: 'gir':emu.get_ir, jb302@29: } jb302@29: jb302@29: if __name__ == '__main__': jb302@29: jb302@29: while True: jb302@29: jb302@29: inp = raw_input('> ').split() jb302@29: if inp == []: jb302@29: continue jb302@29: cmd = inp[0] jb302@29: args = [] jb302@29: jb302@29: #try: jb302@29: # deal with inline execution independently jb302@29: if cmd == 'exc': jb302@29: exc() jb302@29: continue jb302@29: jb302@29: # set block has unique argument syntax jb302@29: if cmd == 'sb': jb302@29: args.append(int(inp[1], 0)) jb302@29: args.append(int(inp[2], 0)) jb302@29: args.append([int(x, 0) for x in inp[3:]]) jb302@29: cmds[cmd](*args) jb302@29: continue jb302@29: jb302@29: # decode args jb302@29: i = 0 jb302@29: for word in inp[1:]: jb302@29: if word in syms.keys(): jb302@29: args.append(syms[word]) jb302@29: # only arguments after 3 will be data for set block jb302@29: # this needs to be in a list jb302@29: else: jb302@29: args.append(int(word, 0)) jb302@29: i = i + 1 jb302@29: jb302@29: resp = cmds[cmd](*args) jb302@29: if resp == None: jb302@29: continue jb302@29: else: jb302@29: print [hex(struct.unpack('>B', x)[0]) for x in resp] jb302@29: jb302@29: #except: jb302@29: # print 'invalid command or argument syntax' jb302@29: # continue jb302@29: