Ejemplo n.º 1
0
def print_obj(env, opinfo):
    obj = opinfo.operands[0]
    string = get_obj_str(env, obj)
    write(env, string)

    if DBG:
        warn('    obj', obj, '(', get_obj_str(env, obj), ')')
Ejemplo n.º 2
0
def get_next_prop(env, opinfo):
    obj = opinfo.operands[0]
    prop_num = opinfo.operands[1]

    next_prop_num = 0
    if obj:
        if prop_num == 0:
            prop_start = get_prop_list_start(env, obj)
            next_prop_num = get_prop_num(env, prop_start)
        else:
            prop_data_ptr = get_prop_data_ptr_from_obj(env, obj, prop_num)
            if prop_data_ptr == 0:
                msg = 'get_next_prop: passed nonexistant prop '
                msg += str(prop_num)+' for obj '+str(obj)+' ('+get_obj_str(env,obj)+')'
                print_prop_list(env, obj)
                err(msg)
            sizenum_ptr = get_sizenum_ptr(env, prop_data_ptr)
            size = get_prop_size(env, sizenum_ptr)
            next_prop_num = get_prop_num(env, prop_data_ptr + size)
    set_var(env, opinfo.store_var, next_prop_num)

    if DBG:
        warn('    prop_num', prop_num)
        warn('    next_prop_num', next_prop_num)
        print_prop_list(env, obj)
Ejemplo n.º 3
0
def print_obj(env, opinfo):
    obj = opinfo.operands[0]
    string = get_obj_str(env, obj)
    write(env, string)

    if DBG:
        warn('    obj', obj, '(', get_obj_str(env, obj), ')')
Ejemplo n.º 4
0
def insert_obj(env, opinfo):
    obj = opinfo.operands[0]
    dest = opinfo.operands[1]

    if not obj or not dest:
        return

    # it doesn't say explicitly to make obj's parent
    # field say dest, but *surely* that's the right
    # thing to do. Right?
    # (based on what the ops seems to expect, I think so)

    # Also, should I remove it from its old parent?
    # Looks like, based on the current bug I have.
    _remove_obj(env, obj)
    # Ok, Yep. That totally fixed things.

    dest_child = get_child_num(env, dest)

    set_parent_num(env, obj, dest)
    set_sibling_num(env, obj, dest_child)
    set_child_num(env, dest, obj)

    if DBG:
        warn('    obj', obj, '(', get_obj_str(env, obj), ')')
        warn('    dest', dest, '(', get_obj_str(env, dest), ')')
Ejemplo n.º 5
0
def insert_obj(env, opinfo):
    obj = opinfo.operands[0]
    dest = opinfo.operands[1]

    if not obj or not dest:
        return

    # it doesn't say explicitly to make obj's parent
    # field say dest, but *surely* that's the right
    # thing to do. Right? 
    # (based on what the ops seems to expect, I think so)

    # Also, should I remove it from its old parent?
    # Looks like, based on the current bug I have.
    _remove_obj(env, obj)
    # Ok, Yep. That totally fixed things.

    dest_child = get_child_num(env, dest)

    set_parent_num(env, obj, dest)
    set_sibling_num(env, obj, dest_child)
    set_child_num(env, dest, obj)

    if DBG:
        warn('    obj', obj, '(', get_obj_str(env,obj), ')')
        warn('    dest', dest, '(', get_obj_str(env,dest), ')')
Ejemplo n.º 6
0
def scan_table(env, opinfo):
    val = opinfo.operands[0]
    tab_addr = opinfo.operands[1]
    tab_len = opinfo.operands[2]
    if len(opinfo.operands) > 3:
        form = opinfo.operands[3]
    else:
        form = 0x82
    val_size = (form >> 7) + 1  # word or byte
    field_len = form & 127

    addr = 0
    for i in range(tab_len):
        test_addr = tab_addr + i * field_len
        if val_size == 2:
            test_val = env.u16(test_addr)
        else:
            test_val = env.mem[test_addr]
        if val == test_val:
            addr = test_addr
            break
    found = addr != 0
    set_var(env, opinfo.store_var, addr)
    if found == opinfo.branch_on:
        handle_branch(env, opinfo.branch_offset)

    if DBG:
        warn('    found', found)
        warn('    addr', addr)
Ejemplo n.º 7
0
def scan_table(env, opinfo):
    val = opinfo.operands[0]
    tab_addr = opinfo.operands[1]
    tab_len = opinfo.operands[2]
    if len(opinfo.operands) > 3:
        form = opinfo.operands[3]
    else:
        form = 0x82
    val_size = (form >> 7) + 1 # word or byte
    field_len = form & 127

    addr = 0
    for i in range(tab_len):
        test_addr = tab_addr + i*field_len
        if val_size == 2:
            test_val = env.u16(test_addr)
        else:
            test_val = env.mem[test_addr]
        if val == test_val:
            addr = test_addr
            break
    found = addr != 0
    set_var(env, opinfo.store_var, addr)
    if found == opinfo.branch_on:
        handle_branch(env, opinfo.branch_offset)

    if DBG:
        warn('    found', found)
        warn('    addr', addr)
