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

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

    target.SaveByte(data & 0xFF, list)
    target.SaveByte((data >> 8) & 0xFF, list)
def SaveByte(data, list=True):
    """
    Save byte in code memory. We come here because a directive has generated
    data to be written in code memory. If we're still below the program size
    data bytes need to be translated to RETLW instructions. Otherwise a byte
    has to be stored as a word with high byte 0.
    Also check whether the end of memory is passed, in which case a warning
    is issued.
    """

    global Asm, Cross

    if dec.Asm.Memory == 0:
        # We only need to do something special inside code memory
        if dec.Asm.PH_Address > dec.Asm.Max_Address:
            # We're past the end of program memory. Save as word instead

            # Temporarily raise program limit to avoid warnings
            limit = dec.Asm.Max_Address
            dec.Asm.Max_Address = 0x1FFF

            # Save a word as usual
            CodeWord(data & 0xFF, list)

            # Restore original limit
            dec.Asm.Max_Address = limit
        else:
            # Combine data with RETLW opcode
            CodeWord(0x3400 + (data & 0xFF), list)
            # This is an instruction, so it has an execution time
            dec.Asm.Timing = "2"
    else:
        # All other memories can be done as usual
        target.SaveByte(data, list)
Example #3
0
def DirCW():

    """
    Set the Configuration word.
    This Configuration word is usually stored at the last location in memory,
    which is word address $0FFF (or byte addresses ($1FFE and $1FFF).
    Programming devices expect that word to be there. The SB-Assembler only
    checks that the Configuration word is stored beyond the program memory.
    """

    global Asm, Cross

    if dec.Asm.Memory != 0:
        # The .CW directive can only be used in program memory
        errors.DoError(dec.Cross.Name + 'codemem', False)
        return

    if dec.Asm.PH_Address <= dec.Asm.Max_Address:
        # We're still in program memory. We can't have that
        errors.DoError(dec.Cross.Name + 'progmem', False)
        return

    if assem.NowChar() == '#':
        # Ignore the # symbol
        assem.NowChar(True)

    config = assem.EvalExpr()[0]

    if dec.Asm.Pass == 2 and (config < 0 or config > 0x0FFF):
        # Only 12 bits allowed
        errors.DoError('range', False)

    # Temporarily raise program limit
    limit = dec.Asm.Max_Address
    dec.Asm.Max_Address = 0x0FFF

    # Bypass the RETLW pointer
    target.SaveByte(config & 0xFF)
    target.SaveByte((config >> 8) & 0x0F)

    # Restore original limit
    dec.Asm.Max_Address = limit

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

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

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

        target.SaveByte(data & 0xFF, list)
        target.SaveByte((data >> 8) & 0xFF, list)
Example #5
0
def DirID():

    """
    Set the ID words.
    These ID words are usually stored directly behind the program memory, or
    directly behind the EEPROM memory if that is present.
    The SB-Assembler only checks that the Configuration word is stored beyond
    the program memory.
    """

    global Asm, Cross

    if dec.Asm.Memory != 0:
        # The .ID directive can only be used in program memory
        errors.DoError(dec.Cross.Name + 'codemem', False)
        return

    if dec.Asm.PH_Address <= dec.Asm.Max_Address:
        # We're still in program memory. We can't have that
        errors.DoError(dec.Cross.Name + 'progmem', False)
        return

    if assem.NowChar() == '#':
        # Ignore the # symbol
        assem.NowChar(True)

    id = assem.EvalExpr()[0]

    # Temporarily raise program limit
    limit = dec.Asm.Max_Address
    dec.Asm.Max_Address = 0x0FFF

    # Save the ID, one nibble at a time
    target.SaveByte(id & 0x000F)
    target.SaveByte(0)
    target.SaveByte((id >> 4) & 0x000F)
    target.SaveByte(0)
    target.SaveByte((id >> 8) & 0x000F)
    target.SaveByte(0)
    target.SaveByte((id >> 12) & 0x000F)
    target.SaveByte(0)

    # Restore original limit
    dec.Asm.Max_Address = limit

    NoMore()
Example #6
0
def BincHEX(line):

    """
    Parse a plain HEX line.
    This one's easy.
    """

    for i in range(0, len(line), 2):
        # Translate each hex digit pair into a byte

        value = HexPair(line[i:i+2])
        if not value[0]:
            target.SaveByte(value[1], False)
        else:
            return True

    return False
def DirID():
    """
    Set the ID words.
    These ID words are usually at word location $000 to $8003.
    The SB-Assembler only checks that the Configuration word is stored beyond
    the program memory.
    ID words can only store the 7 least significant bits. The SB-Assembler
    does not check the range. It simply truncates to 7 bits.
    """

    global Asm, Cross

    id2 = 0
    id3 = 0
    id4 = 0

    if dec.Asm.Memory != 0:
        # The .ID directive can only be used in program memory
        errors.DoError(dec.Cross.Name + 'codemem', False)
        return

    if dec.Asm.PH_Address <= dec.Asm.Max_Address:
        # We're still in program memory. We can't have that
        errors.DoError(dec.Cross.Name + 'progmem', False)
        return

    if assem.NowChar() == '#':
        # Ignore the # symbol
        assem.NowChar(True)

    id1 = assem.EvalExpr()[0]

    if assem.MoreParameters():
        # More than 1 ID word are given
        if assem.NowChar() == '#':
            # Ignore the # symbol
            assem.NowChar(True)

        id2 = assem.EvalExpr()[0]

    if assem.MoreParameters():
        # More than 2 ID word are given
        if assem.NowChar() == '#':
            # Ignore the # symbol
            assem.NowChar(True)

        id3 = assem.EvalExpr()[0]

    if assem.MoreParameters():
        # More than 1 ID word are given
        if assem.NowChar() == '#':
            # Ignore the # symbol
            assem.NowChar(True)

        id4 = assem.EvalExpr()[0]

    # Temporarily raise program limit
    limit = dec.Asm.Max_Address
    dec.Asm.Max_Address = 0x1FFFF

    # Save the ID, one nibble at a time
    target.SaveByte(id1 & 0x007F)
    target.SaveByte(0)
    target.SaveByte(id2 & 0x007F)
    target.SaveByte(0)
    target.SaveByte(id3 & 0x007F)
    target.SaveByte(0)
    target.SaveByte(id4 & 0x007F)
    target.SaveByte(0)

    # Restore original limit
    dec.Asm.Max_Address = limit

    NoMore()