diff options
Diffstat (limited to 'devtools/tasmrecover')
22 files changed, 194 insertions, 138 deletions
diff --git a/devtools/tasmrecover/dreamweb/backdrop.asm b/devtools/tasmrecover/dreamweb/backdrop.asm index c02d95bbe9..5dfe20bf5d 100644 --- a/devtools/tasmrecover/dreamweb/backdrop.asm +++ b/devtools/tasmrecover/dreamweb/backdrop.asm @@ -874,4 +874,3 @@ over147: mov ch,0 -
\ No newline at end of file diff --git a/devtools/tasmrecover/dreamweb/debug.asm b/devtools/tasmrecover/dreamweb/debug.asm index 991e240fd1..951da4fa3f 100644 --- a/devtools/tasmrecover/dreamweb/debug.asm +++ b/devtools/tasmrecover/dreamweb/debug.asm @@ -379,4 +379,3 @@ debugtextr: db "00000",0 endif -
\ No newline at end of file diff --git a/devtools/tasmrecover/dreamweb/dreamweb.asm b/devtools/tasmrecover/dreamweb/dreamweb.asm index ea61338ae3..d357c5cd73 100644 --- a/devtools/tasmrecover/dreamweb/dreamweb.asm +++ b/devtools/tasmrecover/dreamweb/dreamweb.asm @@ -135,13 +135,24 @@ Dreamweb proc near dodecisions: call cls call setmode call decide + + cmp quitrequested, 0 + jnz exitgame + cmp getback,4 jz mainloop call titles + + cmp quitrequested, 0 + jnz exitgame + call credits -playgame: call clearchanges +playgame: + cmp quitrequested, 0 + jnz exitgame + call clearchanges call setmode call loadpalfromiff mov location,255 @@ -194,7 +205,11 @@ alreadyloaded: mov newlocation,255 call startup mov commandtype,255 -mainloop: call screenupdate +mainloop: + cmp quitrequested, 0 + jnz exitgame + + call screenupdate cmp wongame,0 jnz endofgame cmp mandead,1 @@ -235,7 +250,9 @@ endofgame: call clearbeforeload call hangon call endgame jmp quickquit2 - + +exitgame: + ret endp @@ -6219,6 +6236,8 @@ savefiles db "DREAMWEB.D00",0 Recname db "DREAMWEB.DEM",0 +Quitrequested db 0 + ;-------------------------------------------------------End of code segment---- @@ -6257,6 +6276,3 @@ STACKSPACE ends - - -
\ No newline at end of file diff --git a/devtools/tasmrecover/dreamweb/keypad.asm b/devtools/tasmrecover/dreamweb/keypad.asm index d75a4fde82..8ac38524aa 100644 --- a/devtools/tasmrecover/dreamweb/keypad.asm +++ b/devtools/tasmrecover/dreamweb/keypad.asm @@ -1755,4 +1755,3 @@ Findtext1 proc near endp -
\ No newline at end of file diff --git a/devtools/tasmrecover/dreamweb/look.asm b/devtools/tasmrecover/dreamweb/look.asm index b5bc913a73..399e1f16fd 100644 --- a/devtools/tasmrecover/dreamweb/look.asm +++ b/devtools/tasmrecover/dreamweb/look.asm @@ -164,4 +164,3 @@ dogetback: mov getback,1 -
\ No newline at end of file diff --git a/devtools/tasmrecover/dreamweb/monitor.asm b/devtools/tasmrecover/dreamweb/monitor.asm index 7cc1a5a4dd..247ba10f2b 100644 --- a/devtools/tasmrecover/dreamweb/monitor.asm +++ b/devtools/tasmrecover/dreamweb/monitor.asm @@ -1493,4 +1493,3 @@ finishcurdel: -
\ No newline at end of file diff --git a/devtools/tasmrecover/dreamweb/newplace.asm b/devtools/tasmrecover/dreamweb/newplace.asm index cac6e100a7..ac703f6b11 100644 --- a/devtools/tasmrecover/dreamweb/newplace.asm +++ b/devtools/tasmrecover/dreamweb/newplace.asm @@ -53,7 +53,10 @@ Selectlocation proc near call playchannel0 mov newlocation,255 -select: call delpointer +select: + cmp quitrequested, 0 + jnz quittravel + call delpointer call readmouse call showpointer call vsync @@ -578,4 +581,3 @@ Readcitypic proc near -
\ No newline at end of file diff --git a/devtools/tasmrecover/dreamweb/object.asm b/devtools/tasmrecover/dreamweb/object.asm index 93710d3c23..bdd043d588 100644 --- a/devtools/tasmrecover/dreamweb/object.asm +++ b/devtools/tasmrecover/dreamweb/object.asm @@ -2583,8 +2583,10 @@ findlenextext: mov cl,[es:si] sub bx,extext push bx ax sub cx,bx + cmp cx, 0xffff; BIG FIXME! Find out why this is happening + jz $1 rep movsb - pop bx +$1: pop bx sub extextpos,bx pop si @@ -2605,4 +2607,3 @@ beforethistext: mov [es:di],ax -
\ No newline at end of file diff --git a/devtools/tasmrecover/dreamweb/print.asm b/devtools/tasmrecover/dreamweb/print.asm index e1c2d451c9..a2052285f0 100644 --- a/devtools/tasmrecover/dreamweb/print.asm +++ b/devtools/tasmrecover/dreamweb/print.asm @@ -588,4 +588,3 @@ nomod: ret endp endif -
\ No newline at end of file diff --git a/devtools/tasmrecover/dreamweb/saveload.asm b/devtools/tasmrecover/dreamweb/saveload.asm index f10d87149d..369e799d53 100644 --- a/devtools/tasmrecover/dreamweb/saveload.asm +++ b/devtools/tasmrecover/dreamweb/saveload.asm @@ -109,7 +109,11 @@ restartops: call showopbox call showmainops call worktoscreenm donefirstops: mov getback,0 -waitops: call readmouse +waitops: + cmp quitrequested, 0 + jnz justret + + call readmouse call showpointer call vsync call dumppointer @@ -260,7 +264,11 @@ doload: mov loadingorsave,1 call namestoold mov getback,0 -loadops: call delpointer +loadops: + cmp quitrequested, 0 + jnz quitloaded + + call delpointer call readmouse call showpointer call vsync @@ -354,7 +362,11 @@ dodiscops: call scanfornames call worktoscreenm mov getback,0 -discopsloop: call delpointer +discopsloop: + cmp quitrequested, 0 + jnz quitdiscops + + call delpointer call readmouse call showpointer call vsync @@ -364,6 +376,7 @@ discopsloop: call delpointer call checkcoords cmp getback,0 jz discopsloop +quitdiscops: ret discopslist: dw opsx+59,opsx+114,opsy+30,opsy+76,loadgame @@ -411,7 +424,11 @@ dosave: mov loadingorsave,2 mov getback,0 -saveops: call delpointer +saveops: + cmp quitrequested, 0 + jnz quitsavegame + + call delpointer call checkinput call readmouse call showpointer @@ -423,6 +440,7 @@ saveops: call delpointer call checkcoords cmp getback,0 jz saveops +quitsavegame: ret savelist: dw opsx+176,opsx+192,opsy+60,opsy+76,getbacktoops @@ -1398,7 +1416,12 @@ Decide proc near call fadescreenup mov getback,0 -waitdecide: call readmouse +waitdecide: + cmp quitrequested, 0 + jz $1 + ret +$1: + call readmouse call showpointer call vsync call dumppointer @@ -1482,6 +1505,8 @@ alreadyloadold: mov ax,mousebutton call doload cmp getback,4 jz noloadold + cmp quitrequested, 0 + jnz noloadold call showdecisions call worktoscreenm mov getback,0 @@ -1492,4 +1517,3 @@ noloadold: ret -
\ No newline at end of file diff --git a/devtools/tasmrecover/dreamweb/sblaster.asm b/devtools/tasmrecover/dreamweb/sblaster.asm index 9eb9afc08f..46eb8e2366 100644 --- a/devtools/tasmrecover/dreamweb/sblaster.asm +++ b/devtools/tasmrecover/dreamweb/sblaster.asm @@ -1290,4 +1290,3 @@ nopitflip: cli -
\ No newline at end of file diff --git a/devtools/tasmrecover/dreamweb/sprite.asm b/devtools/tasmrecover/dreamweb/sprite.asm index bb7ba402f8..fadea3b790 100644 --- a/devtools/tasmrecover/dreamweb/sprite.asm +++ b/devtools/tasmrecover/dreamweb/sprite.asm @@ -441,7 +441,7 @@ notinbed: ret Edeninbath proc near cmp generaldead,0 - jz notinbed + jz notinbath cmp sartaindead,0 jnz notinbath call showgamereel @@ -5031,4 +5031,3 @@ finishevery2: ret -
\ No newline at end of file diff --git a/devtools/tasmrecover/dreamweb/talk.asm b/devtools/tasmrecover/dreamweb/talk.asm index d2c27f059b..6bee4409b7 100644 --- a/devtools/tasmrecover/dreamweb/talk.asm +++ b/devtools/tasmrecover/dreamweb/talk.asm @@ -577,4 +577,3 @@ doredes: call delpointer -
\ No newline at end of file diff --git a/devtools/tasmrecover/dreamweb/titles.asm b/devtools/tasmrecover/dreamweb/titles.asm index a47f31a327..8f2b46e3f4 100644 --- a/devtools/tasmrecover/dreamweb/titles.asm +++ b/devtools/tasmrecover/dreamweb/titles.asm @@ -9,7 +9,10 @@ Titles proc near else call clearpalette call biblequote + cmp quitrequested, 0 + jnz titlesearly call intro +titlesearly: ret endif @@ -580,4 +583,3 @@ realcreditsearly: -
\ No newline at end of file diff --git a/devtools/tasmrecover/dreamweb/use.asm b/devtools/tasmrecover/dreamweb/use.asm index 250aa00240..508e8bd4c1 100644 --- a/devtools/tasmrecover/dreamweb/use.asm +++ b/devtools/tasmrecover/dreamweb/use.asm @@ -3807,4 +3807,3 @@ nowinch: call showfirstuse -
\ No newline at end of file diff --git a/devtools/tasmrecover/dreamweb/vars.asm b/devtools/tasmrecover/dreamweb/vars.asm index e38470a7de..8646697e52 100644 --- a/devtools/tasmrecover/dreamweb/vars.asm +++ b/devtools/tasmrecover/dreamweb/vars.asm @@ -561,4 +561,3 @@ gameerror db 0 howmuchalloc dw 0 -
\ No newline at end of file diff --git a/devtools/tasmrecover/dreamweb/vgafades.asm b/devtools/tasmrecover/dreamweb/vgafades.asm index 26874a428f..06cc9d6a44 100644 --- a/devtools/tasmrecover/dreamweb/vgafades.asm +++ b/devtools/tasmrecover/dreamweb/vgafades.asm @@ -864,4 +864,3 @@ Initialmoncols proc near endp -
\ No newline at end of file diff --git a/devtools/tasmrecover/dreamweb/vgagrafx.asm b/devtools/tasmrecover/dreamweb/vgagrafx.asm index 1d8e5f5dc7..110fc95ee0 100644 --- a/devtools/tasmrecover/dreamweb/vgagrafx.asm +++ b/devtools/tasmrecover/dreamweb/vgagrafx.asm @@ -1760,4 +1760,3 @@ Title7graphics db "DREAMWEB.I07",0 Palettescreen db "DREAMWEB.PAL",0 -
\ No newline at end of file diff --git a/devtools/tasmrecover/tasm-recover b/devtools/tasmrecover/tasm-recover index 35e20d20ab..96fd6c45fa 100755 --- a/devtools/tasmrecover/tasm-recover +++ b/devtools/tasmrecover/tasm-recover @@ -19,6 +19,9 @@ generator = cpp(context, "DreamGen", blacklist = [ 'cls', 'printundermon', 'worktoscreen', - 'width160' + 'width160', + 'convertkey', + 'readabyte', + 'readoneblock' ]) generator.generate('dreamweb') #start routine diff --git a/devtools/tasmrecover/tasm/cpp.py b/devtools/tasmrecover/tasm/cpp.py index 3e5ae78438..0196e5b45c 100644 --- a/devtools/tasmrecover/tasm/cpp.py +++ b/devtools/tasmrecover/tasm/cpp.py @@ -36,20 +36,19 @@ class cpp: self.failed = list(blacklist) self.translated = [] self.proc_addr = [] - self.forwards = [] + self.methods = [] self.fd.write("""%s #include \"%s\" namespace %s { - """ %(banner, header, namespace)) def expand_cb(self, match): name = match.group(0).lower() if len(name) == 2 and \ ((name[0] in ['a', 'b', 'c', 'd'] and name[1] in ['h', 'x', 'l']) or name in ['si', 'di', 'es', 'ds', 'cs']): - return "context.%s" %name + return "%s" %name if self.indirection == -1: try: @@ -74,7 +73,7 @@ namespace %s { if size == 0: raise Exception("invalid var '%s' size %u" %(name, size)) if self.indirection == 0: - value = "context.data.%s(k%s)" %("byte" if size == 1 else "word", name.capitalize()) + value = "data.%s(k%s)" %("byte" if size == 1 else "word", name.capitalize()) elif self.indirection == -1: value = "%s" %g.offset self.indirection = 0 @@ -135,7 +134,7 @@ namespace %s { m = re.match(r'seg\s+(.*?)$', expr) if m is not None: - return "context.data" + return "data" match_id = True m = re.match(r'offset\s+(.*?)$', expr) @@ -174,7 +173,7 @@ namespace %s { plus = "" match_id = False #print "COMMON_REG: ", reg, plus - expr = "context.%s%s" %(reg, plus) + expr = "%s%s" %(reg, plus) expr = re.sub(r'\b([0-9][a-fA-F0-9]*)h', '0x\\1', expr) expr = re.sub(r'\b([0-1]+)b', parse_bin, expr) @@ -188,9 +187,9 @@ namespace %s { if indirection == 1: if size == 1: - expr = "context.%s.byte(%s)" %(seg_prefix, expr) + expr = "%s.byte(%s)" %(seg_prefix, expr) elif size == 2: - expr = "context.%s.word(%s)" %(seg_prefix, expr) + expr = "%s.word(%s)" %(seg_prefix, expr) else: expr = "@invalid size 0" elif indirection == 0: @@ -238,9 +237,11 @@ namespace %s { jump_proc = True if jump_proc: - self.add_forward(name) - return "{ %s(context); return; }" %name + return "{ %s(); return; }" %name else: + # TODO: name or self.resolve_label(name) or self.mangle_label(name)?? + if name in self.proc.retlabels: + return "return /* (%s) */" % (name) return "goto %s" %self.resolve_label(name) def _label(self, name): @@ -253,17 +254,12 @@ namespace %s { print "+scheduling function %s..." %name self.proc_queue.append(name) - def add_forward(self, name): - if name not in self.forwards and name not in self.failed: - self.forwards.append(name) - def _call(self, name): name = name.lower() if name == 'ax': - self.body += "\t__dispatch_call(context, %s);\n" %self.expand('ax', 2) + self.body += "\t__dispatch_call(%s);\n" %self.expand('ax', 2) return - self.body += "\t%s(context);\n" %name - self.add_forward(name); + self.body += "\t%s();\n" %name self.schedule(name) def _ret(self): @@ -286,111 +282,111 @@ namespace %s { self.body += "\t%s = %s;\n" %self.parse2(dst, src) def _add(self, dst, src): - self.body += "\tcontext._add(%s, %s);\n" %self.parse2(dst, src) + self.body += "\t_add(%s, %s);\n" %self.parse2(dst, src) def _sub(self, dst, src): - self.body += "\tcontext._sub(%s, %s);\n" %self.parse2(dst, src) + self.body += "\t_sub(%s, %s);\n" %self.parse2(dst, src) def _and(self, dst, src): - self.body += "\tcontext._and(%s, %s);\n" %self.parse2(dst, src) + self.body += "\t_and(%s, %s);\n" %self.parse2(dst, src) def _or(self, dst, src): - self.body += "\tcontext._or(%s, %s);\n" %self.parse2(dst, src) + self.body += "\t_or(%s, %s);\n" %self.parse2(dst, src) def _xor(self, dst, src): - self.body += "\tcontext._xor(%s, %s);\n" %self.parse2(dst, src) + self.body += "\t_xor(%s, %s);\n" %self.parse2(dst, src) def _neg(self, dst): dst = self.expand(dst) - self.body += "\tcontext._neg(%s);\n" %(dst) + self.body += "\t_neg(%s);\n" %(dst) def _cbw(self): - self.body += "\tcontext.ax.cbw();\n" + self.body += "\tax.cbw();\n" def _shr(self, dst, src): - self.body += "\tcontext._shr(%s, %s);\n" %self.parse2(dst, src) + self.body += "\t_shr(%s, %s);\n" %self.parse2(dst, src) def _shl(self, dst, src): - self.body += "\tcontext._shl(%s, %s);\n" %self.parse2(dst, src) + self.body += "\t_shl(%s, %s);\n" %self.parse2(dst, src) #def _sar(self, dst, src): - # self.body += "\tcontext._sar(%s%s);\n" %self.parse2(dst, src) + # self.body += "\t_sar(%s%s);\n" %self.parse2(dst, src) #def _sal(self, dst, src): - # self.body += "\tcontext._sal(%s, %s);\n" %self.parse2(dst, src) + # self.body += "\t_sal(%s, %s);\n" %self.parse2(dst, src) #def _rcl(self, dst, src): - # self.body += "\tcontext._rcl(%s, %s);\n" %self.parse2(dst, src) + # self.body += "\t_rcl(%s, %s);\n" %self.parse2(dst, src) #def _rcr(self, dst, src): - # self.body += "\tcontext._rcr(%s, %s);\n" %self.parse2(dst, src) + # self.body += "\t_rcr(%s, %s);\n" %self.parse2(dst, src) def _mul(self, src): src = self.expand(src) - self.body += "\tcontext._mul(%s);\n" %(src) + self.body += "\t_mul(%s);\n" %(src) def _div(self, src): src = self.expand(src) - self.body += "\tcontext._div(%s);\n" %(src) + self.body += "\t_div(%s);\n" %(src) def _inc(self, dst): dst = self.expand(dst) - self.body += "\tcontext._inc(%s);\n" %(dst) + self.body += "\t_inc(%s);\n" %(dst) def _dec(self, dst): dst = self.expand(dst) - self.body += "\tcontext._dec(%s);\n" %(dst) + self.body += "\t_dec(%s);\n" %(dst) def _cmp(self, a, b): - self.body += "\tcontext._cmp(%s, %s);\n" %self.parse2(a, b) + self.body += "\t_cmp(%s, %s);\n" %self.parse2(a, b) def _test(self, a, b): - self.body += "\tcontext._test(%s, %s);\n" %self.parse2(a, b) + self.body += "\t_test(%s, %s);\n" %self.parse2(a, b) def _js(self, label): - self.body += "\tif (context.flags.s())\n\t\t%s;\n" %(self.jump_to_label(label)) + self.body += "\tif (flags.s())\n\t\t%s;\n" %(self.jump_to_label(label)) def _jns(self, label): - self.body += "\tif (!context.flags.s())\n\t\t%s;\n" %(self.jump_to_label(label)) + self.body += "\tif (!flags.s())\n\t\t%s;\n" %(self.jump_to_label(label)) def _jz(self, label): - self.body += "\tif (context.flags.z())\n\t\t%s;\n" %(self.jump_to_label(label)) + self.body += "\tif (flags.z())\n\t\t%s;\n" %(self.jump_to_label(label)) def _jnz(self, label): - self.body += "\tif (!context.flags.z())\n\t\t%s;\n" %(self.jump_to_label(label)) + self.body += "\tif (!flags.z())\n\t\t%s;\n" %(self.jump_to_label(label)) def _jl(self, label): - self.body += "\tif (context.flags.l())\n\t\t%s;\n" %(self.jump_to_label(label)) + self.body += "\tif (flags.l())\n\t\t%s;\n" %(self.jump_to_label(label)) def _jg(self, label): - self.body += "\tif (!context.flags.le())\n\t\t%s;\n" %(self.jump_to_label(label)) + self.body += "\tif (!flags.le())\n\t\t%s;\n" %(self.jump_to_label(label)) def _jle(self, label): - self.body += "\tif (context.flags.le())\n\t\t%s;\n" %(self.jump_to_label(label)) + self.body += "\tif (flags.le())\n\t\t%s;\n" %(self.jump_to_label(label)) def _jge(self, label): - self.body += "\tif (!context.flags.l())\n\t\t%s;\n" %(self.jump_to_label(label)) + self.body += "\tif (!flags.l())\n\t\t%s;\n" %(self.jump_to_label(label)) def _jc(self, label): - self.body += "\tif (context.flags.c())\n\t\t%s;\n" %(self.jump_to_label(label)) + self.body += "\tif (flags.c())\n\t\t%s;\n" %(self.jump_to_label(label)) def _jnc(self, label): - self.body += "\tif (!context.flags.c())\n\t\t%s;\n" %(self.jump_to_label(label)) + self.body += "\tif (!flags.c())\n\t\t%s;\n" %(self.jump_to_label(label)) def _xchg(self, dst, src): - self.body += "\tcontext._xchg(%s, %s);\n" %self.parse2(dst, src) + self.body += "\t_xchg(%s, %s);\n" %self.parse2(dst, src) def _jmp(self, label): self.body += "\t%s;\n" %(self.jump_to_label(label)) def _loop(self, label): - self.body += "\tif (--context.cx)\n\t\t%s;\n" %self.jump_to_label(label) + self.body += "\tif (--cx)\n\t\t%s;\n" %self.jump_to_label(label) def _push(self, regs): p = str(); for r in regs: r = self.expand(r) - p += "\tcontext.push(%s);\n" %(r) + p += "\tpush(%s);\n" %(r) self.body += p def _pop(self, regs): @@ -399,35 +395,35 @@ namespace %s { self.temps_count -= 1 i = self.temps_count r = self.expand(r) - p += "\t%s = context.pop();\n" %r + p += "\t%s = pop();\n" %r self.body += p def _rep(self): - self.body += "\twhile(context.cx--)\n\t" + self.body += "\twhile(cx--)\n\t" def _lodsb(self): - self.body += "\tcontext._lodsb();\n" + self.body += "\t_lodsb();\n" def _lodsw(self): - self.body += "\tcontext._lodsw();\n" + self.body += "\t_lodsw();\n" - def _stosb(self, n): - self.body += "\tcontext._stosb(%s);\n" %("" if n == 1 else n) + def _stosb(self, n, clear_cx): + self.body += "\t_stosb(%s%s);\n" %("" if n == 1 else n, ", true" if clear_cx else "") - def _stosw(self, n): - self.body += "\tcontext._stosw(%s);\n" %("" if n == 1 else n) + def _stosw(self, n, clear_cx): + self.body += "\t_stosw(%s%s);\n" %("" if n == 1 else n, ", true" if clear_cx else "") - def _movsb(self, n): - self.body += "\tcontext._movsb(%s);\n" %("" if n == 1 else n) + def _movsb(self, n, clear_cx): + self.body += "\t_movsb(%s%s);\n" %("" if n == 1 else n, ", true" if clear_cx else "") - def _movsw(self, n): - self.body += "\tcontext._movsw(%s);\n" %("" if n == 1 else n) + def _movsw(self, n, clear_cx): + self.body += "\t_movsw(%s%s);\n" %("" if n == 1 else n, ", true" if clear_cx else "") def _stc(self): - self.body += "\tcontext.flags._c = true;\n " + self.body += "\tflags._c = true;\n " def _clc(self): - self.body += "\tcontext.flags._c = false;\n " + self.body += "\tflags._c = false;\n " def __proc(self, name, def_skip = 0): try: @@ -443,6 +439,7 @@ namespace %s { self.proc = proc_module.proc(name) self.proc.stmts = copy(src_proc.stmts) self.proc.labels = copy(src_proc.labels) + self.proc.retlabels = copy(src_proc.retlabels) #for p in xrange(skip, len(self.proc.stmts)): # s = self.proc.stmts[p] # if isinstance(s, op.basejmp): @@ -453,7 +450,7 @@ namespace %s { self.proc_addr.append((name, self.proc.offset)) self.body = str() - self.body += "void %s(Context &context) {\n\tSTACK_CHECK(context);\n" %name; + self.body += "void %sContext::%s() {\n\tSTACK_CHECK;\n" %(self.namespace, name); self.proc.optimize() self.unbounded = [] self.proc.visit(self, skip) @@ -479,6 +476,8 @@ namespace %s { self.proc.stmts.append(s) self.proc.add("ret") print "skipping %d instructions, todo: %d" %(start, len(self.proc.stmts) - start) + print "re-optimizing..." + self.proc.optimize(keep_labels=[label]) self.proc.visit(self, start) self.body += "}\n"; self.translated.insert(0, self.body) @@ -499,7 +498,7 @@ namespace %s { fd = open(fname, "wt") fd.write("namespace %s {\n" %self.namespace) for p in procs: - fd.write("void %s(Context &context) {\n\t::error(\"%s\");\n}\n\n" %(p, p)) + fd.write("void %sContext::%s() {\n\t::error(\"%s\");\n}\n\n" %(self.namespace, p, p)) fd.write("} /*namespace %s */\n" %self.namespace) fd.close() @@ -520,13 +519,11 @@ namespace %s { print "continuing on %s" %name self.proc_done.append(name) self.__proc(name) + self.methods.append(name) self.write_stubs("_stubs.cpp", self.failed) + self.methods += self.failed done, failed = len(self.proc_done), len(self.failed) - for f in self.forwards: - if f not in self.failed: - self.fd.write("void %s(Context &context);\n" %f) - self.fd.write("\n") self.fd.write("\n".join(self.translated)) self.fd.write("\n\n") @@ -540,20 +537,19 @@ namespace %s { n += 1 if (n & 0xf) == 0: data_impl += "\n\t\t" - data_impl += "};\n\tcontext.ds.assign(src, src + sizeof(src));\n" + data_impl += "};\n\tds.assign(src, src + sizeof(src));\n" self.hd.write( """\n#include "dreamweb/runtime.h" namespace %s { - void __dispatch_call(Context &context, unsigned addr); - void __start(Context &context); +class %sContext : public Context { +public: + void __start(); + void __dispatch_call(uint16 addr); -""" %(self.namespace)) - for f in self.failed: - self.hd.write("\tvoid %s(Context &context);\n" %f) - - offsets_decl = "\n" +""" +%(self.namespace, self.namespace)) offsets = [] for k, v in self.context.get_globals().items(): if isinstance(v, op.var): @@ -563,20 +559,21 @@ namespace %s { offsets = sorted(offsets, key=lambda t: t[1]) for o in offsets: - offsets_decl += "\tconst static uint16 k%s = %s;\n" %o - offsets_decl += "\n" - self.hd.write(offsets_decl); + self.hd.write("\tconst static uint16 k%s = %s;\n" %o) + self.hd.write("\n") + for p in set(self.methods): + self.hd.write("\tvoid %s();\n" %p) - self.hd.write("\n}\n\n#endif\n") + self.hd.write("};\n}\n\n#endif\n") self.hd.close() - self.fd.write("\nvoid __start(Context &context) { %s%s(context); \n}\n" %(data_impl, start)) + self.fd.write("\nvoid %sContext::__start() { %s%s(); \n}\n" %(self.namespace, data_impl, start)) - self.fd.write("\nvoid __dispatch_call(Context &context, unsigned addr) {\n\tswitch(addr) {\n") + self.fd.write("\nvoid %sContext::__dispatch_call(uint16 addr) {\n\tswitch(addr) {\n" %self.namespace) self.proc_addr.sort(cmp = lambda x, y: x[1] - y[1]) for name,addr in self.proc_addr: - self.fd.write("\t\tcase 0x%04x: %s(context); break;\n" %(addr, name)) - self.fd.write("\t\tdefault: ::error(\"invalid call to %04x dispatched\", (uint16)context.ax);") + self.fd.write("\t\tcase 0x%04x: %s(); break;\n" %(addr, name)) + self.fd.write("\t\tdefault: ::error(\"invalid call to %04x dispatched\", (uint16)ax);") self.fd.write("\n\t}\n}\n\n} /*namespace*/\n") self.fd.close() diff --git a/devtools/tasmrecover/tasm/op.py b/devtools/tasmrecover/tasm/op.py index 9baebccfc3..10fdd8a568 100644 --- a/devtools/tasmrecover/tasm/op.py +++ b/devtools/tasmrecover/tasm/op.py @@ -317,26 +317,30 @@ class _lodsw(baseop): class _stosw(baseop): def __init__(self, arg): self.repeat = 1 + self.clear_cx = False def visit(self, visitor): - visitor._stosw(self.repeat) + visitor._stosw(self.repeat, self.clear_cx) class _stosb(baseop): def __init__(self, arg): self.repeat = 1 + self.clear_cx = False def visit(self, visitor): - visitor._stosb(self.repeat) + visitor._stosb(self.repeat, self.clear_cx) class _movsw(baseop): def __init__(self, arg): self.repeat = 1 + self.clear_cx = False def visit(self, visitor): - visitor._movsw(self.repeat) + visitor._movsw(self.repeat, self.clear_cx) class _movsb(baseop): def __init__(self, arg): self.repeat = 1 + self.clear_cx = False def visit(self, visitor): - visitor._movsb(self.repeat) + visitor._movsb(self.repeat, self.clear_cx) class _in(baseop): def __init__(self, arg): diff --git a/devtools/tasmrecover/tasm/proc.py b/devtools/tasmrecover/tasm/proc.py index 1350ea1e0b..ed7053df89 100644 --- a/devtools/tasmrecover/tasm/proc.py +++ b/devtools/tasmrecover/tasm/proc.py @@ -9,6 +9,7 @@ class proc: self.calls = [] self.stmts = [] self.labels = set() + self.retlabels = set() self.__label_re = re.compile(r'^(\S+):(.*)$') self.offset = proc.last_addr proc.last_addr += 4 @@ -22,9 +23,9 @@ class proc: self.labels.remove(label) except: pass - for l in self.stmts: - if isinstance(l, op.label) and l.name == label: - self.stmts.remove(l) + for i in xrange(len(self.stmts)): + if isinstance(self.stmts[i], op.label) and self.stmts[i].name == label: + self.stmts[i] = op._nop(None) return def optimize_sequence(self, cls): @@ -47,7 +48,8 @@ class proc: n = j - i if n > 1: print "Eliminate consequtive storage instructions at %u-%u" %(i, j) - del stmts[i + 1:j] + for k in range(i+1,j): + stmts[k] = op._nop(None) stmts[i].repeat = n else: i = j @@ -60,20 +62,28 @@ class proc: if i + 1 >= len(stmts): break if isinstance(stmts[i + 1], cls): - stmts[i + 1].repeat = 'context.cx' - del stmts[i] + stmts[i + 1].repeat = 'cx' + stmts[i + 1].clear_cx = True + stmts[i] = op._nop(None) i += 1 return - def optimize(self): + def optimize(self, keep_labels=[]): print "optimizing..." - #trivial simplifications, removing last ret + #trivial simplifications while len(self.stmts) and isinstance(self.stmts[-1], op.label): print "stripping last label" self.stmts.pop() - if isinstance(self.stmts[-1], op._ret) and (len(self.stmts) < 2 or not isinstance(self.stmts[-2], op.label)): - print "stripping last ret" - self.stmts.pop() + #mark labels that directly precede a ret + for i in range(len(self.stmts)): + if not isinstance(self.stmts[i], op.label): + continue + j = i + while j < len(self.stmts) and isinstance(self.stmts[j], (op.label, op._nop)): + j += 1 + if j == len(self.stmts) or isinstance(self.stmts[j], op._ret): + print "Return label: %s" % (self.stmts[i].name,) + self.retlabels.add(self.stmts[i].name) #merging push ax pop bx constructs i = 0 while i + 1 < len(self.stmts): @@ -101,16 +111,26 @@ class proc: if not isinstance(s, op.label): continue print "checking label %s..." %s.name - used = False - for j in self.stmts: - if isinstance(j, op.basejmp) and j.label == s.name: - print "used" - used = True - break + used = s.name in keep_labels + if s.name not in self.retlabels: + for j in self.stmts: + if isinstance(j, op.basejmp) and j.label == s.name: + print "used" + used = True + break if not used: print self.labels self.remove_label(s.name) + #removing duplicate rets and rets at end + for i in xrange(len(self.stmts)): + if isinstance(self.stmts[i], op._ret): + j = i+1 + while j < len(self.stmts) and isinstance(self.stmts[j], op._nop): + j += 1 + if j == len(self.stmts) or isinstance(self.stmts[j], op._ret): + self.stmts[i] = op._nop(None) + self.optimize_sequence(op._stosb); self.optimize_sequence(op._stosw); self.optimize_sequence(op._movsb); |