Ejemplo n.º 8
0
def get_next_prop(env, opinfo):
    obj = opinfo.operands[0]
    prop_num = opinfo.operands[1]

    next_prop_num = 0
    if obj:
        if prop_num == 0:
            prop_start = get_prop_list_start(env, obj)
            next_prop_num = get_prop_num(env, prop_start)
        else:
            prop_data_ptr = get_prop_data_ptr_from_obj(env, obj, prop_num)
            if prop_data_ptr == 0:
                msg = 'get_next_prop: passed nonexistant prop '
                msg += str(prop_num) + ' for obj ' + str(
                    obj) + ' (' + get_obj_str(env, obj) + ')'
                print_prop_list(env, obj)
                err(msg)
            sizenum_ptr = get_sizenum_ptr(env, prop_data_ptr)
            size = get_prop_size(env, sizenum_ptr)
            next_prop_num = get_prop_num(env, prop_data_ptr + size)
    set_var(env, opinfo.store_var, next_prop_num)

    if DBG:
        warn('    prop_num', prop_num)
        warn('    next_prop_num', next_prop_num)
        print_prop_list(env, obj)
Ejemplo n.º 9
0
def _print_addr(env, addr):
    packed_string = read_packed_string(env, addr)
    string = unpack_string(env, packed_string)
    write(env, string)

    if DBG:
        warn('    helper: _print_addr')
        warn('            addr', addr)
Ejemplo n.º 10
0
def _print_addr(env, addr):
    packed_string = read_packed_string(env, addr)
    string = unpack_string(env, packed_string)
    write(env, string)

    if DBG:
        warn('    helper: _print_addr')
        warn('            addr', addr)
Ejemplo n.º 11
0
def get_parent(env, opinfo):
    obj = opinfo.operands[0]

    parent_num = get_parent_num(env, obj)
    set_var(env, opinfo.store_var, parent_num)

    if DBG:
        warn('    obj', obj, '(', get_obj_str(env, obj), ')')
        warn('    parent', parent_num, '(', get_obj_str(env, parent_num), ')')
Ejemplo n.º 12
0
def get_parent(env, opinfo):
    obj = opinfo.operands[0]

    parent_num = get_parent_num(env, obj)
    set_var(env, opinfo.store_var, parent_num)

    if DBG:
        warn('    obj', obj,'(',get_obj_str(env, obj),')')
        warn('    parent', parent_num, '(',get_obj_str(env, parent_num),')')
Ejemplo n.º 13
0
def test(env, opinfo):
    bitmap = opinfo.operands[0]
    flags = opinfo.operands[1]
    result = bitmap & flags == flags

    if result == opinfo.branch_on:
        handle_branch(env, opinfo.branch_offset)

    if DBG:
        warn('    bitmap', bin(bitmap))
        warn('    flags', bin(flags))
Ejemplo n.º 14
0
def read_char(env, opinfo):
    # NOTE: operands[0] must be 1, but I ran into a z5 that passed no operands
    # (strictz) so let's just ignore the first operand instead...
    if len(opinfo.operands) > 1:
        if len(opinfo.operands) != 3:
            err('read_char: num operands must be 1 or 3')
        if opinfo.operands[1] != 0 or opinfo.operands[2] != 0:
            if DBG:
                warn('read_char: interrupts not impl\'d yet!')
    c = ascii_to_zscii(env.screen.getch_or_esc_seq())[0]
    set_var(env, opinfo.store_var, c)
Ejemplo n.º 15
0
def test(env, opinfo):
    bitmap = opinfo.operands[0]
    flags = opinfo.operands[1]
    result = bitmap & flags == flags

    if result == opinfo.branch_on:
        handle_branch(env, opinfo.branch_offset)

    if DBG:
        warn('    bitmap', bin(bitmap))
        warn('    flags', bin(flags))
Ejemplo n.º 16
0
def read_char(env, opinfo):
    # NOTE: operands[0] must be 1, but I ran into a z5 that passed no operands
    # (strictz) so let's just ignore the first operand instead...
    if len(opinfo.operands) > 1:
        if len(opinfo.operands) != 3:
            err('read_char: num operands must be 1 or 3')
        if opinfo.operands[1] != 0 or opinfo.operands[2] != 0:
            if DBG:
                warn('read_char: interrupts not impl\'d yet!')
    c = ascii_to_zscii(env.screen.getch_or_esc_seq())[0]
    set_var(env, opinfo.store_var, c)
Ejemplo n.º 17
0
def get_child(env, opinfo):
    obj = opinfo.operands[0]

    child_num = get_child_num(env, obj)
    set_var(env, opinfo.store_var, child_num)

    result = child_num != 0
    if result == opinfo.branch_on:
        handle_branch(env, opinfo.branch_offset)

    if DBG:
        warn('    obj', obj, '(', get_obj_str(env, obj), ')')
        warn('    child', child_num, '(', get_obj_str(env, child_num), ')')
Ejemplo n.º 18
0
def get_sibling(env, opinfo):
    obj = opinfo.operands[0]

    sibling_num = get_sibling_num(env, obj)
    set_var(env, opinfo.store_var, sibling_num)

    result = sibling_num != 0
    if result == opinfo.branch_on:
        handle_branch(env, opinfo.branch_offset)

    if DBG:
        warn('    obj', obj,'(',get_obj_str(env, obj),')')
        warn('    sibling', sibling_num, '(',get_obj_str(env, sibling_num),')')
Ejemplo n.º 19
0
def get_child(env, opinfo):
    obj = opinfo.operands[0]

    child_num = get_child_num(env, obj)
    set_var(env, opinfo.store_var, child_num)

    result = child_num != 0
    if result == opinfo.branch_on:
        handle_branch(env, opinfo.branch_offset)

    if DBG:
        warn('    obj', obj,'(',get_obj_str(env, obj),')')
        warn('    child', child_num, '(',get_obj_str(env, child_num),')')
