def __init__(self, operand_string, instruction, value=None): super().__init__(instruction) self.type = OperandType.EXTENDED self.operand_string = operand_string if value: self.value = value return match = EXTENDED_REGEX.match(self.operand_string) if match: self.value = Value.create_from_str(match.group("value"), instruction) else: self.value = Value.create_from_str(operand_string, instruction)
def __init__(self, operand_string, instruction, value=None): super().__init__(instruction) self.type = OperandType.EXPRESSION self.operand_string = operand_string match = EXPRESSION_REGEX.match(operand_string) if not match: raise ValueError( "[{}] is not a valid expression".format(operand_string)) self.left = Value.create_from_str(match.group("left"), instruction) self.right = Value.create_from_str(match.group("right"), instruction) self.operation = match.group("operation") self.value = NoneValue("")
def __init__(self, operand_string, instruction, value=None): super().__init__(instruction) self.type = OperandType.DIRECT self.operand_string = operand_string if value: self.value = value return match = DIRECT_REGEX.match(self.operand_string) if match: self.value = Value.create_from_str(match.group("value"), instruction) else: self.value = Value.create_from_str(operand_string, instruction) if self.value is None or self.value.byte_len() != 1: raise ValueError( "[{}] is not a direct value".format(operand_string))
def __init__(self, operand_string, instruction, value=None): super().__init__(instruction) self.type = OperandType.RELATIVE if not instruction.is_short_branch and not instruction.is_long_branch: raise OperandTypeError("[{}] is not a branch instruction".format(instruction.mnemonic)) self.operand_string = operand_string self.value = value if value else Value.create_from_str(operand_string, instruction)
def __init__(self, operand_string, instruction): super().__init__(instruction) self.operand_string = operand_string self.type = OperandType.PSEUDO if not instruction.is_pseudo: raise ValueError("[{}] is not a pseudo instruction".format( instruction.mnemonic)) self.value = Value.create_from_str(operand_string, instruction)
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 resolve_symbols(self, symbol_table): if self.left != "": if self.left not in ["A", "B", "D"]: self.left = Value.create_from_str(self.left, self.instruction, default_mode_extended=False) if self.left.is_symbol(): self.left = self.left.resolve(symbol_table) if self.left.is_address_expression() or self.left.is_expression(): self.left = self.left.resolve(symbol_table) return self
def __init__(self, operand_string, instruction, value=None): super().__init__(instruction) self.operand_string = operand_string if value: self.value = value return try: self.value = Value.create_from_str(operand_string, instruction) except ValueTypeError: raise OperandTypeError("[{}] unknown operand type".format(operand_string))
def __init__(self, operand_string, instruction, value=None): super().__init__(instruction) self.type = OperandType.DIRECT self.operand_string = operand_string if value: self.value = value return self.value = Value.create_from_str(operand_string, instruction) if not self.value.is_direct() and not self.value.is_explicit_direct(): raise OperandTypeError("[{}] is not a direct value".format(self.operand_string))
def __init__(self, operand_string, instruction): super().__init__(instruction) self.operand_string = operand_string self.type = OperandType.PSEUDO if not instruction.is_pseudo: raise OperandTypeError("[{}] is not a pseudo instruction".format(instruction.mnemonic)) self.value = NoneValue() if instruction.is_include else Value.create_from_str(operand_string, instruction) if instruction.is_pseudo_define: if self.operand_string.startswith("$") and len(self.operand_string) > 3: self.value = ExtendedNumericValue(self.value.int) elif self.value.hex_len() == 2: self.value = DirectNumericValue(self.value.int)
def __init__(self, operand_string, instruction, value=None): super().__init__(instruction) self.type = OperandType.IMMEDIATE self.operand_string = operand_string if value: self.value = value return match = IMMEDIATE_REGEX.match(operand_string) if not match: raise ValueError( "[{}] is not an immediate value".format(operand_string)) self.value = Value.create_from_str(match.group("value"), instruction)
def __init__(self, operand_string, instruction, value=None): super().__init__(instruction) self.operand_string = operand_string if value: self.value = value return if UNKNOWN_REGEX.search(operand_string): raise ValueError("[{}] invalid operand".format(operand_string)) try: self.value = Value.create_from_str(operand_string, instruction) except ValueError: self.value = NoneValue()
def __init__(self, operand_string, instruction): super().__init__(instruction) self.type = OperandType.INDEXED self.operand_string = operand_string try: self.value = Value.create_from_str(self.operand_string, self.instruction) except ValueTypeError: raise OperandTypeError("[{}] is not an indexed value".format(operand_string)) if not self.value.is_leftright(): raise OperandTypeError("[{}] is not an indexed value".format(operand_string)) self.left = self.value.left self.right = self.value.right
def resolve_symbols(self, symbol_table): if not self.value.is_none() and not self.value.is_leftright(): self.value = self.value.resolve(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, default_mode_extended=False) if self.left.is_symbol(): self.left = self.left.resolve(symbol_table) if self.left.is_address_expression() or self.left.is_expression(): self.left = self.left.resolve(symbol_table) return self
def __init__(self, operand_string, instruction, value=None): super().__init__(instruction) self.type = OperandType.IMMEDIATE self.operand_string = operand_string if value: self.value = value return try: self.value = Value.create_from_str(self.operand_string, instruction) except ValueTypeError: raise OperandTypeError("[{}] is not an immediate value".format(operand_string)) if not self.value.is_immediate(): raise OperandTypeError("[{}] is not an immediate value".format(operand_string))
def __init__(self, operand_string, instruction): super().__init__(instruction) self.type = OperandType.EXTENDED_INDIRECT self.operand_string = operand_string if not (self.operand_string.startswith("[") and self.operand_string.endswith("]")): raise OperandTypeError("[{}] is not an extended indexed value".format(operand_string)) try: stripped_operand_string = operand_string[1:-1] self.value = Value.create_from_str(stripped_operand_string, self.instruction) except ValueTypeError: raise OperandTypeError("[{}] is not an extended indexed value".format(operand_string)) if self.value.is_leftright(): self.left = self.value.left self.right = self.value.right
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 test_create_from_string_16_bit_immediate_instruction_size_correct(self): instruction = Instruction(mnemonic="ZZZ", mode=Mode(imm=0xDE, imm_sz=2), is_16_bit=True) result = Value.create_from_str("$01", instruction) self.assertEqual(4, result.size_hint)
def test_value_create_from_str_raises_on_bad_value(self): with self.assertRaises(ValueTypeError) as context: Value.create_from_str("invalid!", self.instruction) self.assertEqual("[invalid!] is an invalid value", str(context.exception))
def test_value_create_from_str_symbol_correct(self): result = Value.create_from_str("symbol", self.instruction) self.assertTrue(result.is_symbol())
def test_value_create_from_str_string_correct(self): result = Value.create_from_str("'$DEAD'", self.fcc_instruction) self.assertTrue(result.is_string()) self.assertEqual("$DEAD", result.ascii())
def test_create_from_string_8_bit_immediate_instruction_size_correct_string_literal(self): instruction = Instruction(mnemonic="ZZZ", mode=Mode(imm=0xDE, imm_sz=2)) result = Value.create_from_str("#'A", instruction) self.assertEqual(65, result.int) self.assertEqual(2, result.size_hint)
def test_create_from_string_character_literal_works_correctly(self): result = Value.create_from_str("'A") self.assertEqual(65, result.int)
def test_value_create_from_str_numeric_correct(self): result = Value.create_from_str("$DEAD", self.instruction) self.assertTrue(result.is_numeric()) self.assertEqual("DEAD", result.hex())
def translate(self): if not self.instruction.mode.ind: raise OperandTypeError( "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_address(): size += 2 return CodePackage( op_code=NumericValue(self.instruction.mode.ind), post_byte=NumericValue(0x9F), additional=self.value, size=size, max_size=size, ) if not type(self.value) == str and self.value.is_numeric(): size += 2 return CodePackage( op_code=NumericValue(self.instruction.mode.ind), post_byte=NumericValue(0x9F), additional=self.value, size=size, max_size=size, ) raw_post_byte = 0x80 post_byte_choices = [] size = self.instruction.mode.ind_sz max_size = size additional = NoneValue() additional_needs_resolution = False 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 OperandTypeError("[{}] 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 OperandTypeError("[{}] 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 OperandTypeError("[{}] invalid indexed expression".format(self.operand_string)) if type(self.left) == str: self.left = Value.create_from_str(self.left) if self.left.is_address(): additional_needs_resolution = True self.left = NumericValue(self.left.int) if self.left.is_expression(): additional_needs_resolution = True if self.left.is_address_expression(): additional_needs_resolution = True additional = self.left if "PCR" in self.right: if additional_needs_resolution: raw_post_byte |= 0x00 post_byte_choices = [0x9C, 0x9D] max_size += 2 else: size += 2 if self.left.is_extended() else 1 max_size = size raw_post_byte |= 0x9D if self.left.is_extended() else 0x9C else: size += additional.byte_len() max_size = size raw_post_byte |= 0x99 if self.left.is_extended() else 0x98 return CodePackage( op_code=NumericValue(self.instruction.mode.ind), post_byte=NumericValue(raw_post_byte), post_byte_choices=post_byte_choices, additional=additional, size=size, max_size=max_size, additional_needs_resolution=additional_needs_resolution, )