How to fix old amfv z4 files

Modern interpreters cannot play these old versions of amfv:
firstalpha.zip: Infocom (Z-machine 4, Release 47, Serial 850313)
gamma.zip: Infocom (Z-machine 4, Release 131, Serial 850628)

Moreover
fullalpha.zip: Infocom (Z-machine 4, Release 84, Serial 850516)
can be played but $verify will fail.

This because interpreters expect z4 files to be at least N*4 bytes long, where N is the 16-bits value stored in the header at offset 0x1a.

Unfortunately early z4 files didn’t follow that rule.

Files can easily be fixed by changing the value stored in the header and by appending 2 zero bytes to the files.

firstalpha.zip: change the value in the header from 0xe9a3 to 0x74d2 and append 2 zero bytes to the file
fullalpha.zip: change the value in the header from 0xb8e8 to 0xb8e9 and append 2 zero bytes to the file
gamma.zip: just append 2 zero bytes to the file

The modified files can be played with frotz and $verify is correct for all of them.

5 Likes

I’m not going to “fix” the files at https://eblong.com/infocom/ because that’s an archive of original files.

Some Z-code interpreters have a list of behavior exceptions for specific Infocom files. This fix may get added to those lists. However, not all Z-code interpreters do that, so we should keep this info on file for future software archeologists.

1 Like

Is that a call for submissions? :wink:

One I can think of, that I don’t know if any modern interpreter handles, is the DELAY routine in Bureaucracy. It’s used to introduce delays at various points when using the computer terminal near the end of the game. Without that some messages are overwritten before you can ever read them.

I think timed input was a thing even in v4 games, but Bureaucracy still opts to implement it as a busy-wait loop. I wish they hadn’t, and the only solution I’ve been able to think about would be to hard-code the address of the DELAY routine and intercept all calls to it. But at least that gives us an insight into the relative speed of Infocom’s own interpreters:

<CONSTANT DELAYS <PTABLE (BYTE) 1 ; "ZIL"
                         10     ; "ZIP20"
                         1      ; "APPLE II"
                         4      ; "MAC"
                         4      ; "AMIGA"
                         4      ; "ST"
                         1      ; "COMPAQ/PC"
                         1      ; "128"
                         1      ; "64...">>

<DEFINE DELAY ("OPT" (SEC:FIX 1) "AUX" (N:FIX <GETB ,DELAYS <LOWCORE INTID>>))
  ; "N is number of 1000s to count down to get 1-sec. delay"
  <SET N <* 1000 .N .SEC>>
  <REPEAT ()
    <COND (<L=? <SET N <- .N 1>> 0> <RETURN>)>>>
2 Likes

I added specific notes to the Infocom collection page, at least.

1 Like

Bocfel patches that: https://github.com/garglk/garglk/blob/c839c001795078b9a674af06be61950c88cab9da/terps/bocfel/patches.cpp#L281

3 Likes