def load(self) -> None: if self.all_labels: return # Load default macros self._symbol_table = {**self.all_labels, **self.default_macros} # Get the data from file after removing CVS and empty lines. file_lines = File.open(self.file_name) # Create a list of Line objects lines = Line.from_file(file_lines) # Remove suffix like &CG1 from label and only keep the accepted commands. lines = [ line.remove_suffix() for line in lines if line.command in self._command ] # Create LabelReference for each label and add it to dummy macro data_map. second_list: List[Tuple[Line, int]] = list() for line in lines: try: self._command[line.command](line) except EquDataTypeHasAmpersandError: pass except NotFoundInSymbolTableError: second_list.append((line, self._location_counter)) # Add the saved equates which were not added in the first pass self._second_pass("EQU", second_list) # Add the saved DS which were not added in the first pass self._second_pass("DS", second_list) return
def reg_branch(self, line: Line) -> RegisterBranch: operand1, operand2 = line.split_operands() reg = Register(operand1) if not reg.is_valid(): raise RegisterInvalidError branch = self.get_branch(operand2) return RegisterBranch(line, reg, branch)
def branch_condition(self, line: Line) -> BranchCondition: operand1, operand2 = line.split_operands() mask = self.get_value(operand1) if not 0 <= mask <= BranchGeneric.MAX_VALUE: raise ConditionMaskError branch = self.get_branch(operand2) return BranchCondition(line, branch, mask)
def reg_reg(line: Line) -> RegisterRegister: operand1, operand2 = line.split_operands() reg1 = Register(operand1) reg2 = Register(operand2) if not reg1.is_valid() or not reg2.is_valid(): raise RegisterInvalidError return RegisterRegister(line, reg1, reg2)
def reg_field_index(self, line: Line) -> RegisterFieldIndex: operand1, operand2 = line.split_operands() reg = Register(operand1) if not reg.is_valid(): raise RegisterInvalidError field = self.field_index(operand2) return RegisterFieldIndex(line, reg, field)
def field_data(self, line: Line) -> FieldData: operand1, operand2 = line.split_operands() field = self.field_base_dsp(operand1) data = self.get_value(operand2) if not 0 <= data <= FieldData.MAX_VALUE: raise DataInvalidError return FieldData(line, field, data)
def reg_reg_field(self, line: Line) -> RegisterRegisterField: operand1, operand2, operand3 = line.split_operands() reg1 = Register(operand1) reg2 = Register(operand2) if not reg1.is_valid() or not reg2.is_valid(): raise RegisterInvalidError field = self.field_base_dsp(operand3) return RegisterRegisterField(line, reg1, reg2, field)
def field_bits(self, line: Line) -> FieldBits: try: operand1, operand2 = line.split_operands() except ValueError: raise AssemblyError(line) field = self.field_base_dsp(operand1) bits = self.get_bits(operand2) return FieldBits(line, field, bits)
def reg_reg_branch(self, line: Line) -> RegisterRegisterBranch: operand1, operand2, operand3 = line.split_operands() reg1 = Register(operand1) reg2 = Register(operand2) if not reg1.is_valid() or not reg2.is_valid(): raise RegisterInvalidError branch = self.get_branch(operand3) return RegisterRegisterBranch(line, reg1, reg2, branch)
def branch_condition_reg(self, line: Line) -> BranchConditionRegister: operand1, operand2 = line.split_operands() mask = self.get_value(operand1) if not 0 <= mask <= BranchGeneric.MAX_VALUE: raise ConditionMaskError reg = Register(operand2) if not reg.is_valid(): raise RegisterInvalidError return BranchConditionRegister(line, mask, reg)
def reg_label(self, line: Line) -> RegisterFieldIndex: reg_index: RegisterFieldIndex = self.reg_field_index(line) _, operand2 = line.split_operands() if operand2.startswith("*"): expression = line.label + operand2[1:] reg_index.field.dsp = self.get_value(expression) reg_index.field.base = Register("R8") reg_index.field.name = self.get_field_name(reg_index.field.base, reg_index.field.dsp, 4) return reg_index
def using(self, line: Line) -> None: operands = line.split_operands() if len(operands) != 2: raise UsingInvalidError base = Register(operands[1]) if not base.is_valid(): raise UsingInvalidError dsect_name = self.name if operands[0] == '*' else operands[0] self.set_using(dsect_name, base)
def globz(self, line: Line) -> RegisterData: globc = self.key_value(line) reg = globc.get_value("REGR") or globc.get_value("REGS") or globc.get_value("REGC") base = Register(reg) if not base.is_valid(): raise RegisterInvalidError(line) self.load_macro("GLOBAL", base=reg) line.command = "LHI" return RegisterData(line, base, config.GLOBAL)
def reg_data_field(self, line: Line) -> RegisterDataField: operand1, operand2, operand3 = line.split_operands() reg = Register(operand1) if not reg.is_valid(): raise RegisterInvalidError data = self.get_value(operand2) if not 0 <= data <= RegisterDataField.MAX_VALUE: raise DataInvalidError field = self.field_base_dsp(operand3) return RegisterDataField(line, reg, data, field)
def drop(self, line: Line) -> None: operands = line.split_operands() registers = [Register(operand) for operand in operands] if any(not register.is_valid() for register in registers): raise DropInvalidError(line) for drop_register in registers: self._using = { macro_name: register for macro_name, register in self._using.items() if register.reg != drop_register.reg }
def field_len_field(self, line: Line) -> FieldLenField: try: operand1, operand2 = line.split_operands() except ValueError: raise AssemblyError(line) field_len = self.field_len(operand1, FieldLenField.MAX_LEN) try: field = self.field_base_dsp(operand2) except NotFoundInSymbolTableError: raise NotFoundInSymbolTableError(line) return FieldLenField(line, field_len, field)
def test_reg_reg(self): seg: Segment = segments['TS02'] self.assertRaises(RegisterInvalidError, seg.reg_reg, Line.from_line(' LR R16,R15')) self.assertRaises(RegisterInvalidError, seg.reg_reg, Line.from_line(' LR R1,RBD')) seg.assemble() # Check R02,RDA node = seg.nodes['TS020010'] self.assertEqual(0x008, seg.lookup('TS020010').dsp) self.assertEqual(2, seg.lookup('TS020010').length) self.assertEqual('R2', node.reg1.reg) self.assertEqual('R14', node.reg2.reg) # Check RGA,2 with JNZ TS020010 & it contains multiple instruction before JNZ node = seg.nodes['TS020020'] self.assertEqual(0x00A, seg.lookup('TS020020').dsp) self.assertEqual('R2', node.reg1.reg) self.assertEqual('R2', node.reg2.reg) node = seg.nodes['TS020020.5'] self.assertEqual('JNZ', node.on) self.assertSetEqual({'TS020030', 'TS020040'}, node.next_labels) for index in range(1, 5): node = seg.nodes[f"TS020020.{index}"] self.assertEqual('R6', node.reg1.reg) self.assertEqual('LR', node.command) # Check 4,R04 node = seg.nodes['TS020030'] self.assertEqual(0x018, seg.lookup('TS020030').dsp) self.assertEqual(2, seg.lookup('TS020030').length) self.assertEqual('R4', node.reg1.reg) self.assertEqual('R4', node.reg2.reg) self.assertSetEqual({'TS020040'}, node.next_labels) # Check DS 0H node = seg.nodes['TS020040'] self.assertEqual(0x01A, seg.lookup('TS020040').dsp) self.assertEqual('TS020040', node.label) self.assertEqual('DS', node.command) # Check BCTR R5,0 node = seg.nodes['TS020040.1'] self.assertEqual('R5', node.reg1.reg) self.assertEqual('R0', node.reg2.reg)
def reg_data(self, line: Line) -> RegisterData: operand1, operand2 = line.split_operands() reg = Register(operand1) if not reg.is_valid(): raise RegisterInvalidError data = self.get_value(operand2) max_unsigned_value = (1 << RegisterData.DATA_LENGTH) - 1 min_signed_value = -1 << RegisterData.DATA_LENGTH - 1 max_signed_value = (1 << RegisterData.DATA_LENGTH - 1) - 1 if not min_signed_value <= data <= max_unsigned_value: raise DataInvalidError((line, data)) if data > max_signed_value: data -= max_unsigned_value + 1 # Two"s complement negative number return RegisterData(line, reg, data)
def ds(self, line: Line) -> List[Dc]: operands = line.split_operands() try: ds: Dc = self._get_dc(operands[0]) except DcInvalidError: raise DcInvalidError(line) dc_list: List[Dc] = [ds] if line.label: self.add_label(line.label, ds.start, ds.length, self.name) if len(operands) > 1: for operand in operands[1:]: dc_list.append(self._get_dc( operand)) # Increment location counter for multiple values return dc_list
def datas(self, line: Line) -> None: operands = line.split_operands() if len(operands) < 3: raise UsingInvalidError if not Register(operands[0]).is_valid(): raise UsingInvalidError suffix: Optional[str] = operands[1] if operands[1] else None for operand in operands[2:]: if operand not in macros: raise UsingInvalidError(line) self.load_macro(operand, base=operands[0], suffix=suffix, override=False) return
def equ(self, line: Line) -> None: if line.label is None: raise EquLabelRequiredError(line) operands = line.split_operands() dsp_operand = operands[0] length = 1 if dsp_operand[0] == '&' or (len(dsp_operand) > 1 and dsp_operand[1] == "'" and dsp_operand[0] != 'L' and '&' in dsp_operand): raise EquDataTypeHasAmpersandError(line) if len(operands) > 1: length = self.get_value(operands[1]) try: self.add_label(line.label, self.get_value(dsp_operand), length, self.name, self.is_based(dsp_operand)) except NotFoundInSymbolTableError: raise NotFoundInSymbolTableError(line) return
def assemble(self) -> None: if self.nodes: return # Default processing self.set_using(self.name, Register("R8")) self.load_macro("EB0EB", base="R9") # Get the data from line after removing CVS and empty lines. file_lines = File.open(self.file_name) # Create a list of Line objects lines = Line.from_file(file_lines) # First pass - Build Symbol Table and generate constants. self._build_symbol_table(lines) # Update index of each line lines = self._update_index(lines) # Generate constants self._generate_constants() # Second pass - Assemble instructions and populates nodes. self._assemble_instructions(lines) return
def test_segment(self): self.maxDiff = None seg: Segment = segments[self.SEG_NAME] lines = Line.from_file(File.open(segments[self.SEG_NAME].file_name)) instructions = [ line.command for line in lines if line.command not in macros ] unknown_in_assembly = { command for command in instructions if command not in seg.all_commands } self.assertSetEqual(set(), unknown_in_assembly, "\nUnknown in assembly.") seg.assemble() unknown_in_execute = { node.command for _, node in seg.nodes.items() if node.command not in TpfServer()._ex } self.assertSetEqual(set(), unknown_in_execute, "\nUnknown in execute.")
def key_value(self, line: Line) -> KeyValue: operands_list: List[str] = line.split_operands() operands: List[Tuple[str, Union[Optional[str], List[Tuple[str, Optional[str]]]]]] = list() branches: List[str] = list() for operand in operands_list: key_value = re.split(r"=(?![^()]*[)])", operand) if len(key_value) > 1 and key_value[1].startswith("(") and key_value[1].endswith(")"): sub_operands = key_value[1][1:-1] operands.append((key_value[0], list())) for sub_operand in sub_operands.split(","): sub_key_value = sub_operand.split("=") value = sub_key_value[1] if len(sub_key_value) > 1 else None operands[-1][1].append((sub_key_value[0], value)) if self.is_branch(value): branches.append(value) else: value = key_value[1] if len(key_value) > 1 else None operands.append((key_value[0], value)) if self.is_branch(value): branches.append(value) return KeyValue(line, operands, branches)
def test_subroutine(self): seg: Segment = segments['TS09'] self.assertRaises(RegisterInvalidError, seg.reg_branch, Line.from_line(" BAS R16,TS09S100")) self.assertRaises(RegisterInvalidError, seg.branch_mnemonic_reg, Line.from_line(" BR -1")) seg.assemble() # BAS R4,TS09S100 node = seg.nodes['TS090010.1'] self.assertEqual('R4', node.reg.reg) self.assertEqual('TS09S100', node.branch.name) self.assertEqual('R8', node.branch.base.reg) # JAS R2,TS09S100 node = seg.nodes['TS090010.2'] self.assertEqual('R2', node.reg.reg) self.assertEqual('TS09S200', node.branch.name) self.assertEqual('R8', node.branch.base.reg) # BZR R4 node = seg.nodes['TS09S100.2'] self.assertIsNone(node.goes) self.assertEqual({'TS09S100.3'}, node.next_labels) self.assertEqual('BZR', node.on) self.assertEqual('R4', node.reg.reg) self.assertEqual(8, node.mask) # AHI R2,1 self.assertEqual('AHI', seg.nodes['TS09S100.3'].command) # LTR R1,R1 self.assertEqual('LTR', seg.nodes['TS09S100.4'].command) # NOPR 0 node = seg.nodes['TS09S100.5'] self.assertEqual('NOPR', node.command) self.assertIsNone(node.goes) self.assertEqual({'TS09S100.6'}, node.next_labels) self.assertEqual('NOPR', node.on) self.assertEqual('R0', node.reg.reg) self.assertEqual(0, node.mask) # AHI R2,1 self.assertEqual('AHI', seg.nodes['TS09S100.6'].command) # BR R4 node = seg.nodes['TS09S100.7'] self.assertEqual('BR', node.command) self.assertIsNone(node.goes) self.assertEqual(set(), node.next_labels) self.assertEqual('BR', node.on) self.assertEqual('R4', node.reg.reg) self.assertEqual(15, node.mask) # BCR 0,R2 node = seg.nodes['TS09S200.1'] self.assertEqual('BCR', node.command) self.assertIsNone(node.goes) self.assertEqual({'TS09S200.2'}, node.next_labels) self.assertEqual('BCR', node.on) self.assertEqual('R2', node.reg.reg) self.assertEqual(0, node.mask) # BCR 15,R2 node = seg.nodes['TS09S200.2'] self.assertEqual('BCR', node.command) self.assertIsNone(node.goes) self.assertEqual('TS09S200.3', node.fall_down) self.assertEqual('R2', node.reg.reg) self.assertEqual(15, node.mask) # BCR 8,R2 node = seg.nodes['TS09S200.3'] self.assertIsNone(node.goes) self.assertEqual({'TS09S200.4'}, node.next_labels) self.assertEqual('R2', node.reg.reg) self.assertEqual('BCR', node.on) self.assertEqual(8, node.mask)
def test_field_variants(self): seg: Segment = segments['TS04'] self.assertRaises(FieldLengthInvalidError, seg.field_len_field, Line.from_line(" MVC 2(257,R3),26(R4)")) self.assertRaises(FieldLengthInvalidError, seg.field_len_field, Line.from_line(" OC EBW000(,R4),EBW000")) self.assertRaises(FieldLengthInvalidError, seg.field_len_field, Line.from_line(" OC EBW000(,R4),EBW000")) seg.assemble() # Check FieldLenField # XC CE1WKA,CE1WKA node = seg.nodes['TS040100.1'] self.assertEqual('CE1WKA', node.field_len.name) self.assertEqual('R9', node.field_len.base.reg) self.assertEqual(0x8, node.field_len.dsp) self.assertEqual(211, node.field_len.length) # CLC L'CE1WKA+EBW000+4(CE1FA1-CE1FA0,R9),CE1FA1(R9) with BNE TS040110 node = seg.nodes['TS040100.2'] self.assertEqual('R9_AREA', node.field_len.name) self.assertEqual('R9', node.field_len.base.reg) self.assertEqual(0xe0, node.field_len.dsp) self.assertEqual(7, node.field_len.length) self.assertEqual('R9_AREA', node.field.name) self.assertEqual(0xe8, node.field.dsp) node = seg.nodes['TS040100.3'] self.assertEqual('BNE', node.on) self.assertEqual('TS040110', node.goes) # MVC EBW000(L'CE1WKA-1),EBW001 node = seg.nodes['TS040100.4'] self.assertEqual('EBW000', node.field_len.name) self.assertEqual('R9', node.field_len.base.reg) self.assertEqual(0x8, node.field_len.dsp) self.assertEqual(210, node.field_len.length) self.assertEqual('EBW001', node.field.name) self.assertEqual(0x9, node.field.dsp) self.assertEqual('TS040100.5', node.fall_down) # CLC 2(2,R2),=C'I/' with BE TS040110 node = seg.nodes['TS040100.5'] self.assertEqual('R2_AREA', node.field_len.name) self.assertEqual('R2', node.field_len.base.reg) self.assertEqual(2, node.field_len.dsp) self.assertEqual(1, node.field_len.length) self.assertEqual('R8', node.field.base.reg) literal = node.field.name self.assertTrue(seg.lookup(literal).is_literal) self.assertEqual( 'I/', seg.get_constant_bytes(literal).decode(encoding='cp037')) node = seg.nodes['TS040100.6'] self.assertEqual('TS040110', node.goes) self.assertEqual('BE', node.on) # CLC =C'C/',2(R2) with BL TS040110 node = seg.nodes['TS040100.7'] self.assertEqual('R2_AREA', node.field.name) self.assertEqual('R2', node.field.base.reg) self.assertEqual(2, node.field.dsp) self.assertEqual('R8', node.field_len.base.reg) self.assertEqual(1, node.field_len.length) literal = node.field_len.name self.assertTrue(seg.lookup(literal).is_literal) self.assertEqual( 'C/', seg.get_constant_bytes(literal).decode(encoding='cp037')) node = seg.nodes['TS040100.8'] self.assertEqual('TS040110', node.goes) self.assertEqual('BL', node.on) # MVC 23(L'CE1WKA,R3),26(R4) node = seg.nodes['TS040110.1'] self.assertEqual('R3_AREA', node.field_len.name) self.assertEqual('R3', node.field_len.base.reg) self.assertEqual(23, node.field_len.dsp) self.assertEqual(211, node.field_len.length) self.assertEqual('R4_AREA', node.field.name) self.assertEqual(26, node.field.dsp) # Check FieldLenFieldLen # PACK CE1DCT,CE1DET node = seg.nodes['TS040200.1'] self.assertEqual('CE1DCT', node.field_len1.name) self.assertEqual('CE1DET', node.field_len2.name) self.assertEqual('R9', node.field_len2.base.reg) self.assertEqual(15, node.field_len1.length) self.assertEqual(3, node.field_len2.length) self.assertEqual(0x374, node.field_len1.dsp) self.assertEqual(0x370, node.field_len2.dsp) # UNPK EBW008-EBW000(L'CE1FA1,R3),10(16,R15) node = seg.nodes['TS040200.2'] self.assertEqual('R3_AREA', node.field_len1.name) self.assertEqual('R15_AREA', node.field_len2.name) self.assertEqual('R15', node.field_len2.base.reg) self.assertEqual(3, node.field_len1.length) self.assertEqual(15, node.field_len2.length) self.assertEqual(8, node.field_len1.dsp) self.assertEqual(10, node.field_len2.dsp) # Check FieldData # CLI EBW000,#$BCLASS with BNE TS040310 node = seg.nodes['TS040300.1'] self.assertEqual('EBW000', node.field.name) self.assertEqual(0xC2, node.data) node = seg.nodes['TS040300.2'] self.assertEqual('BNE', node.on) self.assertEqual('TS040310', node.goes) # MVI 23(R4),L'CE1WKA node = seg.nodes['TS040300.3'] self.assertEqual('R4_AREA', node.field.name) self.assertEqual('R4', node.field.base.reg) self.assertEqual(23, node.field.dsp) self.assertEqual(212, node.data)
def test_field_bits(self): seg_name = 'TS01' seg: Segment = segments[seg_name] self.assertRaises(FieldLengthInvalidError, seg.field_bits, Line.from_line(" OI 23(2,R9),1")) self.assertRaises(RegisterInvalidError, seg.field_bits, Line.from_line(" OI 23(L'EBW001),1")) self.assertRaises(NotFoundInSymbolTableError, seg.field_bits, Line.from_line(" OI ERROR_FIELD,1")) self.assertRaises(BitsInvalidError, seg.field_bits, Line.from_line(" OI 8(R9),250+250")) self.assertRaises(FieldDspInvalidError, seg.field_bits, Line.from_line(" OI -1(R2),1")) self.assertRaises(FieldDspInvalidError, seg.field_bits, Line.from_line(" OI 4096(R2),1")) seg.assemble() # Check EBW008-EBW000(9),1 node = seg.nodes['$$TS01$$.1'] self.assertEqual('R9', node.field.base.reg) self.assertEqual(8, node.field.dsp) self.assertEqual('R9_AREA', node.field.name) self.assertTrue(node.bits.bit7.on) self.assertEqual("#BIT7", node.bits.bit7.name) # Check EBW000,X'80' node = seg.nodes['$$TS01$$.2'] self.assertEqual('R9', node.field.base.reg) self.assertEqual(8, node.field.dsp) self.assertEqual('EBW000', node.field.name) self.assertTrue(node.bits.bit0.on) self.assertEqual("#BIT0", node.bits.bit0.name) self.assertEqual(0x80, node.bits.value) # Check 23(R9),23 node = seg.nodes['$$TS01$$.3'] self.assertEqual('R9_AREA', node.field.name) self.assertEqual('R9', node.field.base.reg) self.assertEqual(23, node.field.dsp) self.assertTrue(node.bits.bit7.on) self.assertEqual("#BIT3=0x10+#BIT5=0x04+#BIT6=0x02+#BIT7=0x01", str(node.bits)) self.assertEqual(0b00010111, node.bits.value) # Check EBT000+L'CE1DSTMP(R9),CE1SEW+CE1CPS+CE1DTX+CE1SNP node = seg.nodes['$$TS01$$.4'] self.assertEqual('R9_AREA', node.field.name) self.assertEqual('R9', node.field.base.reg) self.assertEqual(0x78, node.field.dsp) self.assertEqual("CE1SEW=0x80+CE1CPS=0x40+CE1DTX=0x20+CE1SNP=0x10", str(node.bits)) self.assertEqual(0xf0, node.bits.value) self.assertFalse(node.bits.bit6.on) # Check L'EBW000+3+EBW008-EBW000(9),X'FF'-CE1SEW-CE1CPS node = seg.nodes['$$TS01$$.5'] self.assertEqual('R9_AREA', node.field.name) self.assertEqual('R9', node.field.base.reg) self.assertEqual(0x0c, node.field.dsp) self.assertEqual("#BITA-CE1SEW=0x80-CE1CPS=0x40", str(node.bits)) self.assertEqual(0x3f, node.bits.value) self.assertTrue(node.bits.bit6.on) # Check TM with BZ TS010010 node = seg.nodes['$$TS01$$.7'] self.assertEqual('TS010010', node.goes) self.assertEqual('BZ', node.on) self.assertSetEqual({'$$TS01$$.8', 'TS010010'}, node.next_labels) # Check fall down to label node = seg.nodes['$$TS01$$.8'] self.assertEqual('TS010010', node.fall_down) # Check TS010010 EQU * node = seg.nodes['TS010010'] self.assertEqual('TS010010', node.label) self.assertEqual('EQU', node.command) # Check OI EBT000,1 self.assertEqual('EBT000', seg.nodes['TS010010.1'].field.name) # Check OI PD0_C_ITM,1 self.assertEqual(0xC1, seg.nodes['TS010010.3'].field.dsp) # Check OI PD0_C_ITM,1 self.assertEqual('PD0_C_ITM', seg.nodes['TS010010.4'].field.name) self.assertEqual('R0', seg.nodes['TS010010.4'].field.base.reg) # Check OI EBW000,#PD0_FLDEMP self.assertEqual(0x03, seg.nodes['TS010010.5'].bits.value)
def test_branch_condition(self): seg: Segment = segments['TS06'] seg.add_label('TS06INVALID', 0, 0, 'NOT_TS06') self.assertRaises(BranchInvalidError, seg.branch_mnemonic, Line.from_line(' BNZ TS06INVALID')) self.assertRaises(ConditionMaskError, seg.branch_condition, Line.from_line(' JC -1,TS06E100')) self.assertRaises(ConditionMaskError, seg.branch_condition, Line.from_line(' BC 16,TS06E100')) self.assertRaises(RegisterInvalidError, seg.branch_condition, Line.from_line(' JC 14,8(-1)')) self.assertRaises(NotFoundInSymbolTableError, seg.branch_mnemonic, Line.from_line(' JE 12,TS061000')) self.assertRaises(ValueError, seg.branch_condition, Line.from_line(' BC TS060100')) self.assertRaises(NotFoundInSymbolTableError, seg.branch_condition, Line.from_line(' JC A,TS060100')) seg.assemble() # LTR R1, R1 with multiple goes node = seg.nodes['TS060100.1'] self.assertEqual('LTR', node.command) self.assertEqual('R1', node.reg1.reg) self.assertEqual('R1', node.reg2.reg) # LR R2,R3 node = seg.nodes['TS060100.2'] self.assertEqual('LR', node.command) self.assertEqual('R2', node.reg1.reg) self.assertEqual('R3', node.reg2.reg) # JNZ TS060120 node = seg.nodes['TS060100.3'] self.assertEqual('TS060100.4', node.fall_down) self.assertEqual('JNZ', node.on) self.assertEqual('TS060120', node.goes) self.assertEqual('JNZ', node.command) self.assertEqual('TS060120', node.branch.name) self.assertEqual(7, node.mask) self.assertEqual('R0', node.branch.index.reg) # LR R3,R4 node = seg.nodes['TS060100.4'] self.assertEqual('R3', node.reg1.reg) self.assertEqual('R4', node.reg2.reg) # JP TS060130 node = seg.nodes['TS060100.5'] self.assertEqual('JP', node.command) self.assertEqual('TS060130', node.branch.name) self.assertEqual(2, node.mask) node = seg.nodes['TS060100.6'] # LR R5,R6 self.assertEqual('R5', node.reg1.reg) self.assertEqual('R6', node.reg2.reg) # LTR R2, R2 with a single goes node = seg.nodes['TS060110'] self.assertEqual('R2', node.reg2.reg) # LR R2,R3 node = seg.nodes['TS060110.1'] self.assertEqual('R2', node.reg1.reg) self.assertEqual('R3', node.reg2.reg) # JC 7,TS060130 node = seg.nodes['TS060110.2'] self.assertSetEqual({'TS060110.3', 'TS060130'}, node.next_labels) self.assertEqual('TS060110.3', node.fall_down) self.assertEqual('JC', node.on) self.assertEqual('TS060130', node.goes) self.assertEqual('JC', node.command) self.assertEqual('TS060130', node.branch.name) self.assertEqual(7, node.mask) # LR R3,R4 node = seg.nodes['TS060110.3'] self.assertEqual('R3', node.reg1.reg) self.assertEqual('R4', node.reg2.reg) # J TS060100 node = seg.nodes['TS060110.4'] self.assertEqual('J', node.command) self.assertEqual('TS060100', node.branch.name) self.assertEqual(15, node.mask) self.assertSetEqual({'TS060100'}, node.next_labels) self.assertIsNone(node.fall_down) self.assertEqual('J', node.on) self.assertEqual('TS060100', node.goes) # LTR R3,R3 with a single goes node = seg.nodes['TS060120.1'] self.assertEqual('R3', node.reg2.reg) # BC 8,TS060110 node = seg.nodes['TS060120.2'] self.assertSetEqual({'TS060120.3', 'TS060110'}, node.next_labels) self.assertEqual('TS060120.3', node.fall_down) self.assertEqual('BC', node.on) self.assertEqual('TS060110', node.goes) self.assertEqual('TS060120.2', node.label) self.assertEqual('BC', node.command) self.assertEqual('TS060110', node.branch.name) self.assertEqual(8, node.mask) # AR R5,R2 with a single goes node = seg.nodes['TS060120.3'] self.assertEqual('R2', node.reg2.reg) # LR R2,R4 node = seg.nodes['TS060120.4'] self.assertEqual('R2', node.reg1.reg) self.assertEqual('R4', node.reg2.reg) # BC 2,TS060120 node = seg.nodes['TS060120.5'] self.assertSetEqual({'TS060120', 'TS060130'}, node.next_labels) self.assertEqual('TS060130', node.fall_down) self.assertEqual('BC', node.on) self.assertEqual('TS060120', node.goes) self.assertEqual('BC', node.command) self.assertEqual('TS060120', node.branch.name) self.assertEqual(2, node.mask) # LTR R4,R4 with single goes node = seg.nodes['TS060130.1'] self.assertEqual('R4', node.reg2.reg) # BNO TS060100 node = seg.nodes['TS060130.2'] self.assertSetEqual({'TS060100', 'TS060130.3'}, node.next_labels) self.assertEqual('TS060130.3', node.fall_down) self.assertEqual('BNO', node.on) self.assertEqual('TS060100', node.goes) self.assertEqual('BNO', node.command) self.assertEqual('TS060100', node.branch.name) self.assertEqual(14, node.mask) # JC 15,TS060120 node = seg.nodes['TS060130.3'] self.assertEqual('JC', node.command) self.assertEqual('JC', node.on) self.assertEqual('TS060130.4', node.fall_down) self.assertEqual('TS060120', node.branch.name) self.assertEqual(15, node.mask) self.assertEqual('TS060120', node.goes) # BC 15,TS060120 node = seg.nodes['TS060130.6'] self.assertEqual('BC', node.command) self.assertEqual('BC', node.on) self.assertEqual('TS060130.7', node.fall_down) self.assertEqual('TS060120', node.branch.name) self.assertEqual(15, node.mask) self.assertEqual('TS060120', node.goes) # LR R3,R5 node = seg.nodes['TS060130.7'] self.assertEqual('R3', node.reg1.reg) self.assertEqual('R5', node.reg2.reg) # BACKC node = seg.nodes['TS060130.8'] self.assertEqual('BACKC', node.command) # B TS060100 node = seg.nodes['TS060130.9'] self.assertEqual('B', node.command) self.assertEqual('TS060100', node.branch.name) self.assertEqual(15, node.mask) self.assertSetEqual({'TS060100'}, node.next_labels) self.assertIsNone(node.fall_down) self.assertEqual('B', node.on) self.assertEqual('TS060100', node.goes) # Check TS060140 # BC 0,TS060130 node = seg.nodes['TS060140.3'] self.assertEqual('BC', node.command) self.assertEqual('TS060130', node.goes) self.assertEqual(0, node.mask) self.assertSetEqual({'TS060140.4', 'TS060130'}, node.next_labels) self.assertEqual('TS060140.4', node.fall_down) self.assertEqual('BC', node.on) # NOP TS060130 node = seg.nodes['TS060140.6'] self.assertEqual('NOP', node.command) self.assertEqual('TS060130', node.goes) self.assertEqual(0, node.mask) self.assertSetEqual({'TS060140.7', 'TS060130'}, node.next_labels) self.assertEqual('TS060140.7', node.fall_down) # JC 0,TS060130 node = seg.nodes['TS060140.9'] self.assertEqual('JC', node.command) self.assertEqual('TS060130', node.goes) self.assertEqual(0, node.mask) self.assertSetEqual({'TS060140.10', 'TS060130'}, node.next_labels) self.assertEqual('TS060140.10', node.fall_down) # JNOP TS060130 node = seg.nodes['TS060140.12'] self.assertEqual('JNOP', node.command) self.assertEqual('TS060130', node.goes) self.assertEqual(0, node.mask) self.assertSetEqual({'TS060150', 'TS060130'}, node.next_labels) self.assertEqual('TS060150', node.fall_down) # B TS06E100(R14) node = seg.nodes['TS060150'] self.assertEqual('B', node.command) self.assertEqual(15, node.mask) self.assertEqual('TS06E100', node.branch.name) self.assertEqual('R8', node.branch.base.reg) self.assertEqual('R14', node.branch.index.reg)
def root_line(self) -> Line: line = Line.from_line(f"{self.root_label()} EQU *") line.index = 0 return line
def test_reg_field_index(self): seg: Segment = segments['TS03'] self.assertRaises(RegisterInvalidError, seg.reg_field_index, Line.from_line(' LA R1,2(R1,R3,R4)')) self.assertRaises(RegisterInvalidError, seg.reg_field_index, Line.from_line(' L R16,0(R9)')) self.assertRaises(RegisterIndexInvalidError, seg.reg_field_index, Line.from_line(' LA R1,2(ABC,R1)')) seg.assemble() # L R1,CE1CR1 node = seg.nodes['$$TS03$$.1'] self.assertEqual('R1', node.reg.reg) self.assertEqual('CE1CR1', node.field.name) self.assertEqual('R9', node.field.base.reg) self.assertEqual(0x170, node.field.dsp) self.assertEqual('R0', node.field.index.reg) # LA R2,2 node = seg.nodes['$$TS03$$.2'] self.assertEqual('R2', node.reg.reg) self.assertEqual('2', node.field.name) self.assertEqual('R0', node.field.base.reg) self.assertEqual(2, node.field.dsp) self.assertEqual('R0', node.field.index.reg) # IC R1,3(R3,R4) node = seg.nodes['$$TS03$$.3'] self.assertEqual('R1', node.reg.reg) self.assertEqual('R4_AREA', node.field.name) self.assertEqual('R4', node.field.base.reg) self.assertEqual(3, node.field.dsp) self.assertEqual('R3', node.field.index.reg) # STH R3,L'CE1CR1 node = seg.nodes['$$TS03$$.4'] self.assertEqual('R3', node.reg.reg) self.assertEqual("L'CE1CR1", node.field.name) self.assertEqual('R0', node.field.base.reg) self.assertEqual(4, node.field.dsp) self.assertEqual('R0', node.field.index.reg) # N R5,EBW008-EB0EB(R6) node = seg.nodes['$$TS03$$.5'] self.assertEqual('R5', node.reg.reg) self.assertEqual('R6_AREA', node.field.name) self.assertEqual('R6', node.field.base.reg) self.assertEqual(16, node.field.dsp) self.assertEqual('R0', node.field.index.reg) # ST R2,L'EBW000+2(R6,) node = seg.nodes['$$TS03$$.6'] self.assertEqual('R2', node.reg.reg) self.assertEqual('R6_AREA', node.field.name) self.assertEqual('R6', node.field.base.reg) self.assertEqual(3, node.field.dsp) self.assertEqual('R0', node.field.index.reg) # STC 5,EBT000(0,9) node = seg.nodes['$$TS03$$.7'] self.assertEqual('R5', node.reg.reg) self.assertEqual('R9_AREA', node.field.name) self.assertEqual('R9', node.field.base.reg) self.assertEqual(0x070, node.field.dsp) self.assertEqual('R0', node.field.index.reg) # STC CVB RGC,L'CE1CR1+EBW000(,REB) node = seg.nodes['$$TS03$$.8'] self.assertEqual('R4', node.reg.reg) self.assertEqual('R9_AREA', node.field.name) self.assertEqual('R9', node.field.base.reg) self.assertEqual(12, node.field.dsp) self.assertEqual('R0', node.field.index.reg) # CVD R06,6000(R00,R00) node = seg.nodes['$$TS03$$.9'] self.assertEqual('R6', node.reg.reg) self.assertEqual('R0_AREA', node.field.name) self.assertEqual('R0', node.field.base.reg) self.assertEqual(4095, node.field.dsp) self.assertEqual('R0', node.field.index.reg) # CH R15,4(R15) node = seg.nodes['$$TS03$$.10'] self.assertEqual('R15', node.reg.reg) self.assertEqual('R15_AREA', node.field.name) self.assertEqual('R15', node.field.base.reg) self.assertEqual(4, node.field.dsp) self.assertEqual('R0', node.field.index.reg) # L R1,CE1CR1(R3) node = seg.nodes['$$TS03$$.11'] self.assertEqual('R1', node.reg.reg) self.assertEqual('CE1CR1', node.field.name) self.assertEqual('R9', node.field.base.reg) self.assertEqual(0x170, node.field.dsp) self.assertEqual('R3', node.field.index.reg) # L R1,12 node = seg.nodes['$$TS03$$.12'] self.assertEqual('R1', node.reg.reg) self.assertEqual('12', node.field.name) self.assertEqual('R0', node.field.base.reg) self.assertEqual(12, node.field.dsp) self.assertEqual('R0', node.field.index.reg) # CH R15,=H'99' node = seg.nodes['$$TS03$$.13'] self.assertEqual('R15', node.reg.reg) self.assertEqual('R8', node.field.base.reg) literal = node.field.name self.assertTrue(seg.lookup(literal).is_literal) self.assertEqual(bytearray([0x00, 0x63]), seg.get_constant_bytes(literal)) # N R0,=A(X'1F') node = seg.nodes['$$TS03$$.14'] self.assertEqual('R0', node.reg.reg) self.assertEqual('R8', node.field.base.reg) literal = node.field.name self.assertTrue(seg.lookup(literal).is_literal) self.assertEqual(bytearray([0x00, 0x00, 0x00, 0x1F]), seg.get_constant_bytes(literal)) # L R6,PD0_RT_ADR node = seg.nodes['$$TS03$$.15'] self.assertEqual('R4', node.field.base.reg) self.assertEqual(0x078, node.field.dsp) field_name = node.field.name self.assertEqual(4, seg.lookup(field_name).length) self.assertEqual('PD0WRK', seg.lookup(field_name).name) # L R6,PD0_RT_ADRX node = seg.nodes['$$TS03$$.16'] self.assertEqual('R5', node.field.base.reg) self.assertEqual(0x078, node.field.dsp) field_name = node.field.name self.assertEqual(4, seg.lookup(field_name).length) self.assertEqual('PD0WRKX', seg.lookup(field_name).name)