annotate cli.py @ 42:792da050d8c4 tip

more dox
author james <jb302@eecs.qmul.ac.uk>
date Tue, 22 Apr 2014 14:25:14 +0100
parents 6b947f6d69d9
children
rev   line source
jb302@29 1 #!/usr/bin/env python
jb302@29 2 # cli.py - a command line to control the emulator using
jb302@29 3 # the debug control class
jb302@29 4
jb302@29 5 import struct
jb302@40 6 import sys
jb302@29 7 from StringIO import StringIO
jb302@29 8 from io import BytesIO
jb302@29 9 from subprocess import Popen, PIPE, STDOUT
jb302@29 10
jb302@29 11 from asm import asm
jb302@29 12 from dbg import dbg
jb302@29 13
jb302@34 14 # start emu instance
jb302@34 15 emu = dbg.controller()
jb302@34 16 emu.Emu = Popen(['bin/emu'], stdout=PIPE, stdin=PIPE, stderr=PIPE)
jb302@34 17
jb302@34 18 # symbol encodings
jb302@29 19 syms = {
jb302@29 20 'R0_0':0,
jb302@29 21 'R1_0':1,
jb302@29 22 'R2_0':2,
jb302@29 23 'R3_0':3,
jb302@29 24 'DPH':4,
jb302@29 25 'SPH':5,
jb302@29 26 'PCH':6,
jb302@29 27 'TMPH':7,
jb302@30 28 'R0_1':8,
jb302@29 29 'R1_1':9,
jb302@29 30 'R2_1':10,
jb302@29 31 'R3_1':11,
jb302@29 32 'DPL':12,
jb302@29 33 'SPL':13,
jb302@29 34 'PCL':14,
jb302@29 35 'TMPL':15,
jb302@29 36 'BS':0,
jb302@29 37 'IE':1,
jb302@29 38 'OV':2,
jb302@29 39 'S':3,
jb302@29 40 'P':4,
jb302@29 41 'AC':5,
jb302@29 42 'Z':6,
jb302@29 43 'C':7
jb302@29 44 }
jb302@29 45
jb302@34 46 # command line command strings
jb302@34 47 cmds = {
jb302@34 48 'step':emu.step,
jb302@40 49 'frun':emu.free_run,
jb302@34 50 'run':emu.run,
jb302@34 51 'runl':emu.run_len,
jb302@34 52 'gr':emu.get_reg,
jb302@34 53 'sr':emu.set_reg,
jb302@34 54 'gf':emu.get_flag,
jb302@34 55 'sf':emu.set_flag,
jb302@34 56 'gb':emu.get_block,
jb302@34 57 'sb':emu.set_block,
jb302@34 58 'ga':emu.get_a,
jb302@34 59 'gfs':emu.get_flags,
jb302@34 60 'gi':emu.get_ir,
jb302@34 61 'sbp':emu.set_bp
jb302@34 62 }
jb302@29 63
jb302@29 64 # assemble and execute inline asm.
jb302@29 65 # bytecode is copied to where ever the PC is and then executed
jb302@29 66 def exc():
jb302@29 67
jb302@29 68 while True:
jb302@29 69 # file like objects for source and byte code
jb302@29 70 code = StringIO()
jb302@29 71 bytecode = BytesIO()
jb302@29 72
jb302@29 73 # get the PC
jb302@29 74 pch = struct.unpack('>B', emu.get_reg(syms['PCH']))[0]
jb302@29 75 pcl = struct.unpack('>B', emu.get_reg(syms['PCL']))[0]
jb302@29 76
jb302@29 77 # get user input
jb302@34 78 c = raw_input('>> ')
jb302@34 79 if c == 'end':
jb302@29 80 break
jb302@29 81 code.write(c)
jb302@29 82
jb302@29 83 try:
jb302@29 84 # assemble and determine length bytes
jb302@29 85 a, l = asm.first_pass(code)
jb302@29 86 if l.keys() != []:
jb302@29 87 print 'labels not yet supported in interpreter mode'
jb302@29 88 continue
jb302@34 89 bytecode, d = asm.second_pass(bytecode, a, l)
jb302@29 90 bytecode.seek(0)
jb302@29 91 byte_array = bytearray(bytecode.read())
jb302@29 92 except:
jb302@29 93 print 'invalid instruction'
jb302@29 94 continue
jb302@29 95
jb302@34 96 print 'PC:', hex(pcl | (pch << 8)),'BC:', [hex(b) for b in byte_array]
jb302@29 97 # write to emu memory and execute
jb302@29 98 emu.set_block(pch, pcl, byte_array)
jb302@29 99 emu.step()
jb302@29 100
jb302@34 101
jb302@34 102 # request input and run command
jb302@34 103 def req_run():
jb302@34 104 inp = raw_input('> ').split()
jb302@34 105 if inp == []:
jb302@34 106 return
jb302@34 107 cmd = inp[0]
jb302@34 108 args = []
jb302@34 109
jb302@34 110 try:
jb302@34 111 if cmd == 'exit':
jb302@34 112 emu.Emu.kill()
jb302@34 113 exit()
jb302@34 114 # deal with inline execution independently
jb302@34 115 if cmd == 'exc':
jb302@34 116 exc()
jb302@34 117 return
jb302@34 118
jb302@34 119 # set block has unique argument syntax
jb302@34 120 if cmd == 'sb':
jb302@34 121 args.append(int(inp[1], 0))
jb302@34 122 args.append(int(inp[2], 0))
jb302@34 123 args.append([int(x, 0) for x in inp[3:]])
jb302@34 124 cmds[cmd](*args)
jb302@34 125 return
jb302@34 126
jb302@34 127 # decode args
jb302@34 128 i = 0
jb302@34 129 for word in inp[1:]:
jb302@34 130 if word in syms.keys():
jb302@34 131 args.append(syms[word])
jb302@34 132 # only arguments after 3 will be data for set block
jb302@34 133 # this needs to be in a list
jb302@34 134 else:
jb302@34 135 args.append(int(word, 0))
jb302@34 136 i = i + 1
jb302@34 137
jb302@34 138 resp = cmds[cmd](*args)
jb302@34 139 if resp == None:
jb302@34 140 return
jb302@34 141 else:
jb302@34 142 print [hex(struct.unpack('>B', x)[0]) for x in resp]
jb302@34 143
jb302@34 144 except Exception, e:
jb302@34 145 print e
jb302@34 146 print 'invalid command or argument syntax'
jb302@34 147 return
jb302@34 148
jb302@29 149
jb302@29 150 if __name__ == '__main__':
jb302@40 151 try:
jb302@40 152 with open(sys.argv[1], 'rb') as f:
jb302@40 153 prog = bytearray(f.read())
jb302@40 154 emu.set_block(0, 0, prog)
jb302@40 155 except IndexError:
jb302@40 156 pass
jb302@40 157
jb302@29 158 while True:
jb302@34 159 req_run()
jb302@29 160