Matthew Garrett ([personal profile] mjg59) wrote2013-09-22 14:10
Entry tags:

Implementing UEFI Boot to Zork

One of the earlier examples of students using MIT computer resources to lay the groundwork for a later commercial endeavour, Zork was originally written in a LISP derivative called MDL. This was later tuned into the Zork Implementation Language, a domain specific language that was compiled to target the Z-machine rather than a specific piece of hardware. Combined with machine-specific Z-machine interpreters, this allowed rapid porting of games to a wide range of platforms - the only thing that needed to be rewritten was the interpreter, and that could be reused for any future games running on the same hardware.

Infocom were eventually acquired and killed off, but fan interest in their games continued. New Z-machine interpreters were written in order to allow their games (including Zork) to be run on platforms that Infocom had never targetted. One of the best known is Frotz. This has the advantage of being (a) portable and (b) including a "dumb" UI that makes no assumptions about the availablity of any vaguely useful functionality. Like, say, a Curses library.

So, Frotz seemed like the natural choice when this happened. But despite having a set of functionality that makes it look much more like an OS than a boot environment, UEFI doesn't actually expose a standard C library. The EFI Application Development Kit solves this particular design decision. Porting Frotz ended up involving far more fixing up of Frotz bugs that tripped up -Werror than anything else. One note, though - make sure you include DevShell in the list of required packages at build time, otherwise file i/o will mysteriously fail.

The tying of file i/o to the shell protocol unfortunately means that Frotz can't be directly launched by the firmware. The Boot to Zork images therefore contain a UEFI shell in the standard boot location (\EFI\BOOT\BOOTX64.EFI) which is executed when the firmware attempts to boot the device. The shell then looks for a file called "startup.nsh" in the root directory of the boot device and executes it. Unfortunately this doesn't actually set the shell equivalent of the current device, and so just launching Frotz from startup.nsh fails when Frotz can't open the Zork data file. The solution for this is simple, if ugly - the script walks through the list of devices, looking for one that contains ZORK1.DAT in the root directory. It then changes to that device and launches Frotz. If Frotz exits, it then resets the system.

This could be avoided by doing some more work and turning Frotz into a more UEFI-native application. Teaching Frotz to make native UEFI calls would avoid the requirement for the shell protocols, and the firmware provides a mechanism to obtain the path of the currently running executable which would avoid the need to explicitly locate the device. But I'm lazy and this was a "I'm spending the day on a plane" project initially inspired by a Sazerac-fuelled conversation during the UEFI plugfest, not a demonstration of UEFI best practices.

UEFI Boot To Zork and the source code to the modified Frotz can be downloaded here.

(Anonymous) 2013-09-22 19:49 (UTC)(link)
Presumably the need for the shell is also part of the reason why the current version of Frotz could not be Secure Boot signed?

Why you no git?

(Anonymous) 2013-09-23 14:31 (UTC)(link)

Re: Why you no git?

(Anonymous) 2013-09-24 02:48 (UTC)(link)
Hmm... "give knife to troll" or continue booting...

OK so on the return flight, if you [stop drinking | drink more] absinthe drinks, maybe re-code Roberta Williams "King's Quest" in GRUB2 statements using dozens of background images?

Re: Why you no git?

(Anonymous) 2013-09-24 17:29 (UTC)(link)
I'll see about folding in what changes are practical into the Frotz codebase That'll put it in a git repo in some fashion.

David Griffith

Re: Why you no git?

[identity profile] 2013-10-09 19:05 (UTC)(link)
Upstream is in Git:

(I know because I did the conversion from all the tarballs I could find plus Subversion. It wasn't simple.)

Re: Why you no git?

[identity profile] 2013-10-09 19:11 (UTC)(link)
David Griffith (the current maintainer) has a clone on GitHub also:

which Zork?

(Anonymous) 2013-09-23 18:37 (UTC)(link)
Are we talking Zork I here? I at first thought of the old MIT version which (AFAIK) predates the commercial Zork-[1,2,3] and was written in (or at least distributed as) Fortran. I'm told it included most of what was in all 3 commercial Zorks, but have no direct personal knowledge of that.

(I recall having hacked the Fortran source in to C, using F2C, back when I ran Coherent at home, pre-linux, and with only a bit of butchering of the resulting C got a working game. several years prior to that, I also had a version for PDP-11, at work.)

Re: which Zork?

(Anonymous) 2013-09-24 02:50 (UTC)(link)
Actually, to correct my own post. It appears that someone later ported Zork aka Dungeon to fortran for reasons which escape me :-).
But the original version was definetely MDL.

Re: which Zork?

(Anonymous) 2013-09-25 02:56 (UTC)(link)
And I'm glad they did, or I wouldn't have been successful porting it to the Burroughs B6810 we had in college! That (and Adventure before that, plugh!) launched an interest in text based games and AI applications that continues with me today.

Re: which Zork?

(Anonymous) 2013-09-25 23:11 (UTC)(link)
I got my hands on a Zork executable compiled from that Fortran code for DEC's RT-11 OS. I had Unix v6 on a PDP-11/45, so I wrote an RT-11 emulator for Unix in order to run Zork. It was good enough that I could distribute it (via magtape at Usenix meetings, there being no github in 1979.) That allowed an RT-11 shop in Portland to switch to Unix, which created a sysadmin job, which let me move there. Thanks Zork!

Re: which Zork?

(Anonymous) 2013-09-24 02:47 (UTC)(link)
No the original zork was written mdl (a lisp variant).
Your thinking of Adventure which was written in fortran and predates zork.

Re: which Zork?

(Anonymous) 2013-09-24 17:23 (UTC)(link)
Infocom games were written in a MDL variant called ZIL for Zork Implementation Language. There's a document about it on the IF Archive.

Sounds interesting, eh ?

(Anonymous) 2013-09-25 07:43 (UTC)(link)
Then next there will probably be a port of ScummVM to UEFI, or what ?

adventure crashes

(Anonymous) 2014-01-05 19:39 (UTC)(link)
On my system (ASUS P875-M-LE with latest UEFI version 1301) the adventure keeps crashing. It is like this: when I type something suddenly ^@ appears (this is just one character - probably the representation of a 0 byte). When I do not delete this and type on and press "enter" then the computer does directly a reboot.