Esempio n. 1
0
File: target.py Progetto: Ivoah/6502
def NewOrgSet(memory):

    """
    Handle flushing of the current target line.
    We possibly have to close an unformatted target file as well.
    Possible parameter values are 0 for code memory and 2 for EEPROM memory
    """

    if dec.Asm.Pass == 2:
        # Only during pass 2

        if memory == 0:
            # In code memory
            if dec.Asm.Code_Tformat != '':
                # A targetfile is open
                FlushTarget(0)
                if dec.Asm.Code_Tformat in ('BIN', 'HEX'):
                    # It's an unformattedtext target file
                    if dec.Asm.Code_Tfile.tell() != 0:
                        # Unformatted target file is not empty
                        CloseTarget(0)
                        errors.DoWarning('tclosed', True)
        else:
            # It's EEPROM or RAM section
            if dec.Asm.Eeprom_Tformat != '':
                # A target file is open
                FlushTarget(2)
                if dec.Asm.Eeprom_Tformat in ('BIN', 'HEX'):
                    # It'sn unformatted target file
                    if dec.Asm.Eeprom_Tfile.tell() != 0:
                        # Unformatted target file is not empty
                        CloseTarget(2)
                        errors.DoWarning('tclosed', True)
Esempio n. 2
0
def CrossMnemonic():
    """
    Instructions have to start on an even byte location, so we'll do a
    boundary sync first.
    Then we'll check if the given directive is known to us.
    Depending on the chosen family some directives may not be valid.
    Parse the mnemonic if it is valid.
    """

    global Asm

    target.BoundarySync()

    if dec.Asm.AVR_Family == 0:
        # AVR Family not specified, assume XMega family
        errors.DoWarning(dec.Cross.Name + 'nofamily', False)
        dec.Asm.AVR_Family = 4

    if dec.Asm.Mnemonic in dec.Asm.Instructions:

        if not (FamilyCheck(dec.Asm.Instructions[dec.Asm.Mnemonic][1],
                            dec.Asm.Instructions[dec.Asm.Mnemonic][2])):
            # Opcode not supported by this family
            errors.DoError('badopco', False)
        else:
            # Opcode is supported by this family, do it
            dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][4]
            func = dec.Asm.Instructions[dec.Asm.Mnemonic][0]
            func()
    else:
        errors.DoError('badopco', False)
Esempio n. 3
0
def Immediate():
    """
    Immediate operand instructions.
    Instructions optionally accept the traditional # / = and \ prefixes.
    Only the RETLW instruction will accept multiple operatnds, which are
    stored sequentially in program memory.
    """

    global Asm

    opcode = dec.Asm.Instructions[dec.Asm.Mnemonic][1]
    dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2]

    if opcode == 0x0C00:
        # Operand field may be empty for RETLW instruction
        if dec.Asm.Parse_Pointer == 0 or dec.Asm.Optional is False:
            # No parameter is following
            CodeWord(opcode)
            return

    while True:
        prefix = '#'
        if assem.NowChar() in '#/=\\':
            # A prefix is given, let's get it
            prefix = assem.NowChar(True)

        value = assem.EvalExpr()[0]

        if dec.Asm.Mnemonic == "BANKSEL":
            # BANKSEL is the same as MOVLB with modified operand
            value = (value // 256) & 0x0F

        if not dec.Flags.ErrorInLine:
            # No error in this line, let's continue
            if prefix == '#':
                # Keep lower byte
                value = value & 0xFF
            elif prefix == '/':
                # Keep 2nd lower byte
                value = (value >> 8) & 0xFF
            elif prefix == '=':
                # Keep 2nd upper byte
                value = (value >> 16) & 0xFF
            else:
                # Keep upper byte
                value = (value >> 24) & 0xFF

        if opcode == 0x0100:
            # MOVLB range is limited to 4 bits
            value = value & 0x0F

        CodeWord(opcode + value)

        if not assem.MoreParameters():
            # No more parameters
            break

        if opcode != 0x0C00:
            # Only the RETLW instruction allows multiple literal bytes
            errors.DoWarning('extrign', False)
Esempio n. 4
0
def NoMore():
    """
    No more operands shoudl follow. Raise a warning if more parameters follow.
    """

    if assem.MoreParameters():
        errors.DoWarning('extrign', False)
Esempio n. 5
0
def IncPP():
    """
    Increment the Program Pointer.
    """

    global Asm

    dec.Asm.Fraction = dec.Asm.Fraction + 1
    if dec.Asm.Fraction >= dec.Asm.PP_TA_Factor:
        dec.Asm.PP_Address = dec.Asm.PP_Address + 1
        dec.Asm.PH_Address = dec.Asm.PH_Address + 1
        dec.Asm.Fraction = 0

    if not dec.Flags.DummyMode:
        if dec.Asm.Pass == 2 and (not dec.Asm.Code_Twrap) and\
                dec.Asm.TA_Address > dec.Asm.Code_Tmaxadd:
            dec.Asm.Code_Twrap = True
            # True because will only happen in pass 2
            errors.DoWarning('trange', True)
            dec.Asm.TA_Address = dec.Asm.TA_Address & dec.MAX32
        dec.Asm.TA_Address = dec.Asm.TA_Address + 1

    if dec.Asm.Code_Tformat in ('INT', 'INS'):
        if (dec.Asm.TA_Address & 0xFFFF) == 0:
            # Segment changed! Flush current line before change of segment
            FlushTarget(0)
Esempio n. 6
0
def NoMore():
    """
    No more parameters are expected.
    Raise a warning if more paramters are found anyway.
    """

    if assem.MoreParameters():
        errors.DoWarning('extrign', False)
Esempio n. 7
0
def NoMore():
    """
    A useful function which tests if no more parameters are given when we
    don't expect any more at the end of the operand parsing.
    """

    if assem.MoreParameters():
        errors.DoWarning('extrign', False)
Esempio n. 8
0
def NoMore():
    """
    This must be the end of the line. Raise an error if it's not. Or a warning
    if more parameters follow.
    """

    if assem.MoreParameters():
        errors.DoWarning('extrign', False)
Esempio n. 9
0
def Immediate():
    """
    Immediate operand instructions.
    Instructions optionally accept the traditional # / = and \ prefixes.
    Only GOTO and CALL don't, they are only tolerant to the # prefix
    Only the RETLW instruction will accept multiple operatnds, which are
    stored sequentially in program memory.
    """

    global Asm

    opcode = dec.Asm.Instructions[dec.Asm.Mnemonic][1]
    dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2]

    if opcode == 0x3400:
        # Operand field may be empty for RETLW instruction
        if dec.Asm.Parse_Pointer == 0 or dec.Asm.Optional is False:
            # No parameter is following
            CodeWord(opcode)
            return

    while True:
        prefix = '#'
        if assem.NowChar() in '#/=\\':
            # A prefix is given, let's get it
            prefix = assem.NowChar(True)

        value = assem.EvalExpr()

        if not dec.Flags.ErrorInLine:
            # No error in this line, let's continue
            if opcode == 0x2000 or opcode == 0x2800:
                # Allow 11 bits of operand for GOTO
                CodeWord(opcode + (value[0] & 0x7FF))
                if prefix != '#':
                    # Only the default prefix is allowed
                    errors.DoError('badoper', False)
            elif prefix == '#':
                # Save opcode and lower byte
                CodeWord(opcode + (value[0] & 0xFF))
            elif prefix == '/':
                # Save opcode and 2nd lower byte
                CodeWord(opcode + ((value[0] >> 8) & 0xFF))
            elif prefix == '=':
                # Save opcode and 2nd upper byte
                CodeWord(opcode + ((value[0] >> 16) & 0xFF))
            else:
                # Save opcode and upper byte
                CodeWord(opcode + ((value[0] >> 24) & 0xFF))

        if not assem.MoreParameters():
            # No more parameters
            break

        if opcode != 0x3400:
            # Only the RETLW instruction allows multiple literal bytes
            errors.DoWarning('extrign', False)
