To:	Users
From:	Bob Supnik
Subj:	PDP-1 LISP
Date:	25-Apr-2005

				COPYRIGHT NOTICE

The following copyright notice applies to both the LISP source and binary:

	Original code published in 1964, written by L. Peter Deutsch
	Portions Copyright (C) 1997 Digital Equipment Corporation

	All Rights Reserved except as specified below.

	Permission is hereby granted to use, copy, modify, and distribute
	this software (or portions thereof) for any purpose, without fee,
	subject to these conditions:

	(1) If any part of the source code for this software is distributed,
	then this copyright and no-warranty notice must be included
	unaltered; and any additions, deletions, or changes to the original
	files must be clearly indicated in accompanying documentation.

	(2) If only executable code is distributed, then the accompanying
	documentation must state that "this software is based in part on the
	original work of L. Peter Deutsch".

	(3) Permission for use of this software is granted only if the user
	accepts full responsibility for any undesirable consequences; the
	authors accept NO LIABILITY for damages of any kind.

	These conditions apply to any software derived from or based on this
	code, not just to the unmodified code.

	Permission is NOT granted for the use of any author's name or
	company name in advertising or publicity relating to this software
	or products derived from it.


1. Introduction

This package contains the source and binary for PDP-1 LISP, a LISP interpreter
for the PDP-1.  This historic program was written by Peter Deutsch in 1963 and
1964.  It was the first LISP interpreter on an interactive system and one of
the first in general use.

The package contains the following items:

	lisp.mac		LISP source code, complete in one file
	lisp.rim		LISP binary in read-in mode (RIM) format
	macro1.c		assembler for LISP

To assemble LISP, you must first compile the assembler:

	cc macro1.c -o macro1

and then use it to assemble the sources:

	macro1 lisp.mac

The assembler is NOT a line for line reconstruction of PDP-1 macro; it contains
exactly enough functionality to assemble LISP, and no more.


2. History Of The Program

The following comments were supplied by Peter Deutsch, the program's author:

"I wrote PDP-1 Lisp because I had a strong mathematical bent, I'd become
intrigued with the Lisp language as a result of having somehow picked up a
copy of the original Lisp 1.5 Programmer's Manual at MIT, and I wanted to
have an interactive Lisp implementation to play with rather than having to
submit card decks at the MIT Computation Center.  (Bear in mind that I was
in high school at the time -- 1960-1964.)  I'd ingratiated myself with the
folks at the TX-0 (and later PDP-1) lab at MIT, so I had pretty free access
to the machine there.

