Esempio n. 1
0
class IndexedOperand(Operand):
    def __init__(self, operand_string, instruction):
        super().__init__(instruction)
        self.type = OperandType.INDEXED
        self.operand_string = operand_string
        self.right = ""
        self.left = ""
        if "," not in operand_string or instruction.is_string_define:
            raise ValueError(
                "[{}] is not an indexed value".format(operand_string))
        if len(operand_string.split(",")) != 2:
            raise ValueError(
                "[{}] incorrect number of commas in indexed value".format(
                    operand_string))
        self.left, self.right = operand_string.split(",")

    def resolve_symbols(self, symbol_table):
        if self.left != "":
            if self.left != "A" and self.left != "B" and self.left != "D":
                self.left = Value.create_from_str(self.left, self.instruction)
                if self.left.is_type(ValueType.SYMBOL):
                    self.left = self.get_symbol(self.left.ascii(),
                                                symbol_table)
        return self

    def translate(self):
        if not self.instruction.mode.ind:
            raise ValueError(
                "Instruction [{}] does not support indexed addressing".format(
                    self.instruction.mnemonic))
        raw_post_byte = 0x00
        size = self.instruction.mode.ind_sz
        additional = NoneValue()

        # Determine register (if any)
        if "X" in self.right:
            raw_post_byte |= 0x00
        if "Y" in self.right:
            raw_post_byte |= 0x20
        if "U" in self.right:
            raw_post_byte |= 0x40
        if "S" in self.right:
            raw_post_byte |= 0x60

        if self.left == "":
            raw_post_byte |= 0x80
            if "-" in self.right or "+" in self.right:
                if "+" in self.right:
                    raw_post_byte |= 0x00
                if "++" in self.right:
                    raw_post_byte |= 0x01
                if "-" in self.right:
                    raw_post_byte |= 0x02
                if "--" in self.right:
                    raw_post_byte |= 0x03
            else:
                raw_post_byte |= 0x04

        elif self.left == "A" or self.left == "B" or self.left == "D":
            raw_post_byte |= 0x80
            if self.left == "A":
                raw_post_byte |= 0x06
            if self.left == "B":
                raw_post_byte |= 0x05
            if self.left == "D":
                raw_post_byte |= 0x0B

        else:
            if "+" in self.right or "-" in self.right:
                raise ValueError("[{}] invalid indexed expression".format(
                    self.operand_string))
            if type(self.left) == str:
                self.left = NumericValue(self.left)
            if self.left.is_type(ValueType.ADDRESS):
                raise ValueError(
                    "[{}] cannot translate address in left hand side".format(
                        self.operand_string))
            numeric = self.left
            if numeric.byte_len() == 2:
                size += 2
                if "PC" in self.right:
                    raw_post_byte |= 0x8D
                    additional = numeric
                else:
                    raw_post_byte |= 0x89
                    additional = numeric
            elif numeric.byte_len() == 1:
                if "PC" in self.right:
                    raw_post_byte |= 0x8C
                    additional = numeric
                    size += 1
                else:
                    if numeric.int <= 0x1F:
                        raw_post_byte |= numeric.int
                    else:
                        raw_post_byte |= 0x88
                        additional = numeric
                        size += 1

        return CodePackage(op_code=NumericValue(self.instruction.mode.ind),
                           post_byte=NumericValue(raw_post_byte),
                           additional=additional,
                           size=size)
