示例#1
0
def GetDest(filereg):
    """
    Get the destination for register file instructions.
    It can either accept W or F or nothing.
    Or it can accept any expression as long as it returns 0 or 1.
    Only when a destination is given the optional access bank selector can
    also be given. If not, the assembler will pick the proper access bank
    mode for you.
    """

    global Asm

    dest = 0x200

    if assem.MoreParameters():
        # Direction is specified

        temp = dec.Asm.Parse_Pointer

        direction = assem.GetWord().upper()
        if direction == "W":
            # Direction towards W register
            dest = 0
        elif direction == "F":
            # Direction towards File register
            dest = 0x200
        else:
            # Neither W nor F. Must be an expression now
            dec.Asm.Parse_Pointer = temp
            dest = assem.EvalExpr()[0]
            if dec.Asm.Pass == 2 and (dest < 0 or dest > 1):
                # That's a range error!
                errors.DoError('range', False)
            dest = (dest & 1) * 0x200

        if assem.MoreParameters():
            # Good, the access bank selector is given. That's easy
            accessbank = assem.EvalExpr()[0]
            if dec.Asm.Pass == 2 and (accessbank < 0 or accessbank > 1):
                # Oops, this is not good
                errors.DoError('range', False)
        else:
            # Now we have to decide
            accessbank = 0
            if filereg >= dec.Asm.AccessBank18 and filereg <\
                    (dec.Asm.AccessBank18 + 0xF00):
                # Outside of access bank range. Use BSR mode instead
                accessbank = 1

    else:
        # Direction was not specified, so access bank select is also automatic
        accessbank = 0
        if filereg >= dec.Asm.AccessBank18 and filereg <\
                (dec.Asm.AccessBank18 + 0xF00):
            # Outside of access bank range. Use BSR mode instead
            accessbank = 1

    dest += (accessbank & 1) << 8

    return dest
示例#2
0
def Bits():
    """
    Handle Bit instructions
    Both bit set/clr as well as branch bit set/clr instructions are handled
    by this routine.
    """

    global Asm

    if MissingOperand():
        return

    bitno = assem.EvalExpr()[0]
    opcode = dec.Asm.Instructions[dec.Asm.Mnemonic][1] + ((bitno & 7))
    dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2]

    if not assem.MoreParameters():
        # We expected more parameters
        errors.DoError('missoper', False)
        return

    param = dec.Asm.Parse_Line[dec.Asm.Parse_Pointer:dec.Asm.Parse_Pointer+2]\
        .upper()

    if param in ('A,', 'X,', 'Y,', 'A ', 'X ', 'Y '):
        assem.NowChar(True)
        if param[0] == 'A':
            mem = 255
        elif param[0] == 'X':
            mem = 128
        else:
            mem = 129
    else:
        mem = assem.EvalExpr()[0]

    if dec.Asm.Mnemonic[1] == 'R':
        # It's a branch instruction
        if not assem.MoreParameters():
            # We expected more parameters
            errors.DoError('missoper', False)
            return
        dest = assem.EvalExpr()[0]
        offset = dest - dec.Asm.BOL_Address - 3

        target.CodeByte(opcode)
        target.CodeByte(mem)
        target.CodeByte(offset)
        if dec.Asm.Pass == 2 and (offset < -128 or offset > +127):
            errors.DoError('range', False)

    else:
        # It wasn't a branch instruction
        target.CodeByte(opcode)
        target.CodeByte(mem)

    if dec.Asm.Pass == 2:
        if (bitno < 0 or bitno > 7) or (mem < 0 or mem > 255):
            errors.DoError('range', False)

    NoMore()
示例#3
0
def BranchBit():
    """
    Handle the bit test branch instructions.
    """

    global Asm

    if MissingOperand():
        # We need operands
        return

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

    par1 = GetBit()

    if not assem.MoreParameters():
        # Oops only one operand given
        errors.DoError('missoper', False)
        return

    value = assem.EvalExpr()
    offset = value[0] - dec.Asm.BOL_Address - 3

    if dec.Asm.Pass == 2 and (offset < -128 or offset > 127):
        # Out of range
        errors.DoError('range', False)

    target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1])
    target.CodeByte(par1)
    target.CodeByte(offset)

    NoMore()
