示例#1
2
文件: program.py 项目: nony05/pcbasic
def renum(new_line, start_line, step):
    """ Renumber stored program. """
    new_line = 10 if new_line is None else new_line
    start_line = 0 if start_line is None else start_line
    step = 10 if step is None else step
    # get a sorted list of line numbers
    keys = sorted([ k for k in state.basic_state.line_numbers.keys() if k >= start_line])
    # assign the new numbers
    old_to_new = {}
    for old_line in keys:
        if old_line < 65535 and new_line > 65529:
            raise error.RunError(error.IFC)
        if old_line == 65536:
            break
        old_to_new[old_line] = new_line
        state.basic_state.last_stored = new_line
        new_line += step
    # write the new numbers
    for old_line in old_to_new:
        state.basic_state.bytecode.seek(state.basic_state.line_numbers[old_line])
        # skip the \x00\xC0\xDE & overwrite line number
        state.basic_state.bytecode.read(3)
        state.basic_state.bytecode.write(str(vartypes.value_to_uint(old_to_new[old_line])))
    # rebuild the line number dictionary
    new_lines = {}
    for old_line in old_to_new:
        new_lines[old_to_new[old_line]] = state.basic_state.line_numbers[old_line]
        del state.basic_state.line_numbers[old_line]
    state.basic_state.line_numbers.update(new_lines)
    # write the indirect line numbers
    state.basic_state.bytecode.seek(0)
    while util.skip_to_read(state.basic_state.bytecode, ('\x0e',)) == '\x0e':
        # get the old g number
        jumpnum = vartypes.uint_to_value(bytearray(state.basic_state.bytecode.read(2)))
        try:
            newjump = old_to_new[jumpnum]
        except KeyError:
            # not redefined, exists in program?
            if jumpnum in state.basic_state.line_numbers:
                newjump = jumpnum
            else:
                linum = get_line_number(state.basic_state.bytecode.tell())
                console.write_line('Undefined line ' + str(jumpnum) + ' in ' + str(linum))
        state.basic_state.bytecode.seek(-2, 1)
        state.basic_state.bytecode.write(str(vartypes.value_to_uint(newjump)))
    # stop running if we were
    flow.set_pointer(False)
    # reset loop stacks
    state.basic_state.gosub_return = []
    state.basic_state.for_next_stack = []
    state.basic_state.while_wend_stack = []
    # renumber error handler
    if state.basic_state.on_error:
        state.basic_state.on_error = old_to_new[state.basic_state.on_error]
    # renumber event traps
    for handler in state.basic_state.events.all:
        if handler.gosub:
            handler.set_jump(old_to_new[handler.gosub])
示例#2
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')
示例#3
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')
示例#4
0
文件: debug.py 项目: nony05/pcbasic
def show_program():
    """ Write a marked-up hex dump of the program to the log. """
    code = state.basic_state.bytecode.getvalue()
    offset_val, p = 0, 0
    for key in sorted(state.basic_state.line_numbers.keys())[1:]:
        offset, linum = code[p+1:p+3], code[p+3:p+5]
        last_offset = offset_val
        offset_val = vartypes.uint_to_value(bytearray(offset)) - program.program_memory_start
        linum_val  = vartypes.uint_to_value(bytearray(linum))
        logging.debug(    (code[p:p+1].encode('hex') + ' ' +
                        offset.encode('hex') + ' (+%03d) ' +
                        code[p+3:p+5].encode('hex') + ' [%05d] ' +
                        code[p+5:state.basic_state.line_numbers[key]].encode('hex')),
                     offset_val - last_offset, linum_val )
        p = state.basic_state.line_numbers[key]
    logging.debug(code[p:p+1].encode('hex') + ' ' +
                code[p+1:p+3].encode('hex') + ' (ENDS) ' +
                code[p+3:p+5].encode('hex') + ' ' + code[p+5:].encode('hex'))
示例#5
0
文件: util.py 项目: nony05/pcbasic
def parse_jumpnum(ins, allow_empty=False, err=error.STX):
    """ Parses a line number pointer as in GOTO, GOSUB, LIST, RENUM, EDIT, etc. """
    if skip_white_read_if(ins, (tk.T_UINT, )):
        return vartypes.uint_to_value(bytearray(ins.read(2)))
    else:
        if allow_empty:
            return -1
        # Syntax error
        raise error.RunError(err)
示例#6
0
文件: util.py 项目: nony05/pcbasic
def parse_jumpnum(ins, allow_empty=False, err=error.STX):
    """ Parses a line number pointer as in GOTO, GOSUB, LIST, RENUM, EDIT, etc. """
    if skip_white_read_if(ins, (tk.T_UINT,)):
        return vartypes.uint_to_value(bytearray(ins.read(2)))
    else:
        if allow_empty:
            return -1
        # Syntax error
        raise error.RunError(err)
