def test_fx55_writes_registers_to_ram(self, max_register): """Fx55 writes register contents to RAM correctly""" vm = Chip8VirtualMachine() self._write_values_to_memory( vm, max_register, 0xA00, 128 ) for index in range(0, max_register+1): assert vm.memory[0xA00 + index] == 128 + index
def test_fx65_loads_ram_to_registers(self, max_register): """Fx65 reads ram contents to registers correctly""" vm = Chip8VirtualMachine() self._load_from_memory( vm, max_register, 0xA00, 128 ) for register_index in range(0, max_register+1): assert vm.v_registers[register_index] == 128 + register_index
def test_fx07_set_vx_to_delay_timer_value( v_register_index, v_initial_value, delay_timer_value ): vm = Chip8VirtualMachine() vm.delay_timer = delay_timer_value load_and_execute_instruction(vm, 0xF007, x=v_register_index) assert vm.v_registers[v_register_index] == delay_timer_value
def test_fx65_does_not_touch_other_registers(self, max_register): """Fx65 doesn't touch registers past x""" vm = Chip8VirtualMachine() self._load_from_memory( vm, max_register, 0xA00, 128 ) # memory outside of the write area isn't touched, excludes # the load point of the fx55 instruction for register_index in range(max_register + 1, 16): assert vm.v_registers[register_index] == 0
def test_fx55_does_not_touch_other_memory(self, write_location): """Fx55 doesn't touch RAM outside the range it's supposed to""" vm = Chip8VirtualMachine() self._write_values_to_memory( vm, 0xF, write_location, 128 ) # memory outside of the write area isn't touched, excludes # the load point of the fx55 instruction for memory_index in chain( range(0x202, write_location), range(write_location + 18, len(vm.memory)) ): assert vm.memory[memory_index] == 0
def test_fx1e_adds_vx_to_i_register( source_register: int, initial_i: int, value_to_add: int): """ FX1E Adds VX and I, storing the result in I :param source_register: which register will be pulled from :param initial_i: initial value for i to hold :param value_to_add: value that will be added to the I register """ vm = Chip8VirtualMachine() vm.i_register = initial_i vm.v_registers[source_register] = value_to_add load_and_execute_instruction(vm, 0xF01E, x=source_register) assert vm.i_register == initial_i + value_to_add
def test_fx15_sets_delay_timer_from_vx( self, source_register, initial_delay_value, set_value ): """ FX15 sets delay timer to value in VX :param source_register: which VX register to set DT from :param initial_delay_value: the value DT will initially hold :param set_value: the value DT will have after setting :return: """ vm = Chip8VirtualMachine() vm.delay_timer = initial_delay_value vm.v_registers[source_register] = set_value load_and_execute_instruction(vm, 0xF015, x=source_register) assert vm.delay_timer == set_value
def test_fx29_load_address_for_digit_sprite_to_i( digit_to_sprite, digit_storage_start ): """ FX29 Loads address for the sprite of the digit in VX to I register :param digit_to_sprite: digit to load sprite for, 0-16 :param digit_storage_start: where digits will be stored in RAM :return: """ vm = Chip8VirtualMachine(digit_start=digit_storage_start) for source_register in range(0, 16): vm.program_counter = EXECUTION_START vm.v_registers[source_register] = digit_to_sprite load_and_execute_instruction(vm, 0xF029, x=source_register) i = vm.i_register assert vm.memory[i:i+vm.digit_length] ==\ DEFAULT_DIGITS[digit_to_sprite]
def test_fx33_store_bcd_of_vx_starting_at_i( v_register_index, i_reg_value, value_to_bcd, expected_result_digits ): """ FX33 Stores BCD of the value in VX starting at location in I register :param v_register_index: which x register to use :param i_reg_value: where in memory to store the bcd :param value_to_bcd: what will be converted :param expected_result_digits: the expected digit output :return: """ vm = Chip8VirtualMachine() vm.i_register = i_reg_value vm.v_registers[v_register_index] = value_to_bcd load_and_execute_instruction(vm, 0xF033, x=v_register_index) for index, digit in enumerate(expected_result_digits): assert vm.memory[i_reg_value + index] == digit
def test_valuerror_on_unhandled_instruction( patterned_unrecognizeable_instruction): """Unhandled instructions raise ValueError""" vm = Chip8VirtualMachine() with pytest.raises(ValueError): load_and_execute_instruction(vm, patterned_unrecognizeable_instruction)
def test_ram_size(ram_size): vm = Chip8VirtualMachine(memory_size=ram_size) print(vm.memory) assert len(vm.memory) == ram_size
def test_typeerror_on_not_a_type(self): """Non-type passed in video_ram_type""" with pytest.raises(TypeError): vm = Chip8VirtualMachine(video_ram_type="not a type")
def test_typeerror_on_bad_vram_type(self): """Non-VideoRam class passed in video_ram_type""" with pytest.raises(TypeError): vm = Chip8VirtualMachine(video_ram_type=BadClass)
def test_vm_raises_no_error_on_good_types(self, vram_type): vm = Chip8VirtualMachine(video_ram_type=vram_type)