Ejemplo n.º 20
0
def save(env, opinfo):
    # TODO handle optional operands
    if len(opinfo.operands) > 0:
        if DBG:
            warn('restore: found operands (not yet impld): '+str(opinfo.operands))
        set_var(env, opinfo.store_var, 0)
        return

    filename = env.screen.get_line_of_input('input save filename: ')
    if quetzal.write(env, filename):
        set_var(env, opinfo.store_var, 1)
    else:
        set_var(env, opinfo.store_var, 0)
Ejemplo n.º 21
0
def get_prop(env, opinfo):
    obj = opinfo.operands[0]
    prop_num = opinfo.operands[1]

    prop_data_ptr = get_prop_data_ptr_from_obj(env, obj, prop_num)
    is_default_prop = prop_data_ptr == 0
    if is_default_prop:
        base = env.hdr.obj_tab_base
        result = env.u16(base + 2*(prop_num-1))
    else:
        sizenum_ptr = get_sizenum_ptr(env, prop_data_ptr)
        size = get_prop_size(env, sizenum_ptr)
        if size == 1:
            result = env.mem[prop_data_ptr]
        elif size == 2 or FORGIVING_GET_PROP:
            result = env.u16(prop_data_ptr)
        else:
            msg = 'illegal op: get_prop on outsized prop (not 1-2 bytes)'
            msg += ' - prop '+str(prop_num)
            msg += ' of obj '+str(obj)+' ('+get_obj_str(env, obj)+')'
            msg += ' (sized at '+str(size)+' bytes)'
            print_prop_list(env, obj)
            err(msg)

    set_var(env, opinfo.store_var, result)

    if DBG:
        warn('    obj', obj,'(',get_obj_str(env,obj),')')
        warn('    prop_num', prop_num)
        warn('    result', result)
        warn('    is_default_prop', is_default_prop)
        print_prop_list(env, obj)
Ejemplo n.º 22
0
def check_arg_count(env, opinfo):
    arg_num = opinfo.operands[0]
    frame = env.callstack[-1]
    result = frame.num_args >= arg_num

    if result == opinfo.branch_on:
        handle_branch(env, opinfo.branch_offset)

    if DBG:
        warn('    arg_num', arg_num)
        warn('    num args in frame', frame.num_args)
        warn('    branch_offset', opinfo.branch_offset)
        warn('    branch_on', opinfo.branch_on)
        warn('    result', result)
Ejemplo n.º 23
0
def get_sibling(env, opinfo):
    obj = opinfo.operands[0]

    sibling_num = get_sibling_num(env, obj)
    set_var(env, opinfo.store_var, sibling_num)

    result = sibling_num != 0
    if result == opinfo.branch_on:
        handle_branch(env, opinfo.branch_offset)

    if DBG:
        warn('    obj', obj, '(', get_obj_str(env, obj), ')')
        warn('    sibling', sibling_num, '(', get_obj_str(env, sibling_num),
             ')')
Ejemplo n.º 24
0
def get_prop(env, opinfo):
    obj = opinfo.operands[0]
    prop_num = opinfo.operands[1]

    prop_data_ptr = get_prop_data_ptr_from_obj(env, obj, prop_num)
    is_default_prop = prop_data_ptr == 0
    if is_default_prop:
        base = env.hdr.obj_tab_base
        result = env.u16(base + 2 * (prop_num - 1))
    else:
        sizenum_ptr = get_sizenum_ptr(env, prop_data_ptr)
        size = get_prop_size(env, sizenum_ptr)
        if size == 1:
            result = env.mem[prop_data_ptr]
        elif size == 2 or FORGIVING_GET_PROP:
            result = env.u16(prop_data_ptr)
        else:
            msg = 'illegal op: get_prop on outsized prop (not 1-2 bytes)'
            msg += ' - prop ' + str(prop_num)
            msg += ' of obj ' + str(obj) + ' (' + get_obj_str(env, obj) + ')'
            msg += ' (sized at ' + str(size) + ' bytes)'
            print_prop_list(env, obj)
            err(msg)

    set_var(env, opinfo.store_var, result)

    if DBG:
        warn('    obj', obj, '(', get_obj_str(env, obj), ')')
        warn('    prop_num', prop_num)
        warn('    result', result)
        warn('    is_default_prop', is_default_prop)
        print_prop_list(env, obj)
Ejemplo n.º 25
0
def check_arg_count(env, opinfo):
    arg_num = opinfo.operands[0]
    frame = env.callstack[-1]
    result = frame.num_args >= arg_num

    if result == opinfo.branch_on:
        handle_branch(env, opinfo.branch_offset)

    if DBG:
        warn('    arg_num', arg_num)
        warn('    num args in frame', frame.num_args)
        warn('    branch_offset', opinfo.branch_offset)
        warn('    branch_on', opinfo.branch_on)
        warn('    result', result)
Ejemplo n.º 26
0
def save(env, opinfo):
    # TODO handle optional operands
    if len(opinfo.operands) > 0:
        if DBG:
            warn('restore: found operands (not yet impld): ' +
                 str(opinfo.operands))
        set_var(env, opinfo.store_var, 0)
        return

    filename = env.screen.get_line_of_input('input save filename: ')
    if quetzal.write(env, filename):
        set_var(env, opinfo.store_var, 1)
    else:
        set_var(env, opinfo.store_var, 0)