示例#7
0
def bload(g, offset):    
    """ Load a file into a block of memory. """
    if g.read(1) != '\xfd':
        raise error.RunError(54)
    seg = vartypes.uint_to_value(bytearray(g.read(2)))
    foffset = vartypes.uint_to_value(bytearray(g.read(2)))
    if offset == None:
        offset = foffset
    # size. this gets ignored; even the \x1a at the end gets dumped onto the screen.
    vartypes.uint_to_value(bytearray(g.read(2))) 
    buf = bytearray(g.read())
    # remove any EOF marker at end 
    if buf and buf[-1] == 0x1a:  
        buf = buf[:-1]
    if tandy_syntax:
        buf = buf[:-7]        
    g.close()
    addr = seg * 0x10 + offset
    set_memory_block(addr, buf)
示例#8
0
def show_program():
    """ Write a marked-up hex dump of the program to the log. """
    code = state.basic_state.bytecode.getvalue()
    offset_val, p = 0, 0
    for key in sorted(state.basic_state.line_numbers.keys())[1:]:
        offset, linum = code[p + 1:p + 3], code[p + 3:p + 5]
        last_offset = offset_val
        offset_val = vartypes.uint_to_value(
            bytearray(offset)) - program.program_memory_start
        linum_val = vartypes.uint_to_value(bytearray(linum))
        logging.debug(
            (code[p:p + 1].encode('hex') + ' ' + offset.encode('hex') +
             ' (+%03d) ' + code[p + 3:p + 5].encode('hex') + ' [%05d] ' +
             code[p + 5:state.basic_state.line_numbers[key]].encode('hex')),
            offset_val - last_offset, linum_val)
        p = state.basic_state.line_numbers[key]
    logging.debug(code[p:p + 1].encode('hex') + ' ' +
                  code[p + 1:p + 3].encode('hex') + ' (ENDS) ' +
                  code[p + 3:p + 5].encode('hex') + ' ' +
                  code[p + 5:].encode('hex'))
示例#9
0
文件: util.py 项目: nony05/pcbasic
def parse_line_number(ins):
    """ Parse line number and leave pointer at first char of line. """
    # if end of program or truncated, leave pointer at start of line number C0 DE or 00 00
    off = ins.read(2)
    if off == '\0\0' or len(off) < 2:
        ins.seek(-len(off), 1)
        return -1
    off = ins.read(2)
    if len(off) < 2:
        ins.seek(-len(off)-2, 1)
        return -1
    else:
        return vartypes.uint_to_value(bytearray(off))
示例#10
0
文件: util.py 项目: nony05/pcbasic
def parse_line_number(ins):
    """ Parse line number and leave pointer at first char of line. """
    # if end of program or truncated, leave pointer at start of line number C0 DE or 00 00
    off = ins.read(2)
    if off == '\0\0' or len(off) < 2:
        ins.seek(-len(off), 1)
        return -1
    off = ins.read(2)
    if len(off) < 2:
        ins.seek(-len(off) - 2, 1)
        return -1
    else:
        return vartypes.uint_to_value(bytearray(off))
示例#11
0
def get_value_for_varptrstr(varptrstr):
    """ Get a value given a VARPTR$ representation. """
    if len(varptrstr) < 3:
        raise error.RunError(error.IFC)
    varptrstr = bytearray(varptrstr)
    varptr = vartypes.uint_to_value(bytearray(varptrstr[1:3]))
    found_name = ''
    for name in state.basic_state.var_memory:
        _, var_ptr = state.basic_state.var_memory[name]
        if var_ptr == varptr:
            found_name = name
            break
    if found_name == '':
        raise error.RunError(error.IFC)
    return var.get_var(found_name)
示例#12
0
 def __init__(self, fhandle, filetype, number, name, mode,
                    seg, offset, length):
     """ Initialise program file object and write header. """
     devices.RawFile.__init__(self, fhandle, filetype, mode)
     self.number = number
     # don't lock binary files
     self.lock = ''
     self.access = 'RW'
     self.seg, self.offset, self.length = 0, 0, 0
     if self.mode == 'O':
         self.write(devices.type_to_magic[filetype])
         if self.filetype == 'M':
             self.write(vartypes.value_to_uint(seg) +
                        vartypes.value_to_uint(offset) +
                        vartypes.value_to_uint(length))
             self.seg, self.offset, self.length = seg, offset, length
     else:
         # drop magic byte
         self.read_raw(1)
         if self.filetype == 'M':
             self.seg = vartypes.uint_to_value(bytearray(self.read(2)))
             self.offset = vartypes.uint_to_value(bytearray(self.read(2)))
             # size gets ignored: even the \x1a at the end is read
             self.length = vartypes.uint_to_value(bytearray(self.read(2)))
