Пример #1
0
def test_zbyte_bitwise_operations():
    zb = ZByte.from_unsigned_int(0b1010_1010) << 1
    assert zb.unsigned_int == 0b0101_0100

    zb = ZByte.from_unsigned_int(0b0000_1111) << 4
    assert zb.unsigned_int == 0b1111_0000

    zb = ZByte.from_unsigned_int(0b1111_0000) >> 4
    assert zb.unsigned_int == 0b0000_1111

    zb = ZByte.from_unsigned_int(0b0001_0000) >> 1
    assert zb.unsigned_int == 0b0000_1000

    zb = ZByte.from_unsigned_int(0b1111_1111) & 0b0101_0101
    assert zb.bytes == b'\x55'

    zb = ZByte.from_unsigned_int(0b1111_0000) | 0b0000_1111
    assert zb.bytes == b'\xff'

    zb = ~ZByte.from_unsigned_int(0b0101_0101)
    assert zb.unsigned_int == 0b1010_1010

    zb = ~ZByte.from_unsigned_int(0b0000_1111)
    assert zb.unsigned_int == 0b1111_0000

    zb = ZByte.from_unsigned_int(0b1010_1100)
    assert zb.is_bit_set(7) is True
    assert zb.is_bit_set(0) is False
    assert zb.is_bit_set(3) is True
    assert zb.is_bit_clear(7) is False
    assert zb.is_bit_clear(0) is True
    assert zb.is_bit_clear(3) is False

    assert ZByte.from_int(1) == ZByte(b'\x01')
    assert ZByte.from_int(42) != ZByte(b'\x01')
Пример #2
0
def test_instantiating_zbyte():
    zb = ZByte(bytes.fromhex('12'))
    assert zb.bytes == b'\x12', 'Instantiate ZByte from bytes'

    zb = ZByte(memoryview(bytes.fromhex('42')))
    assert zb.bytes == b'\x42', 'Instantiate ZByte from memoryview'

    zb = ZByte.from_int(-1)
    assert zb.bytes == b'\xff', 'Instantiate ZByte from int'

    zb = ZByte.from_unsigned_int(0xf0)
    assert zb.bytes == b'\xf0', 'Instantiate ZByte from unsigned int'

    with pytest.raises(TypeError):
        ZByte(22)

    with pytest.raises(ValueError):
        ZByte(b'')

    with pytest.raises(ValueError):
        ZByte.from_int(-129)

    with pytest.raises(ValueError):
        ZByte.from_int(128)

    with pytest.raises(ValueError):
        ZByte.from_unsigned_int(-1)

    with pytest.raises(ValueError):
        ZByte.from_unsigned_int(256)
Пример #3
0
def test_long_form_opcodes(opcodes_v3: ZMachineOpcodeParserV3):
    add, next_pc = opcodes_v3.parse(0x4e83)
    assert add.name == 'add'
    assert len(add.operand_types) == 2
    assert len(add.operands) == 2
    assert add.operand_types == (ZMachineOperandTypes.VARIABLE,
                                 ZMachineOperandTypes.SMALL_CONSTANT)
    assert add.operands == (ZByte(b'\x01'), ZByte(b'\x02'))
    assert next_pc == 0x4e83 + 4
Пример #4
0
def test_short_form_opcodes(opcodes_v3: ZMachineOpcodeParserV3):
    # One operand of type LARGE_CONSTANT
    jump, next_pc = opcodes_v3.parse(0x85ab)
    assert jump.name == 'jump'
    assert len(jump.operand_types) == 1
    assert len(jump.operands) == 1
    assert jump.operand_types[0] == ZMachineOperandTypes.LARGE_CONSTANT
    assert jump.operands[0] == ZWord(bytes([0x00, 0x0b]))
    assert next_pc == 0x85ab + 3

    # One operand of type VARIABLE
    load, next_pc = opcodes_v3.parse(0x7d58)
    assert load.name == 'load'
    assert len(load.operand_types) == 1
    assert len(load.operands) == 1
    assert load.operand_types[0] == ZMachineOperandTypes.VARIABLE
    assert load.operands[0] == ZByte(b'\x00')
    assert next_pc == 0x7d58 + 3

    # Zero operands
    print_ret, next_pc = opcodes_v3.parse(0x4fb1)
    assert print_ret.name == 'print_ret'
    assert print_ret.operand_types is None
    assert print_ret.operands is None
    assert next_pc == 0x4fc4
