Exemplo n.º 1
0
 def assy_skip(self):
     s = self['skip']
     d = self['d']
     if d:
         s = 0x20 - s
         self.dstadr = self.lo - s
     else:
         self.dstadr = self.lo + s
     self += code.Jump(cond="?s", to=self.hi)
     self += code.Jump(cond="?!s", to=self.dstadr)
     return assy.Arg_dst(self.lang.m, self.dstadr)
Exemplo n.º 2
0
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))
Exemplo n.º 3
0
def post_arg_func(asp, ins):
    post_arg_funcs = {
        0xb80c: "WB",
        0xb821: "WB",
        0xb836: "W",
        0xb846: "WWW",
        0xb86c: "WWW",
        0xb892: "WWW",
        0xb989: "WWW",
        0xbabc: "WW",
        0xbb60: "WWW",
        0xbca1: "WWW",
        0xbdeb: "WW",
    }
    for f in ins.flow_out:
        i = post_arg_funcs.get(f.to)
        if i is None:
            continue
        ins.flow_out = []
        ins += code.Call(to=f.to)
        a = ins.hi
        for j in i:
            if j == "W":
                d = asp.bu16(a)
                data.Dataptr(asp, a, a + 2, d)
                a += 2
                if d >= 0x8000:
                    d_q(asp, d)
            elif j == "B":
                cbyte(asp, a)
                # data.Data(asp, a, a + 1)
                a += 1
            else:
                assert False
        ins += code.Jump(to=a)
Exemplo n.º 4
0
 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 flow_check(asp, ins):
    ''' Flow-check to capture inline strings '''
    if ins.lo in (
        0x8000001c,
        0x80002010,
        0x80002028,
    ):
        return
    for f in ins.flow_out:
        if f.to in (
            0x80002010,
            0x80002028,
            0x80002aa8
        ):
            y = data.Txt(asp, ins.hi, label=False, align=2, splitnl=True)
            ins.dstadr = y.hi
            ins.flow_out.pop(-1)
            ins += code.Jump(cond=True, to=ins.dstadr)
        elif f.to in (
            0x80000018,
        ):
            if asp.bu16(ins.lo - 6) == 0x41f9:
                a = asp.bu32(ins.lo - 4)
                y = data.Txt(asp, a, splitnl=True)
        elif f.to in (
            0x80002034,
        ):
            if asp.bu16(ins.lo - 6) == 0x47f9:
                a = asp.bu32(ins.lo - 4)
                y = data.Txt(asp, a, splitnl=True)
        elif f.to in (
            0x8000001c,
            0x800000e2
        ):
            y = data.Txt(asp, ins.hi, label=False, align=2, splitnl=True)
            ins.dstadr = y.hi
            ins.flow_out.pop(-1)
            ins += code.Jump(cond=True, to=ins.dstadr)
        elif f.to in (
            0x80002068,
        ):
            if asp.bu16(ins.lo - 4) == 0x303c:
                a = asp.bu16(ins.lo - 2)
                t = RESHA_PROGRAMS.get(a)
                if t:
                    asp.set_line_comment(ins.lo - 4, t)
Exemplo n.º 6
0
def flow_post_arg(asp, ins):
    z = post_arg.get(ins.dstadr)
    if z is None:
        return
    ins.flow_out.pop(-1)
    if len(z) <= 1:
        a = data.Pstruct(asp, ins.hi, ">h", "%d", ".INFIX").hi
        ins += code.Jump(to=a)
        return
    l = []
    for i in z[1:]:
        if i[1:] == "A6rel":
            r = asp.bs16(ins.hi)
            ins.hi += 2
            if r < 0:
                l.append("(A6-0x%x)" % -r)
            else:
                l.append("(A6+0x%x)" % r)
        elif i[1:] == "abs":
            r = asp.bu16(ins.hi)
            if r & 0x8000:
                r |= 0xffff0000
            ins.hi += 2
            l.append("0x%08x" % r)
        elif i == "drel":
            r = ins.hi + asp.bs16(ins.hi)
            ins.hi += 2
            ins.lcmt += " @0x%x\n" % r
            y = data_double(asp, r)
            l.append("%g" % y.data[0])
        elif i == "brel":
            r = ins.hi + asp.bs16(ins.hi)
            ins.hi += 2
            ins.lcmt += " @0x%x\n" % r
            y = data_bcd(asp, r)
            l.append("%x" % y.data[0])
        elif i == "lrel":
            r = ins.hi + asp.bs16(ins.hi)
            ins.hi += 2
            ins.lcmt += " @0x%x\n" % r
            if not asp.occupied(r):
                data.Pstruct(asp, r, ">L", "%d", ".LONG")
            l.append("%d" % asp.bu32(r))
        elif i == "frel":
            r = ins.hi + asp.bs16(ins.hi)
            ins.hi += 2
            ins.lcmt += " @0x%x\n" % r
            y = data_float(asp, r)
            l.append("%g" % y.val)
        elif i == "bcd":
            r = asp.bu16(ins.hi)
            # y = data.Pstruct(asp, ins.hi, ">H", "%x", ".BCD")
            l.append("%04x" % r)
            ins.hi += 2
        else:
            l.append(i)
    ins.oper.append(assy.Arg_verbatim("(" + ",".join(l) + ")"))
    ins += code.Flow()
 def switch(self, adr, end):
     setup = self.cx.disass(adr)
     dispatch = self.cx.disass(setup.hi)
     dispatch.flow_out = []
     tbl = setup.dstadr
     for off in range(0, end - tbl, 2):
         dispatch += code.Jump(cond="A=0x%02x" % off, to=tbl + off)
         item = self.cx.disass(tbl + off)
         yield off, item, tbl
