[z-machine] Returning 2 from @save in z5

Thomas Thurman thomas@thurman.org.uk
Mon, 29 Sep 2003 20:01:57 +0100


Sticky question here:

Recall that @save and @restore are both store instructions. The Z-spec says that @save stores:

   0 = Save failed
   1 = Save succeeded
   2 = This is a restore

And @restore can store only

   0 = Restore failed

since if it succeeded we would already be somewhere else.

My question is: how can a terp ever validly store a 2, "this is a restore", from @save? Suppose we load an arbitrary game from disk. The PC is pointing at the instruction after the @save which saved the game. We don't know where that @save was storing to, so we can't write the 2 out anywhere.

I've thought of three possible workarounds, but none is satisfactory.

1) My original plan. We know the target of @save while executing @save, so we write the 2 out before we save, and overwrite it with 1 when we're done. Then it's a 2 in the saved state that we restore.

This won't work, for two reasons:

 i. Since it relies on the saved state to give a correct result, all terps would have to have worked this way forever, and AFAIK they don't and haven't.

 ii. The target can be the stack! So we can't overwrite without some horrible special-casing.

So that's pretty useless.

2) The save file format could store where to put the 2. This would be ideal. However, Quetzal has no such field, so this isn't much good either.

3) We could look at the instruction immediately before the PC, check it's an @save, and find its target. This is probably what I'll end up doing for now, but it's a little inelegant. (Of course, this would be impossible in version 3, since there @save is a branch instruction, but that might be OK because then there's no store to get confused over).

This seems to be a universal problem. I haven't yet verified this by running a test story through them, but I've checked the sources of Frotz, Malyon, Zip and Rezrov and they all seem to work by storing 2 to the target of the @restore, not the @save. That's all very well if they have the same target, but there's nothing to say that they will. Besides it's contrary to the standard.

What do people think-- should I go along with the standard, or the crowd? And if the standard's wrong, should that be changed in Standard 1.1 whenever that happens?

T