diff options
Diffstat (limited to 'source/notes/pic-mcu/pickit2/pk2cmd-stuff/pic18.py')
-rw-r--r-- | source/notes/pic-mcu/pickit2/pk2cmd-stuff/pic18.py | 526 |
1 files changed, 526 insertions, 0 deletions
diff --git a/source/notes/pic-mcu/pickit2/pk2cmd-stuff/pic18.py b/source/notes/pic-mcu/pickit2/pk2cmd-stuff/pic18.py new file mode 100644 index 0000000..15c2791 --- /dev/null +++ b/source/notes/pic-mcu/pickit2/pk2cmd-stuff/pic18.py @@ -0,0 +1,526 @@ +def render(instr): + if 'ops' in instr: + optexts = [] + for op in instr['ops']: + if isinstance(op, dict) and 'type' in op: + optext = op['text'] if 'text' in op else hex(op['value']) + optexts.append(optext) + else: + optexts.append(str(op)) + return "{} {}".format(instr['mnemonic'], ', '.join(optexts)) + else: + return instr['mnemonic'] + +def sext(number, bit): + mask = 1 << bit + if number & mask > 0: + return - ((~number & (mask - 1)) + 1) + else: + return number + +NAMES = { + 0xF60: '_ZERO_', + 0xF61: '_ZERO_', + 0xF62: 'SPPDATA', + 0xF63: 'SPPCFG', + 0xF64: 'SPPEPS', + 0xF65: 'SPPCON', + 0xF66: 'UFRML', + 0xF67: 'UFRMH', + 0xF68: 'UIR', + 0xF69: 'UIE', + 0xF6A: 'UEIR', + 0xF6B: 'UEIE', + 0xF6C: 'USTAT', + 0xF6D: 'UCON', + 0xF6E: 'UADDR', + 0xF6F: 'UCFG', + 0xF70: 'UEP0', + 0xF71: 'UEP1', + 0xF72: 'UEP2', + 0xF73: 'UEP3', + 0xF74: 'UEP4', + 0xF75: 'UEP5', + 0xF76: 'UEP6', + 0xF77: 'UEP7', + 0xF78: 'UEP8', + 0xF79: 'UEP9', + 0xF7A: 'UEP10', + 0xF7B: 'UEP11', + 0xF7C: 'UEP12', + 0xF7D: 'UEP13', + 0xF7E: 'UEP14', + 0xF7F: 'UEP15', + 0xF80: 'PORTA', + 0xF81: 'PORTB', + 0xF82: 'PORTC', + 0xF83: 'PORTD', + 0xF84: 'PORTE', + 0xF85: '_ZERO_', + 0xF86: '_ZERO_', + 0xF87: '_ZERO_', + 0xF88: '_ZERO_', + 0xF89: 'LATA', + 0xF8A: 'LATB', + 0xF8B: 'LATC', + 0xF8C: 'LATD', + 0xF8D: 'LATE', + 0xF8E: '_ZERO_', + 0xF8F: '_ZERO_', + 0xF90: '_ZERO_', + 0xF91: '_ZERO_', + 0xF92: 'TRISA', + 0xF93: 'TRISB', + 0xF94: 'TRISC', + 0xF95: 'TRISD', + 0xF96: 'TRISE', + 0xF97: '_ZERO_', + 0xF98: '_ZERO_', + 0xF99: '_ZERO_', + 0xF9A: '_ZERO_', + 0xF9B: 'OSCTUNE', + 0xF9C: '_ZERO_', + 0xF9D: 'PIE1', + 0xF9E: 'PIR1', + 0xF9F: 'IPR1', + 0xFA0: 'PIE2', + 0xFA1: 'PIR2', + 0xFA2: 'IPR2', + 0xFA3: '_ZERO_', + 0xFA4: '_ZERO_', + 0xFA5: '_ZERO_', + 0xFA6: 'EECON1', + 0xFA7: 'EECON2', + 0xFA8: 'EEDATA', + 0xFA9: 'EEADR', + 0xFAA: '_ZERO_', + 0xFAB: 'RCSTA', + 0xFAC: 'TXSTA', + 0xFAD: 'TXREG', + 0xFAE: 'RCREG', + 0xFAF: 'SPBRG', + 0xFB0: 'SPBRGH', + 0xFB1: 'T3CON', + 0xFB2: 'TMR3L', + 0xFB3: 'TMR3H', + 0xFB4: 'CMCON', + 0xFB5: 'CVRCON', + 0xFB6: 'ECCP1AS', + 0xFB7: 'ECCP1DEL', + 0xFB8: 'BAUDCON', + 0xFB9: '_ZERO_', + 0xFBA: 'CCP2CON', + 0xFBB: 'CCPR2L', + 0xFBC: 'CCPR2H', + 0xFBD: 'CCP1CON', + 0xFBE: 'CCPR1L', + 0xFBF: 'CCPR1H', + 0xFC0: 'ADCON2', + 0xFC1: 'ADCON1', + 0xFC2: 'ADCON0', + 0xFC3: 'ADRESL', + 0xFC4: 'ADRESH', + 0xFC5: 'SSPCON2', + 0xFC6: 'SSPCON1', + 0xFC7: 'SSPSTAT', + 0xFC8: 'SSPADD', + 0xFC9: 'SSPBUF', + 0xFCA: 'T2CON', + 0xFCB: 'PR2', + 0xFCC: 'TMR2', + 0xFCD: 'T1CON', + 0xFCE: 'TMR1L', + 0xFCF: 'TMR1H', + 0xFD0: 'RCON', + 0xFD1: 'WDTCON', + 0xFD2: 'HLVDCON', + 0xFD3: 'OSCCON', + 0xFD4: '_ZERO_', + 0xFD5: 'T0CON', + 0xFD6: 'TMR0L', + 0xFD7: 'TMR0H', + 0xFD8: 'STATUS', + 0xFD9: 'FSR2L', + 0xFDA: 'FSR2H', + 0xFDB: 'PLUSW2', + 0xFDC: 'PREINC2', + 0xFDD: 'POSTDEC2', + 0xFDE: 'POSTINC2', + 0xFDF: 'INDF2', + 0xFE0: 'BSR', + 0xFE1: 'FSR1L', + 0xFE2: 'FSR1H', + 0xFE3: 'PLUSW1', + 0xFE4: 'PREINC1', + 0xFE5: 'POSTDEC1', + 0xFE6: 'POSTINC1', + 0xFE7: 'INDF1', + 0xFE8: 'WREG', + 0xFE9: 'FSR0L', + 0xFEA: 'FSR0H', + 0xFEB: 'PLUSW0', + 0xFEC: 'PREINC0', + 0xFED: 'POSTDEC0', + 0xFEE: 'POSTINC0', + 0xFEF: 'INDF0', + 0xFF0: 'INTCON3', + 0xFF1: 'INTCON2', + 0xFF2: 'INTCON', + 0xFF3: 'PRODL', + 0xFF4: 'PRODH', + 0xFF5: 'TABLAT', + 0xFF6: 'TBLPTRL', + 0xFF7: 'TBLPTRH', + 0xFF8: 'TBLPTRU', + 0xFF9: 'PCL', + 0xFFA: 'PCLATH', + 0xFFB: 'PCLATU', + 0xFFC: 'STKPTR', + 0xFFD: 'TOSL', + 0xFFE: 'TOSH', + 0xFFF: 'TOSU' +} + +def reg_name(number): + if number in NAMES: + return NAMES[number] + else: + return None + +def disassemble(blob, offset): + instr = {} + instr['length'] = 1 + instrbytes = blob[offset:offset + 2] + instrbytes.reverse() +# instrbytes.reverse() +# print("Decoding {:02x}{:02x}...".format(instrbytes[0], instrbytes[1])) + + if instrbytes[0] == 0x00: + # there's a few instructions here... + if instrbytes[1] == 0xff: + instr['mnemonic'] = 'reset' + else: + mnemonicmap = [ + 'nop', + 'BAD', + 'BAD', + 'sleep', + 'clrwdt', + 'push', + 'pop', + 'daw', + 'tblrd*', + 'tblrd*+', + 'tblrd*-', + 'tblrd+*', + 'tblwr*', + 'tblwr*+', + 'tblwr*-', + 'tblwr+*', + 'retfie', + 'retfie fast', + 'return', + 'return fast', + 'callw*'] + + if instrbytes[1] > len(mnemonicmap): + instr['mnemonic'] = 'BAD' + else: + instr['mnemonic'] = mnemonicmap[instrbytes[1]] + elif instrbytes[0] == 0x01: + if instrbytes[1] > 0xf: + instr['mnemonic'] = 'BAD' + else: + instr['mnemonic'] = 'movlb' + instr['ops'] = ["#" + str(instrbytes[1])] + elif instrbytes[0] == 0x02 or instrbytes[0] == 0x03: + instr['mnemonic'] = 'mulwf' + instr['ops'] = ['TODO'] + elif instrbytes[0] >= 0x04 and instrbytes[0] < 0x08: + instr['mnemonic'] = 'decf' + d = (instrbytes[0] >> 1) & 1 + a = instrbytes[0] & 1 + f = instrbytes[1] + if a == 0: + # "Access Bank" + f_physical = f if f < 0x60 else 0xf00 + f + source = { + 'type': 'register', + 'value': f_physical + } + else: + source = { + 'type': 'banked-register', + 'value': f + } + + if d == 0: + dest = { 'type': 'register', + 'value': 'W' } + else: + dest = source + + if a == 0: + instr['ops'] = [ source, dest ] + else: + instr['ops'] = [ source, dest, 'banked' ] + + elif instrbytes[0] >= 0x08 and instrbytes[0] < 0x10: + code = instrbytes[0] & 0x7 + + instr['mnemonic'] = [ + 'sublw', + 'iorlw', + 'xorlw', + 'andlw', + 'retlw', + 'mullw', + 'movlw', + 'addlw' + ][code] + instr['ops'] = ['#' + hex(instrbytes[1])] + elif instrbytes[0] >= 0x10 and instrbytes[0] < 0x20: + code = (instrbytes[0] >> 2) & 0x3 + instr['mnemonic'] = [ + 'iorwf', + 'andwf', + 'xorwf', + 'comf' + ][code] + d = (instrbytes[0] >> 1) & 1 + a = instrbytes[0] & 1 + f = instrbytes[1] + + if a == 0: + # "Access Bank" + f_physical = f if f < 0x60 else 0xf00 + f + source = { + 'type': 'register', + 'value': f_physical + } + else: + source = { + 'type': 'banked-register', + 'value': f + } + + if d == 0: + dest = { 'type': 'register', + 'value': 'W' } + else: + dest = source + + if a == 0: + instr['ops'] = [ source, dest ] + else: + instr['ops'] = [ source, dest, 'banked' ] + + elif instrbytes[0] >= 0x20 and instrbytes[0] < 0x60: + mnemonicSel = instrbytes[0] >> 2 + instr['mnemonic'] = [ + 'mulwf (TODO)', #000000 + 'decf', #000001 + 'BAD', 'BAD', #00001X + 'iorwf', #000100 + 'andwf', #000101 + 'xorwf', #000110 + 'comf', #000111 + 'addwfc', #001000 + 'addwf', #001001 + 'incf', #001010 + 'decfsz', #001011 + 'rrcf', #001100 + 'rlcf', #001101 + 'swapf', #001110 + 'incfsz', #001111 + 'rrncf', #010000 + 'rlncf', #010001 + 'infsnz', #010010 + 'dcfsnz', #010011 + 'movf', #010100 + 'subwfb', #010101 + 'subwfb', #000000 + 'subwf' #000000 + ][mnemonicSel] + d = (instrbytes[0] >> 1) & 1 + a = instrbytes[0] & 1 + f = instrbytes[1] + + if a == 0: + # "Access Bank" + f_physical = f if f < 0x60 else 0xf00 + f + source = { + 'type': 'register', + 'value': f_physical + } + else: + source = { + 'type': 'banked-register', + 'value': f + } + + if d == 0: + dest = { 'type': 'register', + 'value': 'W' } + else: + dest = source + + if a == 0: + instr['ops'] = [ source, dest ] + else: + instr['ops'] = [ source, dest, 'banked' ] + + elif instrbytes[0] >= 0x60 and instrbytes[0] < 0x70: + mnemonicSel = (instrbytes[0] >> 1) & 0x7 + instr['mnemonic'] = [ + 'cpfslt', + 'cpfseq', + 'cpfsgt', + 'tstfsz', + 'setf', + 'clrf', + 'negf', + 'movwf' + ][mnemonicSel] + a = instrbytes[0] & 1 + f = instrbytes[1] + if a == 0: + # "Access Bank" + f_physical = f if f < 0x60 else 0xf00 + f + instr['ops'] = [ + { 'type': 'register', + 'value': f_physical } + ] + else: + instr['ops'] = [ + { 'type': 'banked-register', + 'value': f }, + "banked" + ] + elif instrbytes[0] >= 0x70 and instrbytes[0] < 0xc0: + mnemonicSel = instrbytes[0] >> 4 + instr['mnemonic'] = [ + 'BAD', 'BAD', 'BAD', 'BAD', 'BAD', 'BAD', 'BAD', + 'btg', + 'bsf', + 'bcf', + 'btfss', + 'btfsc' + ][mnemonicSel] + bit = (instrbytes[0] >> 1) & 0x7 + a = instrbytes[0] & 1 + f = instrbytes[1] + if a == 0: + # "Access Bank" + f_physical = f if f < 0x60 else 0xf00 + f + instr['ops'] = [ + { 'type': 'register', + 'value': f_physical }, + bit + ] + else: + instr['ops'] = [ + { 'type': 'banked-register', + 'value': f }, + bit, + "banked" + ] + elif instrbytes[0] >= 0xc0 and instrbytes[0] < 0xd0: + instr['mnemonic'] = 'movff' + instr['length'] = 2 + fs = ((instrbytes[0] & 0xf) << 8) | instrbytes[1] + followingbytes = blob[offset + 2:offset + 4] + followingbytes.reverse() + if followingbytes[0] < 0xf0: + instr['mnemonic'] = 'movff (BAD)' + else: + fd = ((followingbytes[0] & 0xf) << 8) | followingbytes[1] + instr['ops'] = [ + { 'type': 'register', + 'value': fs }, + { 'type': 'register', + 'value': fd } + ] + elif instrbytes[0] >= 0xd0 and instrbytes[0] < 0xd8: + instr['mnemonic'] = 'bra' + n = ((instrbytes[0] & 0x7) << 8) | instrbytes[1] + n = sext(n, 10) + instr['ops'] = [{ + 'type': 'relpostdest', + 'value': n << 1 + }] + elif instrbytes[0] >= 0xd8 and instrbytes[0] < 0xe0: + instr['mnemonic'] = 'rcall' + n = ((instrbytes[0] & 0x7) << 8) | instrbytes[1] + instr['ops'] = [{ + 'type': 'relpostdest', + 'value': n << 1 + }] + elif instrbytes[0] >= 0xe0 and instrbytes[0] <= 0xe8: + code = instrbytes[0] & 0x7 + instr['mnemonic'] = [ + 'bz', + 'bnz', + 'bc', + 'bnc', + 'bov', + 'bnov', + 'bn', + 'bnn' + ][code] + n = instrbytes[1] + n = sext(n, 7) + instr['ops'] = [{ + 'type': 'relpostdest', + 'value': n << 1 + }] + elif instrbytes[0] >= 0xf0 and instrbytes[0] <= 0xff: + instr['mnemonic'] = 'BAD (misdecode)' + elif instrbytes[0] == 0xea: + instr['mnemonic'] = 'push' + instr['ops'] = [instrbytes[1]] + elif instrbytes[0] == 0xec or instrbytes[0] == 0xed: + instr['mnemonic'] = 'call' + s = instrbytes[0] & 1 + instr['length'] = 2 + lowbits = instrbytes[1] + followingbytes = blob[offset + 2:offset + 4] + followingbytes.reverse() + if followingbytes[0] < 0xf0: + instr['mnemonic'] = 'CALL (BAD)' + else: + k = (((followingbytes[0] & 0x0f) << 16) | (followingbytes[1] << 8) | lowbits) + instr['ops'] = [{ + 'type': 'absolutedest', + 'value': k << 1 + }, str(s)] + elif instrbytes[0] == 0xee: + instr['mnemonic'] = 'lfsr' + instr['length'] = 2 + f = (instrbytes[1] >> 4) & 3 + followingbytes = blob[offset + 2:offset + 4] + followingbytes.reverse() + if followingbytes[0] < 0xf0: + instr['mnemonic'] = 'lsfr (BAD)' + else: + k = ((instrbytes[1] & 0xf) << 8) | followingbytes[1] + instr['ops'] = [str(f), hex(k)] + elif instrbytes[0] == 0xef: + instr['mnemonic'] = 'goto' + instr['length'] = 2 + lowbits = instrbytes[1] + followingbytes = blob[offset + 2:offset + 4] + followingbytes.reverse() + if followingbytes[0] < 0xf0: + instr['mnemonic'] = 'GOTO (BAD)' + else: + k = ((followingbytes[0] & 0x0f) << 16) | (followingbytes[1] << 8) | lowbits + instr['ops'] = [{ + 'type': 'absolutedest', + 'value': k << 1 + }] + + else: + instr['mnemonic'] = 'TODO' + + return (offset + instr['length'] * 2, instr) |