Table of Contents


LambdaDelta is an emulator of the LMI Lambda Lisp Machine. Its goal is to simulate the hardware sufficiently to run original microcode and binaries unmodified, with performance and capability comparable to the original hardware.

LambdaDelta is written in C. It is intended to be portable to any reasonably Unix-like operating system, but is developed primarily on GNU/Linux. The initial versions will most likely fail to compile elsewhere, but attempts will be made to rectify this as soon as practical.

SDL Version 1 or 2 is used for console IO, the GNU/Linux tuntap driver or Berkeley Packet Filter is used for network IO, and standard Unix file operations are used for disk and tape IO. LambdaDelta includes code from the Fake86 project by Mike Chambers in its SDU implementation.

LambdaDelta is licensed under the GNU GPL Version 2 or later at your option. Please see the file COPYING for details.

About the Lambda

The LMI Lambda is a NuBus-based machine consisting of at least one Lambda processor, a System Diagnostic Unit, and various NuBus and Multibus peripherals. The System Diagnostic Unit has an Intel 8088 processor, and is responsible for bootstrapping the Lambda processor. The Lambda processor is made up of four cards in a specially wired area of the NuBus backplane. The standard Multibus peripherals are a 3Com ethernet interface, an Interphase SMD disk controller, a Tapemaster 9-track tape controller, and a Quarterback QIC tape controller (not emulated). The SDU software mediates sharing of Multibus peripherals. The SDU hardware provides a DMA path between Multibus space and NuBus space with mapping hardware for routing pages between targets on both busses.

The NuBus peripherals are memory and the VCMEM console controller. There must be one VCMEM for each Lambda processor. The standard configuration has one pair. An optional configuration called LAMBDA-2x2 has two pairs. This enables two simultaneous and separate Lisp environments to share one backplane, memory, disk, and network interface. The result was a considerable cost savings over buying a second machine. The 2x2 machine was also used for operating system development.

There was also an optional 68000-based Unix processor which could run V7 or SVR4. No attempt was made to emulate this. A configuration with a Unix processor was given the suffix "plus", making a "LAMBDA-PLUS" (or "LAMBDA+") a single-user Lambda with a Unix processor and a "LAMBDA-2X2-PLUS" a two-user Lambda with a Unix processor.


Questions, ideas, problems, solutions, praise, complaints, or baseless accusations may be directed to the LispM mailing list on tunes.org. See http://lists.tunes.org/mailman/listinfo/lispm/ for more information.

All contributors to this project are listed in the AUTHORS file.

Getting Started


LambdaDelta requires a set of ROM images from a physical Lambda, and either a disk image of an installed system or images of the installation and source tapes. At the time of release, these items are available from Bitsavers. See http://www.bitsavers.org/ for more information.

Bogodyne ZetaLisp System 500.0 Release 1 can be found at https://www.bogodyne.com/download/download-zetalisp/

Building LambdaDelta

LambdaDelta uses the GNU auto* tools for configuration and compilation. Most features and libraries should be configured automatically when the configure script is run.

To generate the configure script from a git checkout, the usual recipe is aclocal ; autoheader ; autoconf ; automake --add-missing. Your platform may require different invocation(s) of these programs.

