def get_basic_memory(addr):
    """ Retrieve data from BASIC memory. """
    addr -= memory.data_segment*0x10
    # DS:2c, DS:2d  end of memory available to BASIC
    if addr == 0x2C:
        return memory.total_memory % 256
    elif addr == 0x2D:
        return memory.total_memory // 256
    # DS:30, DS:31: pointer to start of program, excluding initial \0
    elif addr == 0x30:
        return (memory.code_start+1) % 256
    elif addr == 0x31:
        return (memory.code_start+1) // 256
    # DS:358, DS:359: start of variable space
    elif addr == 0x358:
        return memory.var_start() % 256
    elif addr == 0x359:
        return memory.var_start() // 256
    # DS:35A, DS:35B: start of array space
    elif addr == 0x35A:
        return state.basic_state.var_current % 256
    elif addr == 0x35B:
        return state.basic_state.var_current // 256
    # DS:35C, DS:35D: end of array space
    elif addr == 0x35C:
        return (state.basic_state.var_current + state.basic_state.array_current) % 256
    elif addr == 0x35D:
        return (state.basic_state.var_current + state.basic_state.array_current) // 256
    elif addr == protection_flag_addr:
        return state.basic_state.protected * 255        
    return -1
Exemple #2
0
def get_basic_memory(addr):
    """ Retrieve data from BASIC memory. """
    addr -= memory.data_segment * 0x10
    # DS:2c, DS:2d  end of memory available to BASIC
    if addr == 0x2C:
        return memory.total_memory % 256
    elif addr == 0x2D:
        return memory.total_memory // 256
    # DS:30, DS:31: pointer to start of program, excluding initial \0
    elif addr == 0x30:
        return (memory.code_start + 1) % 256
    elif addr == 0x31:
        return (memory.code_start + 1) // 256
    # DS:358, DS:359: start of variable space
    elif addr == 0x358:
        return memory.var_start() % 256
    elif addr == 0x359:
        return memory.var_start() // 256
    # DS:35A, DS:35B: start of array space
    elif addr == 0x35A:
        return state.basic_state.var_current % 256
    elif addr == 0x35B:
        return state.basic_state.var_current // 256
    # DS:35C, DS:35D: end of array space
    elif addr == 0x35C:
        return (state.basic_state.var_current +
                state.basic_state.array_current) % 256
    elif addr == 0x35D:
        return (state.basic_state.var_current +
                state.basic_state.array_current) // 256
    elif addr == protection_flag_addr:
        return state.basic_state.protected * 255
    return -1
def set_memory(addr, val):
    """ Set the value at an emulated memory location. """
    if addr >= memory.rom_segment*0x10:
        # ROM includes font memory
        pass
    elif addr >= memory.ram_font_segment*0x10:
        # RAM font memory
        set_font_memory(addr, val)
    elif addr >= memory.video_segment*0x10:
        # graphics and text memory
        set_video_memory(addr, val)
    elif addr >= memory.data_segment*0x10 + memory.var_start():
        # POKING in variables
        set_data_memory(addr, val)
    elif addr >= memory.data_segment*0x10 + memory.code_start:
        # code memory
        set_code_memory(addr, val)
    elif addr >= memory.data_segment*0x10 + memory.field_mem_start:
        # file & FIELD memory
        set_field_memory(addr, val)
    elif addr >= memory.data_segment*0x10:
        set_basic_memory(addr, val)
    elif addr >= low_segment*0x10:
        set_low_memory(addr, val)
    else:
        pass
def get_memory(addr):
    """ Retrieve the value at an emulated memory location. """
    try:
        # try if there's a preset value
        return peek_values[addr]
    except KeyError: 
        if addr >= memory.rom_segment*0x10:
            # ROM font
            return max(0, get_rom_memory(addr))
        elif addr >= memory.ram_font_segment*0x10:
            # RAM font
            return max(0, get_font_memory(addr))
        elif addr >= memory.video_segment*0x10:
            # graphics and text memory
            return max(0, get_video_memory(addr))
        elif addr >= memory.data_segment*0x10 + memory.var_start():
            # variable memory
            return max(0, get_data_memory(addr))
        elif addr >= memory.data_segment*0x10 + memory.code_start:
            # code memory
            return max(0, get_code_memory(addr))   
        elif addr >= memory.data_segment*0x10 + memory.field_mem_start:
            # file & FIELD memory
            return max(0, get_field_memory(addr))
        elif addr >= memory.data_segment*0x10:
            # other BASIC data memory
            return max(0, get_basic_memory(addr))
        elif addr >= low_segment*0x10:
            return max(0, get_low_memory(addr))
        else:    
            return 0