Esempio n. 10
0
def CodeLong(value, list=True):
    """
    Save a long to the target file.
    Give a warning only once if the byte is not written to code memory!
    This is the routine to be used by crosses to save a code long.
    """

    if dec.Asm.Memory != 0 and not dec.Flags.CodeWarn and dec.Asm.Pass == 2:
        dec.Flags.CodeWarn = True
        errors.DoWarning('notcode', True)

    SaveLong(value, list)
Esempio n. 11
0
def CodeWord(data, list="True"):
    """
    Write the code word to the target file.
    We can't rely on target.CodeWord because that would change everything into
    RETLW instructions.
    """

    if dec.Asm.Memory != 0 and not dec.Flags.CodeWarn and dec.Asm.Pass == 2:
        dec.Flags.CodeWarn = True
        errors.DoWarning('notcode', True)

    target.SaveByte(data & 0xFF, list)
    target.SaveByte((data >> 8) & 0xFF, list)
Esempio n. 12
0
def WriteOpcode(data):
    """
    Normally an Opcode byte can just be written to memory. However when the
    Opcde byte is written to the beginning of the page, the assembler assumes
    that you have crossed a page boundary and it will give you a warning.
    Crossing a page boundary is perfectly legal, as long as you know what
    you're doing.
    """

    global Asm

    if dec.Asm.Pass == 2:
        if ((dec.Asm.BOL_Address) & 4095) == 0:
            errors.DoWarning(dec.Cross.Name + 'pagebeg', True)
    target.CodeByte(data)
Esempio n. 13
0
def Absolute():

    global Asm

    if MissingOperand():
        return

    value = assem.EvalExpr()

    if dec.Asm.Pass == 2 or (not value[1]):
        # Test range only if in pass 2, or pass 1 if not forward referenced
        if value[0] > dec.Asm.Max_Address or value[0] < 0:
            # It's a range error, simply ignore everything which doesn't fit
            errors.DoError('range', False)

    target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1])
    target.CodeWord(value[0])

    if value[2] == 2:
        errors.DoWarning('eeprom')

    NoMore()
Esempio n. 14
0
def CodeWord(data, list="True"):
    """
    Write the code word to the target file.
    We don't have to anythong special for the PIC16. We only need to do a
    boundary sync first.
    """

    if dec.Asm.Memory != 0 and not dec.Flags.CodeWarn and dec.Asm.Pass == 2:
        # It's useless to store program code in EEPROM or RAM memory
        dec.Flags.CodeWarn = True
        errors.DoWarning('notcode', True)

    if dec.Asm.Memory == 0:
        # OK, we're in code memory
        if (dec.Asm.PH_Address % 2) != 0:
            # We're at an odd address. Let's save a padding byte
            target.SaveByte(0, False)
            dec.Asm.BOL_Address = dec.Asm.PH_Address
            dec.Asm.List_Address = dec.Asm.PH_Address

        target.SaveByte(data & 0xFF, list)
        target.SaveByte((data >> 8) & 0xFF, list)