示例#4
0
def Conditional():
    """
    Conditional instructions
    reg,dest
    con,dest
    """

    global Asm

    if MissingOperand():
        return

    val = assem.EvalExpr()[0]

    if not assem.MoreParameters():
        errors.DoError('missoper', False)
        return

    dest = assem.EvalExpr()[0]

    if dec.Asm.Pass == 2:
        if (val < 0 or val > 15):
            # Range error
            errors.DoError('range', False)

# !!!! isz on last 2 locations of page causes jump to next page. Strange but
# true according to page 3-42

    target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1] + (val & 15))
    target.CodeByte(dest)
    dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2]

    NoMore()
示例#5
0
def NoMore():
    """
    No more operands shoudl follow. Raise a warning if more parameters follow.
    """

    if assem.MoreParameters():
        errors.DoWarning('extrign', False)
示例#6
0
def Multiply():

    global Asm

    if MissingOperand():
        return

    operand1 = assem.GetWord().upper()

    if operand1 not in 'XY':
        errors.DoError('badoper', False)
        return

    if not assem.MoreParameters():
        errors.DoError('missoper', False)
        return

    if assem.NowChar(True).upper() != 'A':
        errors.DoError('badoper', False)
        return

    if operand1 == 'X':
        target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1][0])
        dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2][0]
    else:
        target.CodeWord(dec.Asm.Instructions[dec.Asm.Mnemonic][1][1])
        dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2][1]

    NoMore()
示例#7
0
def BitInst():
    """
    Bit instructions. These require 2 operands. The first is the register
    number from 0 to 31. The second is the bit number from 0 to 7.

    Dictionary: function, Xmega+Mega+AVR+TINY, newflags, opcode, cycles
    """

    global Asm

    reg = GetReg() << 4

    if not assem.MoreParameters():
        # Only the register number is given, the bit number is missing
        errors.DoError('missoper', False)
        # Write dummy word
        target.CodeWord(0)
        return

    bitno = assem.EvalExpr()[0]

    if dec.Asm.Pass == 2 and (bitno < 0 or bitno > 7):
        # Report range error if bit number not between 0 and 7
        errors.DoError('range', False)
        bitno = 0

    target.CodeWord(dec.Asm.Instructions[dec.Asm.Mnemonic][3] + reg + bitno)

    NoMore()
示例#8
0
def XchdInst():
    """
    Handle the XCHD instruction.
    """

    global Asm

    if MissingOperand():
        # No parameters
        return

    dec.Asm.Timing = '1'

    if assem.NowChar(True).upper() != 'A':
        # First paramter must be an A
        errors.DoError('badoper', False)
        return

    if not assem.MoreParameters():
        # Only one parameter given
        errors.DoError('missoper', False)
        return

    par2 = GetReg()

    if par2[1] != 3:
        # Second parameter may only be @Ri
        errors.DoError('badoper', False)
        return

    target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1] + par2[0])

    NoMore()
示例#9
0
文件: crz80.py 项目: Ivoah/6502
def Exch():

    global Asm

    if MissingOperand():
        return

    reg1 = assem.GetWord().upper()

    if not assem.MoreParameters():
        errors.DoError('missoper', False)
        return

    reg2 = assem.GetWord().upper()

    if (reg1 == 'DE') and (reg2 == 'HL'):
        index = 0
    elif (reg1 == 'AF') and (reg2 == "AF'"):
        index = 1
    elif (reg1 == '(SP)') and (reg2 == 'HL'):
        index = 2
    elif (reg1 == '(SP)') and (reg2 == 'IX'):
        index = 3
    elif (reg1 == '(SP)') and (reg2 == 'IY'):
        index = 4
    else:
        errors.DoError('badoper', False)
        return

    Code(dec.Asm.Instructions[dec.Asm.Mnemonic][1][index])
    dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2][index]

    NoMore()
