class TestFastDisasmMulti(object): def get_disasm(self): z = BasicZ80Disassembler() parent = Basic6502Disassembler() # Use the Z80 processor for style type 64 parent.fast.chunk_type_processor[1] = z.fast.chunk_processor return parent def setup(self): self.editor = MockHexEditor() guess = FileGuess("../test_data/pytest.atr") self.editor.load(guess) self.disasm = self.get_disasm() self.fast = self.disasm.fast def test_ranges(self): self.editor.find_segment("boot code at $0800") s = self.editor.segment r = fast_get_entire_style_ranges(s, user=user_bit_mask, split_comments=[]) print(r) assert r == [((0, 238), 0), ((238, 268), 2), ((268, 332), 0), ((332, 464), 1), ((464, 512), 0)] info_sections = self.fast.get_all(s.rawdata.unindexed_data, s.origin, 0, r)
class TestXex(object): def setup(self): self.editor = MockHexEditor() guess = FileGuess("../test_data/air_defense_v18.atr") self.editor.load(guess) def test_simple(self): d = self.editor.document print(d, len(d), d.segments) for s in d.segments: print(s) source = [] code_seg = d.find_segment_by_name("program code") runad_seg = d.find_segment_by_name("runad") source.append(code_seg) source.append(runad_seg) main, sub = get_xex(source) print(main, sub) print(len(code_seg)) assert len(sub[0]) == len(code_seg) + 4 assert len(sub[1]) == len(runad_seg) + 4 print(list(d.container_segment.iter_comments_in_segment())) for i, c in code_seg.iter_comments_in_segment(): print(i, c) assert c == sub[0].get_comment(i + 4) newdoc = SegmentedDocument.create_from_segments(main, sub) d = {} newdoc.serialize_extra_to_dict(d) print(d) for i, c in d['comments']: print(i, c) assert c == main.get_comment(i) self.editor.save("out.air_defense.atr", document=newdoc)
class TestFastDisasm(object): def get_disasm(self): return Basic6502Disassembler() def setup(self): self.editor = MockHexEditor() guess = FileGuess("../test_data/pytest.atr") self.editor.load(guess) self.disasm = self.get_disasm() self.fast = self.disasm.fast def test_ranges(self): # force the use of the normal disassembler for the other style self.disasm.fast.chunk_type_processor[ 64] = self.disasm.fast.chunk_processor self.editor.find_segment("02: robots I") s = self.editor.segment r = fast_get_entire_style_ranges(s, user=user_bit_mask, split_comments=[]) print(r) assert r == [((0, 497), 0), ((497, 524), 1), ((524, 602), 0), ((602, 690), 1), ((690, 1004), 0), ((1004, 1024), 1), ((1024, 1536), 0), ((1536, 1710), 1), ((1710, 1792), 0), ((1792, 1954), 1), ((1954, 2048), 0)] info_all = self.fast.get_all(s.rawdata.unindexed_data, s.origin, 0) #print info_all.instructions[0:20] info_sections = self.fast.get_all(s.rawdata.unindexed_data, s.origin, 0, r) # for i in range(info_sections.num_instructions): # print info_sections[i].instruction assert len(info_all.instructions) == len(info_sections.instructions) assert np.all(info_all.index_to_row - info_sections.index_to_row == 0)
class TestChunkBreak(object): def get_disasm(self): disasm = Basic6502Disassembler() disasm.add_chunk_processor("data", 1) disasm.add_chunk_processor("antic_dl", 2) disasm.add_chunk_processor("jumpman_level", 3) disasm.add_chunk_processor("jumpman_harvest", 4) return disasm def setup(self): self.disasm = self.get_disasm() self.editor = MockHexEditor() guess = FileGuess("../test_data/pytest.atr") self.editor.load(guess) def test_simple(self): self.editor.find_segment("chunk type changes") s = self.editor.segment r = fast_get_entire_style_ranges(s, user=user_bit_mask) print(r) info = self.disasm.disassemble_segment(s) inst = info.instructions for i in range(info.num_instructions): print(info[i].instruction) assert info[0].instruction.startswith("DEX") assert info[2].instruction.startswith("RTS") assert info[4].instruction == "00" assert info[5].instruction.startswith("7070707070;") def test_recompile(self): self.editor.find_segment("modified boot") s = self.editor.segment info = self.disasm.disassemble_segment(s) disasm = self.disasm.get_disassembled_text() with open("%s.s" % s.name, "w") as fh: fh.write("\n".join(disasm) + "\n") text1 = self.disasm.get_atasm_lst_text() with open("%s.omnivore-lst" % s.name, "w") as fh: fh.write("\n".join(text1) + "\n") def test_bad(self): data = np.fromstring( "\x8dp0L\xaa8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00pppM\x00p\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x8d\x8d\x06\x16\x8e\r", dtype=np.uint8) style = np.empty(len(data), dtype=np.uint8) style[0:17] = 0 style[17:] = 2 raw = SegmentData(data, style) s = DefaultSegment(raw, 0x3bef) info = self.disasm.disassemble_segment(s) inst = info.instructions for i in range(info.num_instructions): print(info[i].instruction) text = self.disasm.get_disassembled_text() print("\n".join(text)) text = self.disasm.get_atasm_lst_text() print("\n".join(text))
class TestChunkBreak(object): def get_disasm(self): disasm = Basic6502Disassembler() disasm.add_chunk_processor("data", 1) disasm.add_chunk_processor("antic_dl", 2) disasm.add_chunk_processor("jumpman_level", 3) disasm.add_chunk_processor("jumpman_harvest", 4) return disasm def setup(self): self.disasm = self.get_disasm() self.editor = MockHexEditor() guess = FileGuess("../test_data/pytest.atr") self.editor.load(guess) def test_simple(self): self.editor.find_segment("chunk type changes") s = self.editor.segment r = fast_get_entire_style_ranges(s, user=user_bit_mask) print(r) info = self.disasm.disassemble_segment(s) inst = info.instructions for i in range(info.num_instructions): print(info[i].instruction) assert info[0].instruction.startswith("DEX") assert info[2].instruction.startswith("RTS") assert info[4].instruction == "00" assert info[5].instruction.startswith("7070707070;") def test_recompile(self): self.editor.find_segment("modified boot") s = self.editor.segment info = self.disasm.disassemble_segment(s) disasm = self.disasm.get_disassembled_text() with open("%s.s" % s.name, "w") as fh: fh.write("\n".join(disasm) + "\n") text1 = self.disasm.get_atasm_lst_text() with open("%s.omnivore-lst" % s.name, "w") as fh: fh.write("\n".join(text1) + "\n") def test_bad(self): data = np.fromstring("\x8dp0L\xaa8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00pppM\x00p\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\x8d\x8d\x06\x16\x8e\r", dtype=np.uint8) style = np.empty(len(data), dtype=np.uint8) style[0:17] = 0 style[17:] = 2 raw = SegmentData(data, style) s = DefaultSegment(raw, 0x3bef) info = self.disasm.disassemble_segment(s) inst = info.instructions for i in range(info.num_instructions): print(info[i].instruction) text = self.disasm.get_disassembled_text() print("\n".join(text)) text = self.disasm.get_atasm_lst_text() print("\n".join(text))
class TestAssemble(object): def setup(self): self.editor = MockHexEditor() guess = FileGuess("../test_data/reassembly-test.xex") self.editor.load(guess) print(self.editor.document.segments) self.segment = self.editor.document.segments[0][6:6 + 0x125] print(self.segment) def test_reassemble(self): source = "../test_data/reassembly-test.s" asm = Assemble(source) assert asm is not None assert len(asm) == 1 assert len(asm.segments) == 1 start, end, source_bytes = asm.segments[0] assert len(source_bytes) == len(self.segment) print(source_bytes) source_data = np.asarray(source_bytes, dtype=np.uint8) print(source_data) segment_data = np.asarray(self.segment, dtype=np.uint8) assert np.all(source_data - segment_data == 0)
class TestFastDisasm(object): def get_disasm(self): return Basic6502Disassembler() def setup(self): self.editor = MockHexEditor() guess = FileGuess("../test_data/pytest.atr") self.editor.load(guess) self.disasm = self.get_disasm() self.fast = self.disasm.fast def test_ranges(self): # force the use of the normal disassembler for the other style self.disasm.fast.chunk_type_processor[64] = self.disasm.fast.chunk_processor self.editor.find_segment("02: robots I") s = self.editor.segment r = fast_get_entire_style_ranges(s, user=user_bit_mask, split_comments=[]) print(r) assert r == [ ((0, 497), 0), ((497, 524), 1), ((524, 602), 0), ((602, 690), 1), ((690, 1004), 0), ((1004, 1024), 1), ((1024, 1536), 0), ((1536, 1710), 1), ((1710, 1792), 0), ((1792, 1954), 1), ((1954, 2048), 0)] info_all = self.fast.get_all(s.rawdata.unindexed_data, s.origin, 0) #print info_all.instructions[0:20] info_sections = self.fast.get_all(s.rawdata.unindexed_data, s.origin, 0, r) # for i in range(info_sections.num_instructions): # print info_sections[i].instruction assert len(info_all.instructions) == len(info_sections.instructions) assert np.all(info_all.index_to_row - info_sections.index_to_row == 0)