Esempio n. 15
0
def CrossInit():

    global Asm, Flags, avrdirlist

    assem.CheckVersions(crossversion, minversion)

    # Tupple consists of these fields:
    # - Function to be called
    # - 8=Xmega, 4=Mega, 2=AVR, 1=Tiny
    # - 128=XMEGA, 64=Enhanced 4M, 32=Enhanced 128k, 16=Enhanced 8k,
    #   8-Classic 128k, 4=Classic 8k, 2=Minimal, 1=Reduced
    # - Opcode
    # - Tiniming
    dec.Asm.Instructions = {
        'ADC': (RegReg, 0b00001111, 0b01111111, 0x1C00, '1'),
        'ADD': (RegReg, 0b00001111, 0b01111111, 0x0C00, '1'),
        'AND': (RegReg, 0b00001111, 0b01111111, 0x2000, '1'),
        'CP': (RegReg, 0b00001111, 0b01111111, 0x1400, '1'),
        'CPC': (RegReg, 0b00001111, 0b01111111, 0x0400, '1'),
        'CPSE': (RegReg, 0b00001111, 0b01111111, 0x1000, '1/2/3'),
        'EOR': (RegReg, 0b00001111, 0b01111111, 0x2400, '1'),
        'FMUL': (RegReg, 0b00001100, 0b01110000, 0x0308, '2'),
        'FMULS': (RegReg, 0b00001100, 0b01110000, 0x0380, '2'),
        'FMULSU': (RegReg, 0b00001100, 0b01110000, 0x0388, '2'),
        'MOV': (RegReg, 0b00001111, 0b01111111, 0x2C00, '1'),
        'MOVW': (RegReg, 0b00001100, 0b01110000, 0x0100, '1'),
        'MUL': (RegReg, 0b00001100, 0b01110000, 0x9C00, '1'),
        'MULS': (RegReg, 0b00001100, 0b01110000, 0x0200, '1'),
        'MULSU': (RegReg, 0b00001100, 0b01110000, 0x0300, '1'),
        'OR': (RegReg, 0b00001111, 0b01111111, 0x2800, '1'),
        'SBC': (RegReg, 0b00001111, 0b01111111, 0x0800, '1'),
        'SUB': (RegReg, 0b00001111, 0b01111111, 0x1800, '1'),
        'ADIW': (RegImm, 0b00001110, 0b01111100, 0x9600, '1'),
        'ANDI': (RegImm, 0b00001111, 0b01111111, 0x7000, '1'),
        'CBR': (RegImm, 0b00001111, 0b01111111, 0x7000, '1'),
        'CPI': (RegImm, 0b00001111, 0b01111111, 0x3000, '1'),
        'LDI': (RegImm, 0b00001111, 0b01111111, 0xE000, '1'),
        'ORI': (RegImm, 0b00001111, 0b01111111, 0x6000, '1'),
        'SBCI': (RegImm, 0b00001111, 0b01111111, 0x4000, '1'),
        'SBIW': (RegImm, 0b00001110, 0b01111100, 0x9700, '2'),
        'SBR': (RegImm, 0b00001111, 0b01111111, 0x6000, '1'),
        'SUBI': (RegImm, 0b00001111, 0b01111111, 0x5000, '1'),
        'ASR': (RegOnly, 0b00001111, 0b01111111, 0x9405, '1'),
        'CLR': (RegOnly, 0b00001111, 0b01111111, 0x2400, '1'),
        'COM': (RegOnly, 0b00001111, 0b01111111, 0x9400, '1'),
        'DEC': (RegOnly, 0b00001111, 0b01111111, 0x940A, '1'),
        'INC': (RegOnly, 0b00001111, 0b01111111, 0x9403, '1'),
        'LAC': (RegOnly, 0b00001000, 0b00000000, 0x9206, '2'),
        'LAS': (RegOnly, 0b00001000, 0b00000000, 0x9205, '2'),
        'LAT': (RegOnly, 0b00001000, 0b00000000, 0x9207, '2'),
        'LSL': (RegOnly, 0b00001111, 0b01111111, 0x0C00, '1'),
        'LSR': (RegOnly, 0b00001111, 0b01111111, 0x9406, '1'),
        'NEG': (RegOnly, 0b00001111, 0b01111111, 0x9401, '1'),
        'POP': (RegOnly, 0b00001111, 0b01111101, 0x900F, '2'),
        'PUSH': (RegOnly, 0b00001111, 0b01111101, 0x920F, '1/2'),
        'ROL': (RegOnly, 0b00001111, 0b01111111, 0x1C00, '1'),
        'ROR': (RegOnly, 0b00001111, 0b01111111, 0x9407, '1'),
        'SER': (RegOnly, 0b00001111, 0b01111111, 0xEF0F, '1'),
        'SWAP': (RegOnly, 0b00001111, 0b01111111, 0x9402, '1'),
        'TST': (RegOnly, 0b00001111, 0b01111111, 0x2000, '1'),
        'XCH': (RegOnly, 0b00001000, 0b00000000, 0x9204, '2'),
        'BRBC': (RelJmp, 0b00001111, 0b01111111, 0xF400, '1/2'),
        'BRBS': (RelJmp, 0b00001111, 0b01111111, 0xF000, '1/2'),
        'BRCC': (RelJmp, 0b00001111, 0b01111111, 0xF400, '1/2'),
        'BRCS': (RelJmp, 0b00001111, 0b01111111, 0xF000, '1/2'),
        'BREQ': (RelJmp, 0b00001111, 0b01111111, 0xF001, '1/2'),
        'BRGE': (RelJmp, 0b00001111, 0b01111111, 0xF404, '1/2'),
        'BRHC': (RelJmp, 0b00001111, 0b01111111, 0xF405, '1/2'),
        'BRHS': (RelJmp, 0b00001111, 0b01111111, 0xF005, '1/2'),
        'BRID': (RelJmp, 0b00001111, 0b01111111, 0xF407, '1/2'),
        'BRIE': (RelJmp, 0b00001111, 0b01111111, 0xF007, '1/2'),
        'BRLO': (RelJmp, 0b00001111, 0b01111111, 0xF000, '1/2'),
        'BRLT': (RelJmp, 0b00001111, 0b01111111, 0xF004, '1/2'),
        'BRMI': (RelJmp, 0b00001111, 0b01111111, 0xF002, '1/2'),
        'BRNE': (RelJmp, 0b00001111, 0b01111111, 0xF401, '1/2'),
        'BRPL': (RelJmp, 0b00001111, 0b01111111, 0xF402, '1/2'),
        'BRSH': (RelJmp, 0b00001111, 0b01111111, 0xF400, '1/2'),
        'BRTC': (RelJmp, 0b00001111, 0b01111111, 0xF406, '1/2'),
        'BRTS': (RelJmp, 0b00001111, 0b01111111, 0xF006, '1/2'),
        'BRVC': (RelJmp, 0b00001111, 0b01111111, 0xF403, '1/2'),
        'BRVS': (RelJmp, 0b00001111, 0b01111111, 0xF003, '1/2'),
        'RCALL': (RelJmp, 0b00001111, 0b01111111, 0xD000, '2/3/4'),
        'RJMP': (RelJmp, 0b00001111, 0b01111111, 0xC000, '2'),
        'CALL': (CallJmp, 0b00001110, 0b01111000, 0x940E, '3/4/5'),
        'JMP': (CallJmp, 0b00001110, 0b01111000, 0x940C, '3'),
        'BLD': (BitInst, 0b00001111, 0b01111111, 0xF800, '1'),
        'BST': (BitInst, 0b00001111, 0b01111111, 0xFA00, '1'),
        'SBRC': (BitInst, 0b00001111, 0b01111111, 0xFC00, '1/2/3'),
        'SBRS': (BitInst, 0b00001111, 0b01111111, 0xFE00, '1/2/3'),
        'CBI': (IOBits, 0b00001111, 0b01111111, 0x9800, '1/2'),
        'SBI': (IOBits, 0b00001111, 0b01111111, 0x9A00, '1/2'),
        'SBIC': (IOBits, 0b00001111, 0b01111111, 0x9900, '2/3/4*'),
        'SBIS': (IOBits, 0b00001111, 0b01111111, 0x9B00, '2/3/4*'),

        # reduced LD has less addressing modes
        'LD': (LDIndexed, 0b00001111, 0b01111111, 1, '1/2/3'),
        'LDD': (LDIndexed, 0b00001110, 0b01111100, 0, '1/2/3'),

        # reduced ST has less addressing modes
        'ST': (STIndexed, 0b00001111, 0b01111111, 1, '1/2'),
        'STD': (STIndexed, 0b00001110, 0b01111100, 0, '1/2'),

        # tiny & reduced LDS and STS have different bit pattern
        'LDS': (LdsSts, 0b00001111, 0b01111101, 0x9000, '2/3'),
        'STS': (LdsSts, 0b00001111, 0b01111101, 0x9200, '2'),
        'ELPM': (ELpm, 0b00001110, 0b01111000, 0x95D8, '3'),
        'LPM': (ELpm, 0b00001110, 0b01110110, 0x95C8, '3'),
        'SPM': (Spm, 0b00001100, 0b01110000, 0x95E8, '*'),
        'IN': (InOut, 0b00001111, 0b01111111, 0xB000, '1'),
        'OUT': (InOut, 0b00001111, 0b01111111, 0xB800, '1'),
        'BCLR': (Sreg, 0b00001111, 0b01111111, 0x9488, '1'),
        'BSET': (Sreg, 0b00001111, 0b01111111, 0x9408, '1'),
        'DES': (Des, 0b00001000, 0b00000000, 0x940B, '1/2'),
        'BREAK': (Inherent, 0b00001101, 0b01100001, 0x9598, '1'),
        'CLC': (Inherent, 0b00001111, 0b01111111, 0x9488, '1'),
        'CLH': (Inherent, 0b00001111, 0b01111111, 0x94D8, '1'),
        'CLI': (Inherent, 0b00001111, 0b01111111, 0x94F8, '1'),
        'CLN': (Inherent, 0b00001111, 0b01111111, 0x94A8, '1'),
        'CLS': (Inherent, 0b00001111, 0b01111111, 0x94C8, '1'),
        'CLT': (Inherent, 0b00001111, 0b01111111, 0x94E8, '1'),
        'CLV': (Inherent, 0b00001111, 0b01111111, 0x94B8, '1'),
        'CLZ': (Inherent, 0b00001111, 0b01111111, 0x9498, '1'),
        'EICALL': (Inherent, 0b00001100, 0b01000000, 0x9519, '3/4*'),
        'EIJMP': (Inherent, 0b00001100, 0b01000000, 0x9419, '2'),
        'ICALL': (Inherent, 0b00001111, 0b01111100, 0x9509, '2/3/4*'),
        'IJMP': (Inherent, 0b00001111, 0b01111100, 0x9409, '2'),
        'NOP': (Inherent, 0b00001111, 0b01111111, 0x0000, '1'),
        'RET': (Inherent, 0b00001111, 0b01111111, 0x9508, '4/5*'),
        'RETI': (Inherent, 0b00001111, 0b01111111, 0x9518, '4/5*'),
        'SEC': (Inherent, 0b00001111, 0b01111111, 0x9408, '1'),
        'SEH': (Inherent, 0b00001111, 0b01111111, 0x9458, '1'),
        'SEI': (Inherent, 0b00001111, 0b01111111, 0x9478, '1'),
        'SEN': (Inherent, 0b00001111, 0b01111111, 0x9428, '1'),
        'SES': (Inherent, 0b00001111, 0b01111111, 0x9448, '1'),
        'SET': (Inherent, 0b00001111, 0b01111111, 0x9468, '1'),
        'SEV': (Inherent, 0b00001111, 0b01111111, 0x9438, '1'),
        'SEZ': (Inherent, 0b00001111, 0b01111111, 0x9418, '1'),
        'SLEEP': (Inherent, 0b00001111, 0b01111111, 0x9588, '1'),
        'WDR': (Inherent, 0b00001111, 0b01111111, 0x95A8, '1')
    }

    length = 0
    for i in dec.Asm.Instructions:
        if len(dec.Asm.Instructions[i][4]) > length:
            length = len(dec.Asm.Instructions[i][4])
    dec.Asm.Timing_Length = length

    dec.Asm.Memory = 0
    if dec.Asm.Pass == 1:
        sys.stdout.write('Loaded ' + dec.Cross.Name[2:] + ' overlay version ' +
                         crossversion + dec.EOL)

    dec.Asm.Max_Address = (1 << 22) - 1
    # Change target factor to 2
    if dec.Asm.PP_TA_Factor != 2:
        if dec.Asm.PP_Address != dec.Asm.TA_Address or\
                dec.Asm.PP_Address != dec.Asm.PH_Address:
            # Oops, this is complicated. Let's warn the programmer
            errors.DoWarning('taconfusion', True)
        # Set the instruction size and double the target address
        dec.Asm.PP_TA_Factor = 2
        dec.Asm.TA_Address *= 2
    dec.Flags.BigEndian = False

    dec.Asm.AVR_Family = 0

    errors.Error_List[dec.Cross.Name + 'nofamily'] =\
        'AVR Family not set. Assuming XMega family.'

    # Fill dictionary with all available directive handlers
    for i in dir(cravr):
        if len(i) == 5 and i[:3] == 'Dir':
            avrdirlist[i[-2:]] = eval(i)

    return