示例#13
0
文件: disk.py 项目: boriel/pcbasic
 def __init__(self, fhandle, filetype, number, name, mode,
                    seg, offset, length):
     """ Initialise program file object and write header. """
     iolayer.RawFile.__init__(self, fhandle, filetype, mode)
     self.number = number
     # don't lock binary files
     self.lock = ''
     self.access = 'RW'
     self.seg, self.offset, self.length = 0, 0, 0
     if self.mode == 'O':
         self.write(iolayer.type_to_magic[filetype])
         if self.filetype == 'M':
             self.write(vartypes.value_to_uint(seg) +
                        vartypes.value_to_uint(offset) +
                        vartypes.value_to_uint(length))
             self.seg, self.offset, self.length = seg, offset, length
     else:
         # drop magic byte
         self.read_raw(1)
         if self.filetype == 'M':
             self.seg = vartypes.uint_to_value(bytearray(self.read(2)))
             self.offset = vartypes.uint_to_value(bytearray(self.read(2)))
             # size gets ignored: even the \x1a at the end is read
             self.length = vartypes.uint_to_value(bytearray(self.read(2)))
示例#14
0
def get_value_for_varptrstr(varptrstr):
    """ Get a value given a VARPTR$ representation. """
    if len(varptrstr) < 3:
        raise error.RunError(error.IFC)
    varptrstr = bytearray(varptrstr)
    varptr = vartypes.uint_to_value(bytearray(varptrstr[1:3]))
    found_name = ''
    for name in state.basic_state.var_memory:
        _, var_ptr = state.basic_state.var_memory[name]
        if var_ptr == varptr:
            found_name = name
            break
    if found_name == '':
        raise error.RunError(error.IFC)
    return var.get_var(found_name)
示例#15
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)
示例#16
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)
示例#17
0
文件: program.py 项目: nony05/pcbasic
def update_line_dict(pos, afterpos, length, deleteable, beyond):
    """ Update line number dictionary after deleting lines. """
    # subtract length of line we replaced
    length -= afterpos - pos
    addr = program_memory_start + afterpos
    state.basic_state.bytecode.seek(afterpos + length + 1)  # pass \x00
    while True:
        next_addr = bytearray(state.basic_state.bytecode.read(2))
        if len(next_addr) < 2 or next_addr == '\0\0':
            break
        next_addr = vartypes.uint_to_value(next_addr)
        state.basic_state.bytecode.seek(-2, 1)
        state.basic_state.bytecode.write(str(vartypes.value_to_uint(next_addr + length)))
        state.basic_state.bytecode.read(next_addr - addr - 2)
        addr = next_addr
    # update line number dict
    for key in deleteable:
        del state.basic_state.line_numbers[key]
    for key in beyond:
        state.basic_state.line_numbers[key] += length
示例#18
0
def update_line_dict(pos, afterpos, length, deleteable, beyond):
    """ Update line number dictionary after deleting lines. """
    # subtract length of line we replaced
    length -= afterpos - pos
    addr = program_memory_start + afterpos
    state.basic_state.bytecode.seek(afterpos + length + 1)  # pass \x00
    while True:
        next_addr = bytearray(state.basic_state.bytecode.read(2))
        if len(next_addr) < 2 or next_addr == '\0\0':
            break
        next_addr = vartypes.uint_to_value(next_addr)
        state.basic_state.bytecode.seek(-2, 1)
        state.basic_state.bytecode.write(
            str(vartypes.value_to_uint(next_addr + length)))
        state.basic_state.bytecode.read(next_addr - addr - 2)
        addr = next_addr
    # update line number dict
    for key in deleteable:
        del state.basic_state.line_numbers[key]
    for key in beyond:
        state.basic_state.line_numbers[key] += length
示例#19
0
def oct_to_str(s):
    """ Convert oct token to Python string. """
    return "&O" + oct(vartypes.uint_to_value(s))[1:]
示例#20
0
def uint_to_str(s):
    """ Convert unsigned int token to Python string. """
    return str(vartypes.uint_to_value(s))