Exemple #5
0
def string_assign_unpacked_into(sequence, offset, num, val):    
    """ Write an unpacked value into a string buffer for given 3-byte sequence. """
    # don't overwrite more of the old string than the length of the new string
    num = min(num, len(val))
    # ensure the length of val is num, cut off any extra characters 
    val = val[:num]
    length = ord(sequence[0:1])
    address = vartypes.uint_to_value(sequence[-2:])
    if offset + num > length:
        num = length - offset
    if num <= 0:
        return     
    if address >= memory.var_start():
        # string stored in string space
        state.basic_state.strings.retrieve(sequence)[offset:offset+num] = val
    else:
        # string stored in field buffers
        # find the file we're in
        start = address - memory.field_mem_start
        number = 1 + start // memory.field_mem_offset
        field_offset = start % memory.field_mem_offset
        try:
            state.io_state.fields[number][field_offset+offset:field_offset+offset+num] = val
        except KeyError, IndexError:
            raise KeyError('Not a field string')
Exemple #6
0
def set_memory(addr, val):
    """ Set the value at an emulated memory location. """
    if addr >= memory.rom_segment * 0x10:
        # ROM includes font memory
        pass
    elif addr >= memory.ram_font_segment * 0x10:
        # RAM font memory
        set_font_memory(addr, val)
    elif addr >= memory.video_segment * 0x10:
        # graphics and text memory
        set_video_memory(addr, val)
    elif addr >= memory.data_segment * 0x10 + memory.var_start():
        # POKING in variables
        set_data_memory(addr, val)
    elif addr >= memory.data_segment * 0x10 + memory.code_start:
        # code memory
        set_code_memory(addr, val)
    elif addr >= memory.data_segment * 0x10 + memory.field_mem_start:
        # file & FIELD memory
        set_field_memory(addr, val)
    elif addr >= memory.data_segment * 0x10:
        set_basic_memory(addr, val)
    elif addr >= low_segment * 0x10:
        set_low_memory(addr, val)
    else:
        pass
Exemple #7
0
def get_memory(addr):
    """ Retrieve the value at an emulated memory location. """
    try:
        # try if there's a preset value
        return peek_values[addr]
    except KeyError:
        if addr >= memory.rom_segment * 0x10:
            # ROM font
            return max(0, get_rom_memory(addr))
        elif addr >= memory.ram_font_segment * 0x10:
            # RAM font
            return max(0, get_font_memory(addr))
        elif addr >= memory.video_segment * 0x10:
            # graphics and text memory
            return max(0, get_video_memory(addr))
        elif addr >= memory.data_segment * 0x10 + memory.var_start():
            # variable memory
            return max(0, get_data_memory(addr))
        elif addr >= memory.data_segment * 0x10 + memory.code_start:
            # code memory
            return max(0, get_code_memory(addr))
        elif addr >= memory.data_segment * 0x10 + memory.field_mem_start:
            # file & FIELD memory
            return max(0, get_field_memory(addr))
        elif addr >= memory.data_segment * 0x10:
            # other BASIC data memory
            return max(0, get_basic_memory(addr))
        elif addr >= low_segment * 0x10:
            return max(0, get_low_memory(addr))
        else:
            return 0
