예제 #1
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()
예제 #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
파일: crz80.py 프로젝트: Ivoah/6502
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
파일: crz80.py 프로젝트: Ivoah/6502
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
파일: crz80.py 프로젝트: Ivoah/6502
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
파일: crz80.py 프로젝트: Ivoah/6502
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])