Esempio n. 16
0
def Stack():
    """
    Handle Push and Pull instructions.
    Any number from of registers and register pairs may be pushed and pulled
    by one instruction, all separated by a comma.
    A warning is issued if you specify a particular register more than once.
    """

    global Asm

    if MissingOperand():
        return

    registers = {
        'CC': 1,
        'CCR': 1,
        'A': 2,
        'B': 4,
        'D': 6,
        'A:B': 6,
        'DP': 8,
        'DPR': 8,
        'X': 16,
        'Y': 32,
        'U': 64,
        'US': 64,
        'S': 64,
        'SP': 64,
        'PC': 128
    }

    stack = dec.Asm.Mnemonic[-1]

    postbyte = 0
    doubled = False

    while True:
        reg = assem.GetWord().upper()
        if reg in registers:
            if reg == stack:
                # S may not be used in PSHS and PULS
                # U may not be used in PSHU and PULU
                errors.DoError('badoper', False)
                return
            bits = registers[reg]
            if (postbyte & bits) != 0:
                doubled = True
            postbyte = postbyte | bits
        else:
            errors.DoError('badoper', False)
            return

        if not assem.MoreParameters():
            break

    if doubled:
        errors.DoWarning('6809double', False)

    count = 0
    for i in range(0, 8):
        if (postbyte & (1 << i)) != 0:
            if i > 3:
                count = count + 2
            else:
                count = count + 1

    target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1])
    target.CodeByte(postbyte)
    dec.Asm.Timing = str(dec.Asm.Instructions[dec.Asm.Mnemonic][2] + count)