Ejemplo n.º 27
0
def clear_attr(env, opinfo):
    obj = opinfo.operands[0]
    attr = opinfo.operands[1]

    if obj:
        obj_addr = get_obj_addr(env, obj)

        attr_byte = attr // 8
        mask = 2**(7 - attr % 8)
        old_val = env.mem[obj_addr + attr_byte]
        env.write8(obj_addr + attr_byte, old_val & ~mask)

    if DBG:
        warn('    obj', obj, '(', get_obj_str(env, obj), ')')
        warn('    attr', attr)
Ejemplo n.º 28
0
def clear_attr(env, opinfo):
    obj = opinfo.operands[0]
    attr = opinfo.operands[1]

    if obj:
        obj_addr = get_obj_addr(env, obj)

        attr_byte = attr // 8
        mask = 2**(7-attr%8)
        old_val = env.mem[obj_addr+attr_byte]
        env.write8(obj_addr+attr_byte, old_val & ~mask)

    if DBG:
        warn('    obj', obj, '(', get_obj_str(env,obj), ')')
        warn('    attr', attr)
Ejemplo n.º 29
0
def restore(env, opinfo):
    # TODO handle optional operands
    if len(opinfo.operands) > 0:
        if DBG:
            warn('restore: found operands (not yet impld): ' +
                 str(opinfo.operands))
        set_var(env, opinfo.store_var, 0)
        return
    loaded = restore_chooser(env)
    if loaded:
        # set and move past save inst's svar byte
        # (which quetzal gives as the PC)
        set_var(env, env.mem[env.pc], 2)
        env.pc += 1
    else:
        set_var(env, opinfo.store_var, 0)
Ejemplo n.º 30
0
def handle_return(env, return_val):
    frame = env.callstack.pop()
    if frame.return_addr == 0:
        err('returned from unreturnable/nonexistant function!')
    if frame.return_val_loc != None:
        set_var(env, frame.return_val_loc, return_val)
    env.pc = frame.return_addr

    if DBG:
        warn('    helper: handle_return')
        warn('        return_val', return_val)
        if frame.return_val_loc:
            warn('        return_val_loc', get_var_name(frame.return_val_loc))
        else:
            warn('        return_val_loc None')
        warn('        return_addr', hex(frame.return_addr))
Ejemplo n.º 31
0
def handle_return(env, return_val):
    frame = env.callstack.pop()
    if frame.return_addr == 0:
        err('returned from unreturnable/nonexistant function!')
    if frame.return_val_loc != None:
        set_var(env, frame.return_val_loc, return_val)
    env.pc = frame.return_addr

    if DBG:
        warn('    helper: handle_return')
        warn('        return_val', return_val)
        if frame.return_val_loc:
            warn('        return_val_loc', get_var_name(frame.return_val_loc))
        else:
            warn('        return_val_loc None')
        warn('        return_addr', hex(frame.return_addr))
Ejemplo n.º 32
0
def restore(env, opinfo):
    # TODO handle optional operands
    if len(opinfo.operands) > 0:
        if DBG:
            warn('restore: found operands (not yet impld): '+str(opinfo.operands))
        set_var(env, opinfo.store_var, 0)
        return

    filename = env.screen.get_line_of_input('input save filename: ')
    loaded = quetzal.load_to_env(env, filename)
    if loaded:
        # set and move past save inst's svar byte
        # (which quetzal gives as the PC)
        set_var(env, env.mem[env.pc], 2)
        env.pc += 1
    else:
        set_var(env, opinfo.store_var, 0)
Ejemplo n.º 33
0
def print_prop_list(env, obj):
    warn('   ',obj,'-',get_obj_str(env, obj)+':')
    ptr = get_prop_list_start(env, obj)
    while env.mem[ptr]:
        num = get_prop_num(env, ptr)
        size = get_prop_size(env, ptr)
        data_ptr = get_prop_data_ptr(env, ptr)
        warn('    prop #',num,' - size',size, end='')
        for i in range(size):
            warn('   ',hex(env.mem[data_ptr+i]), end='')
        warn()
        ptr = data_ptr + size
Ejemplo n.º 34
0
def test_attr(env, opinfo):
    obj = opinfo.operands[0]
    attr = opinfo.operands[1]

    if obj:
        obj_addr = get_obj_addr(env, obj)

        attr_byte = attr // 8
        shift_amt = 7 - attr%8
        attr_val = (env.mem[obj_addr+attr_byte] >> shift_amt) & 1
        result = attr_val == 1
    else:
        result = False
    if result == opinfo.branch_on:
        handle_branch(env, opinfo.branch_offset)

    if DBG:
        warn('    obj', obj, '(', get_obj_str(env,obj), ')')
        warn('    attr', attr)
Ejemplo n.º 35
0
def print_prop_list(env, obj):
    warn('   ',obj,'-',get_obj_str(env, obj)+':')
    ptr = get_prop_list_start(env, obj)
    while env.mem[ptr]:
        num = get_prop_num(env, ptr)
        size = get_prop_size(env, ptr)
        data_ptr = get_prop_data_ptr(env, ptr)
        warn('    prop #',num,' - size',size, end='')
        for i in range(size):
            warn('   ',hex(env.mem[data_ptr+i]), end='')
        warn()
        ptr = data_ptr + size
Ejemplo n.º 36
0
def test_attr(env, opinfo):
    obj = opinfo.operands[0]
    attr = opinfo.operands[1]

    if obj:
        obj_addr = get_obj_addr(env, obj)

        attr_byte = attr // 8
        shift_amt = 7 - attr % 8
        attr_val = (env.mem[obj_addr + attr_byte] >> shift_amt) & 1
        result = attr_val == 1
    else:
        result = False
    if result == opinfo.branch_on:
        handle_branch(env, opinfo.branch_offset)

    if DBG:
        warn('    obj', obj, '(', get_obj_str(env, obj), ')')
        warn('    attr', attr)
