def vectors(self, pj, hi=0x400): y = data.Const(pj, 0, 4, "0x%08x", pj.m.bu32, 4) y.lcmt = "Reset SP" vn = {} vi = {} a = 0x4 while a < hi: x = pj.m.bu32(a) if x in (0x0, 0xffffffff): y = data.Const(pj, a, a + 4, "0x%04x", pj.m.bu32, 4) else: if x not in vn: vi[x] = self.disass(pj, x) vn[x] = [] vn[x].append(a >> 2) if x > a: y = data.Codeptr(pj, a, a + 4, x) y.lcmt = self.vector_name(a >> 2) hi = min(hi, x) a += 4 mv = 0 for i in vn: for v in vn[i]: k = self.vector_name(v) if vi[i] != None: vi[i].lcmt += "--> " + k + "\n" if len(vn[i]) == 1: k = self.vector_name(vn[i][0]) pj.set_label(i, k) else: pj.set_label(i, "VECTORS_%d" % mv) mv += 1
def flow_switch(asp, ins): if ins.dstadr != 0x2f38: return ins.flow_out.pop(0) ins += code.Flow(cond="?") asp.set_label(ins.hi, "break_%04x" % ins.lo) y = data.Const(asp, ins.lo - 2, ins.lo) ncase = asp.bu16(ins.lo - 2) y.typ = ".NCASE" y.fmt = "%d" % ncase cs = switches.get(ins.lo) if cs is None: cs = {} a = ins.lo - 2 for i in range(ncase): a -= 2 ct = cs.get(i) if ct is None: ct = "_%d" % i w = data.Const(asp, a, a + 2) z = asp.bs16(a) w.typ = ".CASE" w.fmt = "0x%x, %d" % (i, z) w.fmt += ", 0x%04x" % (ins.hi + z) ins += code.Jump(cond="0x%x" % i, to=ins.hi + z) if z < 0: asp.set_label(ins.hi + z, ".case_%04x_%s" % (ins.lo, ct))
def flow_switch(pj, ins): if ins.dstadr != 0x2f38: return ins.flow_out.pop(0) ins.add_flow(pj, ">", "?", ins.hi) pj.set_label(ins.hi, "break_%04x" % ins.lo) y = data.Const(pj, ins.lo - 2, ins.lo) ncase = pj.m.bu16(ins.lo - 2) y.typ = ".NCASE" y.fmt = "%d" % ncase cs = switches.get(ins.lo) if cs == None: cs = {} a = ins.lo - 2 for i in range(ncase): a -= 2 ct = cs.get(i) if ct == None: ct = "_%d" % i w = data.Const(pj, a, a + 2) z = pj.m.bs16(a) w.typ = ".CASE" w.fmt = "0x%x, %d" % (i,z) w.fmt += ", 0x%04x" % (ins.hi + z) ins.add_flow(pj, ">", "0x%x" % i, ins.hi + z) if z < 0: pj.set_label(ins.hi + z, ".case_%04x_%s" % (ins.lo, ct))
def romsum(pj): b = 0 c = 0 for x in range(pj.m.lo, pj.m.hi): b += pj.m[x] + c c = b >> 8 c = 1 b &= 0xff print("CKSUM(0x%04x-0x%04x) = 0x%x" % (pj.m.lo, pj.m.hi, b)) if pj.pg == 0: y = data.Const(pj, 0x4002, 0x4003) pj.m.set_label(y.lo, "EPROM_PAGES") if pj.pg < 4: assert b == pj.pg y = data.Const(pj, 0x4001, 0x4002) pj.m.set_label(y.lo, "EPROM_SUM_%d" % pj.pg) y = data.Const(pj, 0x4000, 0x4001, "'%c'") assert pj.m[y.lo] == 0x30 + pj.pg pj.m.set_label(y.lo, "EPROM_PAGE_%d" % pj.pg) else: assert b == 0
def example(): m = mem.Stackup((FILENAME,), nextto=__file__) m2 = mem.WordMem(0, m.hi >> 1, bits=16) for a in range(m.lo, m.hi, 2): m2[a >> 1] = m.bu16(a) cx = hp_hybrid.hp_hybrid() cx.m.map(m2, 0x20, offset=0x20) cx.flow_check.append(fc_call) rom_checksum(cx.m) for a, b in SYMBOLS.items(): if b[0] == '_': cx.m.set_label(a, b[1:]) cx.disass(a) elif b[0] == '#': cx.m.set_label(a, b[1:]) y = data.Data(cx.m, a, a + 1) y.rendered = ".CONST\t0x%04x" % cx.m[a] else: cx.m.set_label(a, b) pat4244024.appendix_b_1(cx, 0x3a49) pat4244024.appendix_b_2(cx, 0x3ac2) pat4244024.appendix_b_3(cx, 0x3ca5) pat4244024.appendix_b_4(cx, 0x3d2c) pat4244024.appendix_b_5(cx, 0x3d4b) pat4244024.appendix_b_7(cx, 0x3df0) pat4244024.appendix_b_8(cx, 0x3e02) pat4244024.appendix_b_9(cx, 0x3e13) pat4244024.appendix_b_10(cx, 0x3e30) pat4244024.appendix_b_11(cx, 0x3e4a) pat4244024.appendix_b_12(cx, 0x3e6c) pat4244024.appendix_b_13(cx, 0x3e78) pat4244024.appendix_b_15(cx, 0x3e86) pat4244024.appendix_b_16(cx, 0x3ebc) pat4244024.appendix_b_17(cx, 0x3ebf) pat4244024.appendix_b_18(cx, 0x3ec2) pat4244024.appendix_b_21(cx, 0x3a35) pat4244024.appendix_b_28a(cx, 0x0020) pat4244024.appendix_b_28b(cx, 0x0200) if True: for a in range(0x3ef, 0x40a): data.Const(cx.m, a, a + 1) y = wgstring(cx.m, cx.m[a]) y.compact = True for a in range(0x1ebb, 0x1ec6): data.Const(cx.m, a, a + 1) y = wgstring(cx.m, cx.m[a]) y.compact = True cx.disass(0x20) code.lcmt_flows(cx.m) return NAME, (cx.m,)
def fc_case(asp, ins, _arg): ins.flow_out.pop(-1) a = ins.lo - 1 n = asp[a] data.Const(asp, a, a + 1) while n < 65535: a -= 1 y = data.Const(asp, a, a + 1) ins += code.Jump(cond="?", to=asp[a]) n += 1
def vector(self, a, n): self.m.set_label(a, n + "_RSV") data.Const(self.m, a, a + 2, func=self.as_mem.bu16, size=2, fmt="0x%04x") a += 2 self.m.set_label(a, n + "_PSW") data.Const(self.m, a, a + 2, func=self.as_mem.bu16, size=2, fmt="0x%04x") a += 2 y = self.codeptr(a) self.m.set_label(y.dst, n + "_VEC") return y.dst
def tt3_2(a): if a in tt: return tt[a] = True tt_output2(pj, a) return softlbl(a, "tt3_2_%04x" % a) while True: if pj.m.rd(a + 2) > 2: break data.Const(pj, a, a + 2, fmt="0x%02x") fp(pj, a + 2, a + 6) a += 6 data.Const(pj, a, a + 2, fmt="0x%02x")
def tt3_2(a): if a in tt: return tt[a] = True tt_output2(cx, a) return softlbl(a, "tt3_2_%04x" % a) while True: if cx.m[a + 2] > 2: break data.Const(cx.m, a, a+2, fmt="0x%02x") fp(cx, a + 2, a + 6) a += 6 data.Const(cx.m, a, a+2, fmt="0x%02x")
def __init__(self, cx, lo, lbl=None): self.cx = cx self.lo = lo self.lbl = lbl if self.lbl: self.cx.m.set_label(self.lo, self.lbl) else: self.cx.m.set_label(self.lo, "BITSPEC_%04x" % self.lo) adr = self.lo while self.cx.m[adr] != 0xff: item = data.Data(self.cx.m, adr, adr + 9) tbl = [] for _j in range(8): j = self.cx.m[adr] adr += 1 if j != 0x1f: tbl.append("+0x%02x.%d" % (j & 0x1f, 7 - (j >> 5))) else: tbl.append("NOP ") tbl.append("0x%02x" % self.cx.m[adr]) adr += 1 item.rendered = ".BITPOS\t" + ", ".join(tbl) item.compact = True data.Const(self.cx.m, adr, adr + 1)
def tt5(a, f, l=None, ex=0): if l == None: l = [] pj.set_label(a, "tt5_%04x" % a) while True: ll = list(l) if pj.m.rd(a) == 0: data.Const(pj, a, a + 1) break t = pj.m.rd(a) if t in token: ll.append(token[t]) else: ll.append("T%02x" % t) e = pj.m.rd(a + 1) if e != 0: ex = f + e * 2 z = pj.m.bu16(ex) # print("%04x" % a, "%04x" % z, "A %02x" % e, ll) pj.set_label(z, "cmd_" + "_".join(ll)) tt_5(pj, a) x = pj.m.bu16(a + 2) if x != 0: tt5(x, f, ll, ex) else: # print("%04x" % a, ll, "%04x" % ex) y = pj.t.find_lo(ex) y[0].lcmt += " ".join(ll) + "\n" # print(y) a += 4
def assy_sw(self): ''' Decode switch table ''' dreg = self['dreg1'] if dreg != self['dreg2']: raise assy.Invalid() if dreg != self['dreg3']: raise assy.Invalid() ptr = self.hi fin = self.lang.m.bu16(self.hi) + self.hi n = 0 while ptr < fin: i = self.lang.m.bs16(ptr) d = self.hi + i if i > 0: fin = min(fin, d) self += code.Jump(cond="0x%x" % n, to=d) data.Const(self.lang.m, ptr, ptr + 2, size=2, func=self.lang.m.bu16) self.lang.m.set_line_comment(ptr, "[0x%x] -> 0x%x" % (n, d)) self.lang.m.set_label(d, "switch@0x%x[0x%x]" % (self.lo, n)) ptr += 2 n += 1 return "D%d.W" % dreg
def tt5(a, f, l = None, ex = 0): if l == None: l = [] cx.m.set_label(a, "tt5_%04x" % a) while True: ll = list(l) if cx.m[a] == 0: if not cx.m.occupied(a): data.Const(cx.m, a, a + 1) break t = cx.m[a] if t in token: ll.append(token[t]) else: ll.append("T%02x" % t) e = cx.m[a + 1] if e != 0: ex = f + e * 2 z = cx.m.bu16(ex) # print("%04x" % a, "%04x" % z, "A %02x" % e, ll) cx.m.set_label(z, "cmd_" + "_".join(ll)) if a not in tt5s: tt5s[a] = tt_5(cx.m, a) x = cx.m.bu16(a + 2) if x != 0: tt5(x, f, ll, ex) else: #print("%04x" % a, ll, "%04x" % ex) for y in cx.m.find(ex): y.lcmt += " ".join(ll) + "\n" #print(y) a += 4
def round_0(cx): ''' Things to do before the disassembler is let loose ''' for a in ( 0x201ec, 0x20212, 0x20226, ): data.Txt(cx.m, a, a + 1); cx.m.set_label(0x20298, "board_id_list") data.Const(cx.m, 0x20298, 0x2029e) for a in ( 0x201b2, 0x201ba, 0x201c2, 0x201ca, 0x201d2, ): data.Txt(cx.m, a, a + 8) for a, b in ( (0x20924, "Load_RegFile_Only()"), (0x20b7a, "Load_RegFile_Dispatch()"), (0x2102a, "Load_Control_Store()"), ): cx.m.set_label(a, b) cx.m.set_block_comment(a, b) cx.m.set_block_comment(0x2115a, "idx=0, adr=6, TYP") cx.m.set_block_comment(0x211a6, "idx=1, adr=7, VAL") cx.m.set_block_comment(0x211f4, "idx=2, adr=3, FIU") cx.m.set_block_comment(0x21242, "idx=4, adr=4, IOC") cx.m.set_block_comment(0x21300, "idx=3, adr=2, SEQ")
def task(pj, cx): pj.todo(0x0000, cx.disass) # 0x70e5 pj.todo(0x0027, cx.disass) pj.todo(0x0066, cx.disass) x = data.Const(pj, 0x0068, 0x0800) x.typ = ".BYTE" x.fmt = "{Payload moved to 0x7000}" pj.todo(0x70d0, cx.disass) pj.todo(0x7322, cx.disass) pj.todo(0x7615, cx.disass) # Interrupt vector table for a in range(16): cx.codeptr(pj, 0x7300 + a * 2) data.Txt(pj, 0x707d, 0x707d + 0x14, label=False) data.Txt(pj, 0x70b0, 0x70b0 + 0xf, label=False) data.Txt(pj, 0x7092, 0x7092 + 0x1d, label=False) data.Txt(pj, 0x73f0, 0x73f0 + 0x12, label=False) data.Txt(pj, 0x7071, 0x7071 + 0x6, label=False) data.Txt(pj, 0x7077, 0x7077 + 0x6, label=False) discover.Discover(pj, cx) pj.set_label(0x7068, "memcpy(BC, DE, L)")
def mopup(pj, cpu): if len(pj.cc_locs) > 0: l = list(pj.cc_locs) l.sort() a = l[0] b = l[0] + 1 for i in l[1:]: if i == b: b += 1 continue y = data.Const(pj, a, b) y.typ = ".COMP" a = i; b = i + 1 y = data.Const(pj, a, b) y.typ = ".COMP"
def drive_desc(a): z = data.Const(cx.m, a, a + 0x14) cx.dataptr(a + 0x14) z = data.Const(cx.m, a + 0x18) cx.m.set_line_comment(z.lo, "Drive number") z = data.Const(cx.m, a + 0x2b, a + 0x2b + 4) cx.m.set_line_comment(z.lo, ".lba") z = data.Const(cx.m, a + 0x19, a + 0x1f) z = data.Const(cx.m, a + 0x20, a + 0x2b) z = data.Const(cx.m, a + 0x2f) z = data.Const(cx.m, a + 0x30, a + 0x3f) z = data.Const(cx.m, a + 0x40, a + 0x4f) z = data.Const(cx.m, a + 0x50, a + 0x5c)
def tx(a, pfx): t0 = a while pj.m[a] != 0: y = lex(pj, a, pfx) a = y.hi if y.f == 0: b = pj.m.bu16(y.lo + 2) p = pfx + "%c" % pj.m[y.lo] pj.m.set_label(b, "LEX_" + p) tx(b, p) data.Const(pj, a, a + 1)
def t1(a): while True: data.Const(pj, a, a + 1) if pj.m.rd(a) == 0: return; a += 1 y = data.Txt(pj, a) a = y.hi cpu.codeptr(pj, a) z = pj.m.bu16(a) pj.set_label(z, "func_" + y.txt) a += 2
def flow_check(self, asp, ins): if hasattr(ins, "fixed_10568"): return ins.flow_out = [] ins.flow_R() ptr = ins.hi exp_name_len = asp[ins.hi + 2] data.Const(asp, ptr, ptr + 3) ptr += 3 y = data.Txt(asp, ptr, ptr + exp_name_len, label=False) ptr += exp_name_len narg = asp[ptr + 2] + asp[ptr + 3] z = data.Const(asp, ptr, ptr + 4 + narg) ptr = z.hi lbl = "exp_" + y.txt + "(" asp.set_label(ins.lo, lbl + ")") # ins.compact = True if ptr & 1 and not asp[ptr]: z = data.Const(asp, ptr, ptr + 1) z.typ = ".PAD" ins.fixed_10568 = True
def arg_o(self, pj, sd): to = self['t' + sd] o = self[sd] nm = 'G' + sd if to == 0: return "R%d" % o if to == 1: return "*R%d" % o if to == 2: v = pj.m.bu16(self.hi) self.hi += 2 self[nm] = v if o != 0: return "R%d+#0x%04x" % (o, v) x = pj.find(v) if len(x) > 0: return assy.Arg_ref(pj, x[0]) try: w = pj.m.bu16(v) except: return assy.Arg_dst(pj, v, "@") # print("XXX", "%04x" % v, "%04x" % w, self.mne) if self.mne[-1] == "b": c = data.Const(pj, v, v + 1) c.typ = ".BYTE" c.fmt = "0x%02x" % pj.m.rd(v) else: c = data.Const(pj, v, v + 2) c.typ = ".WORD" c.fmt = "0x%04x" % w return assy.Arg_ref(pj, c) if to == 3: return "*R%d+" % o
def round_0(cx): ''' Things to do before the disassembler is let loose ''' ioc_hardware.add_symbols(cx.m) ioc_eeprom_exports.add_symbols(cx.m) cx.it.load_string(KERNEL_DESC, KernelIns) cx.dfs_syscalls = dfs_syscalls.DfsSysCalls() ioc_eeprom_exports.add_flow_check(cx) cx.dataptr(0x408) y = data.Const(cx.m, 0x410, 0x416, "%d", cx.m.bu16, 2) cx.m.set_line_comment(y.lo, "Version number") cx.dataptr(0x416)
def arg_o(self, sd): to = self['t' + sd] o = self[sd] nm = 'G' + sd if to == 0: return "R%d" % o if to == 1: return "*R%d" % o if to == 2: v = self.lang.m.bu16(self.hi) self.hi += 2 self[nm] = v if o != 0: return "R%d+#0x%04x" % (o, v) x = list(self.lang.m.find(v)) if x: return assy.Arg_ref(self.lang.m, x[0]) try: w = self.lang.m.bu16(v) except: return assy.Arg_dst(self.lang.m, v, "@") if self.mne[-1] == "b": c = data.Const(self.lang.m, v, v + 1) c.typ = ".BYTE" c.fmt = "0x%02x" % self.lang.m[v] else: c = data.Const(self.lang.m, v, v + 2) c.typ = ".WORD" c.fmt = "0x%04x" % w return assy.Arg_ref(self.lang.m, c) if to == 3: return "*R%d+" % o
def round_1(cx): ''' Let the disassembler loose ''' for key, desc in ioc_eeprom_exports.RESHA_PROGRAMS.items(): a = BASE + SEGMENT * (key & 0xff) ptr = a + (key >> 7) data.Const(cx.m, ptr, ptr + 2, func=cx.m.bu16, size=2) prog = a + cx.m.bu16(ptr) cx.disass(prog) cx.m.set_label(prog, "RESHA_PROGRAM_%04x" % key) t = "RESHA PROGRAM 0x%04x @0x%08x - " % (key, prog) + desc cx.m.set_block_comment(prog, t) cx.m.set_line_comment(ptr, t) for a in range(0x734ea, 0x73542, 4): b = cx.m.bu32(a) if 0x72000 <= b <= 0x74000: cx.codeptr(a) for a, b in ( (0x76040, 0x76084), (0x767f2, 0x767fe), ): for i in range(a, b, 4): cx.codeptr(i) for a, b in ( (0x730a8, None), (0x73258, None), (0x733a2, None), (0x73396, None), (0x74266, "SCSI_D_TEST_UNIT_READY"), (0x743dc, "SCSI_D_SOFT_RESET()"), (0x7459a, "SCSI_D_AWAIT_INTERRUPT()"), (0x77386, "SCSI_T_AWAIT_INTERRUPT()"), (0x77662, None), ): cx.disass(a) if b: cx.m.set_label(a, b) for a, b in ( (0x000743e6, "SCSI_ID=7, EnableAdvancedFeatures"), (0x000743ee, "CMD=Soft Reset"), (0x71206, "????"), (0x71212, "B#13 = GOOD_PARITY"), (0x714da, "B#13 = GOOD_PARITY"), ): cx.m.set_line_comment(a, b)
def t1(a, l): pj.set_label(a, l) while True: data.Const(pj, a, a + 1) if pj.m.rd(a) == 0: return a += 1 y = data.Txt(pj, a, align=1, label=False) a = y.hi cpu.codeptr(pj, a) z = pj.m.bu16(a) if False: # XXX: doesn't work for ERROR print("XXX %04x" % (z - 3), y.txt) pj.todo(z - 3, cpu.disass) pj.set_label(z, "func_" + y.txt) a += 2
def t1(a, l): cx.m.set_label(a, l) while True: data.Const(cx.m, a, a + 1) if cx.m[a] == 0: return; a += 1 y = data.Txt(cx.m, a, align=1, label=False) a = y.hi cx.codeptr(a) z = cx.m.bu16(a) if False: # XXX: doesn't work for ERROR print("XXX %04x" % (z-3), y.txt) cx.disass(z - 3) cx.m.set_label(z, "func_" + y.txt) a += 2
def assy_a_rn(self): ''' Addressing mode Rn/U/P/W ''' imm32 = self['imm12'] rn = REG[self['rn']] if self['u']: imm = "#0x%x" % imm32 else: imm = "#-0x%x" % imm32 p = self.lim[-1].flds.get('p') w = self.lim[-1].flds.get('w') if not p: if not w: #return [assy.Arg_verbatim("[%s]" % rn), assy.Arg_dst(self.lang.m, imm)] return "[%s]," % rn + imm raise assy.Invalid("a_rn mode wrong (!p,w)") if w: return "[%s," % rn + imm + "]!" if self['rn'] != 15 or OBJDUMP_COMPAT: if imm32: return "[%s," % rn + imm + "]" return "[%s]" % rn if self['u']: t = self.hi + 4 + imm32 else: t = self.hi + 4 - imm32 try: v = self.lang.m.lu32(t) if not self.lang.m.occupied(t): data.Const(self.lang.m, t, t + 4, func=self.lang.m.lu32, size=4) self.lcmt += "[%s,%s] = [#0x%x]\n" % (rn, imm, t) return assy.Arg_dst(self.lang.m, v, pfx="#") return "#0x%x" % v except: self.lcmt += "[%s,%s]\n" % (rn, imm) return "[#0x%x]" % t
def rom_checksum(asp): sl = -1 sh = -1 for a in range(0x20, 0x4000): sh += asp[a] >> 8 sl += asp[a] & 0xff if (a & 0x7ff) == 0x7ff: sh &= 0xffff sl &= 0xffff d = 0x8000 + (a + 1) d = d >> 10 d += 6 y = data.Const(asp, d, d + 2) y.lcmt += "ROM Checksum" assert sh == asp[d] assert sl == asp[d + 1] sl = -1 sh = -1 print("ROM Checksum good")
def assy_a_imm4(self): imm32 = (self['imm4h'] << 4) | self['imm4l'] if self['u']: imm = "#0x%x" % imm32 else: imm = "#-0x%x" % imm32 p = self.lim[-1].flds.get('p') w = self.lim[-1].flds.get('w') rn = REG[self['rn']] if not p: if not w: return "[%s]," % rn + imm raise assy.Invalid("a_imm4 mode wrong (!p,w)") if w: return "[%s," % rn + imm + "]!" if True or self['rn'] != 15 or OBJDUMP_COMPAT: if imm32: return "[%s," % rn + imm + "]" return "[%s]" % rn if self['u']: t = self.hi + 4 + imm32 else: t = self.hi + 4 - imm32 try: v = self.lang.m.lu32(t) if not self.lang.m.occupied(t): data.Const(self.lang.m, t, t + 4, func=self.lang.m.lu32, size=4) self.lcmt += "[%s,%s] = [#0x%x]\n" % (rn, imm, t) return "#0x%x" % v except: self.lcmt += "[%s,%s]\n" % (rn, imm) return "[#0x%x]" % t
def round_0(cx): ''' Things to do before the disassembler is let loose ''' ioc_eeprom_exports.add_flow_check(cx) for a in range(BASE, BASE + SIZE, SEGMENT): cx.m.set_block_comment(a, "PROGRAM VECTORS") data.Const(cx.m, a, a + 2) for a, b in ((0x76084, 0x760c8), ): for i in range(a, b, 4): y = cx.dataptr(i) data.Txt(cx.m, y.dst) for a, b in ( (0x7063e, 0x70708), (0x71025, 0x7105f), (0x712a6, 0x7130c), (0x719f2, 0x71a99), (0x74006, 0x7412e), (0x76248, 0x763b1), ): i = a while i < b: y = data.Txt(cx.m, i, splitnl=True) i = y.hi for a in range(0x765e4, 0x76650, 6): y = cx.dataptr(a + 2) data.Txt(cx.m, y.dst) for a in ( 0x7200a, 0x769ce, 0x769ec, 0x76a0a, 0x76a28, ): data.Txt(cx.m, a, splitnl=True)