Esempio n. 17
0
def CrossInit():

    global Asm, Flags, Cross

    assem.CheckVersions(crossversion, minversion)

    dec.Asm.Instructions = {
        'ADDLW': (Immediate, 0x3E00, '1'),
        'ANDLW': (Immediate, 0x3900, '1'),
        'CALL': (Immediate, 0x2000, '2'),
        'GOTO': (Immediate, 0x2800, '2'),
        'IORLW': (Immediate, 0x3800, '1'),
        'MOVLB': (Immediate, 0x0020, '1'),
        'MOVLP': (Immediate, 0x3180, '1'),
        'MOVLW': (Immediate, 0x3000, '1'),
        'RETLW': (Immediate, 0x3400, '2'),
        'SUBLW': (Immediate, 0x3C00, '1'),
        'XORLW': (Immediate, 0x3A00, '1'),
        'B': (Immediate, 0x2800, '2'),
        'BANKSEL': (Immediate, 0x0020, '1'),
        'BRW': (Implied, 0x000B, '2'),
        'CALLW': (Implied, 0x000A, '2'),
        'CLRWDT': (Implied, 0x0064, '1'),
        'OPTION': (Implied, 0x0062, '1'),
        'RESET': (Implied, 0x0001, '1'),
        'RETFIE': (Implied, 0x0009, '2'),
        'RETURN': (Implied, 0x0008, '2'),
        'SLEEP': (Implied, 0x0063, '1'),
        'CLRW': (Implied, 0x0100, '1'),
        'NOP': (Implied, 0x0000, '1'),
        'CLRC': (Implied, 0x1003, '1'),
        'CLRDC': (Implied, 0x1083, '1'),
        'CLRZ': (Implied, 0x1103, '1'),
        'SETC': (Implied, 0x1403, '1'),
        'SETDC': (Implied, 0x1483, '1'),
        'SETZ': (Implied, 0x1503, '1'),
        'SKPC': (Implied, 0x1C03, '1-2'),
        'SKPDC': (Implied, 0x1C83, '1-2'),
        'SKPNC': (Implied, 0x1803, '1-2'),
        'SKPNDC': (Implied, 0x1883, '1-2'),
        'SKPNZ': (Implied, 0x1903, '1-2'),
        'SKPZ': (Implied, 0x1D03, '1-2'),
        'BRA': (Relative, 0x3200, '2'),
        'CLRF': (FileOnly, 0x0180, '1'),
        'MOVWF': (FileOnly, 0x0080, '1'),
        'TRIS': (FileOnly, 0x0060, '1'),
        'MOVFW': (FileOnly, 0x0800, '1'),
        'TSTF': (FileOnly, 0x0880, '1'),
        'ADDWF': (FileW, 0x0700, '1'),
        'ADDWFC': (FileW, 0x3D00, '1'),
        'ANDWF': (FileW, 0x0500, '1'),
        'ASRF': (FileW, 0x3700, '1'),
        'LSLF': (FileW, 0x3500, '1'),
        'LSRF': (FileW, 0x3600, '1'),
        'COMF': (FileW, 0x0900, '1'),
        'DECF': (FileW, 0x0300, '1'),
        'DECFSZ': (FileW, 0x0B00, '1-2'),
        'INCF': (FileW, 0x0A00, '1'),
        'INCFSZ': (FileW, 0x0F00, '1-2'),
        'IORWF': (FileW, 0x0400, '1'),
        'MOVF': (FileW, 0x0800, '1'),
        'RLF': (FileW, 0x0D00, '1'),
        'RRF': (FileW, 0x0C00, '1'),
        'SUBWF': (FileW, 0x0200, '1'),
        'SUBWFB': (FileW, 0x3B00, '1'),
        'SWAPF': (FileW, 0x0E00, '1'),
        'XORWF': (FileW, 0x0600, '1'),
        'BCF': (FileBit, 0x1000, '1'),
        'BSF': (FileBit, 0x1400, '1'),
        'BTFSC': (FileBit, 0x1800, '1-2'),
        'BTFSS': (FileBit, 0x1C00, '1-2'),
        'ADDFSR': (Compiler, (0x3100, 0x3100), '1'),
        'MOVIW': (Compiler, (0x0010, 0x3F00), '1'),
        'MOVWI': (Compiler, (0x0018, 0x3F80), '1'),
        'BC': (Branches, 0x1803, '2-3'),
        'BDC': (Branches, 0x1883, '2-3'),
        'BNC': (Branches, 0x1C03, '2-3'),
        'BNDC': (Branches, 0x1C83, '2-3'),
        'BNZ': (Branches, 0x1D03, '2-3'),
        'BZ': (Branches, 0x1903, '2-3'),
        'ADDCF': (Pseudo, 0x1803, 0x0A00, '2'),
        'ADDDCF': (Pseudo, 0x1883, 0x0A00, '2'),
        'NEGF': (Pseudo, 0x0980, 0x0A00, '2'),
        'SUBCF': (Pseudo, 0x1803, 0x0300, '2'),
        'SUBDCF': (Pseudo, 0x1883, 0x0300, '2'),
        'LCALL': (Long, 0x2000),
        'LGOTO': (Long, 0x2800)
    }

    dec.Asm.Timing_Length = 3

    dec.Asm.Memory = 0  # Select code memory as default
    if dec.Asm.Pass == 1:
        sys.stdout.write('Loaded ' + dec.Cross.Name[2:] + ' overlay version ' +
                         crossversion + dec.EOL)

    dec.Asm.Max_Address = 0x0400 - 1
    dec.Flags.BigEndian = False

    # Change target factor to 2
    if dec.Asm.PP_TA_Factor != 2:
        if dec.Asm.PP_Address != dec.Asm.TA_Address or dec.Asm.PP_Address !=\
                dec.Asm.PH_Address:
            # Oops, this is complicated. Let's warn the programmer
            errors.DoWarning('taconfusion', True)
        # Set the instruction size and double the target address
        dec.Asm.PP_TA_Factor = 2
        dec.Asm.TA_Address *= 2

    dec.Asm.TablePic14 = -1

    errors.Error_List[dec.Cross.Name + 'tcrossed'] =\
        'Table crossed page boundary'
    errors.Error_List[dec.Cross.Name + 'codemem'] =\
        'Directive only allowed within Code memory'
    errors.Error_List[dec.Cross.Name + 'progmem'] =\
        'Directive only allowed beyond program memory'

    dec.Cross.SaveByte = eval('SaveByte')