Ejemplo n.º 37
0
def _remove_obj(env, obj):
    obj_addr = get_obj_addr(env, obj)

    parent = get_parent_num(env, obj)
    sibling = get_sibling_num(env, obj)

    set_parent_num(env, obj, 0)
    set_sibling_num(env, obj, 0)
    if parent == 0:
        return

    child_num = get_child_num(env, parent)
    if child_num == obj:
        set_child_num(env, parent, sibling)
    else:
        sibling_num = get_sibling_num(env, child_num)
        while sibling_num and sibling_num != obj:
            child_num = sibling_num
            sibling_num = get_sibling_num(env, child_num)
        if sibling_num != 0:
            set_sibling_num(env, child_num, sibling)

    if DBG:
        warn('    helper: _remove_obj')
        warn('        obj', obj, '(', get_obj_str(env, obj), ')')
        warn('        parent', parent, '(', get_obj_str(env, parent), ')')
Ejemplo n.º 38
0
def put_prop(env, opinfo):
    obj = opinfo.operands[0]
    prop_num = opinfo.operands[1]
    val = opinfo.operands[2]

    prop_data_ptr = get_prop_data_ptr_from_obj(env, obj, prop_num)
    if prop_data_ptr == 0:
        msg = 'illegal op: put_prop on nonexistant property'
        msg += ' - prop ' + str(prop_num)
        msg += ' not found on obj ' + str(obj) + ' (' + get_obj_str(env,
                                                                    obj) + ')'
        err(msg)

    sizenum_ptr = get_sizenum_ptr(env, prop_data_ptr)
    size = get_prop_size(env, sizenum_ptr)
    if size == 2:
        env.write16(prop_data_ptr, val)
    elif size == 1:
        env.write8(prop_data_ptr, val & 0xff)
    else:
        msg = 'illegal op: put_prop on outsized prop (not 1-2 bytes)'
        msg += ' - prop ' + str(prop_num)
        msg += ' of obj ' + str(obj) + ' (' + get_obj_str(obj) + ')'
        msg += ' (sized at ' + size + ' bytes)'
        err(msg)

    if DBG:
        warn('    obj', obj, '(', get_obj_str(env, obj), ')')
        warn('    prop_num', prop_num)
        warn('    val', val)
        print_prop_list(env, obj)
Ejemplo n.º 39
0
def set_cursor(env, opinfo):
    env.screen.finish_wrapping()

    try:
        row = to_signed_word(opinfo.operands[0])
        col = to_signed_word(opinfo.operands[1])
        if row < 1:  # why do we not error out here?
            row = 1
        if col < 1:  # same question
            col = 1

        # ignores win 0 (S 8.7.2.3)
        if env.current_window == 1:
            if col > env.hdr.screen_width_units:
                if DBG:
                    warn('set_cursor: set outside screen width', col)
                col = env.hdr.screen_width_units
            if row > env.hdr.screen_height_units:
                if DBG:
                    warn('set_cursor: set outside screen height', row)
                row = env.hdr.screen_height_units
            # see 3rd to last note at bottom of section 8
            env.top_window_height = max(env.top_window_height, row - 1)
            # fix that row,col have a 1,1 origin
            env.cursor[env.current_window] = row - 1, col - 1
    except Exception as e:
        warn("Exception during set_cursor:", e, repr(opinfo))
Ejemplo n.º 40
0
def _remove_obj(env, obj):
    obj_addr = get_obj_addr(env, obj)

    parent = get_parent_num(env, obj)
    sibling = get_sibling_num(env, obj)

    set_parent_num(env, obj, 0)
    set_sibling_num(env, obj, 0)
    if parent == 0:
        return

    child_num = get_child_num(env, parent)
    if child_num == obj:
        set_child_num(env, parent, sibling)
    else:
        sibling_num = get_sibling_num(env, child_num)
        while sibling_num and sibling_num != obj:
            child_num = sibling_num
            sibling_num = get_sibling_num(env, child_num)
        if sibling_num != 0:
            set_sibling_num(env, child_num, sibling)

    if DBG:
        warn('    helper: _remove_obj')
        warn('        obj', obj, '(', get_obj_str(env,obj), ')')
        warn('        parent', parent, '(', get_obj_str(env,parent), ')')
Ejemplo n.º 41
0
def put_prop(env, opinfo):
    obj = opinfo.operands[0]
    prop_num = opinfo.operands[1]
    val = opinfo.operands[2]

    prop_data_ptr = get_prop_data_ptr_from_obj(env, obj, prop_num)
    if prop_data_ptr == 0:
        msg = 'illegal op: put_prop on nonexistant property'
        msg += ' - prop '+str(prop_num)
        msg += ' not found on obj '+str(obj)+' ('+get_obj_str(env, obj)+')' 
        err(msg)

    sizenum_ptr = get_sizenum_ptr(env, prop_data_ptr)
    size = get_prop_size(env, sizenum_ptr)
    if size == 2:
        env.write16(prop_data_ptr, val)
    elif size == 1:
        env.write8(prop_data_ptr, val & 0xff)
    else:
        msg = 'illegal op: put_prop on outsized prop (not 1-2 bytes)'
        msg += ' - prop '+str(prop_num)
        msg += ' of obj '+str(obj)+' ('+get_obj_str(obj)+')'
        msg += ' (sized at '+size+' bytes)'
        err(msg)

    if DBG:
        warn('    obj', obj,'(',get_obj_str(env,obj),')')
        warn('    prop_num', prop_num)
        warn('    val', val)
        print_prop_list(env, obj)
