def Read(R): b = Files.ReadByte(R) if b < 0x80: x = b else: x = b - 0x100 return x
def ThisMod(name): global root, AllocPtr res = 0 nofimps = 0 import_ = [None] * 16 mod = root while mod is not None and mod.name != name: mod = mod.next if mod == None: # (*load*) print 'loading:', name R = OpenFile(name) if R: ## Files.Set(R, F, 0) modname = Files.ReadString(R) key = Files.ReadInt(R) version = Files.ReadByte(R) size = Files.ReadInt(R) print 'Module', modname, key, version, size impname = Files.ReadString(R) while impname: impkey = Files.ReadInt(R) impmod = ThisMod(impname) import_[nofimps] = impmod impmod.refcnt += 1 nofimps += 1 impname = Files.ReadString(R) print 'Imports', import_ mod = Module(modname) mod.data = p = AllocPtr AllocPtr = (p + size + 0x10) / 0x20 * 0x20 mod.size = AllocPtr - p mod.num = 1 if root is None else (root.num + 1) mod.next = root root = mod p += DescSize mod.key = key SYSTEM.PUT(mod.num * 4 + MTOrg, p) # (*module table entry*) n = Files.ReadInt(R) print 'type_descriptors', n for _ in range(0, n, 4): w = Files.ReadInt(R) SYSTEM.PUT(p, w) p += 4 varsize = Files.ReadInt(R) assert varsize == (varsize / 4 * 4), repr(varsize) print 'varsize', varsize q = p + varsize while p < q: SYSTEM.PUT(p, 0) p += 4 strx = Files.ReadInt(R) print 'strings', strx for _ in range(strx): ch = Files.Read(R) SYSTEM.PUTBYTE(p, ch) p += 1 while p % 4: SYSTEM.PUTBYTE(p, 0) p += 1 mod.code = p code_length = Files.ReadInt(R) print 'code length', code_length for _ in range(0, code_length, 4): instruction = Files.ReadCode(R) # Foul hackery! SYSTEM.PUT(p, instruction) p += 4 mod.imp = p # (*copy imports*) for i, impmod in enumerate(import_): if impmod is not None: SYSTEM.PUT(p, impmod.data) p += 4 mod.cmd = p # (*commands*) ch = Files.Read(R) while ch: while ch: SYSTEM.PUTBYTE(p, ch) p += 1 ch = Files.Read(R) while p % 4: SYSTEM.PUTBYTE(p, 0) p += 1 n = Files.ReadInt(R) SYSTEM.PUT(p, n) p += 4 ch = Files.Read(R) while p % 4: SYSTEM.PUTBYTE(p, 0) p += 1 mod.ent = p # (*entries*) nofent = Files.ReadInt(R) for _ in range(nofent): w = Files.ReadInt(R) SYSTEM.PUT(p, w) p += 4 mod.ptr = p # (*pointer references*) w = Files.ReadInt(R) while w >= 0: SYSTEM.PUT(p, mod.data + w) p += 4 w = Files.ReadInt(R) SYSTEM.PUT(p, 0) p += 4 fixorgP = Files.ReadInt(R) fixorgD = Files.ReadInt(R) fixorgT = Files.ReadInt(R) w = Files.ReadInt(R) body = mod.code + w if Files.Read(R) != "O": raise ValueError print 'fixorgP', fixorgP print 'fixorgD', fixorgD print 'fixorgT', fixorgT print # (*fixup of BL*) adr = mod.code + fixorgP * 4 while adr != mod.code: inst = SYSTEM.GET(adr) mno = inst / 0x100000 % 0x10 pno = inst / 0x1000 % 0x100 disp = inst % 0x1000 impmod_data_addr = SYSTEM.GET(mod.imp + (mno - 1) * 4) impmod = look_up_module_by_data_addr(impmod_data_addr) dest = SYSTEM.GET(impmod.ent + pno * 4) dest = dest + impmod.code offset = (dest - adr - 4) / 4 SYSTEM.PUT(adr, (offset % 0x1000000) + 0x0F7000000) adr = adr - disp * 4 # (*fixup of LDR/STR/ADD*) adr = mod.code + fixorgD * 4 while adr != mod.code: inst = SYSTEM.GET(adr) mno = inst / 0x100000 % 0x10 disp = inst % 0x1000 if not mno: # (*global*) SYSTEM.PUT(adr, (inst / 0x1000000 * 0x10 + MT) * 0x100000 + mod.num * 4) else: # (*import*) impmod_data_addr = SYSTEM.GET(mod.imp + (mno - 1) * 4) impmod = look_up_module_by_data_addr(impmod_data_addr) v = impmod.num SYSTEM.PUT(adr, (inst / 0x1000000 * 0x10 + MT) * 0x100000 + v * 4) inst = SYSTEM.GET(adr + 4) vno = inst % 0x100 offset = SYSTEM.GET(impmod.ent + vno * 4) if (inst / 0x100) % 2: offset = offset + impmod.code - impmod.data SYSTEM.PUT(adr + 4, inst / 0x10000 * 0x10000 + offset) adr = adr - disp * 4 # (*fixup of type descriptors*) adr = mod.data + fixorgT * 4 while adr != mod.data: inst = SYSTEM.GET(adr) mno = inst / 0x1000000 % 0x10 vno = inst / 0x1000 % 0x1000 disp = inst % 0x1000 if not mno: # (*global*) inst = mod.data + vno else: # (*import*) impmod_data_addr = SYSTEM.GET(mod.imp + (mno - 1) * 4) impmod = look_up_module_by_data_addr(impmod_data_addr) offset = SYSTEM.GET(impmod.ent + vno * 4) inst = impmod.data + offset SYSTEM.PUT(adr, inst) adr = adr - disp * 4 return mod