示例#10
0
def FileFile():
    """
    MOVFF instruction. Moves a file register to a file register. Both can be
    addressed directly with 12-bits.
    Source or destination can be the W register, if the WREG SFR is used.
    The PCL, TOSU, TOSH and TOSL can't be used as destination. A range error
    is reported if you do use these.
    No other range checking is done though.
    """

    global Asm

    source = assem.EvalExpr()[0] & 0xFFF

    if not assem.MoreParameters():
        # Missing 2nd operand
        errors.DoError('missoper', False)
        dest = 0
    else:
        dest = assem.EvalExpr()[0] & 0xFFF

    CodeWord(dec.Asm.Instructions[dec.Asm.Mnemonic][1] + source)
    CodeWord(0xF000 + dest)
    dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2]

    if dec.Asm.Pass == 2 and dest in [0xFF9, 0xFFD, 0xFFE, 0xFFF]:
        # PCL, TOSL, TOSH and TOSU can't be used as destination
        errors.DoError('range', False)

    NoMore()
示例#11
0
def FileBit():
    """
    File register and bit operations.
    Only the bit address is being range checked.
    """

    global Asm

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

    filereg = assem.EvalExpr()[0]

    if assem.MoreParameters():
        # Oh, good, something else is following
        bit = assem.EvalExpr()[0]
        if dec.Asm.Pass == 2 and (bit < 0 or bit > 7):
            # Illegal bit number
            errors.DoError('range', False)
            bit = bit & 0x07
    else:
        # Oops, missing operand
        errors.DoError('missoper', False)
        bit = 0

    CodeWord(opcode + (filereg & 0x7F) + (bit << 7))

    NoMore()
示例#12
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)
示例#13
0
def FileOnly():
    """
    These instructions only require a file register as operand.
    No range checking is done.
    When access bank selector is missing the assembler will determine the
    access bank or BSR mode for you.
    The access bank selector may only be either 0 or 1.
    """

    global Asm

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

    value = assem.EvalExpr()[0]

    if assem.MoreParameters():
        # Good, the access bank selector is given. That's easy
        accessbank = assem.EvalExpr()[0]
        if dec.Asm.Pass == 2 and (accessbank < 0 or accessbank > 1):
            # Oops, this is not good
            errors.DoError('range', False)
    else:
        # Now we have to decide
        accessbank = 0
        if value >= dec.Asm.AccessBank18 and value <\
                (dec.Asm.AccessBank18 + 0xF00):
            # Outside of access bank range. Use BSR mode instead
            accessbank = 1

    accessbank = (accessbank & 1) << 8

    CodeWord(opcode + (value & 0x0FF) + accessbank)
    dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2]

    NoMore()
示例#14
0
def Lfsr():
    """
    File one of the 4 File select register pointers with a 12 bit file
    register address.
    File register number is not range checked.
    """

    global Asm

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

    pointer = assem.EvalExpr()[0]

    if not assem.MoreParameters():
        # Missing operand
        errors.DoError('missoper', False)
        register = 0
    else:
        # Get the operand
        register = assem.EvalExpr()[0]

    if dec.Asm.Pass == 2 and (pointer < 0 or pointer > 3):
        # Range error
        errors.DoError('range', False)
        pointer = pointer & 3

    CodeWord(opcode + (pointer << 4) + ((register >> 8) & 0xF))
    CodeWord(0xF000 + (register & 0xFF))

    NoMore()
示例#15
0
def GetDest():
    """
    Get the destination for register file instructions.
    It can either accept W or F or nothing.
    Or it can accept any expression as long as it returns 0 or 1
    """

    global Asm

    dest = 0x80

    if assem.MoreParameters():
        # Direction is specified

        temp = dec.Asm.Parse_Pointer

        direction = assem.GetWord().upper()
        if direction == "W":
            # Direction towards W register
            dest = 0
        elif direction == "F":
            # Direction towards File register
            dest = 0x80
        else:
            # Neither W nor F. Must be an expression now
            dec.Asm.Parse_Pointer = temp
            dest = assem.EvalExpr()[0]
            if dec.Asm.Pass == 2 and (dest < 0 or dest > 1):
                # That's a range error!
                errors.DoError('range', False)
            dest = (dest & 1) * 0x80

    return dest
