Esempio n. 1
0
def test_timing_both_lt_128():
    """Follow the routine through, checking the timing comments

    This follows the case where both values are less than 128
    I'm just trying to check that the comments are correct!
    """
    RAM[vars.sysArgs:vars.sysArgs + 2] = 3, 5
    # fmt: off
    cycles = 9  # On entry to SYS, 9 cycles have already elapsed
    cycles += Emulator.run_to("SYS_MultiplyBytes_120")
    assert 14 == cycles  # noqa: E702, E241, E272
    cycles += Emulator.run_to("sys_MultiplyBytes.tableEntry")
    assert 29 == cycles  # noqa: E702, E241, E272
    cycles += Emulator.run_to(
        "sys_MultiplyBytes.high-byte-action.store-inverted")
    assert 35 == cycles  # noqa: E702, E241, E272
    cycles += Emulator.run_to("sys_MultiplyBytes.tableExit")
    assert 40 == cycles  # noqa: E702, E241, E272
    cycles += Emulator.run_to("sys_MultiplyBytes#44")
    assert 43 == cycles  # noqa: E702, E241, E272
    cycles += Emulator.run_to("sys_MultiplyBytes.tableEntry")
    assert 51 == cycles  # noqa: E702, E241, E272
    cycles += Emulator.run_to(
        "sys_MultiplyBytes.high-byte-action.restore-and-add")
    assert 57 == cycles  # noqa: E702, E241, E272
    cycles += Emulator.run_to("sys_MultiplyBytes.tableExit")
    assert 64 == cycles  # noqa: E702, E241, E272
    cycles += Emulator.run_to("sys_MultiplyBytes#68")
    assert 67 == cycles  # noqa: E702, E241, E272
    cycles += Emulator.run_to("NEXTY")
    assert 90 == cycles  # noqa: E702, E241, E272
Esempio n. 2
0
def test_read_initial_state():
    # The following are not necessary, but it was very helpful in debugging
    Emulator.run_to(0x2FF, max_instructions=10_000_000)  # Entry of vCPU
    Emulator.run_vcpu_to(0x200)  # Pass through loading sequence
    buffer = bytearray()
    for _ in range(5):
        value = Emulator.read_serial(bits=8)
        buffer.append(value)
    assert buffer == b"READY"
Esempio n. 3
0
def setup_module():
    global vars
    """Load the Emulator from the ROM script"""
    reload(asm)
    name, _ = os.path.splitext(os.path.basename(SCRIPT))
    script_globals = {"__file__": str(SCRIPT.absolute()), "__name__": name}
    with SCRIPT.open("rb") as file:
        exec(compile(file.read(), SCRIPT, "exec"), script_globals)
    Emulator.load_rom_from_asm_module()
    vars = SimpleNamespace(**script_globals)
Esempio n. 4
0
def test_MulShift8(a, b):
    _prepare_for_vcpu_execution_at(execution_address)
    Emulator.run_vcpu_to(
        0x300)  # Run the first page, so the variable is defined
    _write_word(vars.sysFn, asm.symbol("SYS_MultiplyBytes_120"), signed=False)
    _write_word(symbol_table["A"], a, signed=True)
    _write_word(symbol_table["B"], b, signed=True)

    _call_vcpu_function("MulShift8")

    assert int(a * b / 256) == _read_word(vars.vAC, signed=True)
Esempio n. 5
0
def test_timing_one_lt_128():
    """Follow the routine through, checking the timing comments

    This follows the case where one value is less than 128
    """
    RAM[vars.sysArgs:vars.sysArgs + 2] = 3, 160
    # fmt: off
    cycles = 9  # On entry to SYS, 9 cycles have already elapsed
    cycles += Emulator.run_to("sys_MultiplyBytes#68")
    assert 67 == cycles  # noqa: E702, E241, E272
    cycles += Emulator.run_to("sys_MultiplyBytes.oneMsbSetCase")
    assert 85 == cycles  # noqa: E702, E241, E272
    cycles += Emulator.run_to("sys_MultiplyBytes#92")
    assert 91 == cycles  # noqa: E702, E241, E272
