[z-machine] Replicating txd subroutine-finding functionality
Amir Karger
amirkargerweb@yahoo.com
Wed, 19 May 2004 20:40:46 -0700 (PDT)
I'm working on my "translate a Z-file to a working Perl program"
project again. I've got save/restore almost working, at which point
I'll have implemented all of the v3 opcodes. Pretty exciting!
Anyway, this week I remembered that one thing I don't like about my
translator is that it needs txd to find where the subroutines are in
the Z-file. And I can't copy the txd code, because someone on this list
pointed out that it's not open source. (It's terribly tempting having
non-open source C files sitting on one's hard drive.) So I've decided
to try replicating it, at least for easy cases (e.g., Inform, which
seems to be better behaved about where it puts things).
The basic plan is this:
-start at the "main" sub, and translate commands one at a time.
-If I get to a call of any kind (except "call sp" or the like), put the
called address onto my list of subs to look at.
-If I find that I've translated addresses 1000-1100 and 1120-1200,
assume there's a sub at 1101, and try to parse it that way.
- Profit! (No wait, that won't work.)
I have several questions that'll determine whether this will work.
1. will all subs (compiled with "all" compilers) have as their last
opcode one of: ret, ret_popped, rfalse, rtrue, print_ret, jump (only
true jump, and must jump backwards), throw, restart, restore, quit? If
so, then I can keep translating commands in a sub at least until I hit
one of those (and even then, only end the sub if the next packed
address byte is a number from 0-15). I suppose it's technically allowed
to fall off a sub, but I'm hoping compilers wouldn't usually make code
that way. Looking at minizork and advent, I didn't find any other
opcodes.
2. Will space between end of one sub and beginning of the next (at a
packed address) always be zeroes? This will also help determine whether
I've finished a sub.
3. txd yields an extra routine at the end of the code that's just 02b1
(2 locals, rfalse). Is this something Inform adds in? Does it matter?
4. are we guaranteed to find action etc. routine addresses in a certain
place? I can't seem to find info on the web describing how the
addresses for these guys are chosen or how I can figure them out.
My first try at the algorithm found only 66 of 341 minizork
subroutines. I think at least part of the problem is Qs 1&2 above - I'm
ending my subs too early, thus not finding more call routines. But I'm
pretty sure a main problem is the action routines. Minizork has 106 of
them, and some of those call other routines, and I believe pretty much
all of them are called using "call local1" or whatever, so my code
never finds them. (If I were REALLY crazy, I'd actually start executing
the code, and whenever I found a sub I hadn't yet translated, I'd
translate it. But of course I can't guarantee code coverage.)
I'm not expecting this thing to be perfect, or even as good as txd
(which I think someone said could be fooled by certain Zcode tricks).
But I ought to be able to find the vast majority of subs in Zork, and
all the subs in Inform games, it seems to me.
If anyone has better ideas for how to find subroutine starts and ends
in a Zcode game, feel free to speak up.
Thanks,
-Amir Karger
amirkargerweb@yahoo.com
__________________________________
Do you Yahoo!?
Yahoo! Domains – Claim yours for only $14.70/year
http://smallbusiness.promotions.yahoo.com/offer