示例#16
0
def BitInst():

    global Asm

    if MissingOperand():
        return

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

    bitno = assem.EvalExpr()[0]

    if dec.Asm.Pass == 2 and (bitno > 7 or bitno < 0):
        assem.DoError('range', False)
        bitno = bitno & 7

    if not assem.MoreParameters():
        errors.DoError('missoper', False)
        return

    datareg = GetReg()
    if datareg[0] > 5:
        assem.DoError('badoper', False)

    datareg = datareg[1]

    target.CodeByte(opcode + BitSwap(bitno))
    target.CodeByte(datareg)

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

    NoMore()
示例#17
0
def Math():

    global Asm

    if MissingOperand():
        return

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

    if assem.GetWord().upper() != 'A':
        errors.DoError('badoper', False)
        return

    if not assem.MoreParameters():
        errors.DoError('missoper', False)
        return

    value = GetReg()

    for i in range(0, len(opcode[value[0]]), 2):
        byte = opcode[value[0]][i:i + 2]
        if byte == 'XX':
            target.CodeByte(value[1])
        else:
            target.CodeByte(int(byte, 16))

    dec.Asm.Timing = timing[value[0]]

    NoMore()
示例#18
0
文件: crz8.py 项目: Ivoah/6502
def Jumps():

    global Asm

    if MissingOperand():
        return

    if assem.NowChar() == '@':
        # It is an indirect jump

        reg1 = GetReg()

        if reg1[0] == '@rr' or reg1[0] == '@R':
            target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1][1])
            target.CodeByte(reg1[1])
            dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2][1]
            if reg1[1] & 1 != 0:
                errors.DoError('range', False)
        else:
            errors.DoError('badoper', False)
    else:
        # It's not an indirect jump
        if dec.Asm.Mnemonic == 'CALL':
            # It's a CALL instruction
            opcode = dec.Asm.Instructions[dec.Asm.Mnemonic][1][0]
            dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2][0]

        else:
            # It's JP instruction
            conditions = {'F': 0x00, 'C': 0x70, 'NC': 0xF0, 'Z': 0x60,
                          'NZ': 0xE0, 'PL': 0xD0, 'MI': 0x50, 'OV': 0x40,
                          'NOV': 0xC0, 'EQ': 0x60, 'NE': 0xE0, 'GE': 0x90,
                          'LT': 0x10, 'GT': 0xA0, 'LE': 0x20, 'UGE': 0xF0,
                          'ULT': 0x70, 'UGT': 0xB0, 'ULE': 0x30}

            pointer = dec.Asm.Parse_Pointer
            cond = assem.GetWord().upper()

            if cond in conditions and assem.NowChar() == ',':
                # A legal condition code was given
                opcode = conditions[cond] + 13
                dec.Asm.Timing = '10+'
                if not assem.MoreParameters():
                    errors.DoError('missoper', False)
                    return
            else:
                # No condition was given
                dec.Asm.Parse_Pointer = pointer
                dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2][0]
                opcode = dec.Asm.Instructions[dec.Asm.Mnemonic][1][0]

        dest = assem.EvalExpr()

        target.CodeByte(opcode)
        target.CodeWord(dest[0])
        if dec.Asm.Pass == 2 and (dest[0] >> 16) != 0:
            errors.DoError('range', False)

    NoMore()
示例#19
0
def NoMore():
    """
    No more parameters are expected.
    Raise a warning if more paramters are found anyway.
    """

    if assem.MoreParameters():
        errors.DoWarning('extrign', False)
示例#20
0
def FileBit():
    """
    File register and bit operations.
    The file address is being range checked in order to determine the Access
    Bank selection. The bit range is also checked.
    The access bank selection parameter is optional.
    """

    global Asm

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

    filereg = assem.EvalExpr()[0]
    bitno = 0
    accessbank = 0

    if not assem.MoreParameters():
        # Missing operand
        errors.DoError('missoper', False)
    else:
        # Get the operand
        bitno = assem.EvalExpr()[0]

        if assem.MoreParameters():
            # Good, the access bank selector is given. That's easy
            accessbank = assem.EvalExpr()[0]
            if dec.Asm.Pass == 2 and (accessbank < 0 or accessbank > 1):
                # Oops, this is not good
                errors.DoError('range', False)
        else:
            # Now we have to decide
            if filereg >= dec.Asm.AccessBank18 and filereg <\
                    (dec.Asm.AccessBank18 + 0xF00):
                # Outside of access bank range. Use BSR mode instead
                accessbank = 1

    accessbank = (accessbank & 1) << 8

    if dec.Asm.Pass == 2 and (bitno < 0 or bitno > 7):
        # Range error in bit number
        errors.DoError('range', False)

    CodeWord(opcode + (filereg & 0xFF) + (bitno << 9) + accessbank)

    NoMore()