Ejemplo n.º 42
0
def restore(env, opinfo):
    # TODO handle optional operands
    if len(opinfo.operands) > 0:
        if DBG:
            warn('restore: found operands (not yet impld): ' +
                 str(opinfo.operands))
        set_var(env, opinfo.store_var, 0)
        return

    ls = ''
    for k in sorted(env.files):
        ls += str(k) + "\t" + env.files[k][0] + "\n"
    filename = env.screen.get_line_of_input(ls + 'input save filename: ')

    loaded = quetzal.load_to_env(env, filename)
    if loaded:
        # set and move past save inst's svar byte
        # (which quetzal gives as the PC)
        set_var(env, env.mem[env.pc], 2)
        env.pc += 1
    else:
        set_var(env, opinfo.store_var, 0)
Ejemplo n.º 43
0
def verify(env, opinfo):
    vsum = 0
    for i in range(0x40, get_file_len(env)):
        vsum += six.indexbytes(env.orig_mem, i)
    vsum &= 0xffff
    result = vsum == env.hdr.checksum

    if result == opinfo.branch_on:
        handle_branch(env, opinfo.branch_offset)

    if DBG:
        warn('    vsum', vsum)
        warn('    checksum in header', env.hdr.checksum)
        warn('    branch_on', opinfo.branch_on)
        warn('    result', result)
Ejemplo n.º 44
0
def verify(env, opinfo):
    vsum = 0
    for i in range(0x40, get_file_len(env)):
        vsum += six.indexbytes(env.orig_mem, i)
    vsum &= 0xffff
    result = vsum == env.hdr.checksum

    if result == opinfo.branch_on:
        handle_branch(env, opinfo.branch_offset)

    if DBG:
        warn('    vsum', vsum)
        warn('    checksum in header', env.hdr.checksum)
        warn('    branch_on', opinfo.branch_on)
        warn('    result', result)
Ejemplo n.º 45
0
def set_cursor(env, opinfo):
    env.screen.finish_wrapping()

    row = to_signed_word(opinfo.operands[0])
    col = to_signed_word(opinfo.operands[1])
    if row < 1: # why do we not error out here?
        row = 1
    if col < 1: # same question
        col = 1

    # ignores win 0 (S 8.7.2.3)
    if env.current_window == 1:
        if col > env.hdr.screen_width_units:
            if DBG:
                warn('set_cursor: set outside screen width', col)
            col = env.hdr.screen_width_units
        if row > env.hdr.screen_height_units:
            if DBG:
                warn('set_cursor: set outside screen height', row)
            row = env.hdr.screen_height_units
        # see 3rd to last note at bottom of section 8
        env.top_window_height = max(env.top_window_height, row-1)
        # fix that row,col have a 1,1 origin
        env.cursor[env.current_window] = row-1, col-1
Ejemplo n.º 46
0
def jin(env, opinfo):
    obj1 = opinfo.operands[0]
    obj2 = opinfo.operands[1]

    result = get_parent_num(env, obj1) == obj2

    if result == opinfo.branch_on:
        handle_branch(env, opinfo.branch_offset)

    if DBG:
        warn('    obj1', obj1, '(',get_obj_str(env,obj1),')')
        warn('    obj2', obj2, '(',get_obj_str(env,obj2),')')
        warn('    is_parent?', result)
Ejemplo n.º 47
0
def jin(env, opinfo):
    obj1 = opinfo.operands[0]
    obj2 = opinfo.operands[1]

    result = get_parent_num(env, obj1) == obj2

    if result == opinfo.branch_on:
        handle_branch(env, opinfo.branch_offset)

    if DBG:
        warn('    obj1', obj1, '(', get_obj_str(env, obj1), ')')
        warn('    obj2', obj2, '(', get_obj_str(env, obj2), ')')
        warn('    is_parent?', result)
Ejemplo n.º 48
0
def get_prop_addr(env, opinfo):
    obj = opinfo.operands[0]
    prop_num = opinfo.operands[1]

    if obj == 0:
        # from testing, this seems
        # to be the expected behavior
        result = 0
    else:
        result = get_prop_data_ptr_from_obj(env, obj, prop_num)
    set_var(env, opinfo.store_var, result)

    if DBG:
        warn('    obj', obj,'(',get_obj_str(env,obj),')')
        warn('    prop_num', prop_num)
        warn('    result', result)
        if obj:
            print_prop_list(env, obj)
Ejemplo n.º 49
0
def get_prop_addr(env, opinfo):
    obj = opinfo.operands[0]
    prop_num = opinfo.operands[1]

    if obj == 0:
        # from testing, this seems
        # to be the expected behavior
        result = 0
    else:
        result = get_prop_data_ptr_from_obj(env, obj, prop_num)
    set_var(env, opinfo.store_var, result)

    if DBG:
        warn('    obj', obj, '(', get_obj_str(env, obj), ')')
        warn('    prop_num', prop_num)
        warn('    result', result)
        if obj:
            print_prop_list(env, obj)