If the generated configure script fails, try autoreconf -i and re-run it. (See dseagrav/ld#6 for the issue.)

If your system has both SDL1 and SDL2, you will be required to explicitly disable the one you do not want (use --without-SDLx). SDL1 seems to perform better over remote X11 connections, but SDL2 has better performance when running locally.

If you wish to emulate the optional 2x2 configuration, run configure with the option --enable-config-2x2=yes

If you are in possession of a physical Lambda keyboard and/or mouse, you may enable the use of these with the options --enable-config-physkbd and --enable-config-physms. You will need to provide serial interface hardware as required to communicate with these items.

After compilation, run-time options are controlled by a configuration file. If you have the YAML library installed (and configure found it), it will use YAML configuration. Otherwise, it will use the old configuration file.

Configuring LambdaDelta

Note: If you do not have libyaml on your system (or do not wish to install it), please see Old Configuration File for the legacy configuration system..

This is the new configuration method that is intended to be used going forward. The YAML configuration file is named lam.yml and is searched for in the following places, in order:

  1. The directory specified in SYSCONFDIR if it was defined during build.
  2. The user's home directory, as determined by:
    1. The $HOME environment variable, or if that is not defined:
    2. If we are root and were run by sudo, from the sudoer's passwd entry.
    3. If we are root and were not run by sudo, root's passwd entry.
    4. If we are not root, the user's passwd entry.
  3. The current working directory.

Any or all of these locations are valid; Configuration items in later files supersede those specified in earlier files.

You may also specify a configuration file of any name on the command line by using the -c argument. This file, if provided, is loaded last.

Single YAML key/value pairs may also be specified on the command line by specifying them in the form --section-key value. For example, the argument --log-ALL 10 will enable maximum logging of all types.

A full description of the YAML configuration file is beyond the scope of this document; See the "lam.yml" file in the examples directory.

Old Configuration File

Note: This file is provided for people who do not have libyaml on their system and wish to configure LambdaDelta without that dependency. However, it will not continue to be supported.

The old configuration file is named "ld.conf" and must be in the current working directory. An example configuration is provided in the examples directory. Each line of the configuration file has a keyword followed by a number of parameters. The following are the supported keywords and their parameters:

Using LambdaDelta

While the program is running, the window title bar has the following form:

LambdaDelta: VC N | Tape: FNAME | STATUS | DT X

N is the number of the active console, either 0 or 1. N is always zero when the 2x2 configuration is not in use. FNAME is the name of the active tape image file. STATUS is a string describing the state of the Lambda processor associated with this console. The strings have the following meanings:

Status string Meaning
Cold Halted The processor has been powered on and has no state.
Cold Running The halt flag is clear but the state is unknown.
Cold Booting The bootstrap is running.
Lisp Boot Halted The processor halted while Lisp was initializing. (This is an error condition.)
Lisp Booting Lisp is initializing or warm booting.
Running Lisp is running.
Halted Lisp has stopped running. The processor has valid state. If you did not halt lisp, this is an error condition.

After the status string is the time offset. X is a number in deciseconds which indicates how far apart real time and the emulator's time are. The emulator will try to hold this number at 0, but if your computer is not fast enough to run the emulator in real time this number will become negative and decrease further as the times diverge. If the number becomes positive and increases, the throttle is not operating properly. This is a bug which should be reported.

The following keys control emulator functions are cannot be remapped:

All other keys on the keyboard may be remapped using the map_key option described above. The standard mapping preserves the printed key label of the standard typewriter keys. The other keys are mapped as follows:

[ ( [ is the shift state, ( is unshifted
] ) ] is the shift state, ) is unshifted
RIGHT FLAG RIGHT SUPER Does not always work on some platforms
LEFT FLAG LEFT SUPER Does not always work on some platforms

The default keymap is still under development and is subject to change. Feel free to make suggestions or comments.

Preparing ROM Images

The ROM images go in the "roms" subdirectory. The necessary files are:

These can be found in zip files on the PDFs side of Bitsavers.

fossil sync -u

fossil uv export roms/VCMEM.ROM roms/VCMEM.ROM
	Copy of VC_MEM/U43_2516_2242843-0001_0856TI200038.BIN
	from VC_MEM.ZIP.
fossil uv export roms/SDU.ROM roms/SDU.ROM
	Copy of SDU_15165-0003/combined.BIN from

Microcode Symbol Files

In the lisp source tree there are files named bootstrap.lam-uload and ulambda.lmc-sym which correspond to the Lambda bootstrap code downloaded by the SDU and the Lisp microcode. Place these in the LambdaDelta directory to provide symbols for debugging. These are optional.

fossil uv export ulambda.lmc-sym ulambda.lmc-sym
fossil uv export bootstrap.lam-uload bootstrap.lam-uload

Quick setup

Since installation takes a long time, there is a prepared disk image. Do the above two steps (ROM and microcode), followed by:

fossil uv export LAMA-lam.yml lam.yml
fossil uv export LAMA-CMOS.RAM CMOS.RAM
fossil uv export LAMA-disk.img.xz disks/LAMA-disk.img.xz
xz -dc disks/LAMA-disk.img.xz > disks/disk.img

You should be able to start your Lambda machine, and have a usable system.

N.B. If you configured things in a older version of LambdaDelta it is important to refresh the SDU configuration, start ld and issue the config command. When asked if you wish to change anything, answer yes. At the cmd: prompt, type x, boot as usual.

Backup the disk and CMOS file for later.

Installing a New Machine

  1. Prepare your config file, ROM images, tape images, and create the disk image file. Ensure the SDU switch setting is zero in your configuration.

    fossil uv export tapes/00_install.tap tapes/00_install.tap
    fossil uv export tapes/02_system.tap tapes/02_system.tap
    fossil uv export disk-empty.img.xz disks/disk-empty.img.xz
    xz -dc disks/disk-empty.img.xz > disks/disk.img
    cat << EOF > lam.yml
      switch: 0
  2. Start the emulator. Telnet to port 3637 on the host. The emulator should start, and you should have a SDU prompt in your telnet session.

    Ignore the graphical console for the now - It is inoperative until the SDU firmware partition is loaded and the CMOS contents are valid.

    On GNU/Linux systems, to use the Ethernet interface you will need to add a tun interface.


    In another console:

    telnet localhost 3637
  3. Type init and push enter to initialize the busses and SDU. The SDU will reboot.

  4. Ensure the install tape is the active tape.

    Push F12 to switch tapes; for the Bitsavers 00_install.tap tape to work one needs to use ld 0.98.1.

  5. Give the SDU command /tar/setup clear eagle sp shell. Your CMOS should be initialized.

  6. Give the SDU command /tar/load and follow the prompts.

  7. When the load > prompt appears, give the command install and follow the prompts.

    One will get the following message if using the Bitsavers 00_install.tap tape:

    File doesn't start with LMFL
    Skip to next file? (y/n)

    Answer no.

  8. Give the command q to return to the SDU

  9. Close the emulator by closing its window

  10. Edit your config file file and change the SDU switch setting to 1

  11. Restart the emulator. You should get a SDU prompt on the console.

  12. Give the config command to initialize the Lambda configuration. When asked if you want to change anything, type y and press enter.

  13. At the cmd: prompt, give the command lambda.

    If using a 2x2 Lambda, you will be asked which slot -- use 0.

  14. At the lambda cmd: prompt, give the command switches

  15. At the -> prompt, give the command set use_multiplier

  16. Push enter to return to the lambda command level.

  17. Give the command x until config reboots the SDU.

  18. At this point your machine is configured and you can save backups of your lam.yml, disk image, and CMOS image file.

  19. At the SDU prompt, give the command newboot to bring up the bootstrap program.

  20. At the Command: prompt, give the command boot to start lisp.

  21. When the REPL arrives, evaluate (si:set-pack-name "LISPM-A") to set the hostname.

    (si:set-pack-name "LAMA LAMB")
  22. Evaluate (si:%halt) to halt Lisp.

  23. When Lisp halts, press F11 to summon Newboot again

  24. At the Command: prompt, give the boot command to cold-boot Lisp.

  25. When the REPL arrives, evaluate (fs:initialize-file-system) to format the LMFS. Answer Yes when prompted for confirmation.

  26. Push F12 to switch tapes to your distribution tape, if you have one.

  27. Type F1-B to summon the Backup activity.

    Select RETRIEVE from the Modes panel and RESTORE-FILES from the Commands panel; this will start to restore files immediately. When asked to login, use LISPM as your user.

    Takes about three hours on a modern-ish PC.

  28. When done restoring the distribution tape, reboot, load all patches, and save a new load band. To find a suitable partition, evaluate (print-disk-label).

    (login 'lispm)
    (disk-save 2) ; Or some other suitable partition.
    (set-current-band 2)

    If you get a warning about mismatches microcode, just answer that it is OK.

    This is also a good time to make a backup (CMOS.RAM, disk image, and lam.yml).

If you want to poke around on the local file system, you can start Dired by evaluating (dired "lama: ~;*").

At this point you can follow the instructions included with the distribution tape. If it is a backup tape, simply restore it. If it is an actual distribution tape, it may have special loading procedures.

(Re)Compiling the whole system

To compile the whole system, which will only compile files that need to be compiled, evaluate:

(make-system 'system)

If you've done many changes, it might be worth recompiling everything, to do that evaluate:

(make-system 'system ':recompile)

Assembling the microcode load

To assemble a new microcode load evaluate the following:

(load "sys:ulambda;ucode")
(make-system 'ucode)

When using the Bitsavers distribution tape, SYS: ULAMBDA; UC-LAMBDA-ARRAY.LISP will barf; open the file end save it without changes.

To then load the resulting microcode (SYS: UBIN; ULAMBDA LMC); evaluate the form (this will load the latest LMC file):

(si:load-lmc-file t 2) ; Or some other suitable partition.

To test that the microcode loads, switch to the second CPU and summon newboot (F11). At the Command: prompt use the set-uload command to choose a microcode load to boot temporarily. When done, issue boot to boot.

To make it current, evaluate (set-current-microload "LMC2").

Generating a new cold load band

To load the Cold Load Generator, and to make the load band evaluate the following two forms:

(make-system 'cold)
(cold:make-cold 2) ; Or some other suitable partition.

This takes about 20 minutes on a modern-ish PC.

Then one needs to start start the MINI server, issue F1-7 and in the right panel evaluate (mini-server-process).

Switch to the second Lambda using F9, and evaluate (disk-restore 2). This will boot the cold load band, when that is done one can start loading the rest of the system by evaluating (si:qld).

When this has finished, and the new system seems to be working, one can make the load band default by evaluating `(set-current-band "LOD2").

Making distribution tapes

We need two tapes:

To make a distribution tape, load:

Then run, pick the type of tape you are making (source or options):


Install tape consists of the following:


When using a 2x2 setup one can debug the other processor, evaluate (lam:setup) and choose the "local" option. This will setup the debugger, to start it issue F1-RIGHT-CONTROL-D. In the top panel, pick LAM for novice and you can use the right side menu for poking around.

Parition Names

The Lambda supports multiple disk units, to use them the labeling of partitions is important. The first character must correspond to the unit the drive is attached too. So to keep a FILE partition on unit 1 (instead of unit 0), it has to be named 1ILE or 1FILE.

The last digit of a partition name that contain "writable" data is used by the second CPU. E.g, PAGE, METR, FILE are used by the first CPU and PAG1, MET1, FIL1 by the second.

N.B. The real Lambda could only really handle 2 disk units, the controller does support 4 units which is also what LambdaDeleta supports.


Setting up the ldtap interface:

ip tuntap add ldtap mode tap
ip link set ldtap up
ip addr add dev ldtap

In SYS: SITE; SITE.LISP see that the following, or equivlent exists:

			(:INTERNET "" "")
			(:CHAOS 7)))))



Replace IP addresses accordingly.

Recompile all site files, and re-configure the network:

(make-system 'site :recompile)

This is as good place as any to make the changes permanent by saving the world using disk-save.

Initialize a disk label

/tar/setup clear eagle sp shell
unit N