Пример #1
0
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()
Пример #2
0
def Pairs():
    """
    Handle paired operand instructions.
    """

    global Asm

    if MissingOperand():
        return

    reg1 = assem.GetWord().upper()

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

    if assem.NowChar() == ' ':
        errors.DoError('missoper', False)
        return

    if assem.NowChar() in '#/=\\':
        reg2 = '#'
    else:
        reg2 = assem.GetWord().upper()

    operand = reg1 + ',' + reg2

    operands = dec.Asm.Instructions[dec.Asm.Mnemonic][1]
    opcodes = dec.Asm.Instructions[dec.Asm.Mnemonic][2]
    times = dec.Asm.Instructions[dec.Asm.Mnemonic][3]

    if operand in operands:
        index = 0
        for t in operands:
            if t == operand:
                break
            index = index + 1
        target.CodeByte(opcodes[index])
        dec.Asm.Timing = times[index]
        if reg2 == '#':
            prefix = assem.NowChar(True)
            value = assem.EvalExpr()
            if prefix == '#':
                target.CodeByte(value[0])
            elif prefix == '/':
                target.CodeByte(value[0] >> 8)
            elif prefix == '=':
                target.CodeByte(value[0] >> 16)
            else:
                target.CodeByte(value[0] >> 24)
    else:
        errors.DoError('badoper', False)

    NoMore()
Пример #3
0
def MovBit():
    """
    See if first or second operand is a C.
    If it is it is a bit MOV.
    If it is not return False and parse normal MOV.
    """

    global Asm

    # Save the begin pointer in case're on a dead track
    pntr = dec.Asm.Parse_Pointer
    par1 = assem.GetWord().upper()

    if not assem.MoreParameters():
        # We need 2 paarameters
        errors.DoError('missoper', False)
        return

    if par1 == 'C':
        # First parameter is a C

        bitreg = GetBit()

        target.CodeByte(0xA2)
        target.CodeByte(bitreg)
        dec.Asm.Timing = '1'

        NoMore()

        return True

    par2 = assem.GetWord().upper()

    if par2 == 'C':
        # Second parameter is a C

        endpntr = dec.Asm.Parse_Pointer
        dec.Asm.Parse_Pointer = pntr
        bitreg = GetBit()
        dec.Asm.Parse_Pointer = endpntr

        target.CodeByte(0x92)
        target.CodeByte(bitreg)
        dec.Asm.Timing = '2'

        NoMore()

        return True

    # Nope, it's not MOV C, restore pointer and try again
    dec.Asm.Parse_Pointer = pntr

    return False
Пример #4
0
def Exchange():
    """
    Handle EXG and TFR directives.
    Both directives take 2 operands of either 8-bit size or 16-bit size.
    Sizes of the registers may not be mixed.
    """

    global Asm

    if MissingOperand():
        return

    reg1 = assem.GetWord().upper()

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

    reg2 = assem.GetWord().upper()

    words = {
        'A:B': 0,
        'D': 0,
        'X': 1,
        'Y': 2,
        'US': 3,
        'U': 3,
        'SP': 4,
        'S': 4,
        'PC': 5
    }
    bytes = {'A': 8, 'B': 9, 'CC': 10, 'CCR': 10, 'DP': 11, 'DPR': 11}

    if reg1 in words:
        if reg2 in words:
            target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1])
            target.CodeByte((words[reg1] << 4) + words[reg2])
            dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2]
        else:
            errors.DoError('badoper', False)
    elif reg1 in bytes:
        if reg2 in bytes:
            target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1])
            target.CodeByte((bytes[reg1] << 4) + bytes[reg2])
            dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2]
        else:
            errors.DoError('badoper', False)
    else:
        errors.DoError('badoper', False)

    NoMore()
Пример #5
0
def Pointer():
    """
    Pointer pair instructions
    PntrPair
    """

    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 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)
    dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2]

    NoMore()
