diff --git a/chip8/cpu.py b/chip8/cpu.py index 858bfa3..d703ec9 100644 --- a/chip8/cpu.py +++ b/chip8/cpu.py @@ -91,6 +91,8 @@ def __init__( self.sp = STACK_POINTER_START self.index = 0 self.rpl = [0] * NUM_REGISTERS + self.pitch = 64 + self.playback_rate = 4000 self.shift_quirks = shift_quirks self.index_quirks = index_quirks @@ -150,6 +152,7 @@ def __init__( 0x29: self.load_index_with_reg_sprite, # Fs29 - LOAD I, Vs 0x30: self.load_index_with_extended_reg_sprite, # Fs30 - LOAD I, Vs 0x33: self.store_bcd_in_memory, # Fs33 - BCD + 0x3A: self.load_pitch, # Fx3A - PITCH Vx 0x55: self.store_regs_in_memory, # Fs55 - STOR [I], Vs 0x65: self.read_regs_from_memory, # Fs65 - LOAD Vs, [I] 0x75: self.store_regs_in_rpl, # Fs75 - SRPL Vs @@ -923,6 +926,21 @@ def store_bcd_in_memory(self): self.memory[self.index + 2] = int(bcd_value[2]) self.last_op = f"BCD V{x:01X} ({bcd_value})" + def load_pitch(self): + """ + Fx3A - PITCH Vx + + Loads the value from register x into the pitch register. The + register calculation is as follows: + + Bits: 15-12 11-8 7-4 3-0 + F x 3 A + """ + x = (self.operand & 0x0F00) >> 8 + self.pitch = self.v[x] + self.playback_rate = 4000 * 2 ** ((self.pitch - 64) / 48) + self.last_op = f"PITCH V{x:01X}" + def store_regs_in_memory(self): """ Fn55 - STOR [I] @@ -1011,6 +1029,8 @@ def reset(self): self.sp = STACK_POINTER_START self.index = 0 self.rpl = [0] * NUM_REGISTERS + self.pitch = 64 + self.playback_rate = 4000 def load_rom(self, filename, offset=PROGRAM_COUNTER_START): """ diff --git a/test/test_chip8cpu.py b/test/test_chip8cpu.py index 10782b1..6da2310 100644 --- a/test/test_chip8cpu.py +++ b/test/test_chip8cpu.py @@ -37,6 +37,25 @@ def setUp(self): def test_memory_size_default_64k(self): self.assertEqual(65536, len(self.cpu.memory)) + def test_pitch_init_64(self): + self.assertEqual(64, self.cpu.pitch) + self.assertEqual(4000, self.cpu.playback_rate) + + def test_load_pitch(self): + self.cpu.v[1] = 112 + self.cpu.operand = 0xF13A + self.cpu.load_pitch() + self.assertEqual(112, self.cpu.pitch) + self.assertEqual(8000, self.cpu.playback_rate) + + def test_load_pitch_integration(self): + self.cpu.v[1] = 112 + self.cpu.memory[0x0200] = 0xF1 + self.cpu.memory[0x0201] = 0x3A + self.cpu.execute_instruction() + self.assertEqual(112, self.cpu.pitch) + self.assertEqual(8000, self.cpu.playback_rate) + def test_return_from_subroutine(self): for address in range(0x200, 0xFFFF, 0x10): self.cpu.memory[self.cpu.sp] = address & 0x00FF @@ -293,7 +312,6 @@ def test_right_shift_reg_quirks(self): def test_right_shift_reg(self): self.cpu.shift_quirks = False - y = 0x8 for x in range(0xF): for y in range(0xF): for value in range(0, 0xFF, 0x10):