示例#21
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)
示例#22
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)
示例#23
0
文件: crz80.py 项目: Ivoah/6502
def Load():

    global Asm

    if MissingOperand():
        return

    reg1 = GetReg()

    if dec.Flags.ErrorInLine:
        # An error was found in parameter 1, no need to continue
        return

    if not assem.MoreParameters():
        errors.DoError('missoper', False)
        return

    reg2 = GetReg()

    firstpar = 'LD.' + reg1[0]
    if firstpar in dec.Asm.Instructions:
        secpar = dec.Asm.Instructions[firstpar][0]
        opcode = dec.Asm.Instructions[firstpar][1]
        timing = dec.Asm.Instructions[firstpar][2]
        extra = dec.Asm.Instructions[firstpar][3]

        index = 0
        for t in secpar:
            if t == reg2[0]:
                # Found 2nd parameter, now let's save it to the target file
                opc = opcode[index]
                Code(opc)
                dec.Asm.Timing = timing[index]
                if extra[index] == 1:
                    # save one extra byte from operand 2
                    target.CodeByte(reg2[1])
                elif extra[index] == 2:
                    # save two extra bytes from operand 2
                    target.CodeWord(reg2[1])
                elif extra[index] == 3:
                    # save one extra byte from operand 1
                    target.CodeByte(reg1[1])
                elif extra[index] == 4:
                    # save one extra byte from operand 1 and one from operand 2
                    target.CodeByte(reg1[1])
                    target.CodeByte(reg2[1])
                elif extra[index] == 5:
                    # save two extra bytes from operand 1
                    target.CodeWord(reg1[1])
                NoMore()
                return
            index = index + 1

        # This type of parameter was not allowed as second parameter
        errors.DoError('badoper', False)
    else:
        # This type of parameter was not allowed as first parameter
        errors.DoError('badoper', False)
示例#24
0
def InOut():
    """
    These instructions require two operands. A register from 0 to 31 and an
    I/O address from 0 to 63. The IN and OUT instructions have their operand
    order swapped.

    Dictionary: function, Xmega+Mega+AVR+TINY, newflags, opcode, cycles
    """

    global Asm

    if dec.Asm.Mnemonic == 'IN':
        # Get register operand first, then I/O location
        reg = GetReg() << 4

        if not assem.MoreParameters():
            # Oops only register is given
            errors.DoError('missoper', False)
            target.CodeWord(0)  # Write dummy word
            return

        value = assem.EvalExpr()[0]

    else:
        # Get I/O location first, then register
        value = assem.EvalExpr()[0]

        if not assem.MoreParameters():
            # Oops, only I/O location given
            errors.DoError('missoper', False)
            target.CodeWord(0)  # Write dummy word
            return

        reg = GetReg() << 4

    if dec.Asm.Pass == 2 and (value < 0 or value > 63):
        # Check I/O address range in pass 2 only
        errors.DoError('range', False)
        value = 0

    ioreg = (value & 15) + ((value & 48) << 5)

    target.CodeWord(dec.Asm.Instructions[dec.Asm.Mnemonic][3] + reg + ioreg)

    NoMore()