Пример #6
0
def GetPtr():
    """
    A pointer parameter is expected. Legal options are P0, PC, P1, P2 or P3
    They translate to 0..3, where P0 and PC are equal and generate 0
    """

    global Asm

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

    if param == '':
        errors.DoError('missoper', False)
        return 0

    if len(param) == 2 and param[0] == 'P':
        param = param[1]

        if param.isdigit():
            ptr = int(param)
            if ptr > 3:
                errors.DoError('badoper', False)
        else:
            if param == 'C':
                ptr = 0
            else:
                errors.DoError('badoper', False)
                ptr = 0
    else:
        errors.DoError('badoper', False)
        ptr = 0

    return ptr % 4
Пример #7
0
def DirFA():
    """
    Set the device's family.
    If this is not used in a program a warning is given and the assembler
    defaults to the XMega family, which can do everything.
    As of version 3.02.00 of this cross overlay an extra family tree has
    been added to reflect the families found on Wikipedia. This allows for
    a much finer distinction between the capabilities of the processors.
    The old family tree still exists though for backward compatibility.
    - Boundary Sync.
    """

    global Asm

    target.BoundarySync()

    families = [
        'TINY', 'AVR', 'MEGA', 'XMEGA', 'REDUCED', 'MINIMAL', 'CLASSIC8K'
    ]
    families += ['CLASSIC128K', 'ENHANCED8K', 'ENHANCED128K', 'ENHANCED4M']

    if dec.Asm.Parse_Pointer == 0:
        # No parameter given
        errors.DoError('missoper', False)
        return

    family = assem.GetWord().upper()
    if family not in families:
        errors.DoError('badoper', False)
        return

    dec.Asm.AVR_Family = families.index(family) + 1

    NoMore()
Пример #8
0
def DirDE():
    """
    Assign a name to a register.
    - Boundary Sync will be automatic because of the label in the label field
    """

    global Asm

    if dec.Asm.Parse_Pointer == 0:
        # No parameter given
        errors.DoError('missoper', False)
        dec.Asm.New_Label = ''
        return

    register = -1
    reg = assem.GetWord().upper()
    if (len(reg) == 2 or len(reg) == 3) and reg[0] == 'R':
        # Can it be a register name? Must be 2 or 3 chars long and start with R
        reg = reg[1:]
        if reg.isdigit:
            # The register number must be numeric of course
            if len(reg) == 1 or reg[0] != '0':
                # It is numeric, without a leading 0
                register = int(reg)
    if register < 0 or register > 31:
        # It is not a legal register
        errors.DoError('badoper', False)
        dec.Asm.New_Label = ''
    else:
        # It is a legal register, set it's value
        dec.Asm.BOL_Address = register
        dec.Asm.List_Address = register
    dec.Asm.Mnemonic = '.SE'  # Handle rest like .SE
Пример #9
0
def DefineMacro():

    global Asm

    labelfield = ''
    mnemonic = ''

    if dec.Asm.Parse_Line.isspace() or dec.Asm.Parse_Line[0] in dec.COMMENT1:
        # This line contains nothing or comment, don't parse it
        pass
    else:
        if dec.Asm.Parse_Line[0] != ' ':
            # Get label name, but don't bother about syntax
            labelfield = assem.GetWord()
        mnemonic = assem.GetMnemonic()

    if mnemonic != '' and mnemonic[0] == '.':
        # See if any of the reserved mnemonics is given
        mnemonic = mnemonic[1:3]
        if mnemonic in ('MA', 'IN', 'CH', 'BI', 'CO', 'EC'):
            errors.DoError('illdir', False)
            return  # Don't add this line to the macro definition
        if mnemonic == 'EM':
            # End the macro definition
            if labelfield != '':
                # The .EM line doesn't allow a label declaration
                errors.DoError('illdec', False)
                dec.Asm.New_Label = ''
            dec.Asm.Macro_Def = ''
            return  # Don't add this line to the definition!

    if dec.Asm.Pass == 1:
        # Only add to the definition during pass 1
        dec.Asm.Macro[dec.Asm.Macro_Def].append(dec.Asm.Parse_Line)
