diff options
| author | iximeow <me@iximeow.net> | 2018-07-09 21:53:10 -0700 | 
|---|---|---|
| committer | iximeow <me@iximeow.net> | 2018-07-09 21:53:10 -0700 | 
| commit | bb7bbc04ecb9e4feaecf59d7230f377e4c6fc143 (patch) | |
| tree | dfad417c3037964c68b68b74c59509fc8d6642c0 /source/notes/pic-mcu/pickit2/pk2cmd-stuff/pic18.py | |
| parent | aab989297b2f6b5ee4501ae1da1f4ca681cc6b7e (diff) | |
add pic notes
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)  | 
