|
| 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