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)
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)