def load_to_env(env, filename): msg = env.screen.msg try: subname, hdrChunk, memChunk, frames = read(filename) except IOError as ioerr: msg('error reading file: ' + str(ioerr) + '\n') return False if subname != b'IFZS': msg('not a quetzal save file\n') if env.hdr.release != hdrChunk.release: msg('release doesn\'t match\n') elif env.hdr.serial != hdrChunk.serial: msg('serial doesn\'t match\n') elif env.hdr.checksum != hdrChunk.checksum: msg('checksum does\'t match\n') else: env.reset() for i in range(len(memChunk.mem)): if memChunk.compressed: env.mem[i] ^= six.indexbytes(memChunk.mem, i) else: env.mem[i] = six.indexbytes(memChunk.mem, i) env.fixup_after_restore() env.pc = hdrChunk.pc env.callstack = frames # pc is now in wrong place: # must fix based on z version # after this func returns! return True return False
def load_to_env(env, filename): msg = env.screen.msg try: subname, hdrChunk, memChunk, frames = read(filename) except IOError as ioerr: msg('error reading file: '+str(ioerr)+'\n') return False if subname != b'IFZS': msg('not a quetzal save file\n') if env.hdr.release != hdrChunk.release: msg('release doesn\'t match\n') elif env.hdr.serial != hdrChunk.serial: msg('serial doesn\'t match\n') elif env.hdr.checksum != hdrChunk.checksum: msg('checksum does\'t match\n') else: env.reset() for i in range(len(memChunk.mem)): if memChunk.compressed: env.mem[i] ^= six.indexbytes(memChunk.mem, i) else: env.mem[i] = six.indexbytes(memChunk.mem, i) env.fixup_after_restore() env.pc = hdrChunk.pc env.callstack = frames # pc is now in wrong place: # must fix based on z version # after this func returns! return True return False
def from_packed(cls, data): obj = cls() ret_addr_bytearray = bytearray([0, 0, 0, 0]) ret_addr_bytearray[1:] = bytearray(data[:3]) ret_addr_bytes = bytes(ret_addr_bytearray) obj.return_addr = struct.unpack('>I', ret_addr_bytes)[0] flags = six.indexbytes(data, 3) num_locals = flags & 15 if flags & 16: # discard return val obj.return_val_loc = None else: obj.return_val_loc = six.indexbytes(data, 4) # this should never have non-consecutive ones, right? # i.e. you can't have arg 3 without having args 1 and 2 (right?) args_flag = six.indexbytes(data, 5) obj.num_args = 0 for i in range(7): if args_flag >> i: obj.num_args += 1 used_stack_size = struct.unpack('>H', data[6:8])[0] obj.locals = [] for i in range(num_locals): addr = 8 + i * 2 local = struct.unpack('>H', data[addr:addr + 2])[0] obj.locals.append(local) obj.stack = [] for i in range(used_stack_size): addr = 8 + num_locals * 2 + i * 2 word = struct.unpack('>H', data[addr:addr + 2])[0] obj.stack.append(word) obj.size = 8 + num_locals * 2 + used_stack_size * 2 return obj
def from_packed(cls, data): obj = cls() ret_addr_bytearray = bytearray([0,0,0,0]) ret_addr_bytearray[1:] = bytearray(data[:3]) ret_addr_bytes = bytes(ret_addr_bytearray) obj.return_addr = struct.unpack('>I', ret_addr_bytes)[0] flags = six.indexbytes(data, 3) num_locals = flags & 15 if flags & 16: # discard return val obj.return_val_loc = None else: obj.return_val_loc = six.indexbytes(data, 4) # this should never have non-consecutive ones, right? # i.e. you can't have arg 3 without having args 1 and 2 (right?) args_flag = six.indexbytes(data, 5) obj.num_args = 0 for i in range(7): if args_flag >> i: obj.num_args += 1 used_stack_size = struct.unpack('>H', data[6:8])[0] obj.locals = [] for i in range(num_locals): addr = 8+i*2 local = struct.unpack('>H', data[addr:addr+2])[0] obj.locals.append(local) obj.stack = [] for i in range(used_stack_size): addr = 8+num_locals*2+i*2 word = struct.unpack('>H', data[addr:addr+2])[0] obj.stack.append(word) obj.size = 8+num_locals*2+used_stack_size*2 return obj
def decRLE(mem): bigmem = [] i = 0 while i < len(mem): bigmem.append(six.indexbytes(mem, i)) if six.indexbytes(mem, i) == 0: bigmem.extend([0] * six.indexbytes(mem, i + 1)) i += 2 else: i += 1 return bytes(bytearray(bigmem))
def decRLE(mem): bigmem = [] i = 0 while i < len(mem): bigmem.append(six.indexbytes(mem, i)) if six.indexbytes(mem, i) == 0: bigmem.extend([0] * six.indexbytes(mem, i+1)) i += 2 else: i += 1 return bytes(bytearray(bigmem))
def encRLE(mem): small_mem = [] i = 0 while i < len(mem): small_mem.append(six.indexbytes(mem, i)) if six.indexbytes(mem, i) == 0: zero_run = 0 i += 1 while i < len(mem) and six.indexbytes(mem, i) == 0 and zero_run < 255: zero_run += 1 i += 1 small_mem.append(zero_run) else: i += 1 return bytes(bytearray(small_mem))
def from_env(cls, env): obj = cls() obj.name = b'CMem' obj.mem = env.mem[:env.hdr.static_mem_base] for i in range(len(obj.mem)): obj.mem[i] ^= six.indexbytes(env.orig_mem, i) while obj.mem[-1] == 0: obj.mem.pop() obj.mem = bytes(bytearray(obj.mem)) obj.compressed = True return obj
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)