Symbolics Lisp Machine Emulationupdated 7/6/2004
It began with an insane idea:
I'd thought it would be fun to have the lisp source code for the L-machine microcode. An early version is published in the Symbolics patent. So, I OCR'd many of the patent tiff files and cleaned them up. I found emacs lisp-mode to be very helpful.
Emulating the L-machine...
Once I got this idea idea in my head, I found it hard to stop. So, I made a plan, figuring I'd hit a wall or run out of gas at some point. So far, I keep making progress.
Here are the paths I have been going down:
After fixing some macroinstruction misconceptions and filling in some fep communication variables, the emulator has made it out of SYSTEM-STARTUP. It's making good progress through LISP-TOP-LEVEL-WARM.
Arrays are better but not quite right. I fixed up some of the cdr-code handling.
Unfortunately I keep hitting macroinstructions which are not in the original patent microcode. I'm current working on 'take-keyword-argument'. I added a simple command line debugger to help me out. This allows stepping, dumping the stack and displaying memory in various forms.
debug> s 35:-004:00000000026 (0x16) 36:>002:04025410314 (0x205610cc) 37: 004:00000000026 (0x16) op 146 take-keyword-argument FP 0 UNIMPLEMENTED INSTRUCTION! op 146 take-keyword-argument FP 0 top; pc 500664072, sp 36, fp 35 debug> a 026 13777770026 02:205610cc 2:04025410314 DTP-SYMBOL 2:00025410314 : DTP-HEADER-P 66:00024111130 %header-type-symbol ABORT : DTP-ONE-Q-FORWARD 62:00040002263 : DTP-NULL 0:00025410314 : DTP-LIST 4:00014203704 : DTP-ARRAY 7:00100203720 debug> d 04025410314 25410314 36:60509258 66:14024111130 DTP-HEADER-P 66:00024111130 %header-type-symbol ABORT This shows the FP at 35 (octal), SP at 36
I've been writing the l-machine macrocode compendium (it's in with the patent files - look for OPCODE.txt).
As I make progress I've been updating the simulator. So far it starts up and tries hard to find the console and fails. I think it wants some information provided by the FEP. The simulator is a total hack, designed more to prove out my understanding of the hardware and macrocode than anything else. Still, it's fun to play with and does basic macrocode execution.
I'm still confused by arrays and how function cells really look, but I'm making progress.
I managed to OCR the first few hundred pages of the lisp code in the patent. Basically everything which describes the microcode. I didn't OCR all of the PAL code or the FEP LIL code.
I have a hacked version of franz lisp (under linux) which runs some of the original lisp code. There are still some problems, but I've gotten to the point where I can define ucode instructions. I have not tried to emulated any instruction (yet). This is a lot of fun to play with.
So far the world decode program can read l-machine world files, find the starting lisp code and disassable it. It parses all the VM information and populates a 3-tier page tree which will map virtual to physical pages and page them in from the world file.
It starts trying to run the world but the emulation code is nonexistant-to-very-feeble at this point. I'm sure I've got many things wrong, but hey, it's an experiment. I'm only now starting to understand how the stack caching works and how stack frames are suppose to look.
It turns out reading new world files for the i-machine is really easy but readling old l-machine world files was non-obvious. Something odd happens in the process of converting the 36 bit words into a byte stream. I could get part of the word correctly but not all of it. After a few weeks I decided to start looking for ascii text strings and that proved to be the key. Much of the lisp code treats the file as an array of 4 bit nibbles. But for some reason the nibbles on the lower half of the 36 bit word are in a really strange order. Matching ascii text turned out the be the key to decoding this and now I can read the entire file tags and all. The VM page descriptions are straight forward as are the sparse entries for a-memory contents.
Fortunately the a-memory map is tied to the microcode and the symbols are in the microcode symbol table file. This is the key to finding the function-system-startup. Also, there are a number of helper routines written in macrocode which are in the genera 8.3 sources. These allowed me to match up the vm pages with the a-machine pointers and fine tune the disassembly.
I'm now working on the pseudo code descriptions. I need to get straight in my mind what the microcode is doing before I write any more emulation code. I'd like to eliminate the a-memory stack cache, if I can. This was a good idea for the h/w at the time, but the macrocode doesn't know about it and it's not needed for proper emulation (or so we'll see).
I know it's crazy, but with the microcode lisp (and simulation lisp code), it really looks like it would be possible to emulate the l-machine. My goal is to get it working first and then start over with speed in mind. What I have now is a total hack, but it's only intended to be used to explore and try things out. I don't expect this to be fast, because that's not the point. If/when I can get it to boot genera (heh, ok, there, I said it) I'll worry about speed. If anyone wants speed they should be using the i-machine emulator which Symbolics sells, not this total hack.
I'm really doing this for the fun of it, and to learn about the architecture and lisp...
... these pages (generated-with-lisp) ...