Ejemplo n.º 50
0
def decode(env, pc):

    opcode = env.mem[pc]
    form = get_opcode_form(env, opcode)
    count = get_operand_count(opcode, form)

    if form == ExtForm:
        opcode = env.mem[pc+1]

    if form == ShortForm:
        szbyte = (opcode >> 4) & 3
        szbyte = (szbyte << 6) | 0x3f
        operand_ptr = pc+1
        sizes = get_operand_sizes(szbyte)
    elif form == VarForm:
        szbyte = env.mem[pc+1]
        operand_ptr = pc+2
        sizes = get_operand_sizes(szbyte)
        # handle call_vn2/vs2's extra szbyte
        if opcode in (236, 250):
            szbyte2 = env.mem[pc+2]
            sizes += get_operand_sizes(szbyte2)
            operand_ptr = pc+3
    elif form == ExtForm:
        szbyte = env.mem[pc+2]
        operand_ptr = pc+3
        sizes = get_operand_sizes(szbyte)
    elif form == LongForm:
        operand_ptr = pc+1
        sizes = []
        for offset in (6,5):
            if (opcode >> offset) & 1:
                sizes.append(VarSize)
            else:
                sizes.append(ByteSize)
    else:
        err('unknown opform specified: ' + str(form))

    operands = []
    var_op_info = []
    for i in range(len(sizes)):
        size = sizes[i]
        if size == WordSize:
            operands.append(env.u16(operand_ptr))
            operand_ptr += 2
        elif size == ByteSize:
            operands.append(env.mem[operand_ptr])
            operand_ptr += 1
        elif size == VarSize:
            operands.append(None) #this is fixedup after every load from icache
            var_num = env.mem[operand_ptr]
            var_op_info.append( (i,var_num) )
            operand_ptr += 1
        else:
            err('unknown operand size specified: ' + str(size))

    if form == ExtForm:
        dispatch = ops.ext_dispatch
        has_store_var = ops.ext_has_store_var
        has_branch_var = ops.ext_has_branch_var
    else:
        dispatch = ops.dispatch
        has_store_var = ops.has_store_var
        has_branch_var = ops.has_branch_var

    opinfo = OpInfo(operands, var_op_info)

    opinfo.opcode = opcode
    opinfo.is_extended = form == ExtForm

    if has_store_var[opcode]:
        opinfo.store_var = env.mem[operand_ptr]
        opinfo.last_pc_store_var = operand_ptr # to make quetzal saves easier
        operand_ptr += 1

    if has_branch_var[opcode]: # std:4.7
        branch_info = env.mem[operand_ptr]
        opinfo.last_pc_branch_var = operand_ptr # to make quetzal saves easier
        operand_ptr += 1
        opinfo.branch_on = (branch_info & 128) == 128
        if branch_info & 64:
            opinfo.branch_offset = branch_info & 0x3f
        else:
            branch_offset = branch_info & 0x3f
            branch_offset <<= 8
            branch_offset |= env.mem[operand_ptr]
            operand_ptr += 1
            # sign extend 14b # to 16b
            if branch_offset & 0x2000:
                branch_offset |= 0xc000
            opinfo.branch_offset = to_signed_word(branch_offset)

    # handle print_ and print_ret's string operand
    if form != ExtForm and opcode in (178, 179):
        while True:
            word = env.u16(operand_ptr)
            operand_ptr += 2
            operands.append(word)
            if word & 0x8000:
                break

    # After all that, operand_ptr should point to the next opcode
    next_pc = operand_ptr

    if DBG:
        def hex_out(bytes):
            s = ''
            for b in bytes:
                s += hex(b) + ' '
            return s
        op_hex = hex_out(env.mem[pc:next_pc])

        warn('decode: pc', hex(pc))
        warn('      opcode', opcode)
        warn('      form', form)
        warn('      count', count)
        if opinfo.store_var:
            warn('      store_var', ops.get_var_name(opinfo.store_var))
        warn('      sizes', sizes)
        warn('      operands', opinfo.operands)
        warn('      next_pc', hex(next_pc))
        #warn('      bytes', op_hex)

    return dispatch[opcode], opinfo, next_pc
Ejemplo n.º 51
0
def call(env, opinfo):
    packed_addr = opinfo.operands[0]

    if packed_addr == 0:
        if opinfo.store_var != None:
            set_var(env, opinfo.store_var, 0)
        if DBG:
            warn('op: calling 0 (returns false)')
        return

    return_addr = env.pc

    fncache = env.fncache
    if packed_addr in fncache:
        call_addr, local_vars, code_ptr = fncache[packed_addr]
        local_vars = local_vars[:]  # leave cached vars for later hits
    else:
        call_addr = unpack_addr_call(env, packed_addr)
        local_vars, code_ptr = parse_call_header(env, call_addr)
        if call_addr >= env.hdr.static_mem_base:
            fncache[packed_addr] = call_addr, local_vars, code_ptr
            local_vars = local_vars[:]  # leave cached vars for later hits

    # args dropped if past len of locals arr
    num_args = min(len(opinfo.operands) - 1, len(local_vars))
    local_vars[:num_args] = opinfo.operands[1:num_args + 1]

    env.callstack.append(
        Frame(return_addr, num_args, local_vars, opinfo.store_var))
    env.pc = code_ptr

    if DBG:
        warn('        calling', hex(call_addr))
        warn('        returning to', hex(return_addr))
        warn('        using args', opinfo.operands[1:])
        if opinfo.store_var == None:
            warn('        return val will be discarded')
        else:
            warn('        return val will be placed in',
                 get_var_name(opinfo.store_var))
        warn('        num locals:', env.mem[call_addr])
        warn('        local vals:', local_vars)
        warn('        code ptr:', hex(code_ptr))
        warn('        first inst:', env.mem[code_ptr])