Пример #10
0
def Singles():
    """
    Handle single operand instructions.
    """

    global Asm

    if MissingOperand():
        return

    regname = assem.GetWord().upper()

    registers = dec.Asm.Instructions[dec.Asm.Mnemonic][1]
    opcodes = dec.Asm.Instructions[dec.Asm.Mnemonic][2]
    times = dec.Asm.Instructions[dec.Asm.Mnemonic][3]

    if regname in registers:
        index = 0
        for t in registers:
            if t == regname:
                break
            index = index + 1
        target.CodeByte(opcodes[index])
        dec.Asm.Timing = times[index]
    else:
        errors.DoError('badoper', False)

    NoMore()
Пример #11
0
def Returns():

    global Asm

    conditions = {
        'NZ': 0,
        'Z': 1,
        'NC': 2,
        'C': 3,
        'PO': 4,
        'PE': 5,
        'P': 6,
        'M': 7
    }
    if dec.Asm.Optional:
        # Parameter was following within 10 spaces
        condition = assem.GetWord().upper()
        if condition in conditions:
            cond = conditions[condition] << 3
            index = 1
        else:
            cond = 0
            index = 0
    else:
        cond = 0
        index = 0

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

    NoMore()
Пример #12
0
def Stack():

    global Asm

    if MissingOperand():
        return

    operand = assem.GetWord().upper()

    if operand == 'A':
        index = 0
    elif operand == 'X':
        index = 1
    elif operand == 'Y':
        index = 2
    elif operand == 'CC':
        index = 3
    else:
        errors.DoError('badoper', False)
        return

    opcode = (dec.Asm.Instructions[dec.Asm.Mnemonic][1][index])
    if opcode > 255:
        target.CodeWord(opcode)
    else:
        target.CodeByte(opcode)
    dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2][index]

    NoMore()
Пример #13
0
def Stack():

    global Asm

    if MissingOperand():
        return

    pair = assem.GetWord().upper()

    if pair in ('BC', 'DE', 'HL', 'AF'):
        if pair == 'DE':
            offset = 16
        elif pair == 'HL':
            offset = 32
        elif pair == 'AF':
            offset = 48
        else:
            offset = 0
        Code(dec.Asm.Instructions[dec.Asm.Mnemonic][1] + offset)
        dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2][0]
    elif pair in ('IX', 'IY'):
        if pair == 'IX':
            prefix = 0xDD
        else:
            prefix = 0xFD
        Code(prefix)
        Code(dec.Asm.Instructions[dec.Asm.Mnemonic][1] + 32)
        dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2][1]

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

    NoMore()
Пример #14
0
def GetReg():

    global Asm

    pointer = dec.Asm.Parse_Pointer

    register = assem.GetWord().upper()

    if register == 'A':
        return (1, 0xFF)
    elif register == "X":
        return (2, 0x80)
    elif register == "Y":
        return (3, 0x81)
    elif register == "V":
        return (4, 0x82)
    elif register == "W":
        return (5, 0x83)
    elif register == "(X)":
        return (6, 0)
    elif register == "(Y)":
        return (7, 0)
    else:
        dec.Asm.Parse_Pointer = pointer
        value = assem.EvalExpr()[0]
        if dec.Asm.Pass == 2 and (value > 255 or value < 0):
            errors.DoError('range', False)
            value = value & 255

        return (0, value)
Пример #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 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()
Пример #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
def Branch():

    global Asm

    if MissingOperand():
        return

    conditions = {'C': 1, 'NC': 2, 'Z': 3, 'NZ': 4}
    pointer = dec.Asm.Parse_Pointer
    condition = assem.GetWord().upper()
    if dec.Asm.Mnemonic == 'JR' and condition in conditions and\
                           assem.NowChar(True) == ',':
        index = conditions[condition]
    else:
        dec.Asm.Parse_Pointer = pointer
        index = 0

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

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

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

    NoMore()