Esempio n. 18
0
def Multi():
    """
    Handle all other mnemonics of the 6502 instructionset.
    Each addressing mode has a separate entry in the opcode tupple.
    If the opcode is 0x00 the particular instruction is not available
    on the selected model.
    If the cycle length is '0' the particular addressing mode is not
    supported.
    The model is selected by calling either the 6502 overlay, or the
    65c02 or 65sc02 overlays.
    """

    global Asm, sweet16

    if modelindex == 2 and (dec.Asm.Mnemonic in ('STZ', 'TRB', 'TSB')):
        errors.DoError('badopco', False)
        return

    instructions = dec.Asm.Instructions[dec.Asm.Mnemonic][1]
    ctimes = dec.Asm.Instructions[dec.Asm.Mnemonic][modelindex]
    operandbegin = dec.Asm.Parse_Pointer

    # Does implied addressing exist for this instruction?
    optional = dec.Asm.Optional
    pointer = dec.Asm.Parse_Pointer
    if instructions[0] != 0 and ctimes[0] != '0':
        if optional and \
                (dec.Asm.Parse_Line[operandbegin:operandbegin+2].upper() ==
                 "A "):
            optional = False
        if optional is False:
            # No operand followed, use implied addressing mode
            dec.Asm.Timing = ctimes[0]
            target.CodeByte(instructions[0])
            return

    if MissingOperand():
        return

    # There are two compound instructions, save prefix for them first
    if dec.Asm.Mnemonic == 'ADD':
        target.CodeByte(0x18)
    if dec.Asm.Mnemonic == 'SUB':
        target.CodeByte(0x38)

    nowchar = assem.NowChar().upper()

    # Is it immediate addressing mode?
    if nowchar in '#/=\\':
        if instructions[1] == 0 or ctimes[1] == '0':
            errors.DoError('badoper', False)
            return
        prefix = assem.NowChar(True)
        value = assem.EvalExpr()
        dec.Asm.Timing = ctimes[1]
        if prefix == '#':
            operand = value[0]
        elif prefix == '/':
            operand = value[0] >> 8
        elif prefix == '=':
            operand = value[0] >> 16
        else:
            operand = value[0] >> 24
        target.CodeByte(instructions[1])
        target.CodeByte(operand)
        NoMore()
        return

    # Is it some kind if indirect mode?
    if nowchar == '(':
        assem.IncParsePointer()
        value = assem.EvalExpr()
        if assem.NowChar() == ')':
            # It must be (ZP),Y mode now, or is it JMP (IND) ?
            # On the CMOS models it can also be (ZP)
            assem.IncParsePointer()
            if assem.MoreParameters():
                # It must be (zp),y now
                opcode = instructions[5]
                if (opcode != 0) and (assem.NowChar(True).upper() == 'Y'):
                    dec.Asm.Timing = ctimes[5]
                    target.CodeByte(opcode)
                    target.CodeByte(value[0])
                    if dec.Asm.Pass == 2 and ((value[0] >> 8) != 0):
                        errors.DoError('range', False)
                    NoMore()
                    return
                else:
                    errors.DoError('badoper', False)

            else:
                # It is (zp), or (abs) in case of JMP now
                opcode = instructions[10]
                dec.Asm.Timing = ctimes[10]
                if dec.Asm.Mnemonic == "JMP":
                    # It's JMP (IND)
                    target.CodeByte(opcode)
                    target.CodeWord(value[0])
                    if dec.Asm.Pass == 2 and ((value[0] >> 16) != 0):
                        errors.DoError('range', False)
                    if ((value[0] & 255) == 255) and modelindex == 2:
                        # Give warning to user about the 6502 JMP (IND) bug
                        errors.DoWarning('6502bug', False)
                    NoMore()
                    return
                else:
                    # It's (zp) now
                    if ctimes[10] == 0:
                        errors.DoError('badoper', False)
                        return
                    target.CodeByte(opcode)
                    target.CodeByte(value[0])
                    if dec.Asm.Pass == 2 and ((value[0] >> 8) != 0):
                        errors.DoError('range', False)
                    NoMore()
                    return
            return

        # It must be (ZP,X) mode now
        opcode = instructions[4]
        if (opcode != 0 and ctimes[4] != '0') and assem.MoreParameters() \
                and (assem.NowChar(True).upper() == 'X') and \
                (assem.NowChar(True).upper() == ')'):
            dec.Asm.Timing = ctimes[4]
            target.CodeByte(opcode)
            if dec.Asm.Mnemonic == "JMP":
                target.CodeWord(value[0])
                if dec.Asm.Pass == 2 and ((value[0] >> 16) != 0):
                    errors.DoError('range', False)
            else:
                target.CodeByte(value[0])
                if dec.Asm.Pass == 2 and ((value[0] >> 8) != 0):
                    errors.DoError('range', False)
            NoMore()
        else:
            errors.DoError('badoper', False)
        return

    # May now be ZP, ABS, ZP,X ABS,X ZP,Y or ABS,Y

    if nowchar in '<>':
        # Forced ZP or ABS prefix given
        prefix = nowchar
        assem.IncParsePointer()
    else:
        prefix = ''  # We have no preference, let the assembler decide

    value = assem.EvalExpr()
    if prefix == '':
        if value[1]:
            # A forward referenced label is used, force absolute mode
            prefix = '>'
        else:
            # Now decide if ZP is still possible
            if (value[0] >> 8) == 0:
                prefix = '<'
            else:
                prefix = '>'

    if not (assem.MoreParameters()):
        # It's normal ZP or ABS addressing mode
        if prefix == '<':
            index = 2
        else:
            index = 3
    else:
        # It's ZP or ABS indexed with X or Y now
        nowchar = assem.NowChar(True).upper()
        if nowchar == 'X':
            index = 6
        elif nowchar == 'Y':
            index = 8
        else:
            errors.DoError('badoper', False)
            return
        if prefix == '>':
            index = index + 1

    if prefix == '<' and instructions[index] == 0:
        # ZP wanted, but doesn't exist, use ABS instead
        prefix = '>'
        index = index + 1

    if instructions[index] == 0 or ctimes[index] == '0':
        errors.DoError('badoper', False)
        return

    target.CodeByte(instructions[index])
    dec.Asm.Timing = ctimes[index]

    if prefix == '<':
        target.CodeByte(value[0])
        address = value[0] >> 8
    else:
        target.CodeWord(value[0])
        address = value[0] >> 16

    if dec.Asm.Mnemonic == 'JSR':
        # See if it's JSR SWEET16
        if dec.Asm.Parse_Line[operandbegin:operandbegin+8].upper() == \
                'SWEET16 ':
            sweet16 = True

    if dec.Asm.Pass == 2 and address != 0:
        errors.DoError('range', False)
    NoMore()
    return
Esempio n. 19
0
File: target.py Progetto: Ivoah/6502
def SaveByte(value, list=True):

    """
    Save a byte to the current open target file.
    We ignore all bits which don't belong to the byte.
    """

    global Asm, Flags

    value = value & 255     # Ignore irrelevant bits.

    if list:
        listing.ListByte(value)

    if dec.Asm.Memory == 0:
        # In code memory

        # Check if byte is still within address limit
        if (dec.Asm.Pass == 2) and (not dec.Asm.Code_Wrap) and\
                (dec.Asm.PP_Address > dec.Asm.Max_Address):
            dec.Asm.Code_Wrap = True
            # True because will only happen in pass 2
            errors.DoWarning('maxaddr', True)

        if (dec.Asm.Pass == 2) and (dec.Asm.Code_Tformat != '') and\
                (not dec.Flags.DummyMode):
            if len(dec.Asm.Code_Tbuffer) == 0:
                dec.Asm.Code_Tbuffer.append(dec.Asm.TA_Address)
            dec.Asm.Code_Tbuffer.append(value)
            if len(dec.Asm.Code_Tbuffer) > dec.Asm.Code_Tlength:
                FlushTarget(0)

        IncPP()

    elif dec.Asm.Memory == 1:
        # In RAM memory

        # No need to save the byte to RAM memory!

        dec.Asm.RM_Address = dec.Asm.RM_Address + 1

    elif dec.Asm.Memory == 2:
        # In EEPROM memory

        if (dec.Asm.Pass == 2) and (dec.Asm.Eeprom_Tformat != ''):
            if len(dec.Asm.Eeprom_Tbuffer) == 0:
                dec.Asm.Eeprom_Tbuffer.append(dec.Asm.EM_Address)
            dec.Asm.Eeprom_Tbuffer.append(value)
            if len(dec.Asm.Eeprom_Tbuffer) > dec.Asm.Eeprom_Tlength:
                FlushTarget(2)

        if dec.Asm.Pass == 2 and (not dec.Asm.Eeprom_Twrap) and\
                dec.Asm.EM_Address > dec.Asm.Eeprom_Tmaxadd:
            dec.Asm.Eeprom_Twrap = True
            # True because will only happen in pass 2
            errors.DoWarning('trange', True)
            dec.Asm.EM_Address = dec.Asm.EM_Address & ((1 << 32) - 1)

        dec.Asm.EM_Address = dec.Asm.EM_Address + 1

        if dec.Asm.Eeprom_Tformat in ('INT', 'INS'):
            if (dec.Asm.EM_Address & 65535) == 0:
                # Segment changed! Flush current line before change of segment
                FlushTarget(2)
    if dec.Asm.Memory == 0:
        # Code address is not always incremented by 1
        dec.Asm.List_Address = dec.Asm.PH_Address
    else:
        dec.Asm.List_Address = dec.Asm.List_Address + 1