"I think the most interesting aspect of the design philosophy, in retrospect,
was that I instinctively homed in on the fact that when implementing a
language using an interpreter, operations in the language that were
documented as primitive could in fact be implemented within the language
(i.e., interpretively) using simpler primitives.  (Maybe this fact was
common knowledge at the time, and I'm just not remembering it.)  Thus
operations like CAAR were actually implemented in Lisp as (LAMBDA (X) (CAR
(CAR X))).  This was a pure time/space tradeoff, since Lisp S-expressions
took less space than PDP-1 machine code.  I used this approach to tremendous
advantage in my subsequent Lisp work (my PDP-1 Lisp implementation, as you
probably know, was extensively rewritten at BB&N to become the conceptual
predecessor of BBN-Lisp, which in turn engendered Interlisp), and also in
the Smalltalk and PostScript implementations I was involved with later on.

"I did all the development on a machine whose only long-term non-volatile
storage device was paper tape: the word processor read in a paper tape,
allowed you to edit, and then punched out an entire new tape.  (When I
arrived at MIT, the word processor, Expensive Typewriter, didn't have any
facilities for backing up in the input, since it was designed as a
tape-to-tape editor: I rewrote it to be RAM-based, and added a lot of new
facilities.)  You then had to run the edited tape through the assembler,
producing another tape of the executable, and then run *that* tape back into
the machine for execution.  (I also hacked up Expensive Typewriter to
integrate directly with the assembler, using the machine's swapping drum to
pass the source code, so the intermediate tape was no longer needed; in
fact, as I recall, you could even defer punching out the edited tape.)  This
was another theme that has run through a lot of my subsequent career:
sometimes the tools I developed along the way were as interesting as
whatever it was that I was developing using those tools."


3. User's Guide

To run LISP on the PDP-1 simulator, first enable hardware multiply/divide,
which the program requires.  Then load the rim format tape into memory
and begin execution in extend mode.  The program halts; enter the upper
bounds of free storage via the test word switches (TW) and continue.  LISP
runs in extend mode; any value from 07777 to the upper bounds of memory will
work.  The program halts again; enter the size of the push down list via the
test word switches and continue.  List sizes between 200 and 400 words are
suggested.  The program halts a third time; select the input device via the
sense switches (sense switch 5 on for the typewriter, off for the paper tape
reader).  Because the setup is so complicated, save the state of the system
before continuing:

	sim> set cpu mdv
	sim> load lisp.rim
	sim> d extm_init 1
	sim> run

	HALT INSTRUCTION, PC: 002353 (CLA LAT CLI)
	sim> d tw 7777
	sim> c

	HALT INSTRUCTION, PC: 002357 (CLA LAT)
	sim> d tw 400
	sim> c

	HALT INSTRUCTION, PC: 000005 (STF5)
	sim> d ss 2
	sim> save lisp.sav
	sim> c

Quoting from the original operating instructions, "At this point, the LISP
system is ready for manual typewriter input.  As soon as the operator types,
for example:

	(car (quote (a b c d)))

together with a final space at the end of the last right parenthesis, the
computer takes control of the typewriter, impulses a carriage return, and
then types out:

	a

which of course is the correct answer.  Similarly for the other suggested
test sequences in Table 2 below."

				Table 1
		FUNCTIONS AND PROPERTIES OF BASIC PDP-1 LISP

	atom
	car		returns the first item in the argument list.
	cdr		returns all but the first item in the argument list.
	cond x y...	successively evaluates predicates x, y, etc until
			a true predicate is found; returns the value of
			the predicate.
	CONS x y..	returns the concatenation of its argument list.
	eq x y		returns true if x and y are the same, otherwise nil.
			x and y can be atoms or numbers.
	eval x		evaluates a list and returns its value.
	gensym		returns a unique generated atom gnnnnnn.
	greaterp x y	returns true if x > y, otherwise nil.
	go
	list
	loc x		gives the machine register in which the atom
			or list x begins; its value is the location.
	logand x y...	returns the logically and of the argument list.
	logor x y...	returns the logical or of the argument list.
	minus x		returns the one's complement of the argument.
	null x		returns t if the argument is nil or empty, otherwise t.
	numberp x	returns t if the argument is a number, otherwise nil.
	plus x y...	returns the sum of the argument list.
	prin1 x		prints the atom x without the extra space at the
			end.  Its value is nil.
	print
	prog
	quote
	quotient x y	returns x divided by y.
	read
	return
	rplaca
	rplacd
	sassoc
	setq
	stop x		halts the computer with x in the accumulator.
	terpri		prints a carriage return.
	times x y...	returns the product of the argument list
	xeq c a i	executes the machine language instruction c, with a
			in the accumulator and i in the in-out register; and
			returns a value in the form of (a i P) where a is the
			new value of the accumulator after execution, i is
			the new value of the in-out register after execution,
			and P is t if the instruction skipped, and nil if the
			instruction did not skip.

PDP-1 LISP has the following permanent objects.

	oblist		the current list of atomic symbols.
	nil		false value
	t		true value
	expr
	subr
	fexpr
	fsubr
	apval

				Table 2
			SUGGESTED TEST SEQUENCES

	input					response
	-----					--------

	(car (quote (a b c d)))			a

	(cdr (quote (a b c d)))			(b c d)

	oblist					The interpreter will type out
						a complete list of the atomic
						symbols stored within it.

	(list (quote (a b c d)))		((a b c d))

	nil					nil

	(cdr nil)				(apval nil)

	(car (quote (t.nil)))			t

	(cons (atom (cdr t))(list		(nil g000001 g000002)
		(gensym)(gensym)))

	(cond ((eq t nil) (stop 1))		t
		(t (eq (plus 1 1) 2)))

	(prog (u) (print nil)(terpri)		nil
		(print t)(setq u t)		t
		(return u))			t

	(rplacd (quote caar)(quote		caar
		(expr (lambda (x) (car
		(car x))))))

	(caar (quote ((a))))			a

	(stop 2)				The computer stops and puts
						2 in the accumulator.

	(prin1 (quote car))			car, with no punctuation before
						or after; the value of PRIN1 is
						nil.

	(print u)				Prints out the value of u; the
						value of (print u) is u.

	(terpri)				Prints a carriage return; the
						value of (terpri) is nil.

	(loc nil)				This is the register where the
						nil atom starts.

	(loc (quote cond))			This is the register where the
						cond atom starts.

	(logand 6 7 3)				2

	(logor 12 3 15)				17

	(rplaca (quote (nil x y))		((a b) x y)
		(quote (a b)))


4. Provenance Of The Source

The sources to PDP-1 LISP were published in their entirety in the book "The
Programming Language LISP: Its Operation and Applications" by Edmund C.
Berkeley and Daniel G. Bobrow, 1964.  Gordon Greene typed the sources in by
hand, assembled them, and then published the assembly listing on the Internet.
The source used here results from a line by line comparison of the Internet
source with the published source.  Corrections to the Internet source are
noted by /** in the comments field.

The assembler is derived from a PDP-8 assembler written by Gary A. Messenbrink
which I modified to support macros, then PDP-7 code, and finally PDP-1 code.
Paul McJones supplied the LISP book and original listings.  Brian Silverman
at MIT provided help on the functions of the PDP-1 macro assembler.