示例#25
0
def LDIndexed():
    """
    LD indexed takes 2 operands. A register number and an index register,
    which may include a pre-decrement or a post-increment.
    The Y and Z index registers may also have an offset from the register's
    base value. The range of this offset is from 0 to 63.

    Reduced instructionset only has LD  Rd,Z. All others are off limits.
    This is not correctly implemented in the legacy family and cannot be fixed!

    Dictionary: function, Xmega+Mega+AVR+TINY, newflags, 1 or 0, cycles
    """

    global Asm

    reg = GetReg() << 4

    if not assem.MoreParameters():
        # Only the register was given. The index register is missing
        errors.DoError('missoper', False)
        target.CodeWord(0)  # Write dummy word
        return

    value = GetIndex()

    if value[1] == 'X':
        # Get the opcode for LD Rn,X
        if dec.Asm.AVR_Family == 6:
            # Illegal index register for this minimal core
            errors.DoError('badoper', False)
        opcode = 0x900C
    elif value[1] == 'Y':
        # Get the opcode for LD(D) Rn,Y and add offset to it
        if dec.Asm.AVR_Family == 6:
            # Illegal index register for this minimal core
            errors.DoError('badoper', False)
        opcode = 0x8008 + value[2]
        if value[0] != 0 and len(dec.Asm.Mnemonic) == 2:
            # Indicated pre-decrement or post-increment opcode
            opcode = opcode + 0x1000
    else:
        # Get the opcode for LD(D) Rn,Z and add offset to it
        opcode = 0x8000 + value[2]
        if value[0] != 0 and len(dec.Asm.Mnemonic) == 2:
            # Indicate pre-decrement or post-increment opcode
            if dec.Asm.AVR_Family == 6:
                # pre-decrement and post-increment not implemented
                errors.DoError('badoper', False)
            opcode = opcode + 0x1000

    if len(dec.Asm.Mnemonic) == 2:
        # It's LD, not LDD, add the pre-decrement or post-increment flag to it
        opcode = opcode + value[0]

    target.CodeWord(opcode + reg)

    NoMore()
示例#26
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)
示例#27
0
def STIndexed():
    """
    ST indexed takes 2 operands. An index register, which may include a
    pre-decrement or a post-increment, and a register.
    The Y and Z index registers may also have an offset from the register's
    base value. The range of this offset is from 0 to 63.

    Reduced instructionset only has ST  Z,Rd. All others are off limits.
    This is not correctly implemented in the legacy family and cannot be fixed!

    Dictionary: function, Xmega+Mega+AVR+TINY, newflags, 1 or 0, cycles
    """

    global Asm

    value = GetIndex()

    if value[1] == 'X':
        # Get opcode for ST X,Rn
        if dec.Asm.AVR_Family == 6:
            # Illegal index register for this minimal core
            errors.DoError('badoper', False)
        opcode = 0x920C
    elif value[1] == 'Y':
        # Get opcode for ST(D) Y,Rn and add offset to it
        if dec.Asm.AVR_Family == 6:
            # Illegal index register for this minimal core
            errors.DoError('badoper', False)
        opcode = 0x8208 + value[2]
        if value[0] != 0 and len(dec.Asm.Mnemonic) == 2:
            # Indicated pre-decrement or post-increment opcode
            opcode = opcode + 0x1000
    else:
        # Get opcode for ST(D) Z,Rn and add offset to it
        opcode = 0x8200 + value[2]
        if value[0] != 0 and len(dec.Asm.Mnemonic) == 2:
            # Indicated pre-decrement or post-increment opcode
            if dec.Asm.AVR_Family == 6:
                # pre-decrement and post-increment not implemented
                errors.DoError('badoper', False)
            opcode = opcode + 0x1000

    if len(dec.Asm.Mnemonic) == 2:
        # It's ST, not STD, add the pre-decrement or post-increment flag to it
        opcode = opcode + value[0]

    if not assem.MoreParameters():
        errors.DoError('missoper', False)
        target.CodeWord(0)  # Write dummy word
        return

    reg = GetReg() << 4

    target.CodeWord(opcode + reg)

    NoMore()