Esempio n. 2
0
class ExtendedIndexedOperand(Operand):
    def __init__(self, operand_string, instruction, value=None):
        super().__init__(instruction)
        self.type = OperandType.EXTENDED_INDIRECT
        self.operand_string = operand_string
        self.left = None
        self.right = None
        if value is not None:
            self.value = value
            return
        match = EXTENDED_INDIRECT_REGEX.match(self.operand_string)
        if not match:
            raise ValueError(
                "[{}] is not an extended indexed value".format(operand_string))
        parsed_value = match.group("value")
        if "," not in parsed_value:
            self.value = Value.create_from_str(parsed_value, self.instruction)
        elif len(parsed_value.split(",")) == 2:
            self.left, self.right = parsed_value.split(",")
        else:
            raise ValueError(
                "[{}] incorrect number of commas in extended indexed value".
                format(operand_string))

    def resolve_symbols(self, symbol_table):
        if not self.value.is_type(ValueType.NONE) and self.value.is_type(
                ValueType.SYMBOL):
            self.value = self.get_symbol(self.value.ascii(), symbol_table)
            return self

        if self.left and self.left != "":
            if self.left != "A" and self.left != "B" and self.left != "D":
                self.left = Value.create_from_str(self.left, self.instruction)
                if self.left.is_type(ValueType.SYMBOL):
                    self.left = self.get_symbol(self.left.ascii(),
                                                symbol_table)
        return self

    def translate(self):
        if not self.instruction.mode.ind:
            raise ValueError(
                "Instruction [{}] does not support indexed addressing".format(
                    self.instruction.mnemonic))
        size = self.instruction.mode.ind_sz

        if not type(self.value) == str and self.value.is_type(
                ValueType.ADDRESS):
            size += 2
            return CodePackage(op_code=NumericValue(self.instruction.mode.ind),
                               post_byte=NumericValue(0x9F),
                               additional=self.value,
                               size=size)

        if not type(self.value) == str and self.value.is_type(
                ValueType.NUMERIC):
            size += 2
            return CodePackage(op_code=NumericValue(self.instruction.mode.ind),
                               post_byte=NumericValue(0x9F),
                               additional=self.value,
                               size=size)

        raw_post_byte = 0x80
        additional = NoneValue()

        if "X" in self.right:
            raw_post_byte |= 0x00
        if "Y" in self.right:
            raw_post_byte |= 0x20
        if "U" in self.right:
            raw_post_byte |= 0x40
        if "S" in self.right:
            raw_post_byte |= 0x60

        if self.left == "":
            if "-" in self.right or "+" in self.right:
                if self.right == "X+" or self.right == "Y+" or self.right == "U+" or self.right == "S+":
                    raise ValueError(
                        "[{}] not allowed as an extended indirect value".
                        format(self.right))
                if self.right == "-X" or self.right == "-Y" or self.right == "-U" or self.right == "-S":
                    raise ValueError(
                        "[{}] not allowed as an extended indirect value".
                        format(self.right))
                if "++" in self.right:
                    raw_post_byte |= 0x11
                if "--" in self.right:
                    raw_post_byte |= 0x13
            else:
                raw_post_byte |= 0x14

        elif self.left == "A" or self.left == "B" or self.left == "D":
            if self.left == "A":
                raw_post_byte |= 0x16
            if self.left == "B":
                raw_post_byte |= 0x15
            if self.left == "D":
                raw_post_byte |= 0x1B

        else:
            if "+" in self.right or "-" in self.right:
                raise ValueError("[{}] invalid indexed expression".format(
                    self.operand_string))
            if type(self.left) == str:
                self.left = NumericValue(self.left)
            if self.left.is_type(ValueType.ADDRESS):
                raise ValueError(
                    "[{}] cannot translate address in left hand side".format(
                        self.operand_string))
            numeric = self.left
            if numeric.byte_len() == 2:
                size += 2
                if "PC" in self.right:
                    raw_post_byte |= 0x9D
                    additional = numeric
                else:
                    raw_post_byte |= 0x99
                    additional = numeric
            elif numeric.byte_len() == 1:
                size += 1
                if "PC" in self.right:
                    raw_post_byte |= 0x9C
                    additional = numeric
                else:
                    raw_post_byte |= 0x98
                    additional = numeric

        return CodePackage(op_code=NumericValue(self.instruction.mode.ind),
                           post_byte=NumericValue(raw_post_byte),
                           additional=additional,
                           size=size)