Пример #19
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
Пример #20
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()
Пример #21
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()
Пример #22
0
def Djnz():
    """
    Handle DJNZ.
    DJNZ has two opcodes in the instruction table. The first one is for
    DJNZ Rx,dest. The second entry is for DJNZ @Rn,dest.
    If indirect mode doesn't exist the opcode for it should be 00.
    """

    global Asm

    if MissingOperand():
        return

    registers = ('R0', 'R1', 'R2', 'R3', 'R4', 'R5', 'R6', 'R7', '@R0', '@R1')
    regname = assem.GetWord().upper()

    if regname in registers:
        index = 0
        for t in registers:
            if t == regname:
                break
            index = index + 1
        if index < 8:
            # direct addressing mode
            opcode = dec.Asm.Instructions[dec.Asm.Mnemonic][1][0] + index
        else:
            # indirect addressing mode
            opcode = dec.Asm.Instructions[dec.Asm.Mnemonic][1][1]
            if opcode == 0:
                errors.DoError('badoper', False)
                return
            opcode = opcode + (index & 1)
    else:
        errors.DoError('badoper', False)
        return

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

    value = assem.EvalExpr()

    if dec.Asm.Pass == 2:
        temp = (dec.Asm.BOL_Address + 1) >> 8
        dest = value[0] >> 8
        if temp != dest:
            # Destination is not in the same memory page
            errors.DoError('range', False)

    target.CodeByte(opcode)
    target.CodeByte(value[0])
    dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2]

    NoMore()
Пример #23
0
def Jumps():

    global Asm

    if MissingOperand():
        return

    conditions = {
        'NZ': 0,
        'Z': 1,
        'NC': 2,
        'C': 3,
        'PO': 4,
        'PE': 5,
        'P': 6,
        'M': 7
    }
    pointer = dec.Asm.Parse_Pointer
    condition = assem.GetWord().upper()
    if condition in conditions and assem.NowChar(True) == ',':
        # Conditional jump or call
        if assem.NowChar() == " ":
            # Allow a space to follow a comma
            assem.IncParsePointer()
        value = assem.EvalExpr()
        Code(dec.Asm.Instructions[dec.Asm.Mnemonic][1][1] +
             (conditions[condition] << 3))
        target.CodeWord(value[0])
        dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2][1]
        if dec.Asm.Pass == 2 and ((value[0] >> 16) != 0):
            errors.DoErrors('range', False)
    elif condition == '(HL)':
        # (HL)
        Code(dec.Asm.Instructions[dec.Asm.Mnemonic][1][2])
        dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2][2]
    elif condition == '(IX)':
        # (IX)
        Code(dec.Asm.Instructions[dec.Asm.Mnemonic][1][3])
        dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2][3]
    elif condition == '(IY)':
        # (IY)
        Code(dec.Asm.Instructions[dec.Asm.Mnemonic][1][4])
        dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2][3]
    else:
        # Non conditional
        dec.Asm.Parse_Pointer = pointer
        value = assem.EvalExpr()
        Code(dec.Asm.Instructions[dec.Asm.Mnemonic][1][0])
        target.CodeWord(value[0])
        dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2][0]

    NoMore()