Exemplo n.º 8
0
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
Exemplo n.º 9
0
	def attempt(self):
		l,w = recognize(self.pj, self.top, recog0)
		if type(w) != int:
			return False
		self.tbl = l[0].dstadr
		self.top = l[0].lo

		l,w = recognize(self.pj, self.top, recog1)
		if type(w) != int:
			s = []
			j = self.top
			for i in range(10):
				x = self.pj.t.find_hi(j)
				if len(x) != 1:
					break
				s.insert(0, x[0].mne)
				j = x[0].lo
			s = ",".join(s)
			return False
		if w == 2:
			lo = self.pj.m[l[0].lo + 1]
			hi = self.pj.m.[l[2].lo + 1]
			d = l[-1].dstadr
		elif w == 3:
			lo = self.pj.m.bu16(l[0].lo + 1)
			hi = self.pj.m.bu16(l[2].lo + 1)
			d = l[-2].dstadr
		elif w == 4:
			lo = self.pj.m.bu16(l[3].lo + 1)
			hi = self.pj.m.bu16(l[0].lo + 1)
			d = l[-1].dstadr
		else:
			print("S1?? %04x" % self.top, w)
			return False
		l[-1].lcmt += "SWITCH type=%d lo=%d hi=%d\n" % (w, lo, hi)
		# print("S1 %04x" % self.top, w, lo, hi, "D", d)
		self.pj.m.set_label(d, "default")
		a = self.i.hi
		for i in range(lo, hi + 1):
			self.pj.cc_locs.add(a)
			self.pj.cc_locs.add(a + 1)
			u = self.pj.m.bu16(a)
			if u != d:
				self.pj.m.set_label(u, "case_%d" % i)
			self.i += code.Jump(cond="%d" % i, to=u, lang=self.i.lang)
			self.i.lang.disass(self.pj, u)
			a += 2
		return True
Exemplo n.º 10
0
def inline_args(asp, ins):
    for f in ins.flow_out:
        i = i_args.get(f.to)
        if i is None:
            continue
        ins.flow_out = []
        ins += code.Call(to=f.to)
        a = ins.hi
        for j in i:
            if j == "i":
                d = asp.bu16(a)
                data.Dataptr(asp, a, a + 2, d)
                a += 2
            else:
                print("IARG:", j)
                assert False
        ins += code.Jump(to=a)
Exemplo n.º 11
0
 def jmp_table(lo, hi, span, txt="table", src=None):
     x = cx.m.add_range(lo, hi, txt="table")
     if src is None:
         ins = None
     else:
         ins = list(cx.m.find(src))
         print("JMPTABLE %x" % src, ins)
         if len(ins) != 1:
             ins = None
         else:
             ins = ins[0]
             assert len(ins.flow_out) == 1
             ins.flow_out = list()
     for a in range(lo, hi, span):
         if ins is not None:
             ins += code.Jump(to=a)
         cx.disass(a)