示例#28
0
def MovXInst():
    """
    MOVX   A,@DPTR
    MOV    A,@Ri
    MOV    @DPTR,A
    MOV    @Ri,A
    """

    global Asm

    if MissingOperand():
        # We need some operands
        return

    par1 = GetReg()

    if not assem.MoreParameters():
        # Only one operand given
        errors.DoError('missoper', False)
        return

    par2 = GetReg()

    dec.Asm.Timing = '2'
    if par1[1] == 1:
        # Can be either A,@DPTR or A,@Ri
        if par2[1] == 7:
            # It's A,@DPTR for sure
            target.CodeByte(0xE0)
        elif par2[1] == 3:
            # It's A,@Ri
            target.CodeByte(0xE2 + par2[0])
        else:
            # None of the above
            errors.DoError('badoper', False)
            return
    elif par1[1] == 7:
        # It's @DPTR,A mode
        if par2[1] != 1:
            # Second parameter is not A
            errors.DoError('badoper', False)
            return
        target.CodeByte(0xF0)
    elif par1[1] == 3:
        # It's @Ri,A mode
        if par2[1] != 1:
            # Second parameter is not A
            errors.DoError('badoper', False)
            return
        target.CodeByte(0xF2 + par1[0])
    else:
        # 1st parameter is wrong
        errors.DoError('badoper', False)
        return

    NoMore()
示例#29
0
def CpInst():

    global Asm

    if MissingOperand():
        return

    operand1 = GetOperand()

    if not assem.MoreParameters():
        errors.DoError('missoper', False)
        return

    operand2 = GetOperand()

    if operand1[0] == 15:
        # CP A,something

        opcode = (0x00A1, 0x00B1, 0x00C1, 0x00F1, 0x00E1, 0x00D1, 0x90F1,
                  0x90E1, 0x90D1, 0x92B1, 0x92C1, 0x92E1, 0x92D1, 0x91E1,
                  0x91D1)
        timing = ('2', '3', '4', '3', '4', '5', '4', '5', '6', '5', '6', '6',
                  '7', '6', '7')

    elif operand1[0] == 16:
        # CP X,something

        opcode = (0x00A3, 0x00B3, 0x00C3, 0x00F3, 0x00E3, 0x00D3, 0x0000,
                  0x0000, 0x0000, 0x92B3, 0x92C3, 0x92E3, 0x92D3, 0x0000,
                  0x0000)
        timing = ('2', '3', '4', '3', '4', '5', '0', '0', '0', '5', '6', '6',
                  '7', '0', '0')

    elif operand1[0] == 17:
        # CP Y,something

        opcode = (0x90A3, 0x90B3, 0x90C3, 0x0000, 0x0000, 0x0000, 0x90F3,
                  0x90E3, 0x90D3, 0x91B3, 0x91C3, 0x0000, 0x0000, 0x91E3,
                  0x91D3)
        timing = ('3', '4', '5', '0', '0', '0', '4', '5', '6', '5', '6', '0',
                  '0', '6', '7')

    else:
        errors.DoError('badoper', False)
        return

    if operand2[0] > 14:
        errors.DoError('badoper', False)
        return

    prebyte = opcode[operand2[0]] // 256
    opcbyte = opcode[operand2[0]] % 256
    dec.Asm.Timing = timing[operand2[0]]

    SaveAll(prebyte, opcbyte, operand2)
示例#30
0
def PointerData():
    """
    Pointer pair with data instructions
    pointer,data
    """

    global Asm

    MissingOperand()

    parsepointer = dec.Asm.Parse_Pointer
    pointer = -1

    pntr = assem.GetWord().upper()
    if len(pntr) == 2 and pntr[1] == "P":
        # It might as well be a poiner pair
        if pntr[0] >= '0' and pntr[0] <= '7':
            # It sure is
            pointer = int(pntr[0]) * 2

    if pointer == -1:
        # It wasn't a pointer, so it must be an expression now
        dec.Asm.Parse_Pointer = parsepointer
        pointer = assem.EvalExpr()[0]

    if not assem.MoreParameters():
        errors.DoError('missoper', False)
        return

    prefix = '#'
    if assem.NowChar() in '#/=\\':
        prefix = assem.NowChar(True)

    value = assem.EvalExpr()

    if prefix == '#':
        val = value[0] & 255
    elif prefix == '/':
        val = (value[0] >> 8) & 255
    elif prefix == '=':
        val = (value[0] >> 16) & 255
    else:
        val = (value[0] >> 24) & 255

    if dec.Asm.Pass == 2:
        # Range check only in pass 2
        if pointer < 0 or pointer > 15 or pointer % 2 == 1:
            # Range error
            errors.DoError('range', False)

    target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1] + pointer)
    target.CodeByte(val)
    dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2]

    NoMore()