Пример #24
0
def GetBit():
    """
    Legal bit addresses are:
    Direct addresses from 020H.0 to 02FH.7
    SFR addresses which can be devided by 8, followed by .0 to .7
    If the address is not followed by .0 to .7 it is handled as a normal
    address, in which case its value should be below 256.
    """

    global Asm

    pntr = dec.Asm.Parse_Pointer
    par1 = assem.GetWord().upper()
    regbit = 0

    if len(par1) > 2 and par1[-2] == '.' and par1[-1] in '01234567':
        # operand.bit notation. Hide bit number temporarily
        bitno = int(par1[-1])
        parseline = dec.Asm.Parse_Line
        dec.Asm.Parse_Line = parseline[:dec.Asm.Parse_Pointer - 2] + ' '
        dec.Asm.Parse_Pointer = pntr
        value = assem.EvalExpr()
        dec.Asm.Parse_Line = parseline
        dec.Asm.Parse_Pointer = dec.Asm.Parse_Pointer + 2

        if dec.Asm.Pass == 2:
            # Only check rage during pass 2
            if value[0] in range(0x20, 0x30):
                # In RAM area
                regbit = ((value[0] & 15) << 3) + bitno
            elif value[0] in range(0x80, 0xFF, 8):
                # In SFR area
                regbit = value[0] + bitno
            else:
                # Not in legal area
                errors.DoError('range', False)

    else:
        # No operand.bit notation, evaluate normally
        dec.Asm.Parse_Pointer = pntr
        value = assem.EvalExpr()
        regbit = value[0]

        if dec.Asm.Pass == 2 and (value[0] >> 8) != 0:
            # Value not between 0 to 255
            errors.DoError('range', False)

    return regbit
Пример #25
0
def GetPtr():
    """
    A pointer parameter is expected. Legal options are P0, PC, P1, P2 or P3
    They translate to 0..3, where P0 and PC are equal and generate 0.
    For compatibility digits 0, 1, 2 and 3 are also accepted.
    """

    global Asm

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

    if param == '':
        # Empty parameter not allowed
        errors.DoError('missoper', False)
        return 0

    if len(param) == 2 and param[0] == 'P':
        # Strip leading P if parameter length = 2
        param = param[1]
        if param == 'C':
            # Translate PC parameter to 0
            param = '0'

    if len(param) == 1:
        # Parameter length may only be 1 now
        if param.isdigit():
            # The parameter must be digit from 0 to 3 now
            ptr = int(param)
            if ptr > 3:
                errors.DoError('badoper', False)
        else:
            # Parameter was not a digit
            errors.DoError('badoper', False)
            ptr = 0
    else:
        # Parameter length was not 1
        errors.DoError('badoper', False)
        ptr = 0

    return ptr % 4
Пример #26
0
def BitInst():
    """
    Handle CLR, CPL and SETB instructions.
    """

    global Asm

    if MissingOperand():
        # Oops, no operands
        return

    pntr = dec.Asm.Parse_Pointer
    par1 = assem.GetWord().upper()

    if par1 == 'A':
        # A parameter
        opcode = dec.Asm.Instructions[dec.Asm.Mnemonic][1][0]
        dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2][0]
        if opcode == 0:
            # Opcode doesn't exist
            errors.DoError('badoper', False)
        else:
            # Opcode exists
            target.CodeByte(opcode)

    elif par1 == 'C':
        # C parameter
        target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1][1])
        dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2][1]

    else:
        # It's a bit adddress
        dec.Asm.Parse_Pointer = pntr
        par1 = GetBit()
        target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1][2])
        target.CodeByte(par1)
        dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2][2]

    NoMore()
Пример #27
0
def Output():

    global Asm

    if MissingOperand():
        return

    operand = assem.GetWord().upper()

    outputlist = {
        'ADR': 0x51,
        'STATUS': 0x53,
        'DATA': 0x55,
        'WRITE': 0x57,
        'COM1': 0x59,
        'COM2': 0x5B,
        'COM3': 0x5D,
        'COM4': 0x5F,
        'BEEP': 0x69,
        'CLICK': 0x6B,
        'DECK1': 0x6D,
        'DECK2': 0x6F,
        'RBK': 0x71,
        'WBK': 0x73,
        'BSP': 0x77,
        'SF': 0x79,
        'SB': 0x7B,
        'REWIND': 0x7D,
        'TSTOP': 0x7F
    }

    if operand in outputlist:
        target.CodeByte(outputlist[operand])
        dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2]
    else:
        errors.DoError('badoper', False)

    NoMore()