Exemplo n.º 12
0
    def assy_SW(self):

        assert self.lim[-1].assy[0] == "SWITCH"

        # All dr%d must match
        rset = set()
        for i in self.lim:
            for j in i.flds:
                if j[:2] == "dr":
                    rset.add(i[j])
                    if len(rset) > 1:
                        raise assy.Invalid("SWITCH dr# mismatch")
        self.mne = "SWITCH(D%d.%s)" % (rset.pop(), self.sz)

        if len(self.lim) < 3:
            raise assy.Invalid("SWITCH with insufficient limits")

        if self.lim[-2].assy[0] != "+DBL":
            raise assy.Invalid("SWITCH without +DBL")

        self.sz = set()
        for im in self.lim:

            def getfld(x):
                fl = im.get(x + 'l')
                if fl is not None:
                    fh = im.get(x + 'h')
                    if fh is not None:
                        fl |= fh << 16
                        if fl & 0x80000000:
                            fl -= 0x100000000
                    elif fl & 0x8000:
                        fl -= 0x10000
                return fl

            def getjmp():
                j = im.get('j')
                if j is not None:
                    if j & 0x80:
                        j -= 0x100
                    return im.adr + j + int(im.assy[2])
                j = im.get('jj')
                if j is not None:
                    if j & 0x8000:
                        j -= 0x10000
                    return im.adr + j + int(im.assy[2])

            self.sz.add(im.assy[1])
            if im.assy[0] == "+LOW":
                x = getfld('l')
                if x is not None:
                    self.low = x
                x = getfld('s')
                if x is not None:
                    self.sub = x
                x = getfld('a')
                if x is not None:
                    self.add = x
                if im.assy[1] == 'L':
                    m = (1 << 32) - 1
                else:
                    m = (1 << 16) - 1
                assert self.sub == (self.low + self.add) & m

                self.go_lo = getjmp()

            elif im.assy[0] == "+HIGH":
                x = getfld('h')
                if x is not None:
                    self.high = x
                self.go_hi = getjmp()

        if self.low is None and self.high is not None:
            self.low = 0

        if self.low is None or self.high is None:
            print("XXX %x" % self.lo, self)
            for i in self.lim:
                print("--- %s" % str(i))
            print("LOW", self.low, "HIGH", self.high)
            raise assy.Invalid()

        self.nm = "SWITCH_%x" % self.lo
        self.lang.m.set_label(self.lo, self.nm)

        self.wordtable()
        self.range()
        self += code.Jump()
Exemplo n.º 13
0
 def assy_skp(self):
     self += code.Jump(cond="?", to=self.hi)
     self += code.Jump(cond="?", to=self.hi + 1)
Exemplo n.º 14
0
def example():
    m0 = mem.Stackup(FILENAMES, nextto=__file__)

    cx = hp_nanoproc.hp_nanoproc_pg()

    # Slightly confusing mapping of memory for this one.  Probably an
    # artifact of a change from smaller to bigger ROMS along the way.
    cx.m.map(m0, 0x0000, 0x1000)
    cx.m.map(m0, 0x2000, 0x3000, 0x1000)
    cx.m.map(m0, 0x1000, 0x2000, 0x2000)
    cx.m.map(m0, 0x3000, 0x4000, 0x3000)

    cx.disass(0)
    cx.disass(0xff)

    cuts = []

    #######################################################################
    if True:
        for a0 in range(4, 0x20, 4):
            cx.disass(a0)
        ix0 = list(cx.m.find(0x54))
        assert len(ix0) == 1
        ix0 = ix0[0]
        ix0.flow_out = list()
        for a0 in range(4, 0x20, 4):
            ix0 += code.Jump(to=a0)
            i = list(cx.m.find(a0))
            assert len(i) == 1
            i = i[0]
            assert len(i.flow_out) == 1
            dpf = i.flow_out[0].to
            cuts.append((None, dpf))
            ix1 = list(cx.m.find(dpf + 6))
            assert len(ix1) == 1
            ix1 = ix1[0]
            ix1.flow_out = list()
            pg = dpf & ~0x7ff
            print("DISP_%d %x" % (a0 >> 2, dpf))
            cx.m.set_label(dpf, "DISP_%d" % (a0 >> 2))
            for a1 in range(pg, dpf, 2):
                ix1 += code.Jump(to=a1)
                cx.disass(a1)
                v = a0 << 3
                v |= (a1 - pg) >> 1
                cx.m.set_label(a1, "PTR_%02x" % v)

    #######################################################################
    def jmp_table(lo, hi, span, txt="table", src=None):
        x = cx.m.add_range(lo, hi, txt="table")
        if src is None:
            ins = None
        else:
            ins = list(cx.m.find(src))
            print("JMPTABLE %x" % src, ins)
            if len(ins) != 1:
                ins = None
            else:
                ins = ins[0]
                assert len(ins.flow_out) == 1
                ins.flow_out = list()
        for a in range(lo, hi, span):
            if ins is not None:
                ins += code.Jump(to=a)
            cx.disass(a)

    if True:
        jmp_table(0x07d0, 0x0800, 8, "table", 0x007f)
        jmp_table(0x0f80, 0x0fa8, 4, "LED segment table", 0xd0e)
        jmp_table(0x0fa8, 0x0fc0, 2, "table", 0x0aae)
        jmp_table(0x0fc0, 0x0fe0, 4, "table", 0x0b2e)
        jmp_table(0x0fe0, 0x1000, 4, "table", 0x0b49)
        jmp_table(0x1840, 0x1870, 8, "table", 0x1b2e)
        jmp_table(0x1fd0, 0x2000, 8, "table", 0x1d01)
        jmp_table(0x2fb8, 0x3000, 8, "table", 0x2f86)
        jmp_table(0x3fd8, 0x4000, 4, "table", 0x3d17)

    return NAME, (cx.m, )