예제 #1
0
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)
예제 #3
0
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)
예제 #4
0
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)
예제 #5
0
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)
예제 #7
0
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)
예제 #9
0
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)
예제 #10
0
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)
예제 #12
0
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
예제 #13
0
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
예제 #14
0
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)
예제 #15
0
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)
예제 #17
0
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
예제 #18
0
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
예제 #19
0
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)
예제 #20
0
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)