Doom on an Apple Lisa 2: a 68000 at 5 MHz, 1.5 MB of RAM, a 720 × 364 one-bit screen and a ProFile hard disk. It's a port of Frenkel Smeijers' Doom8088: Motorola 68000 Edition, whose AT&T UNIX PC target is nearly the same machine.
There are two builds from one source tree:
- Standalone. The Lisa boots Doom straight off the ProFile with no operating system. This is the one to run: it has twice the memory and sixteen greys.
- UniPlus+. Doom as an ordinary program under UniSoft's UniPlus+ System V, a UNIX port from 1984. This came first and still works.
We did the work under the LisaEm emulator, and the standalone build boots and plays on a real Lisa. It is slow: the best-looking build runs at about 1.1 frames per second.
| Build | Columns | Shades | Heap (bytes) | fps |
|---|---|---|---|---|
| UniPlus+ | 60 | 2 | 612,352 | 1.732 |
| Standalone | 60 | 2 | 1,204,240 | 1.944 |
| Standalone | 120 | 16 greys, dithered | 1,182,720 | 1.112 |
These are 200 frames of -timedemo demo3, which renders every tic with no frame
skipping, so they're worst-case figures. PORT.md says how they were
measured and why the two 2-colour figures should be re-run.
-
A Mac with Python 3 and the m68k cross toolchain. The Makefile hasn't been tried on Linux. The Lisa's own C compiler is never used.
brew install m68k-elf-gcc m68k-elf-binutils -
A WAD. None is in the repository. The game uses Episode 1 WADs preprocessed for Doom8088:
DOOMST2.WADfor 2 colours andDOOMST16.WADfor 16 greys.doom/VENDOR.mdsays where they come from. Put the one you want in the top of the repo, or pass its path withWAD=.
make bootimage COLORS=16
This writes build/profile.image, a 10 MB ProFile image: the boot block, then Doom,
then the WAD as raw sectors from sector 1024. There's no filesystem on it.
If you only want to play it, the
releases page has this image
already built: 16 greys at 120 columns, with DOOMST16.WAD in it.
Options:
COLORS=16 |
16 greys with DOOMST16.WAD. The default is 2 colours with DOOMST2.WAD, matching upstream's black-and-white builds |
WAD=/path/to/DOOMST16.WAD |
where the WAD is |
BOOTIMAGE=/path/to/out.image |
where to write the image |
VWW=120 |
renderer columns: 30, 60 or 120. Only with COLORS=16 |
BENCH=1 |
build the benchmark instead of the game: play demo3 for BOOTFRAMES frames and print the result |
ZONECAP=612352 |
cap the heap, for comparing against the UniPlus+ build at equal memory |
Copy build/profile.image to an ESProFile card as profile.image, connect it to the
built-in parallel port, and start the Lisa from the ProFile. The boot block draws a
progress bar beside the ROM's hourglass while it loads, then Doom draws its face while
the level loads, then the title screen. The machine needs 1.5 MB or more.
Point the ProFile on the built-in parallel port at the image, set the memory to
1536 KB or more, set the speed to 5 MHz before powering on, and leave the speed
alone during a run. The standalone clock only keeps time if the speed is constant.
LisaEm must not have the image open while make bootimage rewrites it.
| Action | Key |
|---|---|
| Walk | keypad 8 2 4 6 |
| Strafe | , . |
| Fire | / |
| Use | Return or Space |
| Weapon | [ ] |
| Automap | Tab |
| Menu | Clear or Backspace |
| Quit | ⌘Q, back to the boot ROM |
The number row types, so IDDQD works.
make # build/doom and build/vidtest
make check # host-side tests, no Lisa needed
make put IMAGE=/path/to/uniplus.image
make wad IMAGE=/path/to/uniplus.image
put copies the programs into /doom on the image and wad copies the WAD there.
FSBASE is the block where the image's root filesystem starts;
tools/extract_profile_image.py --list prints it, and the default is a 20 MB image
with the root on the second half. LisaEm must not have the image open, and back it up
first. tools/README.md has the rules.
Then, on the Lisa, as root (mapping the screen with phys() needs it):
cd /doom
./rundoom
rundoom runs the game and puts the terminal and the bottom four raster lines back
afterwards. ./doom -frames 200 -timedemo demo3 runs the two-minute benchmark.
The keys are the same, with three differences: the arrows or the number row walk, because the console can't tell the keypad apart; the menu is Clear or control-Z E; and quit is control-Z Q.
doom/ |
upstream Doom8088ST, unmodified |
port/i_lisav.c, port/i_lisav16.c |
video, 2-colour and 16-grey, from upstream's i_3b1v.c |
port/i_lisa.c |
system, keyboard and clock under UniPlus+, from upstream's i_3b1.c |
port/i_boot.c |
the same for the standalone build |
port/vidtest.c, port/rundoom |
the UniPlus+ screen test, and the wrapper script |
lib/ |
crt0, system call stubs, a 4 KB libc, nlist, and the Lisa screen code |
boot/ |
boot block, startup, interrupt handlers and machine layer for the standalone build |
tools/ |
mkaout.py (ELF to UniPlus+ a.out), mkboot.py (boot disk layout), disk image tools |
test/ |
the host-side tests |
PORT.md: how the port was done and what went wrong.TOOLCHAIN.md: cross-compiling C for UniPlus+. The executable format, system calls, memory limits and writing a libc. Nothing in it is specific to Doom, so if you're here for the Lisa and not for Doom, start there.
Everything in this repository is GPL v2 or later; LICENSE has the text.
Doom8088ST is GPL v2 or later, and port/ derives from it. The toolchain in lib/,
boot/ and tools/ is original to this repository and under the same licence. Doom
and its WADs belong to id Software. There's no WAD in the repository. The boot image
on the releases page has
upstream's in it, as upstream's own release does.