Пример #28
0
def TableRW():
    """
    The parameter can be the following:
    *       00
    *+      01
    *-      10
    +*      11
    """

    global Asm

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

    first = assem.NowChar()
    option = assem.GetWord("*+-", "*+-", " ")

    if option == "*":
        # Just the pointer
        CodeWord(opcode)
    elif option == "*+":
        # Post increment
        CodeWord(opcode + 1)
    elif option == "*-":
        # Post decerement
        CodeWord(opcode + 2)
    elif option == "+*":
        # Pre increment
        CodeWord(opcode + 3)
    else:
        # It's an error, but which one?
        if first == " ":
            # Missing operand
            errors.DoError("missoper", False)
        else:
            # Bad operand
            errors.DoError("badoper", False)
Пример #29
0
def Mult():

    global Asm

    if MissingOperand():
        return

    pair = assem.GetWord().upper()

    if pair in ('BC', 'DE', 'HL', 'SP'):
        if pair == 'DE':
            offset = 16
        elif pair == 'HL':
            offset = 32
        elif pair == 'SP':
            offset = 48
        else:
            offset = 0
        Code(dec.Asm.Instructions[dec.Asm.Mnemonic][1] + offset)
        dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2]
    else:
        errors.DoError('badoper', False)

    NoMore()
Пример #30
0
def GetOperand():
    """
    Get an operand. This can get complicated.
    Operand can be:
    Index =  0: #
    Index =  1: SHORT
    Index =  2: LONG
    Index =  3: (X)
    Index =  4: (SHORT,X)
    Index =  5: (LONG,X)
    Index =  6: (Y)
    Index =  7: (SHORT,Y)
    Index =  8: (LONG,Y)
    Index =  9: [SHORT]
    Index = 10: [LONG.W]
    Index = 10: {LONG}
    Index = 11: ([SHORT],X)
    Index = 12: ([LONG.W],X)
    Index = 12: ({LONG},X)
    Index = 13: ([SHORT],Y)
    Index = 14: ([LONG.W],Y)
    Index = 14: ({LONG},Y)
    Index = 15: A
    Index = 16: X
    Index = 17: Y
    Index = 18: S
    """

    global Asm

    pntr = dec.Asm.Parse_Pointer

    operand = assem.GetWord().upper()
    if operand == 'A':
        return (15, 0)
    if operand == 'X':
        return (16, 0)
    if operand == 'Y':
        return (17, 0)
    if operand == 'S':
        return (18, 0)
    if operand == '(X)':
        return (3, 0)
    if operand == '(Y)':
        return (6, 0)

    dec.Asm.Parse_Pointer = pntr

    # ----------

    if operand[0] in '#/=\\':
        # Immediate value
        mode = assem.NowChar(True)
        value = assem.EvalExpr()
        if mode == '#':
            return (0, value[0])
        if mode == '/':
            return (0, value[0] >> 8)
        if mode == '=':
            return (0, value[0] >> 16)
        return (0, value[0] >> 24)

# ----------

    if operand[0:2] == '([':
        # Some form of Indexed Indirect mode

        assem.IncParsePointer()
        assem.IncParsePointer()

        pntr = dec.Asm.Parse_Pointer
        line = dec.Asm.Parse_Line
        operand = assem.GetWord('', '', ']').upper()
        endpnt = dec.Asm.Parse_Pointer
        dec.Asm.Parse_Pointer = pntr
        short = True
        if operand[-2:] == '.W':
            short = False
            dec.Asm.Parse_Line = line[:endpnt - 2] + ' '

        value = assem.EvalExpr()
        dec.Asm.Parse_Line = line
        dec.Asm.Parse_Pointer = endpnt

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

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

        nowchar = assem.NowChar(True).upper()
        if nowchar == 'X':
            xymode = 11
        elif nowchar == 'Y':
            xymode = 13
        else:
            xymode = 11
            errors.DoError('badoper', False)

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

        if dec.Asm.Pass == 2 and (value[0] >> 8 != 0):
            errors.DoError('range', False)

        if short:
            return (xymode + 0, value[0])
        else:
            return (xymode + 1, value[0])

