Skip to content

Commit 88b7eb6

Browse files
committed
Forth debugger: add missing disass
1 parent 8f49c80 commit 88b7eb6

File tree

1 file changed

+330
-0
lines changed

1 file changed

+330
-0
lines changed

forth/disass.py

+330
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,330 @@
1+
# Opcodes
2+
# for each, we store the mnemonic and mode id (see 'modes' dict below)
3+
4+
opcodes = {
5+
0: [ 'brk' , 9 ], # brk s
6+
1: [ 'ora' , 11 ], # ora (zp,x)
7+
4: [ 'tsb' , 10 ], # tsb zp
8+
5: [ 'ora' , 10 ], # ora zp
9+
6: [ 'asl' , 10 ], # asl zp
10+
7: [ 'rmb0', 10 ], # rmb0 zp
11+
8: [ 'php' , 9 ], # php s
12+
9: [ 'ora' , 6 ], # ora #
13+
10: [ 'asl' , 5 ], # asl A
14+
12: [ 'tsb' , 0 ], # tsb a
15+
13: [ 'ora' , 0 ], # ora a
16+
14: [ 'asl' , 0 ], # asl a
17+
15: [ 'bbr0', 8 ], # bbr0 r
18+
16: [ 'bpl' , 8 ], # bpl r
19+
17: [ 'ora' , 15 ], # ora (zp),y
20+
18: [ 'ora' , 14 ], # ora (zp)
21+
20: [ 'trb' , 10 ], # trb zp
22+
21: [ 'ora' , 12 ], # ora zp,x
23+
22: [ 'asl' , 12 ], # asl zp,x
24+
23: [ 'rmb1', 10 ], # rmb1 zp
25+
24: [ 'clc' , 7 ], # clc i
26+
25: [ 'ora' , 3 ], # ora a,y
27+
26: [ 'inc' , 5 ], # inc A
28+
28: [ 'trb' , 0 ], # trb a
29+
29: [ 'ora' , 2 ], # ora a,x
30+
30: [ 'asl' , 2 ], # asl a,x
31+
31: [ 'bbr1', 8 ], # bbr1 r
32+
32: [ 'jsr' , 0 ], # jsr a
33+
33: [ 'and' , 11 ], # and (zp,x)
34+
36: [ 'bit' , 10 ], # bit zp
35+
37: [ 'and' , 10 ], # and zp
36+
38: [ 'rol' , 10 ], # rol zp
37+
39: [ 'rmb2', 10 ], # rmb2 zp
38+
40: [ 'plp' , 9 ], # plp s
39+
41: [ 'and' , 6 ], # and #
40+
42: [ 'rol' , 5 ], # rol A
41+
44: [ 'bit' , 0 ], # bit a
42+
45: [ 'and' , 0 ], # and a
43+
46: [ 'rol' , 0 ], # rol a
44+
47: [ 'bbr2', 8 ], # bbr2 r
45+
48: [ 'bmi' , 8 ], # bmi r
46+
49: [ 'and' , 15 ], # and (zp),y
47+
50: [ 'and' , 14 ], # and (zp)
48+
52: [ 'bit' , 12 ], # bit zp,x
49+
53: [ 'and' , 12 ], # and zp,x
50+
54: [ 'rol' , 12 ], # rol zp,x
51+
55: [ 'rmb3', 10 ], # rmb3 zp
52+
56: [ 'sec' , 7 ], # sec i
53+
57: [ 'and' , 3 ], # and a,y
54+
58: [ 'dec' , 5 ], # dec A
55+
60: [ 'bit' , 2 ], # bit a,x
56+
61: [ 'and' , 2 ], # and a,x
57+
62: [ 'rol' , 2 ], # rol a,x
58+
63: [ 'bbr3', 8 ], # bbr3 r
59+
64: [ 'rti' , 9 ], # rti s
60+
65: [ 'eor' , 11 ], # eor (zp,x)
61+
69: [ 'eor' , 10 ], # eor zp
62+
70: [ 'lsr' , 10 ], # lsr zp
63+
71: [ 'rmb4', 10 ], # rmb4 zp
64+
72: [ 'pha' , 9 ], # pha s
65+
73: [ 'eor' , 6 ], # eor #
66+
74: [ 'lsr' , 5 ], # lsr A
67+
76: [ 'jmp' , 0 ], # jmp a
68+
77: [ 'eor' , 0 ], # eor a
69+
78: [ 'lsr' , 0 ], # lsr a
70+
79: [ 'bbr4', 8 ], # bbr4 r
71+
80: [ 'bvc' , 8 ], # bvc r
72+
81: [ 'eor' , 15 ], # eor (zp),y
73+
82: [ 'eor' , 14 ], # eor (zp)
74+
85: [ 'eor' , 12 ], # eor zp,x
75+
86: [ 'lsr' , 12 ], # lsr zp,x
76+
87: [ 'rmb5', 10 ], # rmb5 zp
77+
88: [ 'cli' , 7 ], # cli i
78+
89: [ 'eor' , 3 ], # eor a,y
79+
90: [ 'phy' , 9 ], # phy s
80+
93: [ 'eor' , 2 ], # eor a,x
81+
94: [ 'lsr' , 2 ], # lsr a,x
82+
95: [ 'bbr5', 8 ], # bbr5 r
83+
96: [ 'rts' , 9 ], # rts s
84+
97: [ 'adc' , 11 ], # adc (zp,x)
85+
100: [ 'stz' , 10 ], # stz zp
86+
101: [ 'adc' , 10 ], # adc zp
87+
102: [ 'ror' , 10 ], # ror zp
88+
103: [ 'rmb6', 10 ], # rmb6 zp
89+
104: [ 'pla' , 9 ], # pla s
90+
105: [ 'adc' , 6 ], # adc #
91+
106: [ 'ror' , 5 ], # ror A
92+
108: [ 'jmp' , 4 ], # jmp (a)
93+
109: [ 'adc' , 0 ], # adc a
94+
110: [ 'ror' , 0 ], # ror a
95+
111: [ 'bbr6', 8 ], # bbr6 r
96+
112: [ 'bvs' , 8 ], # bvs r
97+
113: [ 'adc' , 15 ], # adc (zp),y
98+
114: [ 'adc' , 14 ], # adc (zp)
99+
116: [ 'stz' , 12 ], # stz zp,x
100+
117: [ 'adc' , 12 ], # adc zp,x
101+
118: [ 'ror' , 12 ], # ror zp,x
102+
119: [ 'rmb7', 10 ], # rmb7 zp
103+
120: [ 'sei' , 7 ], # sei i
104+
121: [ 'adc' , 3 ], # adc a,y
105+
122: [ 'ply' , 9 ], # ply s
106+
124: [ 'jmp' , 1 ], # jmp (a,x)
107+
125: [ 'adc' , 2 ], # adc a,x
108+
126: [ 'ror' , 2 ], # ror a,x
109+
127: [ 'bbr7', 8 ], # bbr7 r
110+
128: [ 'bra' , 8 ], # bra r
111+
129: [ 'sta' , 11 ], # sta (zp,x)
112+
132: [ 'sty' , 10 ], # sty zp
113+
133: [ 'sta' , 10 ], # sta zp
114+
134: [ 'stx' , 10 ], # stx zp
115+
135: [ 'smb0', 10 ], # smb0 zp
116+
136: [ 'dey' , 7 ], # dey i
117+
137: [ 'bit' , 6 ], # bit #
118+
138: [ 'txa' , 7 ], # txa i
119+
140: [ 'sty' , 0 ], # sty a
120+
141: [ 'sta' , 0 ], # sta a
121+
142: [ 'stx' , 0 ], # stx a
122+
143: [ 'bbs0', 8 ], # bbs0 r
123+
144: [ 'bcc' , 8 ], # bcc r
124+
145: [ 'sta' , 15 ], # sta (zp),y
125+
146: [ 'sta' , 14 ], # sta (zp)
126+
148: [ 'sty' , 12 ], # sty zp,x
127+
149: [ 'sta' , 12 ], # sta zp,x
128+
150: [ 'stx' , 13 ], # stx zp,y
129+
151: [ 'smb1', 10 ], # smb1 zp
130+
152: [ 'tya' , 7 ], # tya i
131+
153: [ 'sta' , 3 ], # sta a,y
132+
154: [ 'txs' , 7 ], # txs i
133+
156: [ 'stz' , 0 ], # stz a
134+
157: [ 'sta' , 2 ], # sta a,x
135+
158: [ 'stz' , 2 ], # stz a,x
136+
159: [ 'bbs1', 8 ], # bbs1 r
137+
160: [ 'ldy' , 6 ], # ldy #
138+
161: [ 'lda' , 11 ], # lda (zp,x)
139+
162: [ 'ldx' , 6 ], # ldx #
140+
164: [ 'ldy' , 10 ], # ldy zp
141+
165: [ 'lda' , 10 ], # lda zp
142+
166: [ 'ldx' , 10 ], # ldx zp
143+
167: [ 'smb2', 10 ], # smb2 zp
144+
168: [ 'tay' , 7 ], # tay i
145+
169: [ 'lda' , 6 ], # lda #
146+
170: [ 'tax' , 7 ], # tax i
147+
172: [ 'ldy' , 0 ], # ldy a
148+
173: [ 'lda' , 0 ], # lda a
149+
174: [ 'ldx' , 0 ], # ldx a
150+
175: [ 'bbs2', 8 ], # bbs2 r
151+
176: [ 'bcs' , 8 ], # bcs r
152+
177: [ 'lda' , 15 ], # lda (zp),y
153+
178: [ 'lda' , 14 ], # lda (zp)
154+
180: [ 'ldy' , 12 ], # ldy zp,x
155+
181: [ 'lda' , 12 ], # lda zp,x
156+
182: [ 'ldx' , 13 ], # ldx zp,y
157+
183: [ 'smb3', 10 ], # smb3 zp
158+
184: [ 'clv' , 7 ], # clv i
159+
185: [ 'lda' , 3 ], # lda a,y
160+
186: [ 'tsx' , 7 ], # tsx i
161+
188: [ 'ldy' , 2 ], # ldy a,x
162+
189: [ 'lda' , 2 ], # lda a,x
163+
190: [ 'ldx' , 3 ], # ldx a,y
164+
191: [ 'bbs3', 8 ], # bbs3 r
165+
192: [ 'cpy' , 6 ], # cpy #
166+
193: [ 'cmp' , 11 ], # cmp (zp,x)
167+
196: [ 'cpy' , 10 ], # cpy zp
168+
197: [ 'cmp' , 10 ], # cmp zp
169+
198: [ 'dec' , 10 ], # dec zp
170+
199: [ 'smb4', 10 ], # smb4 zp
171+
200: [ 'iny' , 7 ], # iny i
172+
201: [ 'cmp' , 6 ], # cmp #
173+
202: [ 'dex' , 7 ], # dex i
174+
203: [ 'wai' , 7 ], # wai i
175+
204: [ 'cpy' , 0 ], # cpy a
176+
205: [ 'cmp' , 0 ], # cmp a
177+
206: [ 'dec' , 0 ], # dec a
178+
207: [ 'bbs4', 8 ], # bbs4 r
179+
208: [ 'bne' , 8 ], # bne r
180+
209: [ 'cmp' , 15 ], # cmp (zp),y
181+
210: [ 'cmp' , 14 ], # cmp (zp)
182+
213: [ 'cmp' , 12 ], # cmp zp,x
183+
214: [ 'dec' , 12 ], # dec zp,x
184+
215: [ 'smb5', 10 ], # smb5 zp
185+
216: [ 'cld' , 7 ], # cld i
186+
217: [ 'cmp' , 3 ], # cmp a,y
187+
218: [ 'phx' , 9 ], # phx s
188+
219: [ 'stp' , 7 ], # stp i
189+
221: [ 'cmp' , 2 ], # cmp a,x
190+
222: [ 'dec' , 2 ], # dec a,x
191+
223: [ 'bbs5', 8 ], # bbs5 r
192+
224: [ 'cpx' , 6 ], # cpx #
193+
225: [ 'sbc' , 11 ], # sbc (zp,x)
194+
228: [ 'cpx' , 10 ], # cpx zp
195+
229: [ 'sbc' , 10 ], # sbc zp
196+
230: [ 'inc' , 10 ], # inc zp
197+
231: [ 'smb6', 10 ], # smb6 zp
198+
232: [ 'inx' , 7 ], # inx i
199+
233: [ 'sbc' , 6 ], # sbc #
200+
234: [ 'nop' , 7 ], # nop i
201+
236: [ 'cpx' , 0 ], # cpx a
202+
237: [ 'sbc' , 0 ], # sbc a
203+
238: [ 'inc' , 0 ], # inc a
204+
239: [ 'bbs6', 8 ], # bbs6 r
205+
240: [ 'beq' , 8 ], # beq r
206+
241: [ 'sbc' , 15 ], # sbc (zp),y
207+
242: [ 'sbc' , 14 ], # sbc (zp)
208+
245: [ 'sbc' , 12 ], # sbc zp,x
209+
246: [ 'inc' , 12 ], # inc zp,x
210+
247: [ 'smb7', 10 ], # smb7 zp
211+
248: [ 'sed' , 7 ], # sed i
212+
249: [ 'sbc' , 3 ], # sbc a,y
213+
250: [ 'plx' , 9 ], # plx s
214+
253: [ 'sbc' , 2 ], # sbc a,x
215+
254: [ 'inc' , 2 ], # inc a,x
216+
255: [ 'bbs7', 8 ], # bbs7 r
217+
}
218+
219+
# Addressing modes
220+
# for each, we store the mode name and instructions length
221+
222+
modes = {
223+
0: [ 'a', 3 ],
224+
1: [ '(a,x)', 3 ],
225+
2: [ 'a,x', 3 ],
226+
3: [ 'a,y', 3 ],
227+
4: [ '(a)', 3 ],
228+
5: [ 'A', 1 ],
229+
6: [ '#', 2 ],
230+
7: [ 'i', 1 ],
231+
8: [ 'r', 2 ],
232+
9: [ 's', 1 ],
233+
10: [ 'zp', 2 ],
234+
11: [ '(zp,x)', 2 ],
235+
12: [ 'zp,x', 2 ],
236+
13: [ 'zp,y', 2 ],
237+
14: [ '(zp)', 2 ],
238+
15: [ '(zp),y', 2 ],
239+
}
240+
241+
def isValidOpcode(b):
242+
return b in opcodes.keys()
243+
244+
# decode an opcode byte b
245+
# returns mnemonic, mode, length
246+
def decode(b):
247+
if isinstance(b,str):
248+
b=hex2dec(b)
249+
if isValidOpcode(b):
250+
o, m = opcodes[b]
251+
m, l = modes[m]
252+
return o, m, l
253+
else:
254+
return None,None,None
255+
256+
def hex2dec(s):
257+
return int(s,16)
258+
259+
def render_instr(_args):
260+
# args is a list: addr, mnemonic, [op1, op2]
261+
# addr: the instruction's address. int or hex str
262+
# mnemonic, op1 & op2 are strings in hex
263+
264+
# we create a copy of the _args list, because we will modify it
265+
args=_args[:]
266+
267+
# we revers the list, so we can pop each item
268+
# and at the end, the operand's byte are correctly ordered
269+
addr = args.pop(0)
270+
if isinstance(addr,str):
271+
addr=hex2dec(addr)
272+
273+
opcode = args.pop(0)
274+
275+
# if isinstance(opcode,str):
276+
# opcode=hex2dec(opcode)
277+
278+
comment = ""
279+
280+
unknown = ".."
281+
282+
o,m,l = decode(opcode)
283+
284+
miss = 0
285+
286+
while True:
287+
miss = l - len(args) - 1 # how many operands bytes we are missing
288+
if miss >= 0:
289+
break
290+
# too much args, remove
291+
args.pop()
292+
293+
args.reverse()
294+
operand="".join(args)
295+
args.reverse() # now we need it again in the chronological order, for hexdump
296+
297+
operand = unknown*miss + operand
298+
299+
hexdump = " ".join( [opcode] + args + [ unknown for _ in range(miss) ])
300+
301+
#if o.startswith("b") and o not in ["bit", "brk"] :
302+
if m == "r" :
303+
if miss==0 :
304+
dest = addr + 2
305+
operand = hex2dec(operand)
306+
if operand > 0x7f:
307+
dest -= 0x100 - operand
308+
else:
309+
dest += operand
310+
operand = "%04X" % dest
311+
else:
312+
# add an extra unknown byte
313+
operand = unknown + operand
314+
315+
if l>1:
316+
operand = "$"+operand
317+
318+
if m == "#":
319+
operand = "#"+operand
320+
if ',x' in m:
321+
operand += ",x"
322+
if m.startswith('('):
323+
operand = "(" + operand + ")"
324+
if m.endswith('y'):
325+
operand += ",y"
326+
if m == "A":
327+
operand = "A"
328+
329+
# return ("%04X: %-10s %s %-8s %-4s %s " % (addr, hexdump.upper(), o, operand, m, comment))
330+
return ("%04X: %s %-8s " % (addr, o, operand))

0 commit comments

Comments
 (0)