def test_scenario2(values): """Test DCL instruction functionality (scenario 2).""" chip_test = Processor() chip_base = Processor() # Simulate conditions at end of instruction in base chip chip_base.PROGRAM_COUNTER = 11 chip_base.RAM[values[2]] = values[1] registervalue = convert_decimal_to_n_bit_slices(8, 4, values[1], 'd') # noqa chip_base.REGISTERS[0] = registervalue[0] chip_base.REGISTERS[1] = registervalue[1] chip_test.PROGRAM_COUNTER = 10 chip_test.RAM[values[2]] = values[1] chip_test.REGISTERS[0] = registervalue[0] chip_test.REGISTERS[1] = registervalue[1] # Perform the instruction under test: # Fetch indirect from left, right = Processor.fin(chip_test, values[0]) # Make assertions that the base chip is now at the same state as # the test chip which has been operated on by the instruction under test. left_r = chip_test.read_register(values[0]) right_r = chip_test.read_register(values[0] + 1) assert left == left_r assert right == right_r assert chip_test.PROGRAM_COUNTER == 11 # Pickling each chip and comparing will show equality or not. assert pickle.dumps(chip_test) == pickle.dumps(chip_base)
def test_scenario1(values): """Test SRC instruction functionality.""" chip_test = Processor() chip_base = Processor() registerpair = values[0] value = values[1] # Set up chip conditions prior to commencement of test insert_registerpair(chip_test, registerpair, value) chip_test.PROGRAM_COUNTER = 0 # Perform the instruction under test: Processor.src(chip_test, registerpair) # Simulate conditions at end of instruction in base chip chip_base.PROGRAM_COUNTER = 0 chip_base.increment_pc(1) insert_registerpair(chip_base, registerpair, value) chip_base.COMMAND_REGISTER = Processor.decimal_to_binary(8, value) # Make assertions that the base chip is now at the same state as # the test chip which has been operated on by the instruction under test. assert chip_test.read_program_counter() == chip_base.read_program_counter() assert chip_test.COMMAND_REGISTER == chip_base.COMMAND_REGISTER # Pickling each chip and comparing will show equality or not. assert pickle.dumps(chip_test) == pickle.dumps(chip_base)
def test_scenario1(value): """Test LDM instruction functionality.""" chip_test = Processor() chip_base = Processor() rv = random.randint(0, 15) # Select a random 4-bit value # Perform the instruction under test: chip_test.PROGRAM_COUNTER = 0 chip_test.ACCUMULATOR = rv # Simulate conditions at end of instruction in base chip chip_base.PROGRAM_COUNTER = 0 chip_base.increment_pc(1) chip_base.ACCUMULATOR = value # Carry out the instruction under test # Perform an LDM operation Processor.ldm(chip_test, value) # Make assertions that the base chip is now at the same state as # the test chip which has been operated on by the instruction under test. assert chip_test.read_program_counter() == chip_base.read_program_counter() assert chip_test.read_accumulator() == chip_base.read_accumulator() # Pickling each chip and comparing will show equality or not. assert pickle.dumps(chip_test) == pickle.dumps(chip_base)
def test_bbl_scenario1(value): """Test BBL instruction functionality.""" chip_test = Processor() chip_base = Processor() pc = 300 # Simulate conditions at end of instruction in base chip chip_base.PROGRAM_COUNTER = 300 chip_base.write_to_stack(chip_base.PROGRAM_COUNTER + 2) chip_base.PROGRAM_COUNTER = 302 # Return chip_base.ACCUMULATOR = value chip_base.STACK_POINTER = 2 # Set up conditions in test chip chip_test.PROGRAM_COUNTER = 300 chip_test.write_to_stack(chip_test.PROGRAM_COUNTER + 2) # Perform the instruction under test: # Return from a subroutine and load a value into the accumulator Processor.bbl(chip_test, value) # Make assertions that the base chip is now at the same state as # the test chip which has been operated on by the instruction under test. assert chip_test.PROGRAM_COUNTER == pc + 2 assert chip_test.STACK_POINTER == 2 assert chip_test.STACK[chip_test.STACK_POINTER] == 302 # Return assert chip_test.PROGRAM_COUNTER == 302 # Pickling each chip and comparing will show equality or not. assert pickle.dumps(chip_test) == pickle.dumps(chip_base)
def test_scenario1(register): """Test XCH instruction functionality.""" chip_test = Processor() chip_base = Processor() rv = random.randint(0, 15) # Select a random 4-bit value # Perform the instruction under test: chip_test.PROGRAM_COUNTER = 0 chip_test.set_accumulator(14) chip_test.REGISTERS[register] = rv # Simulate conditions at end of instruction in base chip chip_base.PROGRAM_COUNTER = 0 chip_base.increment_pc(1) chip_base.set_accumulator(rv) chip_base.REGISTERS[register] = 14 # Carry out the instruction under test # Perform an XCH operation Processor.xch(chip_test, register) # Make assertions that the base chip is now at the same state as # the test chip which has been operated on by the instruction under test. assert chip_test.read_program_counter() == chip_base.read_program_counter() assert chip_test.read_accumulator() == chip_base.read_accumulator() assert chip_test.REGISTERS[register] == chip_base.REGISTERS[register] # Pickling each chip and comparing will show equality or not. assert pickle.dumps(chip_test) == pickle.dumps(chip_base)
def test_jms_scenario1(address12): """Test JMS instruction functionality.""" chip_test = Processor() chip_base = Processor() # Simulate conditions at end of instruction in base chip chip_base.PROGRAM_COUNTER = 300 chip_base.write_to_stack(chip_base.PROGRAM_COUNTER + 2) chip_base.PROGRAM_COUNTER = address12 - 1 # Set up conditions in test chip chip_test.PROGRAM_COUNTER = 300 # Perform the instruction under test: # Jump to a subroutine Processor.jms(chip_test, address12) # Make assertions that the base chip is now at the same state as # the test chip which has been operated on by the instruction under test. assert chip_test.PROGRAM_COUNTER == address12 - 1 assert chip_test.STACK_POINTER == 1 assert chip_test.STACK[chip_test.STACK_POINTER + 1] == 302 # Return # Pickling each chip and comparing will show equality or not. assert pickle.dumps(chip_test) == pickle.dumps(chip_base)
def test_scenario1(values): """Test JIN instruction functionality.""" chip_test = Processor() chip_base = Processor() pcb = values[0] rp = values[1] reg = rp * 2 rp_content = values[2] rpm = Processor.convert_decimal_to_n_bit_slices(8, 4, rp_content, 'd')[1] # noqa rpl = Processor.convert_decimal_to_n_bit_slices(8, 4, rp_content, 'd')[0] # noqa pce = values[3] # Set chip to initial status chip_test.PROGRAM_COUNTER = pcb chip_test.REGISTERS[reg] = rpl chip_test.REGISTERS[reg + 1] = rpm # Perform the instruction under test: Processor.jin(chip_test, rp) # Simulate conditions at end of instruction in base chip chip_base.PROGRAM_COUNTER = pce chip_base.REGISTERS[reg] = rpl chip_base.REGISTERS[reg + 1] = rpm # Make assertions that the base chip is now at the same state as # the test chip which has been operated on by the instruction under test. assert chip_test.read_program_counter() == chip_base.read_program_counter() # Pickling each chip and comparing will show equality or not. assert pickle.dumps(chip_test) == pickle.dumps(chip_base)
def test_scenario1(values): """Test CMC instruction functionality.""" chip_test = Processor() chip_base = Processor() # Perform the instruction under test: chip_test.PROGRAM_COUNTER = 0 chip_test.CARRY = values[0] # Simulate conditions at end of instruction in base chip chip_base.PROGRAM_COUNTER = 0 chip_base.increment_pc(1) chip_base.CARRY = values[1] # Carry out the instruction under test # Perform a CMC operation Processor.cmc(chip_test) # Make assertions that the base chip is now at the same state as # the test chip which has been operated on by the instruction under test. assert chip_test.read_program_counter() == chip_base.read_program_counter() assert chip_test.read_carry() == chip_base.read_carry() # Pickling each chip and comparing will show equality or not. assert pickle.dumps(chip_test) == pickle.dumps(chip_base)
def test_wrm_scenario1(rambank, chip, register, address): """Test WRM instruction functionality.""" import random chip_test = Processor() chip_base = Processor() value = random.randint(0, 15) # Select a random value # Perform the instruction under test: chip_test.PROGRAM_COUNTER = 0 chip_test.CURRENT_RAM_BANK = rambank absolute_address = convert_to_absolute_address(chip_test, rambank, chip, register, address) chip_test.set_accumulator(value) chip_test.COMMAND_REGISTER = \ encode_command_register(chip, register, address, 'DATA_RAM_CHAR') Processor.wrm(chip_test) # Simulate conditions at end of instruction in base chip chip_base.PROGRAM_COUNTER = 0 chip_base.RAM[absolute_address] = value chip_base.set_accumulator(value) chip_base.COMMAND_REGISTER = \ encode_command_register(chip, register, address, 'DATA_RAM_CHAR') chip_base.increment_pc(1) chip_base.CURRENT_RAM_BANK = rambank # Make assertions that the base chip is now at the same state as # the test chip which has been operated on by the instruction under test. assert chip_test.read_program_counter() == chip_base.read_program_counter() assert chip_test.read_accumulator() == chip_base.read_accumulator() # Pickling each chip and comparing will show equality or not. assert pickle.dumps(chip_test) == pickle.dumps(chip_base)
def test_scenario1(values): """Test ADD instruction functionality.""" chip_test = Processor() chip_base = Processor() rr = random.randint(0, 15) # Select a random value # Perform the instruction under test: chip_test.PROGRAM_COUNTER = 0 chip_test.set_accumulator(values[1]) chip_test.CARRY = values[0] chip_test.insert_register(rr, values[2]) # Simulate conditions at end of instruction in base chip chip_base.PROGRAM_COUNTER = 0 chip_base.increment_pc(1) chip_base.CARRY = values[4] chip_base.set_accumulator(values[3]) chip_base.insert_register(rr, values[2]) # Carry out the instruction under test # Perform aN ADD operation Processor.add(chip_test, rr) # Make assertions that the base chip is now at the same state as # the test chip which has been operated on by the instruction under test. assert chip_test.read_program_counter() == chip_base.read_program_counter() assert chip_test.read_carry() == chip_base.read_carry() assert chip_test.read_accumulator() == chip_base.read_accumulator() # Pickling each chip and comparing will show equality or not. assert pickle.dumps(chip_test) == pickle.dumps(chip_base)
def test_wmp_scenario1(rambank, chip): """Test WMP instruction functionality.""" import random chip_test = Processor() chip_base = Processor() value = random.randint(0, 15) # Select a random value # Perform the instruction under test: chip_test.PROGRAM_COUNTER = 0 chip_test.CURRENT_RAM_BANK = rambank chip_test.set_accumulator(value) chip_test.COMMAND_REGISTER = \ encode_command_register(chip, 0, 0, 'RAM_PORT') Processor.wmp(chip_test) # Simulate conditions at end of instruction in base chip chip_base.PROGRAM_COUNTER = 0 chip_base.set_accumulator(value) chip_base.COMMAND_REGISTER = \ encode_command_register(chip, 0, 0, 'RAM_PORT') chip_base.increment_pc(1) chip_base.CURRENT_RAM_BANK = rambank chip_base.RAM_PORT[rambank][chip] = chip_base.ACCUMULATOR # Make assertions that the base chip is now at the same state as # the test chip which has been operated on by the instruction under test. assert chip_test.read_program_counter() == chip_base.read_program_counter() assert chip_test.read_accumulator() == chip_base.read_accumulator() # Pickling each chip and comparing will show equality or not. assert pickle.dumps(chip_test) == pickle.dumps(chip_base)
def test_scenario2(values): """Test JIN instruction failure.""" chip_test = Processor() pcb = values[0] rp = values[1] reg = rp * 2 rp_content = values[2] rpm = Processor.convert_decimal_to_n_bit_slices(8, 4, rp_content, 'd')[1] # noqa rpl = Processor.convert_decimal_to_n_bit_slices(8, 4, rp_content, 'd')[0] # noqa pce = values[3] # Simulate conditions at START of operation in base chip # chip should have not had any changes as the operations will fail chip_test.PROGRAM_COUNTER = pcb chip_test.REGISTERS[reg] = rpl chip_test.REGISTERS[reg + 1] = rpm # Simulate conditions at END of operation in test chip # chip should have not had any changes as the operations will fail # N/A # attempting to use an invalid address with pytest.raises(Exception) as e: assert Processor.jin(chip_test, rp) assert str(e.value) == 'Program counter attempted to be set to ' + str( pce) # noqa assert e.type == ProgramCounterOutOfBounds
def disassemble(chip: Processor, location: str, pc: int, byte: int, show_lbls: bool, lbls: list) -> None: """ Control the dissassembly of a previously assembled program. Parameters ---------- chip : Processor, mandatory The instance of the processor containing the registers, accumulator etc location : str, mandatory The location to which the program should be loaded pc : int, mandatory The program counter value to commence execution byte: int, mandatory Number of bytes to disassemble show_lbls : bool, mandatory true/false - whether to show label table or not. lbls: list, optional any list of labels from the object module Returns ------- None in all instances Raises ------ N/A Notes ----- N/A """ chip.PROGRAM_COUNTER = pc opcode = 0 _tps = retrieve_program(chip, location) byte_count = 0 finish = False # pseudo-opcode (directive) for "end" while finish is False: if byte_count >= byte: finish = True if chip.PROGRAM_COUNTER == chip.MEMORY_SIZE_PRAM: finish = True if opcode == 256: finish = True if not finish: exe, opcode, words = disassemble_instruction(chip, _tps) # Translate and print instruction translate_mnemonic(chip, _tps, exe, opcode, 'D', words, False) byte_count = byte_count + 1 if show_lbls: msg_labels(lbls) return None
def test_scenario1(address12): """Test JUN instruction functionality.""" chip_test = Processor() chip_base = Processor() # Set chip to initial status chip_test.PROGRAM_COUNTER = 0 # Perform the instruction under test: Processor.jun(chip_test, address12) # Simulate conditions at end of instruction in base chip chip_base.PROGRAM_COUNTER = address12 # Make assertions that the base chip is now at the same state as # the test chip which has been operated on by the instruction under test. assert chip_test.read_program_counter() == chip_base.read_program_counter() # Pickling each chip and comparing will show equality or not. assert pickle.dumps(chip_test) == pickle.dumps(chip_base)
def test_scenario1(registerpair): """Test FIM instruction functionality.""" chip_test = Processor() chip_base = Processor() rv = random.randint(0, 205) # Select a random 4-bit value # Perform the instruction under test: chip_test.PROGRAM_COUNTER = 0 # Simulate conditions at end of instruction in base chip chip_base.PROGRAM_COUNTER = 0 chip_base.increment_pc(2) # Convert a register pair into a base register for insertion base_register = registerpair * 2 chip_base.insert_register( base_register, (rv >> 4) & 15) # Bit-shift right and remove low bits # noqa chip_base.insert_register( base_register + 1, rv & 15) # Remove low bits # noqa # Carry out the instruction under test # Perform an FIM operation Processor.fim(chip_test, registerpair, rv) # Make assertions that the base chip is now at the same state as # the test chip which has been operated on by the instruction under test. assert chip_test.read_program_counter() == chip_base.read_program_counter() assert chip_test.read_accumulator() == chip_base.read_accumulator() assert chip_test.REGISTERS[base_register] == chip_base.REGISTERS[ base_register] # noqa assert chip_test.REGISTERS[base_register + 1] == chip_base.REGISTERS[base_register + 1] # noqa # Pickling each chip and comparing will show equality or not. assert pickle.dumps(chip_test) == pickle.dumps(chip_base)
def test_scenario1(values, register): """Test ISZ instruction functionality.""" chip_test = Processor() chip_base = Processor() pc = 100 pcaftjump = 150 pcaftnojump = 102 reg = register value = values[0] if values[1] == 'Y': pcaft = pcaftjump else: pcaft = pcaftnojump # Set both chips to initial status # Program Counter chip_test.PROGRAM_COUNTER = pc chip_base.PROGRAM_COUNTER = pc # Registers chip_test.insert_register(reg, value) chip_base.insert_register(reg, value) chip_base.increment_register(reg) # Perform the instruction under test: Processor.isz(chip_test, reg, pcaftjump) # Simulate conditions at end of instruction in base chip chip_base.PROGRAM_COUNTER = pcaft # Make assertions that the base chip is now at the same state as # the test chip which has been operated on by the instruction under test. assert chip_test.read_program_counter() == chip_base.read_program_counter() # Pickling each chip and comparing will show equality or not. assert pickle.dumps(chip_test) == pickle.dumps(chip_base)
def execute(chip: Processor, location: str, pc: int, monitor: bool, quiet: bool, operations: list) -> bool: """ Control the execution of a previously assembled program. Parameters ---------- chip : Processor, mandatory The instance of the processor containing the registers, accumulator etc location : str, mandatory The location to which the program should be loaded pc : int, mandatory The program counter value to commence execution monitor: bool, mandatory Whether or not the monitor is currently "on" or "off" quiet: bool, mandatory Whether or not quiet mode is on or off operations: list, mandatory List of functions i.e. instructions that are contained within the i4004 Returns ------- True in all instances Raises ------ N/A Notes ----- N/A """ # mccabe: MC0001 / execute is too complex (19) - start # mccabe: MC0001 / execute is too complex (13) # mccabe: MC0001 / execute is too complex (11) # mccabe: MC0001 / execute is too complex (5) breakpoints = [] # noqa chip.PROGRAM_COUNTER = pc opcode = 0 const_chip = 'chip.' _tps = retrieve_program(chip, location) try: # pseudo-opcode (directive) for "end" or end of memory while opcode != 256 and chip.PROGRAM_COUNTER < chip.MEMORY_SIZE_RAM: monitor_command = 'none' _, monitor_command, monitor, breakpoints, exe, opcode = \ process_instruction(chip, breakpoints, _tps, monitor, monitor_command, quiet, _tps[chip.PROGRAM_COUNTER]) if opcode == 256 or chip.PROGRAM_COUNTER == chip.MEMORY_SIZE_RAM: break # Execute instruction exe = const_chip + translate_mnemonic(chip, _tps, exe, opcode, 'E', 0, quiet) command, splitparams, p1, p2 = \ prep_single_instruction(exe, const_chip) if splitparams == ['']: _ = dispatch0(operations, command) elif p2 is None and p1 is not None: _ = dispatch1(operations, command, int(p1)) elif p2 is not None: _ = dispatch2(operations, command, int(p1), int(p2)) except Exception as ex: process_coredump(chip, ex) return False return True
def translate_mnemonic(chip: Processor, _tps: list, exe: str, opcode: str, task: str, words: int, quiet: bool) -> str: """ Formulate the opcodes into mnemonics ready for execution. Parameters ---------- chip : Processor, mandatory The instance of the processor containing the registers, accumulator etc _tps: list, mandatory List representing the memory of the i4004 into which the newly assembled instructions will be placed. exe: str, mandatory pre-formatted exe mnemonic ready for processing opcode: str, mandatory Opcode of the current instruction task: str, mandatory 'D' for Disassembly 'E' for Execution words: int, optional (supply 0) The number of words an instruction uses quiet: bool, mandatory Whether quiet mode is on Returns ------- exe: str A correctly formed, ready-for execution mnemonic Raises ------ N/A Notes ----- N/A """ custom_opcode = False cop = '' # Only mnemonic with 2 characters - fix if exe[:3] == 'ld ': exe = exe[:2] + exe[3:] # Ensure that the correct arguments are passed to the operations if exe[:3] == 'fim': exe = exe.replace('p', '').replace('data8)', '') +\ str(_tps[chip.PROGRAM_COUNTER + 1]) + ')' if exe[:3] == 'isz': # Remove opcode from 1st byte to get register first_byte = zfl(str(_tps[chip.PROGRAM_COUNTER] & 15), 4) exe = 'isz(' + str(int(first_byte, 2)) exe = exe + ',' + str(_tps[chip.PROGRAM_COUNTER + 1]) + ')' if exe[:4] == 'jcn(': custom_opcode = True address = _tps[chip.PROGRAM_COUNTER + 1] conditions = zfl(str(bin(_tps[chip.PROGRAM_COUNTER])[2:], 8)[4:]) b10address = str(address) cop = exe.replace('address8', b10address) exe = exe[:4] + str(int(conditions, 2)) + ',' + b10address + ')' if exe[:4] in ('jun(', 'jms('): custom_opcode = True # Remove opcode from 1st byte hvalue = zfl(bin(_tps[chip.PROGRAM_COUNTER] & 0xffff0000)[2:], 8)[:4] lvalue = zfl(bin(_tps[chip.PROGRAM_COUNTER + 1])[2:], 8) whole_value = str(int(hvalue + lvalue, 2)) cop = exe.replace('address12', whole_value) exe = exe[:4] + whole_value + ')' if task == 'D': if exe[:4] in ('jun(', 'jms(', 'jcn('): opcode = str(_tps[chip.PROGRAM_COUNTER]) + ', ' + \ str(_tps[chip.PROGRAM_COUNTER + 1]) if exe[:3] == 'end': # pseudo-opcode (directive "end" - stop program) custom_opcode = False exe, op = custom_opcode_logic(custom_opcode, cop, exe) if quiet is False: print('{:4} {:>8} {:<10}'.format(chip.PROGRAM_COUNTER, opcode, op.replace('()', ''))) # noqa chip.PROGRAM_COUNTER = chip.PROGRAM_COUNTER + words if task == 'E': exe, op = custom_opcode_logic(custom_opcode, cop, exe) if quiet is False: print(' {:>7} {:<10}'.format(opcode, op.replace('()', ''))) # noqa return exe
def test_wpm_scenario1_write(rambank, chip, register, address): """Test WPM instruction functionality.""" chip_test = Processor() chip_base = Processor() """ This piece of code writes an 8-bit value (consisting of 2 4-bit values) from the accumulator in 2 chunks. The setting up of this code and the execution of several WPM statements is key to the testing, although much has to be set up around those instructions to stage the tests. 1 FIM 0P 224 2 SRC 0P / Select ROM port 14. 3 LDM 1 4 WRR / Turn on write enable. 5 / Set up PRAM address. 6 / 7 FIM 0P 0 8 SRC 0P / Select DATA RAM chip 0 register 0. 9 RD1 / Read middle 4 bits of address. 10 XCH 10 / Save in register 10. 11 RD2 / Read lowest 4 bits of address. 12 XCH 11 / Save in register 11. 13 RD0 / Read highest 4 bits of address. 14 FIM 0P 240 15 SRC 0P / Select ROM port 15. 16 WRR / Write high address. 17 SRC 5P / Write middle + low address (RP5) 18 / 19 LD 2 / High 4 data bits to accumulator. 20 WPM / Write to PRAM 21 LD 3 / Low 4 data bits to accumulator. 22 WPM / Write to PRAM 23 FIM 0P 224 24 SRC 0P / Select ROM port 14. 25 CLB 26 WRR / Turn off write enable. """ # Perform the instruction under test: # Preamble..... chip_test.PROGRAM_COUNTER = 0 # Set PC to be zero chip_test.CURRENT_RAM_BANK = rambank # Set RAM BANK to be the supplied chip_base.PROGRAM_COUNTER = 0 # Set PC to be zero chip_base.CURRENT_RAM_BANK = rambank # Set RAM BANK to be the supplied register_pair = 5 reg_pair_first = (register_pair * 2) reg_pair_second = reg_pair_first + 1 # Lines 1 - 4 chip_test.ROM_PORT[14] = 1 # set the write enable flag # Perform common functionality chunks, _ = common_wpm_code_1(chip_test, chip, rambank, register, address, reg_pair_first, reg_pair_second) # Lines 17 - 18 chip_test.COMMAND_REGISTER = Processor.read_registerpair(chip_test, 5) # Lines 19 - 20 chip_test.set_accumulator(binary_to_decimal(str(chunks[0]))) Processor.wpm(chip_test) # Lines 21 - 22 chip_test.set_accumulator(binary_to_decimal(str(chunks[2]))) Processor.wpm(chip_test) # Lines 23 - 26 chip_test.set_accumulator(0) chip_test.reset_carry() chip_test.ROM_PORT[14] = 0 # Simulate conditions at end of instruction in base chip # Lines 1 - 4 chip_base.ROM_PORT[14] = 1 # set the write enable flag # Perform common functionality chunks, address_to_write_to = common_wpm_code_1(chip_base, chip, rambank, register, address, reg_pair_first, reg_pair_second) # Lines 17 - 18 chip_base.COMMAND_REGISTER = Processor.read_registerpair(chip_test, 5) # Lines 19 - 20 chip_base.set_accumulator(binary_to_decimal(str(chunks[0]))) chip_base.PRAM[address_to_write_to] = chip_base.ACCUMULATOR << 4 chip_base.RAM[address_to_write_to] = chip_base.ACCUMULATOR << 4 Processor.flip_wpm_counter(chip_base) chip_base.increment_pc(1) # Lines 21 - 22 chip_base.set_accumulator(binary_to_decimal(str(chunks[2]))) value = chip_base.ACCUMULATOR chip_base.PRAM[address_to_write_to] = \ chip_base.PRAM[address_to_write_to] + value chip_base.RAM[address_to_write_to] = \ chip_base.RAM[address_to_write_to] + value Processor.flip_wpm_counter(chip_base) chip_base.increment_pc(1) # Lines 23 - 26 chip_base.set_accumulator(0) chip_base.reset_carry() chip_base.ROM_PORT[14] = 0 # Make assertions that the base chip is now at the same state as # the test chip which has been operated on by the instruction under test. assert chip_test.read_program_counter() == chip_base.read_program_counter() assert chip_test.read_accumulator() == chip_base.read_accumulator() # Pickling each chip and comparing will show equality or not. assert pickle.dumps(chip_test) == pickle.dumps(chip_base)
def test_wpm_scenario1_read(rambank, chip, register, address): """Test WPM instruction functionality.""" chip_test = Processor() chip_base = Processor() """ This piece of code reads an 8-bit value (consisting of 2 4-bit values) from the program ram in 2 chunks. The setting up of this code and the execution of several WPM statements is key to the testing, although much has to be set up around those instructions to stage the tests. 1 FIM 0P 0 2 SRC 0P / Select DATA RAM chip 0 register 0. 3 RD1 / Read middle 4 bits of address. 4 XCH 10 / Save in register 10. 5 RD2 / Read lowest 4 bits of address. 6 XCH 11 / Save in register 11. 7 RD0 / Read highest 4 bits of address. 8 FIM 0P 240 9 SRC 0P / Select ROM port 15. 10 WRR / Write high address. 11 SRC 5P / Write middle + low address (RP5) 12 WPM / PRAM data to ROM port 14. 13 WPM / PRAM data to ROM port 15. 14 FIM 0P 224 15 SRC 0P / Select ROM port 14. 16 RDR / Read to accumulator 17 XCH 2 / Save in register 2 18 INC 0 19 SRC 0P / Select ROM port 15 20 RDR / Read to accumulator 21 XCH 3 / Save in register 3 """ # Perform the instruction under test: # Preamble..... chip_test.PROGRAM_COUNTER = 0 # Set PC to be zero chip_test.CURRENT_RAM_BANK = rambank # Set RAM BANK to be the supplied chip_base.PROGRAM_COUNTER = 0 # Set PC to be zero chip_base.CURRENT_RAM_BANK = rambank # Set RAM BANK to be the supplied register_pair = 5 reg_pair_first = (register_pair * 2) reg_pair_second = reg_pair_first + 1 # Perform common functionality chunks, address_to_write_to = common_wpm_code_1(chip_test, chip, rambank, register, address, reg_pair_first, reg_pair_second) # Line 11 chip_test.COMMAND_REGISTER = chip_test.read_registerpair(5) # Lines 12 - 13 Processor.wpm(chip_test) Processor.wpm(chip_test) # Lines 14 - 16 # Get the value from ROM port 14 to accumulator chip_test.set_accumulator(chip_test.ROM_PORT[14]) # Line 17 chip_test.REGISTERS[reg_pair_first] = chip_test.read_accumulator() # Lines 18 - 20 # Get the value from ROM port 15 to accumulator chip_test.set_accumulator(chip_test.ROM_PORT[15]) # Line 21 chip_test.REGISTERS[reg_pair_second] = chip_test.read_accumulator() # Simulate conditions in base chip # Perform common functionality chunks, address_to_write_to = common_wpm_code_1(chip_base, chip, rambank, register, address, reg_pair_first, reg_pair_second) # Line 11 chip_base.COMMAND_REGISTER = chip_base.read_registerpair(5) # Lines 12 - 13 chip_base.ROM_PORT[14] = chip_base.PRAM[address_to_write_to] >> 4 << 4 Processor.flip_wpm_counter(chip_base) chip_base.increment_pc(1) chip_base.ROM_PORT[15] = chip_base.PRAM[address_to_write_to] << 4 >> 4 Processor.flip_wpm_counter(chip_base) chip_base.increment_pc(1) # Lines 14 - 16 # Get the value from ROM port 14 to accumulator chip_base.set_accumulator(chip_base.ROM_PORT[14]) # Line 17 chip_base.REGISTERS[reg_pair_first] = chip_base.read_accumulator() # Lines 18 - 20 # Get the value from ROM port 15 to accumulator chip_base.set_accumulator(chip_base.ROM_PORT[15]) # Line 21 chip_base.REGISTERS[reg_pair_second] = chip_base.read_accumulator() # Make assertions that the base chip is now at the same state as # the test chip which has been operated on by the instruction under test. assert chip_test.read_program_counter() == chip_base.read_program_counter() assert chip_test.read_accumulator() == chip_base.read_accumulator() # Pickling each chip and comparing will show equality or not. assert pickle.dumps(chip_test) == pickle.dumps(chip_base)