Esempio n. 6
0
def test_timing_neither_lt_128():
    """Follow the routine through, checking the timing comments

    This follows the case where neither value is less than 128
    """
    RAM[vars.sysArgs:vars.sysArgs + 2] = 172, 160
    # fmt: off
    cycles = 9  # On entry to SYS, 9 cycles have already elapsed
    cycles += Emulator.run_to("sys_MultiplyBytes#68")
    assert 67 == cycles  # noqa: E702, E241, E272, E221
    cycles += Emulator.run_to("sys_MultiplyBytes#92")
    assert 91 == cycles  # noqa: E702, E241, E272, E221
    cycles += Emulator.run_to("sys_MultiplyBytes#114")
    assert 113 == cycles  # noqa: E702, E241, E272
    cycles += Emulator.run_to("NEXTY")
    assert 118 == cycles  # noqa: E702, E241, E272
Esempio n. 7
0
def test_multiplication_8(a, b):
    """Multiplication of two eight-bit integers should work"""
    Emulator.reset()
    RAM[vars.a] = a
    RAM[vars.b] = b
    Emulator.next_instruction = "multiply 8x8"
    expected_saving = (vars.no_msb_cost_saving if a < 128 and b < 128 else
                       vars.one_msb_cost_saving if a < 128 or b < 128 else 0)

    cycles = Emulator.run_to("done")

    result = int.from_bytes(RAM[vars.result:vars.result + 2],
                            "little",
                            signed=False)
    assert a * b == result
    assert vars.cost_of_8bit_multiply - expected_saving == cycles
Esempio n. 8
0
def test_low_byte_lookup(value):
    """Lookup of the low-byte of a quarter square should work"""
    Emulator.Y = asm.symbol("Quarter-squares lookup table") >> 8
    Emulator.AC = value
    Emulator.next_instruction = "low-byte table entry"

    cycles = Emulator.run_to("low-byte return point")

    assert int(math.floor((value**2) / 4)) & 0xFF == Emulator.AC
    assert vars.cost_of_low_byte_table_entry == cycles
Esempio n. 9
0
def test_multiply_bytes(a, b):
    setup_function()
    RAM[vars.sysArgs:vars.sysArgs + 2] = a, b

    cycles = 10  # Because Next is marked as zero
    cycles += Emulator.run_to("NEXT")

    assert cycles <= MAX_CYCLES
    assert cycles == _sign_extend(Emulator.AC) * -2
    assert a * b == Emulator.vAC
Esempio n. 10
0
def setup_module():
    global vars, symbol_table, execution_address
    """Load the Emulator from the ROM script and Mandelbrot
    """
    reload(asm)
    name, _ = os.path.splitext(os.path.basename(SCRIPT))
    script_globals = {"__file__": str(SCRIPT.absolute()), "__name__": name}
    with SCRIPT.open("rb") as file:
        exec(compile(file.read(), SCRIPT, "exec"), script_globals)
    Emulator.load_rom_from_asm_module()
    vars = SimpleNamespace(**script_globals)

    # This sequence of calls is roughly taken from compilegcl.py
    old_rom_size = asm._romSize
    program = gcl.Program("Mandelbrot", forRom=False)
    user_code = asm.symbol("userCode")
    user_vars = asm.symbol("userVars")
    program.org(user_code)
    asm.align(1)
    asm.zpReset(user_vars)
    with GCL.open("r", encoding="utf-8") as fp:
        for line in fp.readlines():
            program.line(line)
    program.end()
    asm.end()

    # Copy the resulting data straight into RAM, in the appropriate blocks
    data = asm.getRom1()[old_rom_size:]
    index, more_data = 0, bool(data)
    while more_data:
        start_address = int.from_bytes(data[index:index + 2],
                                       "big",
                                       signed=False)
        index += 2
        size = data[index] or 256
        index += 1
        chunk = data[index:index + size]
        index += size
        RAM[start_address:start_address + len(chunk)] = chunk
        more_data = data[index]
    execution_address = program.execute
    symbol_table = program.vars