Esempio n. 20
0
def Immediate():

    """
    Immediate operand instructions.
    Instructions optionally accept the traditional # / = and \ prefixes.
    Only GOTO and CALL don't, they are only tolerant to the # prefix
    No range checking is done, other than that CALL desitnation bit-8 is not
    allowed to be 1.
    Only the RETLW instruction will accept multiple operatnds, which are
    stored sequentially in program memory. RETLW also allows no operands,
    which loads 0 in W.
    """

    global Asm

    opcode = dec.Asm.Instructions[dec.Asm.Mnemonic][1]
    dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2]

    if opcode == 0x800:
        # Operand field may be empty for RETLW instruction
        if dec.Asm.Parse_Pointer == 0 or dec.Asm.Optional is False:
            # No parameter is following
            CodeWord(opcode)
            return

    while True:
        prefix = '#'
        if assem.NowChar() in '#/=\\':
            # A prefix is given, let's get it
            prefix = assem.NowChar(True)

        value = assem.EvalExpr()

        if not dec.Flags.ErrorInLine:
            # No error in this line, let's continue
            if opcode == 0xA00:
                # Allow 9 bits of operand for GOTO
                CodeWord(opcode + (value[0] & 0x1FF))
                if prefix != '#':
                    # Only the default prefix is allowed
                    errors.DoError('badoper', False)
            elif prefix == '#':
                # Save opcode and lower byte
                CodeWord(opcode + (value[0] & 0xFF))
            elif prefix == '/':
                # Save opcode and 2nd lower byte
                CodeWord(opcode + ((value[0] >> 8) & 0xFF))
            elif prefix == '=':
                # Save opcode and 2nd upper byte
                CodeWord(opcode + ((value[0] >> 16) & 0xFF))
            else:
                # Save opcode and upper byte
                CodeWord(opcode + ((value[0] >> 24) & 0xFF))

        if opcode == 0x900:
            # It's a CALL instruction
            if prefix != '#':
                # Only allow # prefix (as it's the default)
                errors.DoError("badoper", False)

            if dec.Asm.Pass == 2 and (value[0] & 0x100) != 0:
                # Range error
                errors.DoError("range", False)

        if not assem.MoreParameters():
            # No more parameters
            break

        if opcode != 0x800:
            # Only the RETLW instruction allows multiple literal bytes
            errors.DoWarning('extrign', False)
Esempio n. 21
0
def GetDisplacement(opcode, allowauto):
    """
    Expected parameters:
     opcode     The basic opcode, can be modified before saving
     allowauto  Flag indicating if @ mode is allowed

    Expected operands:
     @(Px)      Offset = relative 0 and x can be 1 to 3
     @E(Px)     Offset = relative E-reg and x can be 1 to 3
     @expr(Px)  Offset = relative expr and x can be 1 to 3
     (Px)       Offset = relative 0 and x can be 0 to 3 or C
     E          Offset = relative E-reg and reg PC
     E(Px)      Offset = relative E-reg and x can be 0 to 3 or C
     expr(Px)   Offset = relative expr and x can be 0 to 3 or C
     expr       Offset = absolute expr and register is assumed PC
    PS: the P of the pointers is optional

    Not allowed:
     @(PC) or @(P0)
     @E(PC) or @E(P0)
     @expr(PC) or @expr(P0)

    The opcode can be modified the m flag (Auto indexed mode flag) and or
     the pointer before it is save to the target file.

    The assembler will not warn you about page crossings for the EA of the
      instruction. It's the programmer's responsibility to keep data tables
      from crossing page boundaries. The page wrap may even be done
      deliberately.

    Absolute addressing is only allowed for PC relative addressing mode,
     where the (PC) or (P0) part of the operand is omitted.
     The formula to calculate the offset is : DEST-PC-1
     Except for jump instructions where it is: DEST-PC-2
     Fortunately the jump instructions are the only ones which start
     with a J.
    """

    global Asm

    if MissingOperand():
        return

    offset = 0
    forward = False
    error = False
    absolute = False
    reg = '0'
    autoindex = False
    eregister = False

    if allowauto:
        # auto-indexed addressing is allowed
        if assem.NowChar() == '@':
            # It is iato indexed addressing
            opcode = opcode + 4
            assem.IncParsePointer()  # Point at char following @
            autoindex = True

    parseptr = dec.Asm.Parse_Pointer  # Remember current parse pointer

    if assem.NowChar() != '(':
        # Some sort of offset is given
        if assem.GetWord(endchars="( ") == 'E':
            # It is E register
            offset = -128
            eregister = True
        else:
            # It's not the E register, restore pointer
            dec.Asm.Parse_Pointer = parseptr

        if offset == 0:
            # Offset was not E-register
            # Offset can be a displacement or an abosulte value
            express = assem.EvalExpr()
            offset = express[0]
            forward = express[1]

    # This can't be an if, because we may have parsed the offset already
    if assem.NowChar() == '(':
        # A pointer register is given (offset would be relative now)
        assem.IncParsePointer()
        if assem.NowChar(True).upper() == 'P':
            # Still going good
            reg = assem.NowChar(True).upper()
        else:
            # We now allow omitting P for numbered registers
            dec.Asm.Parse_Pointer -= 1
            reg = assem.NowChar(True).upper()
            if reg not in "0123":
                # It can't be a register
                error = True
        if assem.NowChar(True) != ')':
            # Something's wrong
            error = True

        if not error:
            # No error found yet
            if reg == 'C':
                reg = '0'
            if reg < '0' or reg > '3':
                # Something's wrong
                error = True
            if reg == '0' and autoindex:
                # P0 is not allowed together with auto indexed mode
                error = True

        if not error:
            # No error occurred, we know everything now
            opcode = opcode + int(reg)
        else:
            # An error did occur
            error = True
    else:
        # No register given, assuming PC, addressing is absolute now

        if not eregister:
            # The offset was not the E register
            # Now we have to calculate the real offset

            offset = offset - dec.Asm.BOL_Address - 1
            absolute = True

            if dec.Asm.Mnemonic[0].upper() == "J":
                # An extra offset for Jump instructions
                offset = offset - 1

    if autoindex and reg == '0':
        # Auto indexing doesn't allow the PC register
        error = True

    if error:
        # An error has occurred, tell us about it
        errors.DoError("badoper", False)

    NoMore()
    if dec.Asm.Pass == 2 and not forward:
        # Only test range in pass 2
        if offset < -128 or offset > 127:
            # Range error
            errors.DoError('range', False)
        if offset == -128 and absolute:
            # Offset calculated to -128, are you sure!
            errors.DoWarning(dec.Cross.Name + 'offset', True)

    WriteOpcode(opcode)
    WriteOperand(offset)
Esempio n. 22
0
def NoMore():

    if assem.MoreParameters():
        errors.DoWarning('extrign', False)
