Exemple #1
0
 def assemble_extended_direct_operand(self, operand, opcode_key, statement,
                                      opcode_bytes):
     if isinstance(operand.address, Label):
         result = self.assemble_label_operand(operand.address)
     else:
         result = (hi(operand.address), lo(operand.address))
     return bytes(result)
Exemple #2
0
 def value_to_bytes(self, unsigned_offset, operand_bytes_length):
     if operand_bytes_length == 1:
         result = bytes((unsigned_offset, ))
     elif operand_bytes_length == 2:
         result = bytes((hi(unsigned_offset), lo(unsigned_offset)))
     else:
         assert False, f"Unexpected operand bytes length {operand_bytes_length}"
     return result
Exemple #3
0
def _(statement, asm):
    operand = statement.operand
    opcodes = OPCODES[statement.mnemonic]
    opcode_key = single(operand.codes & opcodes.keys())
    opcode = opcodes[opcode_key]
    asm._opcode_bytes = (opcode, ) if opcode <= 0xFF else (hi(opcode),
                                                           lo(opcode))
    operand_bytes = assemble_operand(operand, opcode_key, asm, statement)
    asm._extend(asm._opcode_bytes + operand_bytes)
Exemple #4
0
 def assemble_label_operand(self, label):
     if label.name in self._label_addresses:
         target_address = self._label_addresses[label.name]
         self._unresolved_labels.discard(label)
         result = (hi(target_address), lo(target_address))
     else:
         self._more_passes_required = True
         self._unresolved_labels.add(label)
         result = (0, 0)
     self._unreferenced_labels.discard(label)
     return result
Exemple #5
0
 def assemble_immediate_operand(self, operand, opcode_key, statement,
                                opcode_bytes):
     if isinstance(operand, Label):
         result = self.assemble_label_operand(operand)
     else:
         assert statement.inherent_register.width in {1, 2}
         if statement.inherent_register.width == 1:
             result = (operand.value, )
         elif statement.inherent_register.width == 2:
             result = (hi(operand.value), lo(operand.value))
         else:
             assert False, f"Unexpected inherent register width {statement.inherent_register.width}"
     return bytes(result)
Exemple #6
0
def _(operand, opcode_key, asm, statement):
    # If we know the address of the label, use it
    if operand.name in asm._label_addresses:
        target_address = asm._label_addresses[operand.name]
        if opcode_key in branch_operand_widths:
            operand_bytes_length = branch_operand_widths[opcode_key]
            offset = target_address - asm.pos - len(
                asm._opcode_bytes) - operand_bytes_length
            unsigned_offset = twos_complement(offset, operand_bytes_length * 8)
            if opcode_key == REL8:
                return (unsigned_offset, )
            elif opcode_key == REL16:
                return (hi(unsigned_offset), lo(unsigned_offset))
        else:
            assert opcode_key is IMM
            return (hi(target_address), lo(target_address))
    else:
        asm._more_passes_required = True
        if opcode_key in branch_operand_widths:
            return (0, ) * branch_operand_widths[opcode_key]
        else:
            assert opcode_key is IMM
            return (0, 0)
Exemple #7
0
    def assemble_indexed_operand(self, operand: Indexed, opcode_key, statement,
                                 opcode_bytes):
        if operand.base in RR:
            rr = RR[operand.base]
            if operand.offset in ACCUMULATOR_OFFSET_POST_BYTE:
                # Accumulator offset
                post_byte = ACCUMULATOR_OFFSET_POST_BYTE[operand.offset]
                post_byte |= rr << 5
                return bytes((post_byte, ))
            elif isinstance(operand.offset, Integral):
                if operand.offset == 0:
                    post_byte = 0b10000100
                    post_byte |= rr << 5
                    return bytes((post_byte, ))
                elif -16 <= operand.offset <= +15:
                    # 5-bit offset
                    post_byte = twos_complement(operand.offset, 5)
                    post_byte |= rr << 5
                    return bytes((post_byte, ))
                elif -128 <= operand.offset <= +127:
                    # 8-bit offset
                    post_byte = 0b10001000
                    post_byte |= rr << 5
                    offset_byte = twos_complement(operand.offset, 8)
                    return bytes((post_byte, offset_byte))
                elif -32768 <= operand.offset <= +32767:
                    # 16-bit offset
                    post_byte = 0b10001001
                    post_byte |= rr << 5
                    offset_bytes = twos_complement(operand.offset, 16)
                    return bytes(
                        (post_byte, hi(offset_bytes), lo(offset_bytes)))
            else:
                raise ValueError(
                    f"Cannot use indexed addressing offset {operand.offset} with base {operand.base}"
                )

        elif isinstance(operand.base, AutoIncrementedRegister):
            if operand.base.register not in RR:
                raise ValueError(
                    f"Cannot use auto pre-/post- increment or decrement with register {operand.base.register}"
                )
            rr = RR[operand.base.register]
            post_byte = INDEX_CREMENT_POST_BYTE[operand.base.delta]
            post_byte |= rr << 5
            return bytes((post_byte, ))
        else:
            raise ValueError(
                f"Cannot use {operand.base} as a base register for indexed addressing modes"
            )
Exemple #8
0
def _(operand, opcode_key, asm, statement):
    assert statement.inherent_register.width in {1, 2}
    if statement.inherent_register.width == 1:
        return (operand.value, )
    elif statement.inherent_register.width == 2:
        return (hi(operand.value), lo(operand.value))