import unittest from h8536.decoder import H8536Decoder from h8536.analysis import trace from h8536.rom import Rom def decode(data: list[int]): return H8536Decoder(Rom(bytes(data), base=0)).decode(0) class ManualDecoderExamplesTest(unittest.TestCase): def test_manual_add_general_register_indirect_byte_example(self): instruction = decode([0xD0, 0x21]) self.assertEqual(instruction.text, "ADD:G.B @R0, R1") self.assertEqual(instruction.size, 2) self.assertEqual(instruction.targets, []) def test_manual_add_general_absolute_8_word_example(self): instruction = decode([0x0D, 0x11, 0x21]) self.assertEqual(instruction.text, "ADD:G.W @BR:H'11, R1") self.assertEqual(instruction.size, 3) self.assertEqual(instruction.targets, []) def test_reset_sequence_style_ldc_word_immediate_to_sr(self): instruction = decode([0x0C, 0x07, 0x00, 0x88]) self.assertEqual(instruction.text, "LDC.W #H'0700, SR") self.assertEqual(instruction.size, 4) self.assertEqual(instruction.targets, []) def test_branch_targets_and_flow_metadata_for_bne_and_bra(self): bne = decode([0x26, 0x02]) bra = decode([0x20, 0xFE]) self.assertEqual(bne.text, "BNE loc_0004") self.assertEqual(bne.size, 2) self.assertEqual(bne.kind, "branch") self.assertEqual(bne.targets, [0x0004]) self.assertTrue(bne.fallthrough) self.assertEqual(bra.text, "BRA loc_0000") self.assertEqual(bra.size, 2) self.assertEqual(bra.kind, "jump") self.assertEqual(bra.targets, [0x0000]) self.assertFalse(bra.fallthrough) def test_jsr_rts_and_bsr_basics(self): jsr_abs = decode([0x18, 0x12, 0x34]) jsr_reg = decode([0x11, 0xD8]) rts = decode([0x19]) bsr = decode([0x0E, 0x02]) self.assertEqual(jsr_abs.text, "JSR @loc_1234") self.assertEqual(jsr_abs.size, 3) self.assertEqual(jsr_abs.kind, "call") self.assertEqual(jsr_abs.targets, [0x1234]) self.assertEqual(jsr_reg.text, "JSR @R0") self.assertEqual(jsr_reg.size, 2) self.assertEqual(jsr_reg.kind, "call") self.assertEqual(jsr_reg.targets, []) self.assertEqual(rts.text, "RTS") self.assertEqual(rts.size, 1) self.assertEqual(rts.kind, "return") self.assertEqual(rts.targets, []) self.assertFalse(rts.fallthrough) self.assertEqual(bsr.text, "BSR loc_0004") self.assertEqual(bsr.size, 2) self.assertEqual(bsr.kind, "call") self.assertEqual(bsr.targets, [0x0004]) def test_movfpe_movtpe_extended_general_form(self): movfpe = decode([0x05, 0x80, 0x00, 0x82]) movtpe = decode([0x05, 0x80, 0x00, 0x92]) self.assertEqual(movfpe.text, "MOVFPE.B @BR:H'80, R2") self.assertEqual(movfpe.size, 4) self.assertEqual(movfpe.targets, []) self.assertEqual(movtpe.text, "MOVTPE.B R2, @BR:H'80") self.assertEqual(movtpe.size, 4) self.assertEqual(movtpe.targets, []) def test_trace_tracks_ldc_immediate_to_br_for_short_absolute_operands(self): rom = Rom(bytes([0x04, 0xFE, 0x89, 0x60, 0xFC]), base=0) decoder = H8536Decoder(rom) instructions = trace(decoder, [0], 0, len(rom.data)) self.assertEqual(instructions[0].text, "LDC.B #H'FE, BR") self.assertTrue(instructions[0].writes_br) self.assertEqual(instructions[0].br_value, 0xFE) self.assertEqual(instructions[3].text, "MOV:L.B @SYSCR1, R0") self.assertEqual(instructions[3].references, [0xFEFC]) if __name__ == "__main__": unittest.main()