Exemple #8
0
def string_assign_unpacked_into(sequence, offset, num, val):
    """ Write an unpacked value into a string buffer for given 3-byte sequence. """
    # don't overwrite more of the old string than the length of the new string
    num = min(num, len(val))
    # ensure the length of val is num, cut off any extra characters
    val = val[:num]
    length = ord(sequence[0:1])
    address = vartypes.uint_to_value(sequence[-2:])
    if offset + num > length:
        num = length - offset
    if num <= 0:
        return
    if address >= memory.var_start():
        # string stored in string space
        state.basic_state.strings.retrieve(sequence)[offset:offset + num] = val
    else:
        # string stored in field buffers
        # find the file we're in
        start = address - memory.field_mem_start
        number = 1 + start // memory.field_mem_offset
        field_offset = start % memory.field_mem_offset
        try:
            state.io_state.fields[number].buffer[field_offset +
                                                 offset:field_offset + offset +
                                                 num] = val
        except KeyError, IndexError:
            raise KeyError('Not a field string')
Exemple #9
0
def clear_variables(preserve_common=False, preserve_all=False, preserve_deftype=False):
    """ Reset and clear variables, arrays, common definitions and functions. """
    if not preserve_deftype:
        # deftype is not preserved on CHAIN with ALL, but is preserved with MERGE
        state.basic_state.deftype = ['!']*26
    if not preserve_all:
        if preserve_common:
            # preserve COMMON variables (CHAIN does this)
            common, common_arrays = {}, {}
            for varname in state.basic_state.common_names:
                try:
                    common[varname] = state.basic_state.variables[varname]
                except KeyError:
                    pass
            for varname in state.basic_state.common_array_names:
                try:
                    common_arrays[varname] = state.basic_state.arrays[varname]
                except KeyError:
                    pass
        else:
            # clear option base
            state.basic_state.array_base = None
            common = {}
            common_arrays = {}
            # at least I think these should be cleared by CLEAR?
            state.basic_state.common_names = []
            state.basic_state.common_array_names = []
        # restore only common variables
        # this is a re-assignment which is not FOR-safe; but clear_variables is only called in CLEAR which also clears the FOR stack
        state.basic_state.variables = {}
        state.basic_state.arrays = {}
        state.basic_state.var_memory = {}
        state.basic_state.array_memory = {}
        state.basic_state.var_current = memory.var_start()
        # arrays are always kept after all vars
        state.basic_state.array_current = 0
        # functions are cleared except when CHAIN ... ALL is specified
        state.basic_state.functions = {}
        # reset string space
        new_strings = StringSpace()
        # preserve common variables
        # use set_scalar and dim_array to rebuild memory model
        for v in common:
            full_var = (v[-1], common[v])
            if v[-1] == '$':
                full_var = new_strings.store(copy_str(full_var))
            set_scalar(v, full_var)
        for a in common_arrays:
            dim_array(a, common_arrays[a][0])
            if a[-1] == '$':
                s = bytearray()
                for i in range(0, len(common_arrays[a][1]), vartypes.byte_size['$']):
                    old_ptr = vartypes.bytes_to_string(common_arrays[a][1][i:i+vartypes.byte_size['$']])
                    new_ptr = new_strings.store(copy_str(old_ptr))
                    s += vartypes.string_to_bytes(new_ptr)
                state.basic_state.arrays[a][1] = s
            else:
                state.basic_state.arrays[a] = common_arrays[a]
        state.basic_state.strings = new_strings