Ejemplo n.º 52
0
def show_status(env, opinfo):
    if DBG:
        warn('    (not impld)')
Ejemplo n.º 53
0
def sound_effect(env, opinfo):
    if DBG:
        warn('    (not impld)')
Ejemplo n.º 54
0
def save_undo(env, opinfo):
    set_var(env, opinfo.store_var, -1)
    if DBG:
        warn('    (not impld for now)')
        warn('    (but at least I can notify the game of that)')
Ejemplo n.º 55
0
def call(env, opinfo):
    packed_addr = opinfo.operands[0]

    if packed_addr == 0:
        if opinfo.store_var != None:
            set_var(env, opinfo.store_var, 0)
        if DBG:
            warn('op: calling 0 (returns false)')
        return

    return_addr = env.pc

    fncache = env.fncache
    if packed_addr in fncache:
        call_addr, local_vars, code_ptr = fncache[packed_addr]
        local_vars = local_vars[:] # leave cached vars for later hits
    else:
        call_addr = unpack_addr_call(env, packed_addr)
        local_vars, code_ptr = parse_call_header(env, call_addr)
        if call_addr >= env.hdr.static_mem_base:
            fncache[packed_addr] = call_addr, local_vars, code_ptr
            local_vars = local_vars[:] # leave cached vars for later hits

    # args dropped if past len of locals arr
    num_args = min(len(opinfo.operands)-1, len(local_vars))
    local_vars[:num_args] = opinfo.operands[1:num_args+1]

    env.callstack.append(Frame(return_addr,
                               num_args,
                               local_vars,
                               opinfo.store_var))
    env.pc = code_ptr

    if DBG:
        warn('        calling', hex(call_addr))
        warn('        returning to', hex(return_addr))
        warn('        using args', opinfo.operands[1:])
        if opinfo.store_var == None:
            warn('        return val will be discarded')
        else:
            warn('        return val will be placed in', get_var_name(opinfo.store_var))
        warn('        num locals:', env.mem[call_addr])
        warn('        local vals:', local_vars)
        warn('        code ptr:', hex(code_ptr))
        warn('        first inst:', env.mem[code_ptr])
Ejemplo n.º 56
0
def show_status(env, opinfo):
    if DBG:
        warn('    (not impld)')
Ejemplo n.º 57
0
def sound_effect(env, opinfo):
    if DBG:
        warn('    (not impld)')
Ejemplo n.º 58
0
def step(env):

    pc, icache = env.pc, env.icache
    if pc in icache:
        op, opinfo, env.pc = icache[pc]
    else:
        op, opinfo, env.pc = ops_decode.decode(env, pc)
        if pc >= env.hdr.static_mem_base:
            icache[pc] = op, opinfo, env.pc

    # fixup dynamic operands
    if opinfo.has_dynamic_operands:
        for i, var_num in opinfo.var_op_info:
            opinfo.operands[i] = ops.get_var(env, var_num)

    # for Quetzal
    if opinfo.last_pc_branch_var:
        env.last_pc_branch_var = opinfo.last_pc_branch_var
    if opinfo.last_pc_store_var:
        env.last_pc_store_var = opinfo.last_pc_store_var

    if DBG:
        warn(hex(pc))
        warn('op:', op.__name__)
        warn('    operands', dbg_decode_operands(env, op.__name__, opinfo.operands))
        if opinfo.branch_offset != None:
            warn('    branch_offset', opinfo.branch_offset)
            warn('    branch_to', dbg_decode_branch(env, opinfo.branch_offset))
            warn('    branch_on', opinfo.branch_on)

        op(env, opinfo)

        if opinfo.store_var:
            warn(    'store_var', ops.get_var_name(opinfo.store_var))
            warn(    'stored_result', dbg_decode_result(env, op.__name__, opinfo.store_var))
    else:
        op(env, opinfo)
Ejemplo n.º 59
0
def step(env):

    pc, icache = env.pc, env.icache
    if pc in icache:
        op, opinfo, env.pc = icache[pc]
    else:
        op, opinfo, env.pc = ops_decode.decode(env, pc)
        if pc >= env.hdr.static_mem_base:
            icache[pc] = op, opinfo, env.pc

    # fixup dynamic operands
    if opinfo.has_dynamic_operands:
        for i, var_num in opinfo.var_op_info:
            opinfo.operands[i] = ops.get_var(env, var_num)

    # for Quetzal
    if opinfo.last_pc_branch_var:
        env.last_pc_branch_var = opinfo.last_pc_branch_var
    if opinfo.last_pc_store_var:
        env.last_pc_store_var = opinfo.last_pc_store_var

    if DBG:
        warn(hex(pc))
        warn('op:', op.__name__)
        warn('    operands',
             dbg_decode_operands(env, op.__name__, opinfo.operands))
        if opinfo.branch_offset != None:
            warn('    branch_offset', opinfo.branch_offset)
            warn('    branch_to', dbg_decode_branch(env, opinfo.branch_offset))
            warn('    branch_on', opinfo.branch_on)

        op(env, opinfo)

        if opinfo.store_var:
            warn('store_var', ops.get_var_name(opinfo.store_var))
            warn('stored_result',
                 dbg_decode_result(env, op.__name__, opinfo.store_var))
    else:
        op(env, opinfo)
Ejemplo n.º 60
0
def save_undo(env, opinfo):
    set_var(env, opinfo.store_var, -1)
    if DBG:
        warn('    (not impld for now)')
        warn('    (but at least I can notify the game of that)')