Esempio n. 23
0
def Immediate():
    """
    Immediate operand instructions.
    Instructions optionally accept the traditional # / = and \ prefixes.
    Only GOTO and CALL don't, they are only tolerant to the # prefix
    Only the RETLW instruction will accept multiple operatnds, which are
    stored sequentially in program memory.
    """

    global Asm

    opcode = dec.Asm.Instructions[dec.Asm.Mnemonic][1]
    dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2]

    if opcode == 0x3400:
        # Operand field may be empty for RETLW instruction
        if dec.Asm.Parse_Pointer == 0 or dec.Asm.Optional is False:
            # No parameter is following
            CodeWord(opcode)
            return

    while True:
        prefix = '#'
        if assem.NowChar() in '#/=\\':
            # A prefix is given, let's get it
            prefix = assem.NowChar(True)

        value = assem.EvalExpr()[0]

        if not dec.Flags.ErrorInLine:
            # No error in this line, let's continue
            if dec.Asm.Mnemonic == "BANKSEL":
                # BANKSEL is the same as MOVLB with modified operand
                value = (value // 128) & 0x1F

            if opcode == 0x2000 or opcode == 0x2800:
                # Allow 11 bits of operand for GOTO
                literal = value & 0x7FF
                if prefix != '#':
                    # Only the default prefix is allowed
                    errors.DoError('badoper', False)
            elif prefix == '#':
                # Save opcode and lower byte
                literal = value & 0xFF
            elif prefix == '/':
                # Save opcode and 2nd lower byte
                literal = (value >> 8) & 0xFF
            elif prefix == '=':
                # Save opcode and 2nd upper byte
                literal = (value >> 16) & 0xFF
            else:
                # Save opcode and upper byte
                literal = (value >> 24) & 0xFF

            if opcode == 0x0020:
                # It's MOVLB, limit literal to 5 bits
                if dec.Asm.Pass == 2 and (literal < 0 or literal > 0x1F):
                    # Range error
                    errors.DoError('range', False)
                literal = literal & 0x1F

            if opcode == 0x3180:
                # It's MOVLP, limit literal to 7 bits
                if dec.Asm.Pass == 2 and (literal < 0 or literal > 0x7F):
                    # Range error
                    errors.DoError('range', False)
                literal = literal & 0x7F

            # Save opcode + literal to target
            CodeWord(opcode + literal)

            if not assem.MoreParameters():
                # No more parameters
                break

            if opcode != 0x3400:
                # Only the RETLW instruction allows multiple literal bytes
                errors.DoWarning('extrign', False)

        else:
            # There's an error in the line, simply save a dummy and quit loop
            CodeWord(opcode)
            break
Esempio n. 24
0
def CrossInit():

    global Asm, Flags, Cross

    assem.CheckVersions(crossversion, minversion)

    dec.Asm.Instructions = {
     'RETLW' : (Immediate, 0x800, '2'),
     'CALL'  : (Immediate, 0x900, '2'),
     'GOTO'  : (Immediate, 0xA00, '2'),
     'B'     : (Immediate, 0xA00, '2'),
     'MOVLW' : (Immediate, 0xC00, '1'),
     'IORLW' : (Immediate, 0xD00, '1'),
     'ANDLW' : (Immediate, 0xE00, '1'),
     'XORLW' : (Immediate, 0xF00, '1'),

     'CLRW'  : (Implied, 0x040, '1'),
     'CLRWDT': (Implied, 0x004, '1'),
     'NOP'   : (Implied, 0x000, '1'),
     'OPTION': (Implied, 0x002, '1'),
     'SLEEP' : (Implied, 0x003, '1'),

     'CLRC'  : (Implied, 0x403, '1'),
     'CLRDC' : (Implied, 0x423, '1'),
     'CLRZ'  : (Implied, 0x443, '1'),
     'SETC'  : (Implied, 0x503, '1'),
     'SETDC' : (Implied, 0x523, '1'),
     'SETZ'  : (Implied, 0x543, '1'),
     'SKPC'  : (Implied, 0x703, '1-2'),
     'SKPDC' : (Implied, 0x723, '1-2'),
     'SKPNC' : (Implied, 0x603, '1-2'),
     'SKPNDC': (Implied, 0x623, '1-2'),
     'SKPNZ' : (Implied, 0x643, '1-2'),
     'SKPZ'  : (Implied, 0x743, '1-2'),

     'CLRF'  : (FileOnly, 0x060, '1'),
     'MOVWF' : (FileOnly, 0x020, '1'),
     'TRIS'  : (FileOnly, 0x000, '1'),

     'MOVFW' : (FileOnly, 0x200, '1'),
     'TSTF'  : (FileOnly, 0x220, '1'),

     'ADDWF' : (FileW, 0x1C0, '1'),
     'ANDWF' : (FileW, 0x140, '1'),
     'COMF'  : (FileW, 0x240, '1'),
     'DECF'  : (FileW, 0x0C0, '1'),
     'DECFSZ': (FileW, 0x2C0, '1-2'),
     'INCF'  : (FileW, 0x280, '1'),
     'INCFSZ': (FileW, 0x3C0, '1-2'),
     'IORWF' : (FileW, 0x100, '1'),
     'MOVF'  : (FileW, 0x200, '1'),
     'RLF'   : (FileW, 0x340, '1'),
     'RRF'   : (FileW, 0x300, '1'),
     'SUBWF' : (FileW, 0x080, '1'),
     'SWAPF' : (FileW, 0x380, '1'),
     'XORWF' : (FileW, 0x180, '1'),

     'BCF'   : (FileBit, 0x400 , '1'),
     'BSF'   : (FileBit, 0x500 , '1'),
     'BTFSC' : (FileBit, 0x600 , '1-2'),
     'BTFSS' : (FileBit, 0x700 , '1-2'),

     'BC'    : (Branches, 0x603, '2-3'),
     'BDC'   : (Branches, 0x623, '2-3'),
     'BNC'   : (Branches, 0x703, '2-3'),
     'BNDC'  : (Branches, 0x723, '2-3'),
     'BNZ'   : (Branches, 0x743, '2-3'),
     'BZ'    : (Branches, 0x643, '2-3'),

     'ADDCF' : (Pseudo, 0x603, 0x280, '2'),
     'ADDDCF': (Pseudo, 0x623, 0x280, '2'),
     'NEGF'  : (Pseudo, 0x260, 0x280, '2'),
     'SUBCF' : (Pseudo, 0x603, 0x0C0, '2'),
     'SUBDCF': (Pseudo, 0x623, 0x0C0, '2'),

     'LCALL' : (Long, 0x900),
     'LGOTO' : (Long, 0xA00)
    }

    dec.Asm.Timing_Length = 3

    dec.Asm.Memory = 0              # Select code memory as default
    if dec.Asm.Pass == 1:
        sys.stdout.write('Loaded ' + dec.Cross.Name[2:] +
                         ' overlay version ' + crossversion + dec.EOL)

    dec.Asm.Max_Address = 511
    dec.Flags.BigEndian = False

    # Change target factor to 2
    if dec.Asm.PP_TA_Factor != 2:
        if dec.Asm.PP_Address != dec.Asm.TA_Address or dec.Asm.PP_Address !=\
                dec.Asm.PH_Address:
            # Oops, this is complicated. Let's warn the programmer
            errors.DoWarning('taconfusion', True)
        # Set the instruction size and double the target address
        dec.Asm.PP_TA_Factor = 2
        dec.Asm.TA_Address *= 2

    dec.Asm.TablePic12 = -1

    errors.Error_List[dec.Cross.Name + 'tcrossed'] =\
        'Table crossed page boundary'
    errors.Error_List[dec.Cross.Name + 'codemem'] =\
        'Directive only allowed within Code memory'
    errors.Error_List[dec.Cross.Name + 'progmem'] =\
        'Directive only allowed beyond program memory'

    dec.Cross.SaveByte = eval('SaveByte')