Exemple #10
0
def clear_variables(preserve_common=False, preserve_all=False, preserve_deftype=False):
    """ Reset and clear variables, arrays, common definitions and functions. """
    if not preserve_deftype:
        # deftype is not preserved on CHAIN with ALL, but is preserved with MERGE
        state.basic_state.deftype = ['!']*26
    if not preserve_all:
        if preserve_common:
            # preserve COMMON variables (CHAIN does this)
            common, common_arrays = {}, {}
            for varname in state.basic_state.common_names:
                try:
                    common[varname] = state.basic_state.variables[varname]
                except KeyError:
                    pass
            for varname in state.basic_state.common_array_names:
                try:
                    common_arrays[varname] = state.basic_state.arrays[varname]
                except KeyError:
                    pass
        else:
            # clear option base
            state.basic_state.array_base = None
            common = {}
            common_arrays = {}
            # at least I think these should be cleared by CLEAR?
            state.basic_state.common_names = []
            state.basic_state.common_array_names = []
        # restore only common variables
        # this is a re-assignment which is not FOR-safe; but clear_variables is only called in CLEAR which also clears the FOR stack
        state.basic_state.variables = {}
        state.basic_state.arrays = {}
        state.basic_state.var_memory = {}
        state.basic_state.array_memory = {}
        state.basic_state.var_current = memory.var_start()
        # arrays are always kept after all vars
        state.basic_state.array_current = 0
        # functions are cleared except when CHAIN ... ALL is specified
        state.basic_state.functions = {}
        # reset string space
        new_strings = StringSpace()
        # preserve common variables
        # use set_scalar and dim_array to rebuild memory model
        for v in common:
            full_var = (v[-1], common[v])
            if v[-1] == '$':
                full_var = new_strings.store(copy_str(full_var))
            set_scalar(v, full_var)
        for a in common_arrays:
            dim_array(a, common_arrays[a][0])
            if a[-1] == '$':
                s = bytearray()
                for i in range(0, len(common_arrays[a][1]), vartypes.byte_size['$']):
                    old_ptr = vartypes.bytes_to_string(common_arrays[a][1][i:i+vartypes.byte_size['$']])
                    new_ptr = new_strings.store(copy_str(old_ptr))
                    s += vartypes.string_to_bytes(new_ptr)
                state.basic_state.arrays[a][1] = s
            else:
                state.basic_state.arrays[a] = common_arrays[a]
        state.basic_state.strings = new_strings
Exemple #11
0
def set_str(basic_string, in_str, offset=None, num=None):
    """ Assign a new string into an existing buffer. """
    # if it is a code literal, we now do need to allocate space for a copy
    address = vartypes.string_address(basic_string)
    if address >= memory.code_start and address < memory.var_start():
        basic_string = state.basic_state.strings.store(copy_str(basic_string))
    if num is None:
        view_str(basic_string)[:] = in_str
    else:
        view_str(basic_string)[offset:offset+num] = in_str
    return basic_string
Exemple #12
0
def set_str(basic_string, in_str, offset=None, num=None):
    """ Assign a new string into an existing buffer. """
    # if it is a code literal, we now do need to allocate space for a copy
    address = vartypes.string_address(basic_string)
    if address >= memory.code_start and address < memory.var_start():
        basic_string = state.basic_state.strings.store(copy_str(basic_string))
    if num is None:
        view_str(basic_string)[:] = in_str
    else:
        view_str(basic_string)[offset:offset+num] = in_str
    return basic_string
Exemple #13
0
def get_string_copy_packed(sequence):
    """ Return a packed copy of a string from its 3-byte sequence. """
    length = ord(sequence[0:1])
    address = vartypes.uint_to_value(sequence[-2:])
    if address >= memory.var_start():
        # string is stored in string space
        return state.basic_state.strings.copy_packed(sequence)
    else: 
        # string is stored in code space or field buffers
        if address < memory.field_mem_start:
            return vartypes.pack_string('\0' * length)
        # find the file we're in
        start = address - memory.field_mem_start
        number = 1 + start // memory.field_mem_offset
        offset = start % memory.field_mem_offset
        try:
            return vartypes.pack_string(state.io_state.fields[number][offset:offset+length])
        except KeyError, IndexError:
            return vartypes.pack_string('\0' * length)
Exemple #14
0
def get_string_copy_packed(sequence):
    """ Return a packed copy of a string from its 3-byte sequence. """
    length = ord(sequence[0:1])
    address = vartypes.uint_to_value(sequence[-2:])
    if address >= memory.var_start():
        # string is stored in string space
        return state.basic_state.strings.copy_packed(sequence)
    else:
        # string is stored in code space or field buffers
        if address < memory.field_mem_start:
            return vartypes.pack_string('\0' * length)
        # find the file we're in
        start = address - memory.field_mem_start
        number = 1 + start // memory.field_mem_offset
        offset = start % memory.field_mem_offset
        try:
            return vartypes.pack_string(
                state.io_state.fields[number].buffer[offset:offset + length])
        except KeyError, IndexError:
            return vartypes.pack_string('\0' * length)