示例#21
0
def renum(new_line, start_line, step):
    """ Renumber stored program. """
    new_line = 10 if new_line is None else new_line
    start_line = 0 if start_line is None else start_line
    step = 10 if step is None else step
    # get a sorted list of line numbers
    keys = sorted(
        [k for k in state.basic_state.line_numbers.keys() if k >= start_line])
    # assign the new numbers
    old_to_new = {}
    for old_line in keys:
        if old_line < 65535 and new_line > 65529:
            raise error.RunError(error.IFC)
        if old_line == 65536:
            break
        old_to_new[old_line] = new_line
        state.basic_state.last_stored = new_line
        new_line += step
    # write the new numbers
    for old_line in old_to_new:
        state.basic_state.bytecode.seek(
            state.basic_state.line_numbers[old_line])
        # skip the \x00\xC0\xDE & overwrite line number
        state.basic_state.bytecode.read(3)
        state.basic_state.bytecode.write(
            str(vartypes.value_to_uint(old_to_new[old_line])))
    # rebuild the line number dictionary
    new_lines = {}
    for old_line in old_to_new:
        new_lines[
            old_to_new[old_line]] = state.basic_state.line_numbers[old_line]
        del state.basic_state.line_numbers[old_line]
    state.basic_state.line_numbers.update(new_lines)
    # write the indirect line numbers
    state.basic_state.bytecode.seek(0)
    while util.skip_to_read(state.basic_state.bytecode, ('\x0e', )) == '\x0e':
        # get the old g number
        jumpnum = vartypes.uint_to_value(
            bytearray(state.basic_state.bytecode.read(2)))
        try:
            newjump = old_to_new[jumpnum]
        except KeyError:
            # not redefined, exists in program?
            if jumpnum in state.basic_state.line_numbers:
                newjump = jumpnum
            else:
                linum = get_line_number(state.basic_state.bytecode.tell())
                console.write_line('Undefined line ' + str(jumpnum) + ' in ' +
                                   str(linum))
        state.basic_state.bytecode.seek(-2, 1)
        state.basic_state.bytecode.write(str(vartypes.value_to_uint(newjump)))
    # stop running if we were
    flow.set_pointer(False)
    # reset loop stacks
    state.basic_state.gosub_return = []
    state.basic_state.for_next_stack = []
    state.basic_state.while_wend_stack = []
    # renumber error handler
    if state.basic_state.on_error:
        state.basic_state.on_error = old_to_new[state.basic_state.on_error]
    # renumber event traps
    for handler in state.basic_state.events.all:
        if handler.gosub:
            handler.set_jump(old_to_new[handler.gosub])
示例#22
0
文件: modes.py 项目: nony05/pcbasic
 def record_to_sprite_size(self, byte_array):
     """ Read 4-byte record of sprite size. """
     dx = vartypes.uint_to_value(byte_array[0:2]) / self.bitsperpixel
     dy = vartypes.uint_to_value(byte_array[2:4])
     return dx, dy
示例#23
0
文件: modes.py 项目: nestormh/pcbasic
def record_to_sprite_size_ega(self, byte_array):
    """ Read 4-byte record of sprite size in EGA modes. """
    dx = vartypes.uint_to_value(byte_array[0:2])
    dy = vartypes.uint_to_value(byte_array[2:4])
    return dx, dy
示例#24
0
文件: modes.py 项目: nestormh/pcbasic
 def record_to_sprite_size(self, byte_array):
     """ Read 4-byte record of sprite size. """
     dx = vartypes.uint_to_value(byte_array[0:2]) / self.bitsperpixel
     dy = vartypes.uint_to_value(byte_array[2:4])
     return dx, dy
示例#25
0
def hex_to_str(s):
    """ Convert hex token to Python string. """
    return "&H" + hex(vartypes.uint_to_value(s))[2:].upper()
示例#26
0
def hex_to_str(s):
    """ Convert hex token to Python string. """
    return "&H" + hex(vartypes.uint_to_value(s))[2:].upper()
示例#27
0
 def address(self, key):
     """ Return the address of a given key. """
     return vartypes.uint_to_value(bytearray(key[-2:]))
示例#28
0
 def address(self, key):
     """ Return the address of a given key. """
     return vartypes.uint_to_value(bytearray(key[-2:]))
示例#29
0
def oct_to_str(s):
    """ Convert oct token to Python string. """
    return "&O" + oct(vartypes.uint_to_value(s))[1:]
示例#30
0
文件: modes.py 项目: nony05/pcbasic
def record_to_sprite_size_ega(self, byte_array):
    """ Read 4-byte record of sprite size in EGA modes. """
    dx = vartypes.uint_to_value(byte_array[0:2])
    dy = vartypes.uint_to_value(byte_array[2:4])
    return dx, dy
示例#31
0
def uint_to_str(s):
    """ Convert unsigned int token to Python string. """
    return str(vartypes.uint_to_value(s))