Пример #5
0
def test_set_own_property_v3(zork_v3_obj_table: ZMachineObjectTable):
    # Property #16 is a single-byte property
    pair_of_hands = zork_v3_obj_table.object(1)

    # Set with a single byte
    pair_of_hands.properties.set(16, ZByte(b'\x42'))
    assert ZByte(b'\x42') == pair_of_hands.properties.value(16), \
        'a single byte property is set with a single byte value'

    # Set with two bytes
    pair_of_hands.properties.set(16, ZWord.from_int(-6))
    assert ZByte.from_int(-6) == pair_of_hands.properties.value(16), \
        'a single byte property is set with a two byte value'

    # Property #18 is a two-byte property
    zorkmid = zork_v3_obj_table.object(2)

    zorkmid.properties.set(18, ZWord(b'\x12\x34'))
    assert ZWord(b'\x12\x34') == zorkmid.properties.value(18)
Пример #6
0
def test_zbyte_to_zbyte_math():
    zb = ZByte.from_int(0) + ZByte.from_int(12)
    assert zb.bytes == b'\x0c', 'ZByte + ZByte'

    zb = ZByte.from_int(0) - ZByte.from_int(1)
    assert zb.bytes == b'\xff', 'ZByte - ZByte'

    zb = ZByte.from_int(-128) - ZByte.from_int(1)
    assert zb.bytes == b'\x7f', 'Zbyte arithmetic truncation'

    zb = ZByte.from_int(-2) * ZByte.from_int(8)
    assert zb.int == -16, 'ZByte * ZByte'

    zb = ZByte.from_int(127) * ZByte.from_int(127)
    assert zb.bytes == b'\x01', 'ZByte multiplication truncation'

    zb = ZByte.from_int(3) // ZByte.from_int(2)
    assert zb.bytes == b'\x01', 'ZByte integer division'

    with pytest.raises(ZMachineIllegalOperation, match='Divide by zero'):
        ZByte.from_int(45) // ZByte.from_int(0)

    with pytest.raises(ZMachineIllegalOperation):
        zb.from_int(4) / zb.from_int(8)

    zb = ZByte(b'\x01').inc()
    assert zb.bytes == b'\x02'

    zb = ZByte(b'\xff').inc()
    assert zb.bytes == b'\x00', 'Rollover on increment'

    zb = ZByte.from_int(0).dec()
    assert zb.int == -1

    zb = ZByte(b'\x00').dec()
    assert zb.bytes == b'\xff', 'Rollover on decrement'

    zb = ZByte.from_int(127) % ZByte.from_int(2)
    assert zb.int == 1

    zb = ZByte.from_int(-128) % ZByte.from_int(2)
    assert zb.int == 0
Пример #7
0
def test_variable_form_opcodes(opcodes_v3: ZMachineOpcodeParserV3):
    # Test variable form of 2OP opcode instructions
    call, next_pc = opcodes_v3.parse(0x5157)
    assert call.name == 'je'
    assert len(call.operand_types) == 3
    assert call.operand_types == (ZMachineOperandTypes.VARIABLE,
                                  ZMachineOperandTypes.SMALL_CONSTANT,
                                  ZMachineOperandTypes.SMALL_CONSTANT)
    assert call.operands == (ZByte(b'\x88'), ZByte(b'\x32'), ZByte(b'\x12'))
    assert next_pc == 0x5157 + 6

    # Test unique variable opcode instructions
    call, next_pc = opcodes_v3.parse(0x4f05)
    assert call.name == 'call'
    assert len(call.operand_types) == 3
    assert call.operand_types == (ZMachineOperandTypes.LARGE_CONSTANT,
                                  ZMachineOperandTypes.LARGE_CONSTANT,
                                  ZMachineOperandTypes.LARGE_CONSTANT)
    assert len(call.operands) == 3

    assert call.operands == (ZWord(bytes([0x2a,
                                          0x39])), ZWord(bytes([0x80, 0x10])),
                             ZWord(bytes([0xff, 0xff])))
    assert next_pc == 0x4f05 + 9