def do_list(p, a, nw, fn = None): while a != 0: x = p.t.add(a - 4, a + nw, "XXXTBL") const.dot_txt(p, a - 4, a) if fn != None: fn(p, a) else: for i in range(0,nw): const.word(p, a + i, "%o") a = p.m.rd(a)
def follow_chain(p, a, f = None): while a != 0: if f != None: f(p, a) x = const.word(p, a + 2) x.lcmt("+2 CHAIN") x = const.dot_txt(p, a + 4, a + 7) x.lcmt("+4 NAME") a = p.m.rd(a + 2)
def do_desc(p, a, l, n, desc): if not 'domus_desc' in p.a: p.a['domus_desc'] = dict() id = (a, l, n, desc) if a in p.a['domus_desc']: b = p.a['domus_desc'][a] if b == id: return False print("Redo diff desc @ " + p.m.afmt(a), b, id) return False p.a['domus_desc'][a] = id dtype = n + "Descriptor" if l == 0: for i in desc: try: p.m.rd(a + l) except: break l += i[0] x = p.t.add(a, a + l, dtype) x.blockcmt += n + " descriptor\n" x.fill = False i = 0 for j in desc: if j[1] == "name": x = const.dot_txt(p, a+i, a + i + j[0]) else: x = const.word(p, a + i) x.cmt.append("+%d " % i + j[1]) i += j[0] if i >= l: break while i < l: x = const.word(p, a + i) x.cmt.append("+%d" % i) i += 1 return True
def hint(p): cpu = p.c["domus"] # See RCSL 43-GL-7915 p35 pgd = p.a['progdesc'] print("CATW", pgd) x = const.word(p, pgd + 7) x.cmt.append(" +7 First Area Process") x = const.word(p, pgd + 8) x.cmt.append(" +8 Top Area Process") x = const.word(p, pgd + 9) x.cmt.append(" +9 Head of Unit Chain") x = const.word(p, pgd + 10) x.cmt.append(" +10 Chain of Head of Unit Chain") a = pgd + 11 while True: x = p.t.add(a, a + 20, "UnitDesc") x = const.word(p, a) x.cmt.append(" +0 Driver name reference") x = const.word(p, a + 1) x.cmt.append(" +1 Unit number") x = const.word(p, a + 2) x.cmt.append(" +2 chain") x = const.word(p, a + 3) x.cmt.append(" +3 size of unit desc") x = const.dot_txt(p, a + 4, a + 7) x = const.dot_txt(p, a + 7, a + 10) x = const.word(p, a + 10) x.cmt.append(" +10 Kit displacement") x = const.word(p, a + 11) x.cmt.append(" +11 Kit displacement") n = p.m.rd(a + 2) if n == 0: break a = n
def pz_entries(self): i = self.root.root.spec[0] assert i[0] == 0xffff pz = dict() for j in sorted(i[1]): if j & 0xf700 == 0x0400: k = i[1][j] pz[j & 0xff] = k.spec[0] for i in sorted(pz.keys()): try: w = self.p.m.rd(i) x = const.word(self.p, i) x.lcmt(pz[i]) if w != 0: self.disass(w) self.p.setlabel(w, pz[i]) except mem.MemError: del pz[i] fi = open(self.dir + "/domus_page_zero.txt", "r") for i in fi.readlines(): i = i.strip() if i == "" or i[0] == "#": continue i = i.split() j = int(i[1], 0) if j in pz: print("PZ", pz[i], i) continue try: w = self.p.m.rd(j) x = const.word(self.p, j) x.lcmt(i[0]) except: pass fi.close()
def xx(n): i = n + tbl_base x = inter.intins[n] y = const.word(p,i) id = "op=%d: " % n + x[1] + str(x[2:]) y.cmt.append(id) a = p.m.rd(i) if len(x) == 2: p.setlabel(a, x[1] + " **********") else: p.setlabel(a, x[1]) x = p.m.rd(i) if x != 0: ins = cpu.ins[0x800c] ins.flow("cond", "#%d" % n, x) z = cpu.disass(x) z.lcmt(id)
def xx(n): i = n + tbl_base x = inter.intins[n] y = const.word(p, i) id = "op=%d: " % n + x[1] + str(x[2:]) y.cmt.append(id) a = p.m.rd(i) if len(x) == 2: p.setlabel(a, x[1] + " **********") else: p.setlabel(a, x[1]) x = p.m.rd(i) if x != 0: ins = cpu.ins[0x800c] ins.flow("cond", "#%d" % n, x) z = cpu.disass(x) z.lcmt(id)
def do_disass(self, adr, ins): assert ins.lo == adr assert ins.status == "prospective" try: c = self.root.find(self.p, adr, self.p.m.rd) except: ins.fail("no memory") return ins.mne = c.spec[0] da = None indir = 0 for i in c.spec[1].split(","): if i == "#": if self.rdarg(ins, c, i) != 0: ins.mne += "#" elif i == "@": if self.rdarg(ins, c, i) != 0: ins.mne += "@" indir = 1 elif i == "sh": ins.mne += ( "", "L", "R", "S" )[self.rdarg(ins, c, i)] elif i == "cy": ins.mne += ( "", "Z", "O", "C" )[self.rdarg(ins, c, i)] elif i == "flg": ins.mne += ( "", "S", "C", "P" )[self.rdarg(ins, c, i)] elif i == "tst": ins.mne += ( "BN", "BZ", "DN", "DZ" )[self.rdarg(ins, c, i)] elif i == "dev": ins.oper.append( self.p.m.dfmt( self.rdarg(ins, c, i) ) ) elif i == "skip": j = self.rdarg(ins, c, i) if j: ins.oper.append(( "", "SKP", "SZC", "SNC", "SZR", "SNR", "SEZ", "SBN" )[self.rdarg(ins, c, i)]) if j > 0: ins.flow("cond", "T", ins.lo + 2) if j > 1: ins.flow("cond", "T", ins.lo + 1) elif i == "acs" or i == "acd": ins.oper.append("%d" % self.rdarg(ins, c, i)) elif i == "displ": r = self.rdarg(ins, c, "idx") o = self.rdarg(ins, c, "displ") if r != 0 and o > 128: o -= 256 if r == 0: ins.oper.append(( o, "%s", self.p.m.dfmt(o, False) )) da = o elif r == 1: o += ins.lo ins.oper.append((o, "%s")) da = o else: ins.oper.append(self.p.m.dfmt(o, False)) ins.oper.append("%d" % r) elif i == '""': pass else: print(i, c) ins.fail("Unhandled arg <%s>" % i) return if da != None and indir: try: w = self.p.m.rd(da) const.word(self.p, da) if w != 0: da = w; else: da = None except: da = None # XXX: should also handle SKP instructions masked by macros if ins.mne[1:3] == "SZ" or ins.mne[:3] == "SKP": ins.flow("cond", "?", ins.lo + 1) ins.flow("cond", "?", ins.lo + 2) elif ins.mne[:3] == "JMP": ins.flow("cond", "T", da) elif ins.mne[:3] == "JSR": ins.flow("call", "T", da) elif ins.mne == "JMP@" or ins.mne == "JSR@": if da != None: try: da = self.p.m.rd(da) except: da = None if ins.mne == "JMP": ins.flow("cond", "T", da) else: ins.flow("call", "T", da)
def do_disass(self, adr, ins): assert ins.lo == adr assert ins.status == "prospective" p = self.p try: w = p.m.rd(ins.lo) except: ins.fail("NO MEM") return q = p.m.rdqual(ins.lo) if q != 1: ins.fail("reloc %d INTER" % q) return op = w >> 8 arg = w & 0xff if op not in intins: ins.fail("Unknown INT oper %d" % op) return l = intins[op] #print("%04x" % w, l, ins) ins.spec = l ins.args = list() action = list(l[2:]) for i in action: if type(i) != str: i = i[0] try: nxt = p.m.rd(ins.hi) except: nxt = None if i == ">>2": arg >>= 2 elif i == "ADDR": ins.args.append("addr: " + p.m.afmt(nxt)) ins.hi += 1 elif i == "V": if arg & 3 == 0: ins.args.append("v0: %x" % nxt) ins.hi += 1 elif arg & 3 == 1: ins.args.append("v1: R") elif arg & 3 == 2: ins.args.append("v2: %x" % nxt) ins.hi += 1 elif arg & 3 == 3: ins.args.append("v3: R") arg >>= 2 elif i == "A": tq = p.m.rdqual(ins.hi) ins.hi += 1 if tq == 3: ax = "%o'*2" % (nxt >> 1) if nxt & 1: ax += "+1" else: ax = p.m.afmt(nxt) if arg & 3 == 0: ins.args.append("a0:int " + ax) elif arg & 3 == 1: ins.args.append("a1:str " + ax) elif arg & 3 == 2: ins.args.append("a2:file " + ax) else: ins.args.append("a3:zone " + ax) arg >>= 2 elif i == "ZONE": if p.m.rdqual(nxt) != 1: isn.fail("Zone not reloc") return ins.args.append("zone: " + p.m.afmt(nxt)) p.todo(nxt, desc.zonedesc) ins.hi += 1 arg >>= 2 p.c["domus"].disass(p.m.rd(nxt + 3)) self.disass(p.m.rd(nxt + 3) + 1) elif i == "ARG": ins.args.append("arg: " + p.m.dfmt(arg)) elif i == "BITS": arg = nxt ins.hi += 1 elif i == "STOP": ins.flow("cond","T", None) elif i == "CONST": ins.args.append("ci: " + p.m.dfmt(nxt)) ins.hi += 1 elif i == "CL": ins.args.append("i: " + p.m.dfmt(nxt)) ins.flow("call", "T", nxt + 1) ins.hi += 1 p.c["domus"].disass(nxt) elif i == "LN": ins.args.append("ret: " + p.m.dfmt(nxt)) ins.hi += 1 ins.flow("ret", "T", None) x = p.t.add(nxt, ins.hi, "int_func") elif i == "RET": ins.args.append("ret: " + p.m.dfmt(nxt)) ins.hi += 1 ins.flow("ret", "T", None) const.word(p, nxt - 1) x = p.t.add(nxt - 1, ins.hi, "int_func") elif i == "CALL": ins.args.append("i: " + p.m.dfmt(nxt)) ins.flow("call", "T", nxt + 1) ins.hi += 1 p.c["domus"].disass(nxt) elif i == "N": pass elif i == "GC": l = inter_lib.ident_gc(p, self, ins, arg) ins.args.append("CODEP%d" % arg) a = p.a['procdesc'] - arg const.word(p, a) p.setlabel(a, ".CODEP%d" % arg) a = p.m.rd(a) p.setlabel(a, "CODEP%d" % arg) p.c["domus"].disass(a) cp = arg arg = nxt ins.hi += 1 action += l elif i == "JUMP": ins.hi += 1 ins.args.append("cc: %o" % arg) ins.args.append("jmp: " + p.m.afmt(nxt)) ins.flow("cond", "cc/%o" % arg, nxt) ins.flow("cond", "!cc/%o" % arg, ins.hi) else: print("%04x" % w, l, ins) ins.fail("arg unknown '%s'" % i) return ins.render = self.render
def do_disass(self, adr, ins): assert ins.lo == adr assert ins.status == "prospective" p = self.p try: w = p.m.rd(ins.lo) except: ins.fail("NO MEM") return q = p.m.rdqual(ins.lo) if q != 1: ins.fail("reloc %d INTER" % q) return op = w >> 8 arg = w & 0xff if op not in intins: ins.fail("Unknown INT oper %d" % op) return l = intins[op] #print("%04x" % w, l, ins) ins.spec = l ins.args = list() action = list(l[2:]) for i in action: if type(i) != str: i = i[0] try: nxt = p.m.rd(ins.hi) except: nxt = None if i == ">>2": arg >>= 2 elif i == "ADDR": ins.args.append("addr: " + p.m.afmt(nxt)) ins.hi += 1 elif i == "V": if arg & 3 == 0: ins.args.append("v0: %x" % nxt) ins.hi += 1 elif arg & 3 == 1: ins.args.append("v1: R") elif arg & 3 == 2: ins.args.append("v2: %x" % nxt) ins.hi += 1 elif arg & 3 == 3: ins.args.append("v3: R") arg >>= 2 elif i == "A": tq = p.m.rdqual(ins.hi) ins.hi += 1 if tq == 3: ax = "%o'*2" % (nxt >> 1) if nxt & 1: ax += "+1" else: ax = p.m.afmt(nxt) if arg & 3 == 0: ins.args.append("a0:int " + ax) elif arg & 3 == 1: ins.args.append("a1:str " + ax) elif arg & 3 == 2: ins.args.append("a2:file " + ax) else: ins.args.append("a3:zone " + ax) arg >>= 2 elif i == "ZONE": if p.m.rdqual(nxt) != 1: isn.fail("Zone not reloc") return ins.args.append("zone: " + p.m.afmt(nxt)) p.todo(nxt, desc.zonedesc) ins.hi += 1 arg >>= 2 p.c["domus"].disass(p.m.rd(nxt + 3)) self.disass(p.m.rd(nxt + 3) + 1) elif i == "ARG": ins.args.append("arg: " + p.m.dfmt(arg)) elif i == "BITS": arg = nxt ins.hi += 1 elif i == "STOP": ins.flow("cond", "T", None) elif i == "CONST": ins.args.append("ci: " + p.m.dfmt(nxt)) ins.hi += 1 elif i == "CL": ins.args.append("i: " + p.m.dfmt(nxt)) ins.flow("call", "T", nxt + 1) ins.hi += 1 p.c["domus"].disass(nxt) elif i == "LN": ins.args.append("ret: " + p.m.dfmt(nxt)) ins.hi += 1 ins.flow("ret", "T", None) x = p.t.add(nxt, ins.hi, "int_func") elif i == "RET": ins.args.append("ret: " + p.m.dfmt(nxt)) ins.hi += 1 ins.flow("ret", "T", None) const.word(p, nxt - 1) x = p.t.add(nxt - 1, ins.hi, "int_func") elif i == "CALL": ins.args.append("i: " + p.m.dfmt(nxt)) ins.flow("call", "T", nxt + 1) ins.hi += 1 p.c["domus"].disass(nxt) elif i == "N": pass elif i == "GC": l = inter_lib.ident_gc(p, self, ins, arg) ins.args.append("CODEP%d" % arg) a = p.a['procdesc'] - arg const.word(p, a) p.setlabel(a, ".CODEP%d" % arg) a = p.m.rd(a) p.setlabel(a, "CODEP%d" % arg) p.c["domus"].disass(a) cp = arg arg = nxt ins.hi += 1 action += l elif i == "JUMP": ins.hi += 1 ins.args.append("cc: %o" % arg) ins.args.append("jmp: " + p.m.afmt(nxt)) ins.flow("cond", "cc/%o" % arg, nxt) ins.flow("cond", "!cc/%o" % arg, ins.hi) else: print("%04x" % w, l, ins) ins.fail("arg unknown '%s'" % i) return ins.render = self.render
def do_disass(self, adr, ins): assert ins.lo == adr assert ins.status == "prospective" try: c = self.root.find(self.p, adr, self.p.m.rd) except: ins.fail("no memory") return ins.mne = c.spec[0] da = None indir = 0 for i in c.spec[1].split(","): if i == "#": if self.rdarg(ins, c, i) != 0: ins.mne += "#" elif i == "@": if self.rdarg(ins, c, i) != 0: ins.mne += "@" indir = 1 elif i == "sh": ins.mne += ("", "L", "R", "S")[self.rdarg(ins, c, i)] elif i == "cy": ins.mne += ("", "Z", "O", "C")[self.rdarg(ins, c, i)] elif i == "flg": ins.mne += ("", "S", "C", "P")[self.rdarg(ins, c, i)] elif i == "tst": ins.mne += ("BN", "BZ", "DN", "DZ")[self.rdarg(ins, c, i)] elif i == "dev": ins.oper.append(self.p.m.dfmt(self.rdarg(ins, c, i))) elif i == "skip": j = self.rdarg(ins, c, i) if j: ins.oper.append(("", "SKP", "SZC", "SNC", "SZR", "SNR", "SEZ", "SBN")[self.rdarg(ins, c, i)]) if j > 0: ins.flow("cond", "T", ins.lo + 2) if j > 1: ins.flow("cond", "T", ins.lo + 1) elif i == "acs" or i == "acd": ins.oper.append("%d" % self.rdarg(ins, c, i)) elif i == "displ": r = self.rdarg(ins, c, "idx") o = self.rdarg(ins, c, "displ") if r != 0 and o > 128: o -= 256 if r == 0: ins.oper.append((o, "%s", self.p.m.dfmt(o, False))) da = o elif r == 1: o += ins.lo ins.oper.append((o, "%s")) da = o else: ins.oper.append(self.p.m.dfmt(o, False)) ins.oper.append("%d" % r) elif i == '""': pass else: print(i, c) ins.fail("Unhandled arg <%s>" % i) return if da != None and indir: try: w = self.p.m.rd(da) const.word(self.p, da) if w != 0: da = w else: da = None except: da = None # XXX: should also handle SKP instructions masked by macros if ins.mne[1:3] == "SZ" or ins.mne[:3] == "SKP": ins.flow("cond", "?", ins.lo + 1) ins.flow("cond", "?", ins.lo + 2) elif ins.mne[:3] == "JMP": ins.flow("cond", "T", da) elif ins.mne[:3] == "JSR": ins.flow("call", "T", da) elif ins.mne == "JMP@" or ins.mne == "JSR@": if da != None: try: da = self.p.m.rd(da) except: da = None if ins.mne == "JMP": ins.flow("cond", "T", da) else: ins.flow("call", "T", da)
def c13055(p, a): const.word(p, a + 0) const.word(p, a + 1) const.word(p, a + 3) const.word(p, a + 7)
def c12524(p, a): const.word(p, a + 3) cpu.disass(p.m.rd(a + 3))
def hunt_outtext(p, cpu): """ A very crude value tracker for system calls """ did = dict() for i in cpu.ins: ins = cpu.ins[i] w = p.m.rd(ins.lo) if w & 0xff00 != 0x0c00: continue ac = [None,None,None,None] x = i-1 while x in cpu.ins: ins1 = cpu.ins[x] if ins1.mne != "LDA": #print("!", cpu.render(p, ins1)) break if len(ins1.oper) != 2: #print("!", cpu.render(p, ins1)) break n = int(ins1.oper[0]) ac[n] = ins1.oper[1][0] const.word(p, ac[n]) x -= 1 if ac == [None,None,None,None]: continue s = p.m.afmt(i) s += " " s += cpu.render(p, ins)[0] s += " " for j in range(0,4): i = ac[j] if i != None: s += " AC%d=" % j + p.m.afmt(i) try: w = p.m.rd(i) q = p.m.rdqual(i) s += "=" + p.m.aqfmt(w, q) except: s += "=undef" print(s) if ins.mne == "SEARCHITEM": if ac[1] != None: try: w = p.m.rd(ac[1]) print(" HEAD", p.m.afmt(ac[1]), p.m.afmt(w)) const.word(p, w + 2) except: pass if ac[2] != None: w = p.m.rd(ac[2]) print(" NAME", p.m.afmt(ac[2]), p.m.afmt(w)) try: const.dot_txt(p, w, w + 3) except: pass if ins.mne == "SENDMESSAGE": if ac[1] != None: w = p.m.rd(ac[1]) print(" MSG", p.m.afmt(ac[1]), p.m.afmt(w)) for j in range(0,4): try: const.word(p, w + j) except: pass try: ww = p.m.rd(w + 2) q = p.m.rdqual(w + 2) if q == 3 and ww != 0: const.dot_txt(p, ww >> 1) except: pass if ac[2] != None: w = p.m.rd(ac[2]) print(" DST", p.m.afmt(ac[2]), p.m.afmt(w)) try: const.dot_txt(p, w, w + 3) except: pass if ins.mne[:3] == "OUT" or ins.mne == "OPEN": if ac[2] != None: z = p.m.rd(ac[2]) if z in did: continue did[z] = True print(" ZONE", p.m.afmt(z)) p.todo(z, desc.zonedesc) if ins.mne == "OUTTEXT": if ac[0] != None: t = p.m.rd(ac[0]) if t in did: continue did[t] = True if t != 0: t = t >> 1 print(" TXT", p.m.afmt(ac[0]), p.m.afmt(t)) try: const.dot_txt(p, t) except: pass
def hint(p): p.m.hex = False cpu = p.c["domus"] tbl_base = 0x800d # "PINTGIVEUP" ? cpu.disass(0xa0) def xx(n): i = n + tbl_base x = inter.intins[n] y = const.word(p,i) id = "op=%d: " % n + x[1] + str(x[2:]) y.cmt.append(id) a = p.m.rd(i) if len(x) == 2: p.setlabel(a, x[1] + " **********") else: p.setlabel(a, x[1]) x = p.m.rd(i) if x != 0: ins = cpu.ins[0x800c] ins.flow("cond", "#%d" % n, x) z = cpu.disass(x) z.lcmt(id) for i in inter.intins: xx(i) p.setlabel(0x1000, "TxtBreak") const.dot_txt(p, 0x1000, 0x1005) p.setlabel(0x1005, "TxtError") const.dot_txt(p, 0x1005, 0x100a) p.setlabel(0o100267, "Execute") p.setlabel(0o100273, "GetZoneAddr") p.setlabel(0o100371, "TakeAidxV") p.setlabel(0o100407, "Take2Addr") p.setlabel(0o100644, "Send2Oper") p.setlabel(0o100654, "_OperMsg") p.setlabel(0o101117, "IntGiveup") cpu.disass(0o101117) p.setlabel(0o101131, "PIntGiveup") cpu.disass(0o101131) # Empty table entries const.word(p, 0o100361) const.word(p, 0o100362) # Operator Message const.word(p, 0o100654) const.word(p, 0o100655) const.word(p, 0o100656) const.word(p, 0o100657) const.word(p, 0o100660) const.dot_txt(p, 0o101270, 0o101271) const.dot_txt(p, 0o101271, 0o101272) for i in range(0o101272, 0o101277): const.word(p, i) for i in (0o100325, 0o101331): const.word(p, i) const.dot_txt(p, 0o101332, 0o101333)
def hint(p): p.m.hex = False cpu = p.c["domus"] tbl_base = 0x800d # "PINTGIVEUP" ? cpu.disass(0xa0) def xx(n): i = n + tbl_base x = inter.intins[n] y = const.word(p, i) id = "op=%d: " % n + x[1] + str(x[2:]) y.cmt.append(id) a = p.m.rd(i) if len(x) == 2: p.setlabel(a, x[1] + " **********") else: p.setlabel(a, x[1]) x = p.m.rd(i) if x != 0: ins = cpu.ins[0x800c] ins.flow("cond", "#%d" % n, x) z = cpu.disass(x) z.lcmt(id) for i in inter.intins: xx(i) p.setlabel(0x1000, "TxtBreak") const.dot_txt(p, 0x1000, 0x1005) p.setlabel(0x1005, "TxtError") const.dot_txt(p, 0x1005, 0x100a) p.setlabel(0o100267, "Execute") p.setlabel(0o100273, "GetZoneAddr") p.setlabel(0o100371, "TakeAidxV") p.setlabel(0o100407, "Take2Addr") p.setlabel(0o100644, "Send2Oper") p.setlabel(0o100654, "_OperMsg") p.setlabel(0o101117, "IntGiveup") cpu.disass(0o101117) p.setlabel(0o101131, "PIntGiveup") cpu.disass(0o101131) # Empty table entries const.word(p, 0o100361) const.word(p, 0o100362) # Operator Message const.word(p, 0o100654) const.word(p, 0o100655) const.word(p, 0o100656) const.word(p, 0o100657) const.word(p, 0o100660) const.dot_txt(p, 0o101270, 0o101271) const.dot_txt(p, 0o101271, 0o101272) for i in range(0o101272, 0o101277): const.word(p, i) for i in (0o100325, 0o101331): const.word(p, i) const.dot_txt(p, 0o101332, 0o101333)
def fsym(p, a): l = list() for i in range(0, 4): l.append(const.word(p, a + i, "%o")) l[3].lcmt(str(domus.inter.inter.intins[p.m.rd(a + 3)][1:]))