# ----------

    if operand[0:2] == '({':
        # Indexed Indirect long mode

        assem.IncParsePointer()
        assem.IncParsePointer()
        value = assem.EvalExpr()
        if assem.NowChar(True) != '}':
            errors.DoError('badoper', False)

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

        nowchar = assem.NowChar(True).upper()
        if nowchar == 'X':
            xymode = 12
        elif nowchar == 'Y':
            xymode = 14
        else:
            xymode = 12
            errors.DoError('badoper', False)

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

        if dec.Asm.Pass == 2 and (value[0] >> 8 != 0):
            errors.DoError('range', False)

        return (xymode, value[0])

# ----------

    if operand[0] == '(':
        # Some form of indexed mode.
        # It can be short or long, followed by ,X) or ,Y)

        assem.IncParsePointer()

        prefix = ''
        if operand[0] in '<>':
            # It's forced long or short
            prefix = assem.NowChar(True)

        value = assem.EvalExpr()

        if prefix == '<':
            short = True
            if dec.Asm.Pass == 2 and (value[0] >> 8) != 0:
                errors.DoError('range', False)
        elif prefix == '>' or value[1]:
            short = False
        else:
            short = False
            if (value[0] >> 8) == 0:
                short = True

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

        nowchar = assem.NowChar(True).upper()
        if nowchar == 'X':
            xymode = 4
        elif nowchar == 'Y':
            xymode = 7
        else:
            xymode = 4
            errors.DoError('badoper', False)

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

        if short:
            return (xymode + 0, value[0])
        else:
            return (xymode + 1, value[0])

# ----------

    if operand[0] == '[':
        # Some form of indirect mode, could be [short] or [long.w]

        assem.IncParsePointer()
        pntr = dec.Asm.Parse_Pointer
        line = dec.Asm.Parse_Line
        operand = assem.GetWord('', '', ']').upper()
        endpnt = dec.Asm.Parse_Pointer
        dec.Asm.Parse_Pointer = pntr
        short = True
        if operand[-2:] == '.W':
            short = False
            dec.Asm.Parse_Line = line[:endpnt - 2] + ' '

        value = assem.EvalExpr()
        dec.Asm.Parse_Line = line
        dec.Asm.Parse_Pointer = endpnt

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

        if dec.Asm.Pass == 2 and (value[0] >> 8 != 0):
            errors.DoError('range', False)

        if short:
            return (9, value[0])
        else:
            return (10, value[0])

# ----------

    if operand[0] == '{':
        # Indirect LONG mode

        assem.IncParsePointer()
        value = assem.EvalExpr()
        if assem.NowChar(True) != '}':
            errors.DoError('badoper', False)

        if dec.Asm.Pass == 2 and (value[0] >> 8 != 0):
            errors.DoError('range', False)

        return (10, value[0])

# ----------

# Here only short or long mode option left.
# Must decide whether to use short or long, depending on address size

    prefix = ''
    if operand[0] in '<>':
        # It's forced long or short
        prefix = assem.NowChar(True)

    value = assem.EvalExpr()

    if prefix == '<':
        short = True
        if dec.Asm.Pass == 2 and (value[0] >> 8) != 0:
            errors.DoError('range', False)
    elif prefix == '>' or value[1]:
        short = False
    else:
        short = False
        if (value[0] >> 8) == 0:
            short = True

    if short:
        return (1, value[0])
    else:
        return (2, value[0])