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