Download tests/test_x86.py from AEUPH/hdcstorage: direct link, hf CLI and curl.
- Browser
- Download file 5.11 kB
-
https://huggingface.co/AEUPH/hdcstorage/resolve/main/tests/test_x86.py
- Command line
-
hf download hf://AEUPH/hdcstorage/tests/test_x86.py
-
curl -L -o test_x86.py https://huggingface.co/AEUPH/hdcstorage/resolve/main/tests/test_x86.py
5.11 kB
| import unittest | |
| from hdc.x86 import BIOS, VIDEO_BASE, Boot, CPU, Halt, boot_sector | |
| def load(cpu: CPU, code: list[int]) -> None: | |
| for i, byte in enumerate(code): | |
| cpu.write8(i, byte) | |
| cpu.ip = 0 | |
| cpu.seg["CS"] = 0 | |
| class TestRegisters(unittest.TestCase): | |
| def test_eight_bit_moves_hit_both_halves(self): | |
| cpu = CPU() | |
| load(cpu, [0xB8, 0x34, 0x12, 0xB4, 0x56]) # mov ax,1234h ; mov ah,56h | |
| cpu.step() | |
| self.assertEqual(cpu.r[0], 0x1234) | |
| cpu.step() | |
| self.assertEqual(cpu.al, 0x34) | |
| self.assertEqual(cpu.ah, 0x56) | |
| def test_mov_ds_from_ax(self): | |
| cpu = CPU() | |
| load(cpu, [0xB8, 0xC0, 0x07, 0x8E, 0xD8]) # mov ax,07C0h ; mov ds,ax | |
| cpu.step() | |
| cpu.step() | |
| self.assertEqual(cpu.seg["DS"], 0x07C0) | |
| def test_segment_offset_addressing(self): | |
| cpu = CPU() | |
| cpu.write8(cpu.physical(0x07C0, 0x18), ord("H")) | |
| self.assertEqual(cpu.read8(cpu.physical(0x07C0, 0x18)), ord("H")) | |
| class TestDisplacements(unittest.TestCase): | |
| def test_short_jump_loops_in_place(self): | |
| cpu = CPU() | |
| load(cpu, [0xEB, 0xFE]) # jmp $ | |
| for _ in range(4): | |
| cpu.step() | |
| self.assertEqual(cpu.ip, 0) | |
| def test_backwards_jump_lands_on_the_instruction(self): | |
| cpu = CPU() | |
| load(cpu, [0x90, 0xEB, 0xFD]) # nop ; jmp -3 | |
| cpu.step() | |
| cpu.step() | |
| self.assertEqual(cpu.ip, 0) | |
| def test_conditional_jump_uses_the_flag(self): | |
| cpu = CPU() | |
| load(cpu, [0x31, 0xC0, 0x74, 0x02]) # xor ax,ax ; jz +2 | |
| cpu.step() | |
| cpu.step() | |
| self.assertEqual(cpu.ip, 6) | |
| def test_taken_and_not_taken_paths(self): | |
| cpu = CPU() | |
| load(cpu, [0xB8, 0x01, 0x00, 0x74, 0x02]) # mov ax,1 ; jz +2 | |
| cpu.step() | |
| cpu.step() | |
| self.assertEqual(cpu.ip, 5) # not taken | |
| class TestVideo(unittest.TestCase): | |
| def test_teletype_writes_the_video_buffer(self): | |
| cpu = CPU() | |
| bios = BIOS(cpu) | |
| bios.post() | |
| cpu.ah, cpu.al = 0x0E, ord("A") | |
| bios.video(cpu) | |
| self.assertEqual(chr(cpu.read8(VIDEO_BASE)), "A") | |
| def test_newline_moves_the_cursor(self): | |
| cpu = CPU() | |
| bios = BIOS(cpu) | |
| bios.post() | |
| bios.write("AB\r\nCD") | |
| self.assertEqual(bios.screen()[0], "AB") | |
| self.assertEqual(bios.screen()[1].rstrip(), "CD") | |
| def test_long_line_wraps(self): | |
| cpu = CPU() | |
| bios = BIOS(cpu) | |
| bios.post() | |
| bios.write("X" * 81) | |
| self.assertEqual(cpu.cursor, [1, 1]) | |
| def test_scrolling_keeps_the_latest_line(self): | |
| cpu = CPU() | |
| bios = BIOS(cpu) | |
| bios.post() | |
| for i in range(30): | |
| bios.write("line %d\n" % i) | |
| visible = [line for line in bios.screen() if line.strip()] | |
| self.assertIn("line 29", visible[-1]) | |
| self.assertLessEqual(len(visible), 25) | |
| class TestDisk(unittest.TestCase): | |
| def test_bad_signature_raises(self): | |
| cpu = CPU() | |
| bios = BIOS(cpu, b"\x00" * 512) | |
| bios.post() | |
| with self.assertRaises(Halt): | |
| bios.boot_attempt(cpu) | |
| def test_read_sector_lands_at_es_bx(self): | |
| cpu = CPU() | |
| bios = BIOS(cpu, bytes(range(256)) * 2) | |
| bios.post() | |
| cpu.ah, cpu.al = 0x02, 1 | |
| cpu.r[1] = 0x0001 # CX: cylinder 0, sector 1 | |
| cpu.r[2] = 0x0000 # DX: head 0 | |
| cpu.seg["ES"] = 0x1000 | |
| cpu.r[3] = 0x0000 # BX | |
| bios.read_sector(cpu) | |
| self.assertEqual(cpu.read8(0x10000), 0) | |
| self.assertEqual(cpu.read8(0x10001), 1) | |
| self.assertFalse(cpu.flags & 0x0001) | |
| def test_failed_read_sets_carry(self): | |
| cpu = CPU() | |
| bios = BIOS(cpu, b"") | |
| bios.post() | |
| cpu.ah = 0x02 | |
| bios.read_sector(cpu) | |
| self.assertTrue(cpu.flags & 0x0001) | |
| class TestBootChain(unittest.TestCase): | |
| def test_sector_has_the_signature(self): | |
| sector = boot_sector("hi") | |
| self.assertEqual(len(sector), 512) | |
| self.assertEqual(sector[510:512], b"\x55\xAA") | |
| def test_boot_reaches_the_kernel_handoff(self): | |
| machine = Boot() | |
| machine.post() | |
| result = machine.boot() | |
| self.assertEqual(result["reason"], "kernel") | |
| self.assertEqual(result["stage"], "kernel") | |
| self.assertGreater(result["instructions"], 20) | |
| def test_banner_is_written_to_video_memory(self): | |
| machine = Boot("HELLO KERNEL") | |
| machine.post() | |
| machine.boot() | |
| text = "\n".join(machine.screen()) | |
| self.assertIn("HELLO KERNEL", text) | |
| self.assertIn("POST", text) | |
| def test_ivt_is_populated(self): | |
| machine = Boot() | |
| machine.post() | |
| self.assertNotEqual(machine.cpu.read16(0x10 * 4), 0) | |
| self.assertNotEqual(machine.cpu.read16(0x10 * 4 + 2), 0) | |
| def test_oversized_banner_is_rejected(self): | |
| with self.assertRaises(ValueError): | |
| boot_sector("x" * 600) | |
| if __name__ == "__main__": | |
| unittest.main() | |