From 02d4b61f6b6196de49a8a64d92f4476f3c5909a2 Mon Sep 17 00:00:00 2001 From: Craig Thomas Date: Sun, 23 Jun 2024 23:09:05 -0400 Subject: [PATCH] Add store subset of register operation. --- chip8/cpu.py | 38 ++++++++++++++++++++++++++++++++++---- test/test_chip8cpu.py | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 4 deletions(-) diff --git a/chip8/cpu.py b/chip8/cpu.py index c48508b..daeddb2 100644 --- a/chip8/cpu.py +++ b/chip8/cpu.py @@ -255,10 +255,14 @@ def misc_routines(self): Will execute one of the routines specified in misc_routines. """ operation = self.operand & 0x00FF - try: - self.misc_routine_lookup[operation]() - except KeyError: - raise UnknownOpCodeException(self.operand) + sub_operation = self.operand & 0x000F + if sub_operation == 0x2: + self.store_subset_regs_in_memory() + else: + try: + self.misc_routine_lookup[operation]() + except KeyError: + raise UnknownOpCodeException(self.operand) def clear_return(self): """ @@ -837,6 +841,32 @@ def set_bitplane(self): self.bitplane = (self.operand & 0x0F00) >> 8 self.last_op = f"BITPLANE {self.bitplane:01X}" + def store_subset_regs_in_memory(self): + """ + Fxy2 - STORSUB [I], Vx, Vy + + Store a subset of registers from x to y in memory starting at index. + The x and y calculation is as follows: + + Bits: 15-12 11-8 7-4 3-0 + F x y 2 + + If x is larger than y, then they will be stored in reverse order. + """ + x = (self.operand & 0x0F00) >> 8 + y = (self.operand & 0x00F0) >> 4 + pointer = 0 + if y >= x: + for z in range(x, y+1): + self.memory[self.index + pointer] = self.v[z] + pointer += 1 + else: + for z in range(x, y-1, -1): + self.memory[self.index + pointer] = self.v[z] + pointer += 1 + + self.last_op = f"STORSUB [I], {x:01X}, {y:01X}" + def move_delay_timer_into_reg(self): """ Fx07 - LOAD Vx, DELAY diff --git a/test/test_chip8cpu.py b/test/test_chip8cpu.py index 6586767..1f0485b 100644 --- a/test/test_chip8cpu.py +++ b/test/test_chip8cpu.py @@ -914,6 +914,47 @@ def test_wait_for_keypress_sets_awaiting_keypress(self): self.assertEqual(1, self.cpu.keypress_register) self.assertTrue(self.cpu.awaiting_keypress) + def test_store_subset_regs_one_two(self): + self.cpu.v[1] = 5 + self.cpu.v[2] = 6 + self.cpu.index = 0x5000 + self.cpu.operand = 0xF122 + self.cpu.store_subset_regs_in_memory() + self.assertEqual(5, self.cpu.memory[0x5000]) + self.assertEqual(6, self.cpu.memory[0x5001]) + + def test_store_subset_regs_one_one(self): + self.cpu.v[1] = 5 + self.cpu.v[2] = 6 + self.cpu.index = 0x5000 + self.cpu.operand = 0xF112 + self.cpu.store_subset_regs_in_memory() + self.assertEqual(5, self.cpu.memory[0x5000]) + self.assertEqual(0, self.cpu.memory[0x5001]) + + def test_store_subset_regs_three_one(self): + self.cpu.v[1] = 5 + self.cpu.v[2] = 6 + self.cpu.v[3] = 7 + self.cpu.index = 0x5000 + self.cpu.operand = 0xF312 + self.cpu.store_subset_regs_in_memory() + self.assertEqual(7, self.cpu.memory[0x5000]) + self.assertEqual(6, self.cpu.memory[0x5001]) + self.assertEqual(5, self.cpu.memory[0x5002]) + + def test_store_subset_regs_integration(self): + self.cpu.v[1] = 5 + self.cpu.v[2] = 6 + self.cpu.v[3] = 7 + self.cpu.index = 0x5000 + self.cpu.memory[0x0200] = 0xF3 + self.cpu.memory[0x0201] = 0x12 + self.cpu.execute_instruction() + self.assertEqual(7, self.cpu.memory[0x5000]) + self.assertEqual(6, self.cpu.memory[0x5001]) + self.assertEqual(5, self.cpu.memory[0x5002]) + # M A I N #####################################################################