Esempio n. 11
0
def test_high_byte_lookup(value):
    """Lookup of the high-byte of a quarter square should work"""
    RAM[vars.high_byte_action] = asm.symbol("high-byte action.store")
    Emulator.AC = value
    Emulator.Y = asm.symbol("Quarter-squares lookup table") >> 8
    Emulator.next_instruction = "table entry"

    cycles = Emulator.run_to("high-byte action.store")

    assert int(math.floor((value**2) / 4)) >> 8 == Emulator.AC
    assert vars.cost_of_high_byte_table_entry == cycles
Esempio n. 12
0
def test_multiplication_7(a, b):
    """Multiplication of two seven-bit integers should work"""
    RAM[vars.a] = a
    RAM[vars.b] = b
    Emulator.next_instruction = "multiply 7x7"

    cycles = Emulator.run_to("done")

    result = int.from_bytes(RAM[vars.result:vars.result + 2],
                            "little",
                            signed=False)
    assert a * b == result
    assert vars.cost_of_7bit_multiply == cycles
Esempio n. 13
0
def test_subtract_quarter_square(a, b, previous_value):
    """to done should subtract the"""
    RAM[vars.a] = a
    RAM[vars.b] = b
    RAM[vars.result:vars.result + 2] = (previous_value + 1).to_bytes(
        2, "little", signed=False)
    Emulator.Y = asm.symbol("Quarter-squares lookup table") >> 8
    Emulator.next_instruction = asm.symbol(".after-first-lookup") + 2
    expected = (previous_value - math.floor((a - b)**2 / 4)) & 0xFFFF

    cycles = Emulator.run_to(asm.symbol("done"))

    assert expected == int.from_bytes(RAM[vars.result:vars.result + 2],
                                      "little",
                                      signed=False)
    assert asm.symbol("Quarter-squares lookup table") >> 8 == Emulator.Y
    assert vars.cost_of_7bit_multiply - vars.cost_after_first_lookup - 2 == cycles
Esempio n. 14
0
def test_both_byte_lookup(a, b):
    """Lookup of both bytes of a quarter square should work

    The multiplication routine actually adds 1 to the result,
    so storing it, so check for that.
    """
    RAM[vars.a] = a
    RAM[vars.b] = b
    Emulator.next_instruction = "multiply 7x7"
    expected = int(math.floor(((a + b)**2) / 4)) + 1

    cycles = Emulator.run_to(asm.symbol(".after-first-lookup") + 2)

    assert expected == int.from_bytes(RAM[vars.result:vars.result + 2],
                                      "little",
                                      signed=False)
    assert cycles == vars.cost_after_first_lookup + 2
    assert asm.symbol("Quarter-squares lookup table") >> 8 == Emulator.Y
Esempio n. 15
0
def emulator():
    emulator = Emulator()
    emulator.zero_memory()
    yield emulator
    print(emulator.state)
Esempio n. 16
0
def setup_module():
    Emulator.load_rom_file(_ROM_FILE)
Esempio n. 17
0
def test_write():
    assert _read_bytes(5) == b"READY"
    for b in b"Hello":
        Emulator.send_byte(b)
    assert _read_bytes(5) == b"Hello"
Esempio n. 18
0
def _read_bytes(n):
    buffer = bytearray()
    for _ in range(n):
        buffer.append(Emulator.read_serial(bits=8))
    return bytes(buffer)
Esempio n. 19
0
def setup_function():
    Emulator.reset()
Esempio n. 20
0
def _call_vcpu_function(variable):
    return_point = Emulator.vPC & 0xFF00 | (Emulator.vPC + 2) & 0xFF
    Emulator.AC = symbol_table[variable]
    Emulator.next_instruction = "CALL"
    Emulator.step_vcpu()  # Execute CALL
    Emulator.run_vcpu_to(return_point)