Artifact d18f7bbc1c801de658b9aa020b19530707dad8284926e6d60490bdb0caf2a342:
- File
r30/lisp.mac
— part of check-in
[eb17ceb7f6]
at
2020-04-21 19:40:01
on branch master
— Add Reduce 3.0 to the historical section of the archive, and some more
files relating to version sof PSL from the early 1980s. Thanks are due to
Paul McJones and Nelson Beebe for these, as well as to all the original
authors.git-svn-id: https://svn.code.sf.net/p/reduce-algebra/code/historical@5328 2bfe0521-f11c-4a00-b80e-6202646ff360 (user: arthurcnorman@users.sourceforge.net, size: 197474) [annotate] [blame] [check-ins using] [more...]
;LISP.MAC, 9-Apr-81 21:51, Edit by FRICK ; ;NUMVAL redefined. It now gives error if given anything but INUM or FIXNUM. ;LISP.MAC, 26-Sep-80 10:44, Edit by FRICK ; ;%FSLID defined as support for PRELOAD facility. ;LISP.MAC, 25-Aug-80 12:06, Edit by FRICK ; ;Make ^Z comments work inside other comments. ;Corrected bug in initial dialogue. SYLO+1 is CAILE C,"z" instead ; of CAIG C,"z" ;<FRICK>LISP.MAC.28, 22-Nov-79 15:31:17, Edit by FRICK ; ;Define ERJMP for Tenex. Don't include RSCAN for Tenex. ;<FRICK>LISP.MAC.27, 21-Nov-79 11:21:50, Edit by FRICK ; ;Corrected bug in FUNARG. APFNG+6 is MOVN R,APFNG1 instead of HRRZ R,APFNG1. ;<FRICK>LISP.MAC.26, 13-Nov-79 19:48:53, Edit by FRICK ; ;Convert lower case to upper case on answer to start up questions ;<FRICK>LISP.MAC.24, 11-Nov-79 16:46:11, Edit by FRICK ; ;REMD now returns NIL or the removed type . function, as in Standard Lisp. ;Corrected bug in errormessage for index error in GETV, PUTV. ;PROG2 is again a defined function. ;<FRICK>LISP.MAC.20, 8-Nov-79 19:33:42, Edit by FRICK ; ;Added code for new FASLOD. Switches OFLD and NFLD controls assembling ; of new FASLOD and old FASLOAD. Both might be on at the same time. ;<FRICK>LISP.MAC.3, 1-Nov-79 16:26:25, Edit by FRICK ; ;For high core BPS in Tops-10 now computes start of high core. ; ;Fix bug in XEQ by guaranteeing 0 at end of RSCAN string. ;<FRICK>LISP.MAC.1, 28-Oct-79 16:06:56, Edit by FRICK ; ;An atom as first argument to FILEP means a filename for a file on DSK: ; with blank extension. ; ;XEQnow clears the terminal input buffer before simulating terminal ; input. ;<FRICK>LISP.MAC.4, 26-Oct-79 12:32:56, Edit by FRICK ; ;The charcters "+", "-" and "'" are now preceded by a "!" in PRIN1 and ; EXPLODE. ;<FRICK>LISP.MAC.2, 9-Oct-79 12:59:52, Edit by FRICK ; ;EOF is now signaled by returning the value of the interned id $EOF$. ;This value is originally the uninterned id $EOF$, but it can be ; changed. ; ;Cange of edit of 27-Mar-79. TYI (and READCH) now ignores null. ;<FRICK>LISP.MAC.16, 12-Sep-79 13:07:31, Edit by FRICK ; ;READ does now read negative bignums without dropping the minus sign ; ;When using high core in Tops-10, preserves high core data area. ;<FRICK>LISP.MAC.12, 16-Aug-79 16:13:29, Edit by FRICK ; ;BPS in high core now allowed also in Tops-10. ;Assembler switch SZBPS decides whether size of BPS is user settable. ;SZBPS is allways on if HCBPS is off. EXCORE only defined when SZBPS is ;on. ; ;Function EVLIS now defined. ;<FRICK>LISP.MAC.29, 2-Jul-79 15:11:01, Edit by FRICK ; ;Corrected bug in EQUAL so that EQUAL may return T for vectors. ;<FRICK>LISP.MAC.26, 15-Jun-79 19:08:49, Edit by FRICK ; ;The UUO handler changed to allow UUOs to be executed via a XCT. ;The MAPping functions have been changed to use this. ;<FRICK>LISP.MAC.19, 9-Jun-79 13:39:56, Edit by FRICK ; ;Included "T" and "?" in IDCHTAB. ;<FRICK>LISP.MAC.16, 29-May-79 18:40:20, Edit by FRICK ; ;Corrected error at XTYO so that character count now is reset at CR when ; echoing and TYO treats ascii 37 correctly. ;<FRICK>LISP.MAC.12, 23-May-79 23:07:49, Edit by FRICK ; ;The assembler switch APPL is defined. When on (off by default), EVAL ; return its arg when undefined function or unbound variable. ;<FRICK>LISP.MAC.11, 21-May-79 10:22:03, Edit by FRICK ; ;%SOSSWAP is now under assembler switch SOSSW that is off by default ;<FRICK>LISP.MAC.9, 17-May-79 15:29:09, Edit by FRICK ; ;%SOSSWAP and %SWAP only defined if OPSYS is > 0 (TENEX) ; ;If switch JSYXEQ is on then functions JSYS, %XEQ, ERRSTR and GETAB$ are defined ;<FRICK>LISP.MAC.7, 10-May-79 14:43:10, Edit by FRICK ; ;EOL conversion is now only done on input, not in READ0 routine used by ; COMPRESS or internal string reader READP1. ;The EOL conversion has further been changed so that CR, LF and FF are ; converted as follows: ; a CR is ignored if the next character is LF, FF or CRLF, ; a LF is converted to CRLF, ; a FF is converted to CRLF followed by FF. ;<FRICK>LISP.MAC.3, 4-May-79 18:12:32, Edit by FRICK ; ;Change unsafe BLT in ARGPDL ;<FRICK>LISP.MAC.16, 17-Apr-79 13:52:39, Edit by FRICK ;Call GET jsys as JSYS 200 to avoid name clash. Use SAV or EXE depending ; on OPSYS switch. ;<FRICK>LISP.MAC.15, 9-Apr-79 13:48:00, Edit by FRICK ; ;Removed <ht> in macro ML1 that gives problems in older MACRO versions ;<FRICK>LISP.MAC.14, 1-Apr-79 16:15:23, Edit by FRICK ; ;This file has been renumbered. ;<FRICK>LISP.MAC.13, 29-Mar-79 15:14:41, Edit by FRICK ; ;If the argument to FREEZE is true then the special stack is unbound ; to top level before halting. FREEZE checks if memory allocation is ; necessary when restarting if the argument is true. ;<FRICK>LISP.MAC.12, 27-Mar-79 18:00:20, Edit by FRICK ; ;The TYI routine now reads all characters exept ^Z but including % and ; null. This means that READCH reads % and null. ;<FRICK>LISP.MAC.5, 13-Mar-79 17:37:43, Edit by FRICK ; ;RDSLSH now knows about %. (RDSLSH T) sets % to be a normal letter, ; (RDSLSH NIL) sets % to be comment start. ;<FRICK>LISP.MAC.4, 12-Mar-79 16:31:30, Edit by FRICK ; ;Corrected bug in sixbit messages generated by prevoious edit, now ; generates EOL output again. ; ;*ECHO flag is now tested before *RAISE flag so that the status of ; *RAISE doesn't affect the echoed character. ; ;Corrected bug in MAPCAN, MAPCON: They now work also when NIL is ; returned as value by the applied function. ;<FRICK>LISP.MAC.26, 13-Feb-79 15:25:31, Edit by FRICK ; ;The character strings CR LF and CR FF are now replaced with the single ; character CRLF (ascii 37) in the routine TYID that does all input. ;CRLF is converted back to CR and LF in the internal routine TYO that ; does all output. The only exeption to this is the Lisp function TYO, ; (TYO 37) still will output a ascii 37. ;$EOL$ has as value the character id CRLF, so that READCH now returns ; the value of $EOL$ at end of line and PRINC $EOL$ is equivalent to ; TERPRI. ;SCAN now returns an interned character id in SCNVAL when seeing a ; delimiter. Because of this, UNTYI is replaced with UNREADCH that is ; similar but takes a character id as argument instead of ascii code. ; ;% now indicates start of a comment that ends with CRLF. Everything from ; % to (but not including) CRLF will be transparent to READ but not to ; READCH. SCAN has initially the same start and end of comment as READ ; and it will also not ignore the comment end character. As a consequence ; a comment can only be placed where a CRLF is legal. The special ; comment that starts with a ^Z and ends with CRLF does ignore the CRLF ; so that it can be placed anywhere. ; ;(AND) returns T. ;<FRICK>LISP.MAC.6, 31-Jan-79 14:03:36, Edit by FRICK ; ;READCH and EXPLODE are speeded up by maintaining an array of all ; interned character ids. This array is initially zero, but it is ; updated by INTERN and REMOB. ;<FRICK>LISP.MAC.4, 29-Jan-79 17:37:09, Edit by FRICK ; ;EXPLODE, READ (and COMPRESS) checks that they have the right scanner ; table and temporarily switches table if necessary. If an error occurs, ; this will leave the tables as if (SCANSET NIL) had been executed. ;<FRICK>LISP.MAC.1, 25-Jan-79 14:41:23, Edit by FRICK ; ;Corrected bug in EVAL when calling compiled EXPR with more than 5 args. ;<FRICK>LISP.MAC.13, 3-Jan-79 17:48:17, Edit by FRICK ; ;The use of L as indicator of octal numbers is now controlled by the ; switch ROCT. If ROCT is on then the change in edit of 26-Nov-78 is ; implemented, otherwise it is not. ; ;The symbol ILLAD is defined as the illegal address that generates a garbage ; collection. Setting it to 775777 (-2001) instead of 777777 (-1) seems to ; allewiate the problems mentioned in edit 25-Oct-78. For this reason ; CNSPRB is off by default in all versions of the system. ; ;The ^Z that indicates an ignored cr-lf is now not output if output is ; going to the terminal. ; ;The HALT that ended FREEZE in the Tops-10 version, is changed to EXIT 1, . ;<FRICK>LISP.MAC.7, 26-Nov-78 19:55:50, Edit by FRICK ; ;A number ended by the letter L, is read as an octal number also when ; the value of IBASE is not 8. When the value of BASE is 8, then end ; integers whith L when printed by PRIN1 but not when printed by PRIN2. ;<FRICK>LISP.MAC.1, 8-Nov-78 18:59:12, Edit by FRICK ; ;An atom as first argument to OPEN means a filename for a file on DSK: ; with blank extension. ;<FRICK>LISP.MAC.29, 3-Nov-78 17:15:24, Edit by FRICK ; ;Define SYM entry LMKSTR to make a Lisp string from top of SPDL ;<FRICK>LISP.MAC.28, 1-Nov-78 18:11:11, Edit by FRICK ; ;Make SETPCHAR return previous prompter as a non-interned identifier ;<FRICK>LISP.MAC.25, 25-Oct-78 19:10:13, Edit by FRICK ; ;Define an assembler switch CNSPRB, that when on will insert two instructions ; in the cons routine. These instructions will check explicitly for end ; of the free list instead of detecting the need for garbage collection ; by an illegal memory reference that occurs when the free list is empty. ; Explicit checking is slightly slower, but there seems to be some problems ; with the illegal memory reference mechanism on some virtual memory ; versions of the Tops-10 monitor. ;<FRICK>LISP.MAC.24, 26-Sep-78 16:38:51, Edit by FRICK ; ;Garbage collector now marks from reg REL also. ;<FRICK.SLSHEEP>LISP.MAC.2, 24-Sep-78 16:38:49, Edit by FRICK ; ;Declare some more symbols internal. ;<FRICK>LISP.MAC.17, 18-Sep-78 19:22:04, Edit by FRICK ; ;Fix bug in GCGAG output, so that it works also when number of cells ; collected are more than an INUM. ;<FRICK>LISP.MAC.11, 3-Sep-78 17:11:44, Edit by FRICK ; ;LINELENGTH now checks that its argument is NIL or greater than 0. ;PAGELENGTH now checks that its argument is NIL or greater than or equal to 0. ; ;DIGIT and LITER now returns NIL if their argument is not an ; interned id with a one character print name. ;<FRICK>LISP.MAC.7, 27-Aug-78 15:44:35, Edit by FRICK ; ;The ERROR print routine (also used by WARNING) doesn't relay any ;more on register T being saved. The stack is used instead. ;<FRICK>LISP.MAC.6, 24-Aug-78 16:53:44, Edit by FRICK ;(EQUAL 1 1.0) now returns NIL instead of T. ; ;The first argument to REMFLAG is a list whose elements now not ; have to be ids. REMFLAG does nothing for those that aren't ids. ; ;SUBR and FSUBR are now completely replaced by EXPR and FEXPR. ;For compatibility reason FASLOD will convert (F)SUBR to (F)EXPR and ;give a message about it the end of each load. ; ;Digits in DIGIT, EXPLODE and READCH are now character ids, not INUMs. ; ;The initialization file LISP.LSP is renamed to LISP.SL. ;<FRICK>LISP.MAC.2, 20-Aug-78 18:10:26, Edit by FRICK ; ;Make PATOM available as a SUBR. ;<FRICK>LISP.MAC.254, 1-Aug-78 17:49:50, Edit by FRICK ; ;Define Fasload type 11 to be similar to 13 but the codepointer ; is put on the property list with PUT instead of PUTD. ;<FRICK>LISP.MAC.252, 27-Jul-78 18:53:43, Edit by FRICK ; ;Make ERREx print the left half of register A if it isn't 0. ;This involves a change to PRINL also. ;Make a small change to PRINEL and remove PRIN1B that now is unnecessary. ;<FRICK>LISP.MAC.250, 25-Jul-78 23:52:04, Edit by FRICK ; ;Include this list of changes and renumber pages. ;<FRICK>LISP.MAC.245, 22-Jul-78 19:46:45, Edit by FRICK ; ;Set *ERRMSG to T on toplevel only if it is NIL. ; ;Make the OP routine (i.e. all binary numerical routines) check ;first that the arguments are numbers so that the error message ;"x IS NOT A NUMBER" gets the right "x". ; ;The garbage collector now also marks from the top element of ;the SPDL. ;<FRICK>LISP.MAC.238, 14-Jul-78 13:50:27, Edit by FRICK ; ;RETURN and GO now works in other than the last statement in ;a PROGN. ; ;SKIPTO now initialize register AR4 so that it doesn't think ;everything is EDIT or SOS line numbers. ;<FRICK>LISP.MAC.237, 10-Jul-78 01:21:58, Edit by FRICK SUBTTL HISTORY OF CHANGES --- PAGE 1 ; ;COPYRIGHT (C) 1979 University of Utah. ; ;Permission to copy without fee all or part of this material is granted ;provided that copies are not made or distributed for direct commercial ;advantage, the Utah copyright notice and the title of the program and ;its date appear, and notice is given that copying is by permission of ;the University of Utah. To copy otherwise, or to republish, requires a ;fee and/or specific permission. ; SUBTTL AC DEFINITIONS AND EXTERNALS --- PAGE 2 TITLE LISP INTERPRETER COMMENT TABLE OF CONTENTS 1. History of changes 2. Assembling switches, AC Definitions, Symbols and Externals 3. Top Level and Initialization 4. APR Interrupt routines 5. UUO Handler and SUBR-call routines 6. ERROR Handler and Backtrace 7. TYI and TYO 8. INPUT and OUTPUT initialization and control 9. PRINT 10. READ and SCANner tables 11. Interpretive routines of LISP 12. Arithmetic routines 13. Bignum routines 14. Gfpak. Galois field package 15. EXPLODE, READLIST, FLATSIZE, etc. 16. EVAL and APPLY and bindings 17. ARRAY, EXARRAY, STORE 18. EXAMINE, DEPOSIT, BOOLE 19. Garbage Collector 20. GETSYM, PUTSYM and R50MAK 21. FASLOAD, FASLOD 22. ED - Alvine LOAD EXCISE, MORCOR, MOVSYM, etc. 23. FILEP SOSSWAP JSYS, GETAB#, XEQ 24. RBLK, WBLK 25. CORE, ALLOC 26. SETSYS, LSSAVE 27. Re-allocate code after a ST REHASH 28. Lisp atoms and initial OBLIST BPS, FS, FWS 29. Once-only Lisp Storage Allocator PAGE COMMENT General differences from Stanford's 1.6 are: 1) Octal ppns, 2) Explicit i/o for SOS-linkage, 3) The '*' prompt-char can be dynamically changed, to consist of up to 4 characters; 4) The subr CORE(n) is used to increase (or partially cut) core; 5) The subr ALLOC() just goes to LISPGO to alloc new core; 6) Altmode can be typed as 33 or 175. 7) Binary-I/O (36-bit) by INBIN,OUTBIN,BINI,BINO. 8) BPS & EXAMINE,DEPOSIT may address to 256K, vs old 64K limit. 9) RBLK,WBLK can manipulate overlay-blocks in BPS as files. Assembles for TOPS-20, TENEX or TOPS-10, operating systems depending on the setting of the variable OPSYS. N.B. Code for TENEX and TOPS-20 in CHKACS, CHKAC0, SETAPR makes assumptions about PA1050's acc and ^O handler locations. OPSYS is set here ;OPSYS==0 ;Assembles for TOPS-10. ;OPSYS==1 ;Assembles for TENEX OPSYS==-1 ;Assembles for TOPS-20. IFNDEF OPSYS,<OPSYS==-1> ;TOPS-20 is default ;When OPSYS not is zero, this has the following effects: ; 1) The 10x psi is enabled for 10/50 ^O (simulated); ; 2) The swapout for the SOS-link is done as an inferior fork, ; which returns to LISPGO, unless using LISP.TNX patchs. ; 3) The initial start-up questions are slightly changed. ;SYDEV==1 ;When on has the following effects: ; 1) An initial question for system device or directory ; to use as SYS: device: ; For TENEX version asks for system directory number ; (default: number for <REDUCE>, or if that not ; exists, the users directory). ; For TOPS-10 or -20 version asks for system device ; name (default: SYS: ). ; 2) The subr SETSYS is used to dynamically change SYS: . ;CNSPRB==1 ;When on, will check explicitly for the end of the free list, ; instead of detecting it by an illegal memory reference. ;STL==0 ;When on, will assemble for Standard Lisp ;OCTPPN==0 ;When off, will assemble for SU-AI's PPNs. MOD==1 ;When on, will assemble GFPAK modular arithmetics ;ALOD==1 ;When on will assemble LOAD, *PUTSYM and *GETSYM. ;AED==1 ;When on will assemble ED and GRINDEF interface. ;NFLD==0 ;When off dont assemble new FASLOD OFLD==1 ;When on, assemble old FASLOAD ;RWB==1 ;When on will assemble WBLK and RBLK. ;ASARY==1 ;When on will assemble array routines EPDL==0 ;When on, will create a 3rd pdl pointed to by EP ;FNRG==0 ;When on, will assemble funarg features ;HCBPS==1 ;When on puts BPS in high core ;SZBPS==1 ;When on, size of BPS is user decidable, and EXCORE defined. ;ROCT==1 ;When on will read an integer followed by L as octal ;JSYXEQ==0 ;When off, will not define JSYS, %XEQ, ERRSTR and GETAB$ ;SOSSW==1 ;When on assembles %SOSSWAP, used by SOSLINK ;APPL==1 ;When on, EVAL returns arg when undefined PAGE ;Default values for switches IFE OPSYS,<IFNDEF HCBPS,HCBPS==0 ;(Default low core for 10/50) IFNDEF SZBPS,SZBPS==1 IF1,PRINTX Note: being assembled for TOPS-10, not TENEX or TOPS-20. SEARCH UUOSYM JSYXEQ==0 ; JSYSes not defined in TOPS-10 IFNDEF OCTPPN,< OCTPPN==1 IF1,PRINTX Note: if for SU-AI, reassemble with OCTPPN==0 >> IFN OPSYS,<IFNDEF HCBPS,HCBPS==1 ;(Default high core 400000:676776) IFNDEF SZBPS,SZBPS==0 OCTPPN==1 > ;Permit (0,nnn) format if desired. IFL OPSYS,<SEARCH MONSYM IF1,PRINTX Note: being assembled for TOPS-20, not TENEX or TOPS-10. > IFG OPSYS,<SEARCH STENEX OPDEF ERJMP [JUMP 16,] IF1,PRINTX Note: being assembled for TENEX, not TOPS-10 or TOPS-20. > IFNDEF STL,<STL==1> IFN STL,< IFNDEF AED,AED==0 IFNDEF ALOD,ALOD==0 IFNDEF RWB,RWB==0 IFNDEF ASARY,ASARY==0> IFNDEF SYDEV,<SYDEV==1> ;Default: SYDEV is on. IFNDEF CNSPRB,<CNSPRB==0> IFNDEF MOD,<MOD==0> IFNDEF ALOD,<ALOD==1> IFNDEF AED,<AED==1> IFNDEF RWB,<RWB==1> IFNDEF ASARY,<ASARY==1> IFNDEF NFLD,<NFLD==1> IFNDEF OFLD,<OFLD==0> IFNDEF EPDL,<EPDL==0> IFNDEF APPL,<APPL==0> IFNDEF FNRG,<FNRG==1> IFNDEF HCBPS,HCBPS==1 IFNDEF SZBPS,SZBPS==1 IFE HCBPS,SZBPS==1 IFNDEF ROCT,<ROCT==0> IFNDEF JSYXEQ,<JSYXEQ==1> IFNDEF SOSSW,<SOSSW==0> PAGE TEN==^D10 INUMIN=377777 ;Lower limit of INUMs. BCKETS==77 INITBPS== 2000 ;Initial (default) size of BPS. INITCORE==^D12*2000-1 ;Initial (default) size of Lisp core . MAXCORE==^D124 ;Maximum size of Lisp core, to allow for I/O buffers. MINFBPS==1000 ;Necessary BPS for Fap bootstrap fisltable BOTBPS==1320 ;Necessary BPS for Fap loaded functions ILLAD==775777 ;Illegal address to generate interrupt when free list exhausted. ;Atom type tags ID=1000000-1 ;identifier CODE=ID-1 ;code pointer CODMIN==CODE VECT=CODE-1 ;vector STRNG=VECT-1 ;string FLONU=STRNG-1 ;floating point number FIXNU=FLONU-1 ;single word integer POSNU=FIXNU-1 ;positive bignum. Must be odd NEGNU=POSNU-1 ;negative bignum ATMIN=NEGNU-1 ;addresses bigger than this, are atom tags. INUM0=1+<INUMIN+ATMIN>/2 IFN <ATMIN+INUMIN-2*INUM0>,<INUMIN=INUMIN+1> DEFINE PR%%IN (XX)< PRINTX Maximum INUM modulus is XX > IF1,<XX==ATMIN-INUM0 PR%%IN \XX > PAGE ;Accumulator definitions ;'sacred' means sacred to the interpreter ;'marked' means marked from right and left half by the garbage collector ;'protected' means protected during garbage collection NIL=0 ;sacred, marked, protected ;atom head of NIL A=1 ;marked, protected ;results of functions and first arg of subrs B=A+1 ;marked, protected ;second arg of subrs C=B+1 ;marked, protected ;third arg of subrs AR4=4 ;marked, protected ;fourth arg of subrs (old AR1) AR5=5 ;marked, protected ;fifth arg of subrs (old AR2A) T=6 ;marked, protected ;minus number of args internaly TT=7 ;marked, protected REL=10 ;marked, protected ;rarely used IFE EPDL,< EP==14 S=11 > IFN EPDL,< S==11 EP=11 ;sacred, protected ;exp push down stack pointer > D=12 R=13 ; protected P=14 ;sacred, protected ;regular push down stack pointer F=15 ;sacred ;free storage list pointer FF=16 ;sacred ;full word list pointer SP=17 ;sacred, protected ;special pushdown stack pointer NACS==5 ;number of argument acs NSUA==16 ;maximum number of subr arguments X==0 ;X indicates impure (modified) code locations ; Added Inst-definitions for legibility... OPDEF PCALL [PUSHJ P,] OPDEF PRET [POPJ P,] OPDEF PSAVE [PUSH P,] OPDEF PREST [POP P,] OPDEF PSKPRT [AOS (P)] OPDEF P1DROP [SUB P,[1,,1]] OPDEF P2DROP [SUB P,[2,,2]] OPDEF P3DROP [SUB P,[3,,3]] OPDEF PXDROP [SUB P,] OPDEF CARA [HLRZ ] OPDEF CDRA [HRRZ ] OPDEF RPLCA [HRLM ] OPDEF RPLCD [HRRM ] PAGE ;UUO definitions ;UUOs used to call functions from compiled code ;the number of arguments is given by the ac field ;the address is a pointer either to the function ;name or the code of the function OPDEF FCALL [34B8] ;ordinary function call-may be changed to PCALL OPDEF JCALL [35B8] ;terminal function call-may be changed to JRST OPDEF CALLF [36B8] ;like FCALL but may not be changed to PCALL OPDEF JCALLF [37B8] ;like JCALL but may not be changed to JRST ;error UUOs UOERRE==1 UOERRL==10 UOERRG==20 UOERRI==21 USTRTP==22 ;ERRL and ERRE spans more than one UUO, to allow for larger ac-field ;Ac-field contains error number. OPDEF ERRE1 [1B8] ; 1 ;print expression, ordinary lisp error, bactrace OPDEF ERRE2 [2B8] ; 2 OPDEF ERRE3 [3B8] ; 3 OPDEF ERRE4 [4B8] ; 4 OPDEF ERRE5 [5B8] ; 5 OPDEF ERRE6 [6B8] ; 6 OPDEF ERRE7 [7B8] ; 7 OPDEF ERRL0 [10B8] ; 8 ;ordinary lisp error ;gives backtrace OPDEF ERRL1 [11B8] ; 9 OPDEF ERRL2 [12B8] ; 10 OPDEF ERRL3 [13B8] ; 11 OPDEF ERRL4 [14B8] ; 12 OPDEF ERRL5 [15B8] ; 13 OPDEF ERRL6 [16B8] ; 14 OPDEF ERRL7 [17B8] ; 15 OPDEF ERRG [20B8] ; 16 ;space overflow error ;no backtrace OPDEF ERRI [21B8] ; 17 ;ill. mem. ref. OPDEF STRTIP [22B8] ; 18 ;print error message and continue PAGE ;system UUOs OPDEF TTYUUO [51B8] OPDEF INCHRW [TTYUUO 0,] OPDEF OUTCHR [TTYUUO 1,] OPDEF OUTSTR [TTYUUO 3,] OPDEF INCHWL [TTYUUO 4,] OPDEF INCHSL [TTYUUO 5,] OPDEF CLRBFI [TTYUUO 11,] OPDEF SKPINC [TTYUUO 13,] OPDEF TALK [PCALL TTYCLR] ;this is to turn off control O. ;when ttyser lets you do this ;easily, change me ;system uuos DEVCHR==4 CORE==11 RESET==0 APRINI==16 MSTIME==23 STIME==27 SETUWP==36 PAGE ;I/O bits and constants LNPRVT==6 ;lines per vertical tab TTYPL==0 ;teletype pagelength. No paging LPTPL==0 ;line printer pagelength. No paging TTYLL==105 ;teletype linelength LPTLL==160 ;line printer linelength MLIOB==203 ;max length of I/O buffer NIOB==2 ;no of I/O buffers per device NIOCH==17 ;number of I/O channels FSTCH==1 ;first I/O channel TTCH==0 ;teletype I/O channel BLKSIZE==NIOB*MLIOB+COUNT+1 INB==2 OUTB==1 AVLB==40 DIRB==4 ;special ASCII characters ALTMOD==175 ;LISP'S ALTMODE (TENEX-PA1050 & SU-AI) 33'S CONVERTED. IGCRLF==32 ;ignored cr-lf RUBOUT==177 CRLF==37 ;TYID converts the sequence CR LF or CR FORMF to CRLF. TYO converts back. LF==12 CR==15 TAB==11 BELL==7 DBLQT==42 ;double quote " VT==13 ;vertical tab FORMF==14 ;form feed ;byte pointer field definitions ACFLD==^D12 ;ac field XFLD== ^D17 ;index field OPFLD==^D8 ;opcode field SIGN==400000 ;sign marker for bignums PAGE ;external and internal symbols EXTERNAL .JB41 ;instruction to be executed on UUO EXTERNAL .JBAPR ;address of APR interupt routines EXTERNAL .JBCNI ;interupt condition flags EXTERNAL .JBFF ;first location beyond program EXTERNAL .JBREL ;address of last legal instruction in core image EXTERNAL .JBREN ;reentry address EXTERNAL .JBSA ;starting address EXTERNAL .JBSYM ;address of symbol table EXTERNAL .JBTPC ;program counter at time of interupt EXTERNAL .JBUUO ;uuo is put here with effective address computed EXTERNAL .JBHRL ;RH= High-segment .JBREL, LH set 0. ;apr flags PDOV==200000 ;push down list overflow MPV==20000 ;memory protection violation NXM==10000 ;non-existant memory referenced APRFLG==PDOV+MPV+NXM ;any of the above ;foolst macros: these get relocated (RH addr) relative to FS. DEFINE FOO < XLIST BAZ (\FOOCNT) LIST > DEFINE BAZ (X) <FOOCNT=FOOCNT+1 FOO'X:! SUPPRESS FOO'X > FOOCNT=0 SUBTTL TOP LEVEL AND INITIALIZATION --- PAGE 3 LISPGO: SETOM RETFLG# ;enter via INITFN JRST STRT ;go to re-allocator DEBUGO: SETZM RETFLG ;clear return flag to allow INITFN to be changed JSR CHKACS ;entry point to get into read-eval-print loop JUMPN A,LSPRT2 ; without unbinding spec pdl... ;If NIL looks like an atomheader, we skip ; reseting the ACCs, etc, else refresh... START: CALLI RESET ;Initializations for lisp interrupts... JSR APRSET ;Set up APRs and Tenex ^chars. JSR CHKAC0 ;Reset NIL if necessary, else retain any user additions. IFN AED,SETZM PSAV1 FOO SETZB 1,VERMSG MOVE 17,[1,,2] BLT 17,17 ;clear acs, other than NIL. MOVEI F,ILLAD ;empty fs list LSPRT1: MOVE P,C2# ;Initialize regular PDL. IFN EPDL,MOVE EP,EC2# ;initialize EPDL SKIPE SP,SPSAV# PCALL TUNBIND ;Unbind spec pdl to top MOVE SP,SC2# ;Initialize special PDL. PUSH SP,[0] ;mark for unbind FOO MOVEI B,TRUTH FOO SKIPN ERRSW ;only change if NIL FOO MOVEM B,ERRSW ;print error messages SETZM ERRTN ;return to top level on errors SETOM PRVCNT# ;initialize counter for errio IFN OPSYS,SETZM KBINTF SETZM EXARG ;Delete content of MOVE A,[EXARG,,EXARG+1] ; extended ascs to BLT A,EXARG+NSUA-NACS-1 ; allow gc LSPRT2: PCALL TTYRET ;Return output for gc msg. JSR CHKNIL ;initialize nil SKIPE HASHFG# JRST REHASH ;rehash if necessary SKIPN FF PCALL AGC2 ;garbage collect only if necessary SETZM GCFFLG# SKIPN BSFLG# ;initial bootstrap for macros JRST BOOTS SKIPE BPSFLG# JRST BINER2 ;BPS OVERFLOW DURING A (LOAD T). SKIPN RETFLG ;test for error return JRST LISP2 FOO SKIPE A,INITF CALLF 0,(A) ;evaluate initialization function SETZM RETFLG LISP2: PCALL TTYRET ;return all i/o to tty PCALL TERPRI SKIPE GOBF# ;garbaged oblist flag STRTIP [SIXBIT /_***** GARBAGED OBLIST_!/] SETZM GOBF LISP1: PCALL READ ;this is the top level of lisp PCALL EVAL PCALL TERPRI PCALL PRINT PCALL TERPRI JRST LISP1 PAGE ;return from lisp error LSPRE: CLRBFI ;clear input buffer FOO SKIPE RSTSW JRST LISP2 ;(*rset t) goes to read-eval-print loop without unbind LSPRET: MOVE P,C2 ;return from bell PCALL TERPRI IFN AED,<SKIPE P,PSAV1# ;bell from alvine? JRST [HRRZ REL,ED ;yes, return to alvine JRST 1(REL)]> ;improved magic MOVEM SP,SPSAV ;force unbinding of spec pdl SETOM RETFLG ;set return flag JRST LSPRT1 ;bootstrapper for macro definitions & Lisp extensions... BOOTS: SETOM BSFLG MOVEI A,BSTYI PCALL READP1 PCALL EVAL PCALL READ ;last prog calls ERR, back to LISP1. JRST .-2 BSTYI: ILDB A,[POINT 7,[ASCII /(RDS(OPEN '(SYS:(LISP.SL)) 'INPUT))/]] PRET PAGE ;Verify that NIL is a good atom, perhaps with user properties, ; else reset it (AC0) to be the Urlisp atomheader... IFN OPSYS,< CHKACS: X ;Tenex-Pa1050 needs to be clever about ^C's. CALLI A,MSTIME ;Do a simple op to ensure PA1050 exists. JSR CHKNIL JUMPN A,@CHKACS ;Didn't have to fix it, MOVE NIL,@700032 ; else check last ac0 saved in PA1050. JSR CHKNIL JUMPE A,@CHKACS ; Not ok either, have to refresh all accs. HRLZ 17,700032 ;Was ok, so grab the save-acc blk BLT 17,17 ; from PA1050's area. JRST CHKACS+2 ;Set ac1 non0 and return successfully. CHKAC0: X ;Setup 0 without worrying about 1:17. JSR CHKNIL JUMPN A,@CHKAC0 ;Tenex's was ok, MOVE NIL,@700032 JSR CHKNIL JRST @CHKAC0 > ; or PA1050's, else CNIL2 reset. CHKNIL: X ;Yet another impure loc, for JSRing. JSP TT,CHKNI1 JUMPN A,@CHKNIL ; o.k. MOVE NIL,CNIL3 ; refresh NIL MOVEI A,NIL ;Return 0 if have to reset... JRST @CHKNIL CHKNI1: HLRO A,NIL AOJN A,SETNIL ;LH not -1. CDRA A,NIL CAILE A,@GCPP1 ;(base of FS) CAIL A,@GCP1 ;(base of FWS) JRST SETNIL ; proplist addr not in FS. FOO MOVEI B,VALUE GETNIL: MOVS C,(A) ;Make sure it has a VALUE cell, MOVS A,(C) CAIN B,(A) ; else EVAL would say "#0 Unbound Variable". JRST GOTNIL CARA A,C JUMPN A,GETNIL JRST (TT) GOTNIL: HLRZS A ;We don't require this to be UrLisp's VNIL cell. SKIPE (A) ;Check that it points back to NIL tho, SETNIL: MOVEI A,NIL ; else reset it. JRST (TT) ;Return non0: didn't have to reset. IFE OPSYS,<CHKACS==CHKNIL ;Don't have to worry about separate CHKAC0==CHKNIL> ; PA1050 accs being present after a ^C. SUBTTL APR INTERRUPT ROUTINES --- PAGE 4 ;arithmetic processor interupts ;mem. protect. violation, nonex. mem. or pdl overflow APRINT: MOVEM R,ACSAV+R MOVE R,.JBCNI ;get interrupt bits SETZM .JBCNI ;Clear for compiled-code Pdl check: <JUMPGE P,@.JBAPR> TRNE R,MPV+NXM ;what kind JRST ILLMEM JUMPN NIL,MES21 ;a pdl overflow STRTIP [SIXBIT /_***** PDL OVERFLOW FROM GC - CAN'T CONTINUE!/] JRST START MES21: SETZM .JBUUO SKIPL P ERRG ^D256,[SIXBIT /REG PUSHDOWN CAPACITY EXCEEDED!/] SKIPL SP SPDLOV: ERRG ^D257,[SIXBIT /SPEC PUSHDOWN CAPACITY EXCEEDED!/] IFN EPDL,<SKIPL EP ERRG ^D258,[SIXBIT /EXP PUSHDOWN CAPACITY EXCEEDED!/] > TRNN R,PDOV HALT ;lisp should not be here BINER2: SETZM BPSFLG ERRG ^D259,[SIXBIT /BINARY PROGRAM SPACE EXCEEDED!/] ILLMEM: LDB R,[POINT 4,@.JBTPC,XFLD] ;get index field of bad word CAIN R,F ;is it F ? CAIE F,ILLAD ERRI 2,@.JBTPC ;no! error PSAVE .JBTPC ;yes! save return address MOVEI R,APRFLG CALLI R,APRINI ; reset interupt, MOVEI R,AGC1 JRSTF @R ; garbage collect and continue PAGE APRSET: 0 ;SET UP NECESSARY INTERRUPTS. MOVE A,[JSR UUOH] MOVEM A,.JB41 MOVEI A,APRINT MOVEM A,.JBAPR MOVEI A,APRFLG CALLI A,APRINI ;THIS DOES THE 10/50 SETUP. IFE OPSYS,< IFN HCBPS,< SETZ A, CALLI A,SETUWP ;Necessary as RESET resets high core write bit. HALT > JRST @APRSET> IFN OPSYS,< ; and for TENEX (Accs 1&2 are free): MOVEI 1,400000 ;FORK HANDLE FOR THIS FORK. RIR ;GET THE PA1050 FILE'S LEVTAB,,CHNTAB. IFG OPSYS,< MOVE 1,[XWD 1,CHANL0] EXCH 1,^D30(2) ;Set channel addresses... HRRZS 1 ; Normally would just use chn 0 for ^O CAIL 1,700000 ; but PA1050 also diddles on chn 30, HRRM 1,CHANL0 > ; so do local CHANL0 then PA1050's CFOBF. MOVE 1,[XWD 1,CHANL1] MOVEM 1,1(2) MOVE 1,[XWD 1,CHANL2] MOVEM 1,2(2) MOVE 1,[XWD 1,CHANL3] MOVEM 1,3(2) IFG OPSYS,< MOVE 1,["O"-100,,^D30];Set terminal-characters... ATI > MOVE 1,["P"-100,,1] ATI MOVE 1,["E"-100,,2] ATI MOVE 1,["K"-100,,3] ATI MOVEI 1,400000 IFG OPSYS,<MOVSI 2,(1B0+1B1+1B2+1B3)> IFL OPSYS,<MOVSI 2,(1B1+1B2+1B3)> AIC IFG OPSYS,SETZM CTRLOF# ;Init. SETZM KBINTF# ;Init. JRST @APRSET IFG OPSYS,< CHANL0: SETCMM CTRLOF ;Flip-flop the ^O flag. DEBRK > PAGE CHANL1: PSAVE 1 ; ^P HANDLER... PSAVE 2 ; Prints current file's <Line>/<Page>. PSAVE 3 MOVEI 1," " PBOUT SKIPG LINUM JRST [MOVM 2,LINUM PCALL IPNUM JRST .+3] HRROI 1,LINUM PSOUT MOVEI 1,"/" PBOUT MOVE 2,PGNUM PCALL IPNUM IFG OPSYS,MOVEI 1,37 IFL OPSYS,<MOVEI 1,CR PBOUT MOVEI 1,LF > PBOUT PREST 3 PREST 2 PREST 1 DEBRK IPNUM: MOVEI 1,101 ADDI 2,1 MOVEI 3,^D10 NOUT PRET PRET CHANL2: PSAVE 1 HRROI 1,[ASCIZ /^E /] PSOUT PREST 1 HLLOS KBINTF ;Flag RH -- next UUO becomes (ERR). DEBRK CHANL3: PSAVE 1 HRROI 1,[ASCIZ /^K /] PSOUT PREST 1 HRROS KBINTF ;Flag LH -- next UUO breaks out to top. DEBRK KBINTH: MOVE A,KBINTF ;Handle KB ^char now -- from UUOH, AGC, etc. SETZM KBINTF IFG OPSYS,SETZM CTRLOF TLNE A,-1 ;Which was it? JRST LSPRET ; ^K - escape to top-level. MOVEI A,NIL JRST ERR ; ^E - (ERR NIL) to ERRSET or top. > ;end of IFN OPSYS SUBTTL UUO HANDLER AND SUBR CALL ROUTINES --- PAGE 5 UUOH: X ;jsr location MOVEM T,TSV# MOVEM TT,TTSV# LDB T,[POINT 9,.JBUUO,OPFLD] ;get opcode CAIGE T,34 ;is it a function call? JRST ERROR ;or a LISP error? IFN OPSYS,< SKIPE KBINTF ;Has user hit ^Chars on KB? JRST KBINTH ; Yes, handle it. > HRRZ TT,UUOH SOSA TT MOVEI TT,@(TT) LDB T,[POINT 9,(TT),OPFLD] CAIN T,256 ;Is it XCT JRST .-3 HRRM TT,UUOCL-1 LDB T,[POINT 5,.JBUUO,ACFLD] TRZN T,20 PSAVE UUOH ;call|callf -- return addr. CARA R,@.JBUUO CAIE R,ID JRST UUOS ;if wasn't an id head, else... CAIE T,17 TDZA R,R MOVEI R,1 ;R=0 if T=0-16, else 1(17). CDRA T,@.JBUUO FOO MOVEI D,FUNCELL UUOH1: JUMPE T,UUOH3 MOVS TT,(T) MOVS T,(TT) CAIN D,(T) JRA T,UUOH2 CARA T,TT JRST UUOH1 PAGE UUOH2: CARA TT,T HRL T,.JBUUO ;name of function, for backtrace ;FOO CAIN TT,SUBR ; JRST @UUST(R) ;FOO CAIN TT,FSUBR ; JRST @UUFST(R) CARA D,(T) CAIE D,ID CAIGE D,CODMIN JRST .+2 SUBI R,4 ;its a subr or fsubr FOO CAIN TT,EXPR JRST @UUET(R) FOO CAIN TT,FEXPR JRST @UUFET(R) UUOH4: HRRZ A,.JBUUO ERRE1 ^D16,[SIXBIT /UNDEFINED UUO!/] ;e.g., a MACRO or no def. UUOH3: PSAVE A PSAVE B HRRZ A,.JBUUO FOO MOVEI B,VALUE PCALL GET JUMPE A,UUOH4 CDRA T,(A) HRL T,.JBUUO ;name of function, for backtrace PREST B PREST A JRST UUOEXP PAGE UUOSC: CDRA T,(T) UUOSBR: FOO SKIPE NOUUOF JRST UUOCL MOVE TT,.JBUUO HRLI T,(PCALL) TLNE TT,1000 ;1000 means no push HRLI T,(JRST) TLNN TT,2000 ;2000 means no clobber MOVEM T,X UUOCL: MOVE TT,TTSV MOVE R,T MOVE T,TSV JRST (R) UUOS: HRRZ T,.JBUUO ;If not an atomheader, what? CAIL R,CODMIN JRST UUOSC ; code pointer CAILE T,@GCPP1 ; Base of FS, CAIL T,@GCP1 ; FWS... JRST UUOSBR UUOEXP: PSAVE T ;<fn name or NIL,,func def> LDB T,ARGFLD JUMPE T,IAPPLY CAIN T,17 MOVEI T,1 MOVEI TT,IAPPLY SKIPA R,T ARGPDL: LDB R,ARGFLD ARGP1: HRLZ T,R ADD P,T JUMPGE P,MES21 ;check for stack overflow MOVEI T,1(P) HRLI T,A CAIG R,NACS JRST .+4 BLT T,NACS(P) MOVEI T,NACS+1(P) HRLI T,EXARG ADDI P,(R) BLT T,(P) MOVNI T,(R) JRST (TT) EXARG: BLOCK NSUA-NACS+1 ARGFLD: POINT 4,.JBUUO,ACFLD PAGE ;R=0 => compiler calling a - ;R=1 => compiler calling f type ;for an expr or fexpr that has a code pointer, 4 is subtracted ; from R, to map expr into subr and fexpr into fsubr UUST: UUOSC UUOS2 ;calling f (page 15 - EVAL). UUFST: UUOS9 ;calling - its a f UUOSC UUET: UUOEXP UUOS6 ;calling f its an expr (page 15 - EVAL). UUFET: UUOS3 ;calling - its a fexpr UUOEXP UUOSFE: HRRZ A,.JBUUO ERRE1 ^D17,[SIXBIT /CALLED AS EXPR!/] UUOS9: PSAVE T JSP TT,ARGPDL MOVEI TT,UUOCL QTLFY: MOVEI A,0 ;If AGC and GCGAG(T), can clobber QTLFY1: JUMPE T,(TT) ; .JBUUO and UUOH, so saved in GC. EXCH A,(P) PCALL QTIFY PREST B PCALL CONS AOJA T,QTLFY1 UUOS3: PSAVE T JSP TT,ARGPDL JSP TT,QTLFY JRST UUOS3I SUBTTL ERROR HANDLER AND BACKTRACE --- PAGE 6 ERRSUB: HRRZ A,.JBUUO ;Print SIXBITed messages (errors)... JUMPE A,CPOPJ HRLI A,(POINT 6,0) MOVEM A,ERRPTR# ERRORB: ILDB A,ERRPTR CAIN A,01 ;conversion from sixbit PRET CAIN A,77 HRREI A,CRLF-40 ADDI A,40 PCALL TYO JRST ERRORB WHEAD: PCALL ERRIO MOVEI B,3 JRST ERHED+2 ERHED: PCALL ERRIO MOVEI B,5 PCALL TERPRI MOVEI R,TYO XCT "*",CTY SOJG B,.-1 XCT " ",CTY PRET TOURET: PCALL TERPRI ;subroutine to return output to previously selected device OUTRET: SKIPL PRVCNT ;if prvcnt<0 then there was no device deselect SOSL PRVCNT ;when prvcnt goes negative, then reselect PRET PSAVE PRVSEL# ;previously selected output PREST TYOD PRET ;subroutine to force error messages out on tty ERRIO: FOO CDRA B,ERRSW CAIE B,INUM0 ;inum0 => print message on selected device AOSLE PRVCNT ;Deselected iff PRVCNT already <0. PRET TALK ;undo control o MOVE B,[JRST TTYO] EXCH B,TYOD MOVEM B,PRVSEL PRET ERRTN: 0 ;0 => top level * ;- => pdl to reset to - stored by errorset ;+ => string tyo pout rtn flag PAGE ;subroutine to search oblist for closest function to address in R ERSUB3: JSR CHKNIL ;Reset AC0 if need be. FOO MOVEI A,QST HRLZ B,INT1 MOVNS B SETZB AR5,GOBF CAIL R,STRT MOVEI AR5,STRT FOO CAIL R,FS MOVEI A,NIL PSAVE .JBAPR MOVEI C,[SETOM GOBF ;Intercept ill-mem-refs, flag JRST ERRO2G] ; "garbaged OBLIST" for LISP2. HRRM C,.JBAPR HLRZ C,@RHX5 ERRO2B: JUMPE C,[AOBJN B,.-1 PREST .JBAPR ;oblist done, restore JRST PRIN2D] ;print closest match CARA TT,(C) CDRA TT,(TT) JRST ERRO2C+1 ERRO2C: CARA TT,TT JUMPE TT,ERRO2G MOVS TT,(TT) CARA AR4,(TT) FOO CAIE AR4,FUNCELL JRST ERRO2C CDRA TT,(TT) CDRA TT,(TT) CARA AR4,(TT) CAIE AR4,ID CAIGE AR4,CODMIN JRST ERRO2G CDRA TT,(TT) CAMLE TT,AR5 ;LE to prefer car to quote CAMLE TT,R JRST ERRO2G MOVE AR5,TT CARA A,(C) ERRO2G: CDRA C,(C) JRST ERRO2B PAGE ;dispatcher for error message uuos ERROR: MOVEI B,APRFLG ;Enable 10/50 interrupts. CALLI B,APRINI LDB B,[POINT 9,.JBUUO,OPFLD] ;get opcode CAIL B,UOERRE ;what CAILE B,USTRTP ;is it? JRST ILLUUO ; an illegal opcode LDB R,[POINT 9,.JBUUO,ACFLD] ;error number ADDI R,INUM0 CAIL B,USTRTP JRST STRTYP ;print message and continue FOO SETZM VERMSG CAIL B,UOERRI JRST ERROR2 ;illegal memory reference HRRM R,ERRX ;error number CAIL B,UOERRG JRST ERRORG ;space overflow error CAIL B,UOERRL JRST ERROR1 ;ordinary LISP error FOO HRRZM A,VERMSG ;set EMSG* to expression PSAVE A ;save it FOO SKIPN ERRSW JRST ERREND ;dont print message, call (err nil) PCALL ERHED ;print message on tty PREST A PCALL PRIN1 ;print expression XCT " ",CTY JRST ERRORA ;then ordinary Lisp error ERRORG: SKIPN P,ERRTN ;if in errset, restore p to that level MOVE P,C2 ;else to top level ERROR1: ;and attempt to print message FOO SKIPN ERRSW JRST ERREND ;dont print message, call (err nil) PCALL ERHED ;print message on tty ERRORA: PCALL ERRSUB ;print the message JRST ERRBK ;go the backtrace ;STRTYP uses acs A, B and R STRTYP: PCALL ERRIO PCALL ERRSUB ;print message and continue PCALL OUTRET JRST @UUOH ERROR2: HRRZ A,.JBUUO MOVEI B,[SIXBIT / ILL MEM REF FROM !/] SUBI R,420 JRST ERSUB2 PAGE ILLUUO: HRRZ A,UUOH MOVEI B,[SIXBIT / ILL UUO FROM !/] MOVEI R,INUM0+1 FOO SETZM VERMSG ERSUB2: HRRM R,ERRX FOO SKIPN ERRSW JRST ERREND ;dont print message PSAVE A PSAVE B PCALL ERHED PCALL PRINL2 ;print number PREST A PCALL ERRSUB+1 ;print message PREST R PCALL ERSUB3 ;print nearest oblist match ERRBK: FOO SKIPE BACTRF PCALL BKTRC ;print backtrace PCALL TOURET ;return to previous device ERREND: JSR CHKNIL ;Insure NIL is set properly. ERRX: MOVEI A,X ;(ERR x) error number ERR2: SKIPN ERRTN JRST LSPRE ERR: SKIPN P,ERRTN JRST LSPRET ;not in an errset, or bad error -- go to top level ERR1: PREST B PCALL UBD ;unbind to previous errset IFN EPDL,PREST EP FOO PREST ERRSW PREST ERRTN JRST ERRP4 ;and proceed ERRORSET:PSAVE PA3 PSAVE PA4 PSAVE ERRTN FOO EXCH B,ERRSW ;INUM0 -> print on selected device (not nec TYO). PSAVE B IFN EPDL,PSAVE EP PSAVE SP MOVEM P,ERRTN PUSH SP,[0] ;mark for unbind FOO EXCH C,BACTRF ;bind BACTRF on spdl to save from error FOO HRLI C,BACTRF PUSH SP,C PCALL EVAL PCALL NCONS JRST ERR1 PAGE .ERROR: FOO HRRZM B,VERMSG PSAVE A FOO SKIPN ERRSW JRST .ERR1 MOVE A,B PCALL ERRIO JUMPE A,.ERRO PCALL ERHED+1 PCALL PRINEL .ERRO: FOO SKIPE BACTRF PCALL BKTRC PCALL TOURET .ERR1: JSR CHKNIL PREST A JRST ERR2 PRINEL: JSP D,PATMTP JRST PRIN2 PSAVE A CARA A,(A) PCALL PRIN1 PRINE1: CDRA T,@(P) MOVEM T,(P) JUMPE T,POPAJ XCT " ",CTY CARA A,(T) PCALL PRIN2 JRST PRINE1 ;WARNING prints a warning message on the tty WARNING: FOO SKIPN %MSG JRST FALSE PCALL WHEAD PCALL PRINEL JRST TOURET PAGE BKTRC: ;backtrace subroutine FOO CDRA A,BACTRF ;Nil or non-Nil or 0 or +-n... BKTRA: SETZM RVAL ;No stack-args printed, unless 0 or neg. CAIG A,INUMIN JRST BKTR0A HRREI B,-INUM0(A) SKIPG B SETOM RVAL ;0 or neg also prints stack args. MOVM B,B HRRZ A,P SUB A,B ;Just the top n items or JUMPN B,BKTR0B ;0 == T otherwise. BKTR0A: SKIPN A,ERRTN ;backtrace to previous errset MOVE A,C2 ;or top level BKTR0B: HRRZM A,BAKLEV# STRTIP [SIXBIT /_BACKTRACE_!/] FOO MOVE A,VBPORG PCALL NUMVAL MOVEM A,HVAL MOVEI D,-1(P) BKTR2: CAMG D,BAKLEV JRST FALSE ;done HRRZ A,(D) ;get pdl element FOO CAIGE A,FS JUMPN A,BKTR2B ;this is (hopefully) a true program address IFN HCBPS,< CAML A,HVAL ;Check for High BPS subrs, JRST BKTR2A ; else an INUM. CAILE A,400000 ;PCALL from location 377777 is illegal JRST BKTR1B ;Test it. > IFE HCBPS,< CAILE A,INUMIN ;Check for Excore BPS subrs, JRST BKTR2A ; else an INUM. CAML A,HVAL SOJA D,BKTR2 CAMLE A,JRELO JRST BKTR1B ;Test it. > CAIGE A,@GCP1 ;Within FS or NIL? BKTR2A: SKIPN RVAL ;Want to print args on stack? SOJA D,BKTR2 ; Unknown, neither prog nor sexpr, so skip. MOVEI A,"=" PCALL TYO HRRZ A,(D) BKTR2C: PCALL PRIN2D JRST BKTR1C PAGE BKTR2B: CAIE A,ILIST3 ;evaluating arguments ? JRST BKTR1B ;no HRRZ B,-1(D) ;maybe CAIE B,EXP2 CAIN B,ESB1 JRST BKTR1A ;yes BKTR1B: CAIN A,CPOPJ JRST [HLRZ A,(D) ;calling a function PCALL PRIN2D STRTIP [SIXBIT /-ENTER !/] SOJA D,BKTR2] HLRZ B,-1(A) CAILE B,(JCALLF 17,@(17)) CAIN B,(PCALL) ;tests for various types of calls CAIGE B,(FCALL) JRST [CAIG A,INUMIN SOJA D,BKTR2 ;Not a proper function call. JRST BKTR2A ];This could print as a INUM. PSAVE -1(A) ;save object of function call MOVEI R,-1(A) ;location of function call PCALL ERSUB3 ;print closest oblist match XCT "-",CTY PREST R TLNE R,17 HRRZ R,ERSUB3 ;qst -- cant handle indexed calls HRRZS R CARA B,(R) CAIN B,ID JRST [CDRA A,R ;was calling an atomic function JRST BKTR2C] ;print its name CAIL B,CODMIN ;code pointer ? CDRA R,(R) ;yes PCALL ERSUB3 ;was calling a code location; print closest match BKTR1C: XCT " ",CTY BKTR1: SOJA D,BKTR2 ;continue BKTR1A: HLRE B,-1(D) ADD B,D HLRZ A,-3(B) JUMPE A,BKTR1 PCALL PRIN2D STRTIP [SIXBIT /-EVALARGS !/] SOJA D,BKTR2 PRIN2D: PSAVE D PCALL PRIN2 PREST D PRET SUBTTL TYI & TYO --- PAGE 7 ;Input routines... BINI: PCALL TYID JRST FIX1A ITYI: PCALL TYI FIXI: ADDI A,INUM0 PRET TYICC: PCALL COMIGN TYI: MOVEI AR4,1 TYIC: PCALL TYID1 JUMPE A,.-1 ;Ignore null CAIN A,IGCRLF ;start of ignored cr-lf JRST TYICC ;read comment PRET TYIA: CAIN A,LF ;If it is LF JRST RETCRLF ; then return CRLF CAIN A,FORMF ; else if it is FORMF JRST RCRLFFF ; then return CRLF FF CAIE A,CR PRET PCALL TYID ;Read next character CAIN A,CRLF ;If it is CRLF PRET ; then return it MOVEM A,OLDCH ; else backup character MOVEI A,CR ; and return CR PRET RCRLFFF:MOVEM A,OLDCH ;Backup FF RETCRLF:MOVEI A,CRLF PRET TYID1: SKIPE A,OLDCH JRST TYI1 TYID: JRST TTYI+X ;<SOSG X> for other device input... JRST TYI2X TYI3: ILDB A,X ;pointer SKIPGE INCH ;IF BINARY-MODE INPUT, PRET ; SKIP LINUM &FECHO & RAISE CODE. TYI3A: TDNN AR4,@X ;pointer JRST TYI4 MOVE A,@TYI3A CAMN A,[<ASCII / />+1] ;page mark for stopgap AOSA PGNUM ;increment page number MOVEM A,LINUM MOVNI A,5 ADDM A,@TYID ;adjust character count for line number AOS @TYI3 ;increment byte pointer over line number and tab JRST TYID PAGE TYI4: SKIPLE LINUM JRST TYI4A CAIN A,LF JRST TYI4L CAIE A,FORMF JRST TYI4A SETZM LINUM AOSA PGNUM TYI4L: SOS LINUM TYI4A: FOO SKIPN VFECHO JRST TYI4E CAIN A,"D"-100 ;On! File-input echoed to TTY. JRST TYI4W PCALL XTYO JRST TYI4E TYI4W: IFN OPSYS,< PSAVE 2 ;Unless ^D encountered in file... MOVEI 1,100 ; want to pause during echo, RFMOD ; e.g., demo on a CRT. PSAVE 2 TRZ 2,776000 ;Clear wakeup,echo. TRO 2,020000 ;Set just punctuation, SFMOD WAITSP: PBIN ;Wait til user types a space on KB. CAIE 1," " JRST WAITSP MOVEI 1,100 PREST 2 SFMOD ;Restore old TTYmodes. PREST 2 JRST TYID ;Get next file-character. > IFE OPSYS,< SETSTS TTCH,1+1B28 ;OFF ECHO TO TTY, TO GET <sp>... WAITSP: INCHRW A CAIE A," " JRST WAITSP SETSTS TTCH,1 JRST TYID > PAGE TYI2X: INPUT X,0 TYI2Y: STATZ X,740000 ERRL0 ^D128,AIN.8 ;input error TYI2Z: STATO X,20000 JRST TYI3 ;continue with file PSAVE T ;end of file PSAVE C PSAVE R PSAVE AR4 MOVE A,INCH HLRZ T,CHTAB(A) ;inlst -- remaining files to input JUMPE T,TYI2E ;none left -- stop HRRZ C,CHTAB(A) ;get location of data for this channel MOVE R,CHDEV(C) MOVEM R,DEV MOVE R,CHPPN(C) MOVEM R,PPN PCALL SETIN ;start next input PREST AR4 PREST R PREST C PREST T JRST TYI TYI2E: PCALL INCNT ;(CLOSE (RDS NIL)) TALK ;turn off control o FOO MOVE A,V$EOF$ ;we are done JRST ERR PGLINE: MOVM A,LINUM SKIPG LINUM AOJA A,.+3 MOVE C,[POINT 7,LINUM] PCALL NUM10 ;convert ascii line number to an integer PCALL FIX1A ;(may be larger than INUM size - 99999). SKIPG LINUM ;If not line numbered file PCALL NCONS ; then (pg line) MOVE B,PGNUM HRLI A,INUM0+1(B) JRST DCONSA ; else (pg . line) OLDCH: 0 ; * PGNUM: 0 ; * LINUM: 0 ; * 0 ;zero to terminate num10 PAGE ;teletype input TTYI: FOO SKIPE DDTIFG JRST TTYID INCHSL A ;single char if line has been typed JRST [TALK ;turn off control o. OUTSTR PCHAR ;output THE PROMPT-CHAR(S). INCHWL A ;wait for a line JRST .+1] TTYXIT: CAIN A,BELL JRST LSPRET ;bell returns to top level CAIN A,33 MOVEI A,ALTMOD ;<esc> becomes <alt> (DECUS tty input). TYI4E: FOO SKIPE VRAISE CAIGE A,"A"+40 JRST TYIA CAIG A,"Z"+40 TRZ A,40 ;If flag on, make lowercase into upper. PRET TTYID: TALK ;turn off control o, remove this when ttyser works INCHRW A ;single character input ddt submode style CAIE A,RUBOUT JRST TTYXIT OUTCHR ["\"] ;echo backslash SKIPE PSAV JRST RDRUB ;rubout in read resets to top level of read PRET PCHAR: ASCIZ /*/ ;INITIAL (DEFAULT) PROMPT-CHAR. SETPCH: PCALL GT1PNM TRZ A,377 ;(INSURE NULL AT END OF STRING). EXCH A,PCHAR ;1-4 CHARS. JRST PNGNK2 ;return previous promter as non-interned id PAGE ;output ROUTINES. BINO: PSAVE A PCALL NUMVAL PCALL TYOD JRST POPAJ ITYO: SUBI A,INUM0 PSAVE CFIXI ;go to FIXI after TYO XTYO: CAIN A,CRLF ;is it CRLF JRST TYO+2 ;yes! output as is, do not convert to CR LF TYO: CAIG A,CRLF JRST TYO3 SOSGE CHCT JRST TYO1 TYOD: JRST TTYO+X ;sosg x for other device JRST TYO2X TYO5: IDPB A,X PRET TYO2X: OUT X,0 JRST TYO5 ERRL0 ^D129,[SIXBIT /OUTPUT ERROR!/] TYO3: CAIE A,CRLF JRST TYO3X MOVEI A,CR PCALL TYO3XX MOVEI A,LF TYO3X: CAIG A,CR CAIGE A,TAB JUMPN A,TYO+2 ;everything between 0(null) and 11(tab) decrement chct TYO3XX: PSAVE B MOVE B,LINL CAIN A,TAB JRST [SUB B,CHCT IORI B,7 ;simulate tab effect on chct SUB B,LINL SETCAM B,CHCT JRST TYO4] CAIN A,CR MOVEM B,CHCT ;reset chct after a cr CAIN A,VT JRST [PSAVE C MOVE B,LNCT IDIVI B,LNPRVT ADDI B,1 IMULI B,LNPRVT MOVEM B,LNCT PREST C JRST TYO6] CAIN A,FORMF TYO7: SETZM LNCT CAIE A,LF JRST TYO4 AOS LNCT TYO6: SKIPE B,PAGL CAMLE B,LNCT JRST TYO4 MOVEI A,FORMF JRST TYO7 PAGE TYO1: SKIPN OUTCH JRST TYO11 ;don't print a IGCRLF to terminal PSAVE A ;linelength exceeded MOVEI A,IGCRLF ;ignored cr-lf PCALL TYOD PREST A TYO11: PCALL TERPRI SOSA CHCT TYO4: PREST B JRST TYOD LINELENGTH: JUMPE A,LINEL1 CAIG A,INUM0 ERRE2 ^D36,[SIXBIT /ILLEGAL ARG TO LINELENGTH!/] SUBI A,INUM0 HRRM A,LINL HRRM A,CHCT LINEL1: HRRZ A,LINL CFIXI: JRST FIXI PAGELENGTH: JUMPE A,PAGEL1 CAIGE A,INUM0 ERRE2 ^D37,[SIXBIT /ILLEGAL ARG TO PAGELENGTH!/] SUBI A,INUM0 HRRM A,PAGL JUMPE A,PAGEL1 SKIPE LNCT PCALL EJECT PAGEL1: HRRZ A,PAGL JRST FIXI POSN: SKIPA A,LINL LPOSN: SKIPA A,LNCT SUB A,CHCT JRST FIX1A LINL: TTYLL ;* CHCT: TTYLL ;* PAGL: TTYPL LNCT: 0 ;teletype output TTYO: ;Output 1 char from A... IFG OPSYS,SKIPN CTRLOF ; unless ^O on. OUTCHR A PRET PAGE TTYRET: PCALL OUTCNT JRST INCNT TTYCLR: ;Turn off ^O, in a way such that msg IFLE OPSYS, < ; or promptchar will print. SKPINC PRET PRET > IFG OPSYS, < PSAVE A MOVEI 1,101 DOBE SETZM CTRLOF JRST POPAJ > TTOCH: 0 ;* 0 ;tty page number -- always zero 0 ;tty line number -- always zero TTOLL: TTYLL ;* TTOHP: TTYLL ;* TTOPL: TTYPL TTOVP: 0 SUBTTL INPUT AND OUTPUT INITIALIZATION AND CONTROL --- PAGE 8 ;convert ascii to sixbit for device initialization routines SIXMAK: SETZM SIXMK2# MOVE AR4,[POINT 6,SIXMK2] HRROI R,SIXMK1 PCALL PRINTA ;use print to unpack ascii characters MOVE A,SIXMK2 PRET SIXMK1: ADDI A,40 TLNN AR4,770000 PRET ;last character position -- ignore remaining chars CAIN A,"."+40 MOVEI A,0 ;ignore dots at end of numbers for decimal base CAIN A,":"+40 HRLI AR4,(POINT 6,0,29) ;deposit : in last char position IDPB A,AR4 PRET ;subroutine to process next item in file name list INXTIO: JUMPE T,FALSE CDRA T,(T) NXTIO: CARA A,(T) PCALL ATOM JUMPE A,CPOPJ ;non-atomic CARA A,(T) JRST SIXMAK ;make sixbit if atomic IFN OCTPPN,<IOPPNX==NUMVAL> PAGE IOSUB: PCALL NXTIO MOVEM T,DEVDAT# LDB B,[POINT 6,A,35] JUMPE A,IOPPN ;non-atomic item, must be ppn or (file.ext) CAIE B,":"-40 JRST IOFIL ;not a device name -- must be file name TRZ A,77 ;clear out the : IFN OPSYS,PCALL CHKDIR IODEV2: MOVEM A,DEV PCALL INXTIO JUMPN A,IOFIL2 ;not ppn or (fil.ext) IOPPN: JUMPE T,FIL PCALL PPNEXT JUMPN A,IOEXT ;(fil.ext) CARA A,(T) CARA A,(A) ;caar is project number PCALL IOPPNX HRLM A,PPN ;project number CARA A,(T) PCALL CADR ;cadar is programmer number PCALL IOPPNX HRRM A,PPN ;programmer number MOVSI A,(SIXBIT /DSK/) ;disk is assumed JRST IODEV2 IOFIL: JUMPN A,IOFIL3 ;was it an atom JUMPE T,FIL ;no, was it nil (end) PCALL PPNEXT JUMPE A,CPOPJ ;see a ppn, no file named IOEXT: CARA A,(T) ;(file.ext) CDRA A,(A) ;get cdr == extension PCALL SIXMAK HLLZM A,EXT CARA A,(T) CARA A,(A) ;get car = file name PCALL SIXMAK FIL: JUMPE T,.+2 CDRA T,(T) SKIPE DEV PRET PSAVE A ;no device named MOVSI A,(SIXBIT /DSK/) MOVEM A,DEV JRST POPAJ IOFIL2: LDB B,[POINT 6,A,35] CAIN B,":"-40 JRST FALSE ;saw a :,not file name IOFIL3: SETZM EXT ;file name -- clear extension JRST FIL PAGE PPNEXT: CARA A,(T) CDRA A,(A) ;cdar JRST ATOM ;ppn iff (not(atom(cdar l))) IFE OCTPPN,< IOPPNX: PCALL SIXMAK TRNE A,77 PRET LSH A,-6 JRST .-3 > IFN OPSYS,< CHKDIR: CAME A,[SIXBIT /DIR/] ;i.e., (... DIR: directory filename ...) PRET PSAVE T PCALL INXTIO JUMPE A,NIXDIR ;NON-ATOMIC. CARA A,(T) PCALL PNAMUK SETZM 1(C) IFG OPSYS ,< MOVSI A,400000 HRROI B,1(SP) STDIR JRST NIXDIR JRST NIXDIR HRRZM A,PPN > IFL OPSYS, < HRLI A,440700 ; MAKE UP A HRRI A,1(SP) ; BYTE POINTER MOVE B,A MOVEI C,"<" LP1: ILDB 4,A IDPB C,B MOVE C,4 JUMPN C,LP1 MOVEI C,">" ; PUT IN LEFT BRACKET IDPB C,B IDPB 4,B MOVEI A,0 HRROI B,1(SP) RCDIR ERJMP NIXDIR SYSNU: HRLI C,X MOVEM C,PPN > P1DROP ;SLUFF. USEDSK: MOVSI A,(SIXBIT /DSK/) PRET NIXDIR: PREST T ;TRY AS FILENAME INSTEAD. JRST USEDSK > ;end of IFN OPSYS PAGE ;subroutine to reset all i/o channels -- used by excise and realloc IOBRST: X ;jsr location HRRZ A,.JBREL HRLM A,.JBSA MOVEM A,CORUSE MOVEM A,.JBSYM SETZM CHTAB+FSTCH MOVE A,[XWD CHTAB+FSTCH,CHTAB+FSTCH+1] BLT A,CHTAB+NIOCH+FSTCH-1 ;clear channel table JRST @IOBRST CHTAB=.-FSTCH ;GC'D BY GCMKL AS AN ARRAY, SINCE LH=LIST, BLOCK NIOCH ;[1-17] RH=ADDR OF .JBFF DATA BLK. ;* ;channel data CHNAM==0 ;name of channel CHDEV==1 ;name of device CHPPN==2 ;ppn for input channel CHOCH==3 ;oldch for input channels CHPAGE==4 ;page number for input CHLINE==5 ;line number for input CHDAT==6 ;device data POINTR==7 ;byte pointer for device buffer COUNT==10 ;character count for device buffer CHLL==2 ;linelength for output channel CHHP==3 ;hposit for output channels CHPL==4 ;pagelength for output channel CHVP==5 ;vposit for output channels ;flags in left half of CHNAM BINM==400000 ;binary I/O OUTM==1 ;output PAGE OPEN: JUMPE A,.+3 JSP D,ATMTYP PCALL NCONS MOVE T,A SETZB A,DEV FOO CAIE B,INBIN FOO CAIN B,OUTBIN TLO A,BINM ;binary I/O FOO CAIE B,OUTPUT FOO CAIN B,OUTBIN TLO A,OUTM ;output FOO CAIE B,INPUT JUMPE A,[MOVE A,B ERRE1 ^D18,[SIXBIT /NOT A KEYWORD FOR OPEN!/]] MOVE B,[-NIOCH,,FSTCH] OPEN1: SKIPN C,CHTAB(B) JRST OPEN2 ;found free channel without buffer SKIPN CHNAM(C) JRST DEVCLR ;found free channel with buffer AOBJN B,OPEN1 ;try next channel ERRL0 ^D130,[SIXBIT "NO I/O CHANNELS LEFT!"] OPEN2: PSAVE A MOVEI A,BLKSIZ PCALL MORCOR ;expand core for buffer if necessary MOVE C,A PREST A HRRM C,CHTAB(B) DEVCLR: HRRZ C,CHTAB(B) HRR A,B HLLOM A,CHNAM(C) MOVEI B,INUM0(B) PSAVE B SETZM PPN TLNE A,OUTM JRST SETOUT PCALL SETIN JRST POPAJ PAGE SETIN: PSAVE A ;CHANNEL #. PCALL IOSUB ;get device and file name MOVEM A,LOOKIN ;file name MOVE A,DEV CALLI A,DEVCHR TLNN A,INB JRST AIN.2 ;not input device TLNN A,AVLB JRST AIN.4 ;not available PREST A HLLZS ININIT MOVEI B,13 SKIPGE A HRRM B,ININIT ;BINARY-INBIN. DPB A,[POINT 4,ININIT,ACFLD] ;set up channel numbers DPB A,[POINT 4,INLOOK,ACFLD] DPB A,[POINT 4,ININBF,ACFLD] HRRZ B,CHTAB(A) HRLM T,CHTAB(A) ;save remaining file name list MOVEI A,CHDAT(B) MOVEM A,DEV+1 ;pointer to bufdat IFN SYDEV,<PCALL SYSDEV> ;Check for SYS: ININIT: INIT X,X ;INIT CHN#,STATUS DEV: X ;SIXBIT /DEV/ X ;XWD 0,IBUF JRST AIN.7 ;cant init PUSH B,DEV PUSH B,PPN INLOOK: LOOKUP X,LOOKIN JRST AIN.7 ;cant find file PUSH B,[0] ;oldch PUSH B,[0] ;line number PUSH B,[0] ;page number ADDI B,4 HRRM B,.JBFF ININBF: INBUF X,NIOB JRST TRUE PAGE IFN SYDEV, < ;shunt SYS: to <LISP>'s dir (or wherever). SYSDEV: MOVSI A,(SIXBIT /SYS/) CAME A,DEV PRET IFG OPSYS,<MOVSI A,(SIXBIT /DSK/)> IFLE OPSYS,<MOVE A,SYSNUM> MOVEM A,DEV IFG OPSYS,<PSAVE SYSNUM PREST PPN > PRET > ENTR: LOOKIN: BLOCK 4 EXT=LOOKIN+1 PPN=LOOKIN+3 PAGE SETOUT: PSAVE A PCALL IOSUB ;get device and file name MOVEM A,ENTR ;file name SETZM ENTR+2 ;zero creation date PREST A DPB A,[POINT 4,OUINIT,ACFLD] ;setup channel numbers DPB A,[POINT 4,OUTENT,ACFLD] DPB A,[POINT 4,OUTOBF,ACFLD] HRRZ B,CHTAB(A) MOVEI A,CHDAT(B) HRLM A,DEVO+1 MOVE A,DEV MOVEM A,DEVO CALLI A,DEVCHR TLNN A,OUTB JRST AOUT.2 ;not output device TLNN A,AVLB JRST AOUT.4 ;not available HLLZS OUINIT MOVEI A,13 SKIPGE CHNAM(B) HRRM A,OUINIT ;BINARY-OUTBIN. OUINIT: INIT X,X ;INIT CHN#,STATUS DEVO: X ;SIXBIT /DEV/ X ;XWD OBUF,0 JRST AOUT.4 ;cant init PUSH B,DEV OUTENT: ENTER X,ENTR JRST OUTERR ;cant enter PUSH B,[LPTLL] ;linelength PUSH B,[LPTLL] ;chrct PUSH B,[LPTPL] ;pagelength PUSH B,[0] ;linct ADDI B,4 HRRM B,.JBFF OUTOBF: OUTBUF X,NIOB JRST POPAJ OUTERR: MOVE A,DEVDAT LDB B,[POINT 3,ENTR+1,35] CAIE B,2 ERRE1 ^D19,[SIXBIT /DIRECTORY FULL!/] ERRE1 ^D20,[SIXBIT /FILE IS WRITE PROTECTED!/] PAGE INCNT: MOVEI A,NIL ;(CLOSE (RDS NIL)) PSAVE [JRST CLOSE] RDS: PSAVE INCH# PCALL IOSEL TLNE A,OUTM ;test to see if it is an input channel ERRL0 ^D131,[SIXBIT/NO INPUT - RDS!/] SKIPN TT MOVEI TT,TTOCH-CHOCH ;tty deselect MOVEI D,CHOCH(TT) HRLI D,OLDCH BLT D,CHLINE(TT) ;save channel data JUMPE A,ITTYRE ;select tty DPB A,[POINT 4,TYI2X,ACFLD] ;set up channel numbers DPB A,[POINT 4,TYI2Y,ACFLD] DPB A,[POINT 4,TYI2Z,ACFLD] HRRM B,TYI3 ;set up tyi parameters HRRM B,TYI3A MOVSI B,CHOCH(C) INC3: HRRI B,OLDCH BLT B,LINUM ;restore channel data MOVEM T,TYID FOO PREST VINC EXCH A,INCH ;flags,,channel#. IOEND: HRRZS A JUMPN A,FIXI PRET ITTYRE: MOVE T,[JRST TTYI] ;reselect tty MOVSI B,TTOCH JRST INC3 PAGE OUTCNT: MOVEI A,NIL ;(CLOSE (WRS NIL)) PSAVE [JRST CLOSE] WRS: PSAVE OUTCH# PCALL IOSEL TLNN A,OUTM ;is it output channel JUMPN A,[ERRL0 ^D132,[SIXBIT /NO OUTPUT - WRS!/]] SKIPN TT MOVEI TT,TTOLL-CHLL ;tty deselect MOVEI D,CHLL(TT) HRLI D,LINL BLT D,CHVP(TT) ;save channel data JUMPE A,OTTYRE ;return to tty DPB A,[POINT 4,TYO2X,ACFLD] ;set up tyo2 channel numbers HRRM B,TYO5 ;set up tyo2 parameters MOVSI B,CHLL(C) OUTC3: HRRI B,LINL BLT B,LNCT ;get channel data MOVEM T,TYOD FOO PREST VOUTC EXCH A,OUTCH ;flags,,channel#. JRST IOEND OTTYRE: MOVE T,[JRST TTYO] MOVSI B,TTOLL ;tty reselect JRST OUTC3 PAGE IOSEL: PCALL GCHNO ;convert into channel number SKIPE TT,A ADDI TT,INUM0 EXCH TT,-1(P) SKIPE TT HRRZ TT,CHTAB(TT) JUMPE A,CPOPJ SKIPE C,CHTAB(A) SKIPN T,CHNAM(C) JRST CPOPJ1 HLL A,T MOVEI B,POINTR(C) MOVEI T,COUNT(C) HRLI T,(SOSG) PRET CLOSE: PCALL GCHNO ;convert into channel number ICLOSE: JUMPE A,CPOPJ ;don't close terminal cannel SKIPE D,CHTAB(A) SETZM CHNAM(D) ;blast channel name DPB A,[POINT 4,.+1,ACFLD] RELEASE X, ;release channel HRRZS CHTAB(A) ;release channel table entry JRST FIXI ;convert A into channel number GCHNO: SKIPE A SUBI A,INUM0 CAIG A,NIOCH JUMPGE A,CPOPJ ADDI A,INUM0 ERRE1 ^D21,[SIXBIT /IS NOT A CHANNEL NAME!/] AOUT.2: AIN.2: MOVE A,DEVDAT ERRE1 ^D22,[SIXBIT /ILLEGAL DEVICE!/] AOUT.4: AIN.4: MOVE A,DEVDAT ERRE1 ^D23,[SIXBIT /DEVICE NOT AVAILABLE!/] AIN.7: MOVE A,DEVDAT ERRE1 ^D24,[SIXBIT /CAN'T FIND FILE!/] SUBTTL PRINT --- PAGE 9 PRINT: MOVEI R,TYO PCALL PRIN1 TERPRI: PSAVE A MOVEI A,CRLF TERPR1: PCALL TYO CPOPAJ: JRST POPAJ EJECT: MOVEI A,CR PCALL TYO MOVEI A,FORMF PCALL TYO JRST FALSE PRINC: PSAVE A PCALL GTFCH JRST TERPR1 PRIN2: SKIPA R,.+1 PRIN1: HRRZI R,TYO ;<HRRZI> = <551>, NEGATIVE FOR PRIN2. PSAVE A PCALL PRINTA JRST POPAJ PRINTA: HLRZ B,SLSH ;PRIN3 OR PRIN3C SET BY SCANSET SKIPGE R MOVEI B,PRIN4 HRRM B,PRIN5 PRINT4: PSAVE A JSP D,PATMTP JRST PRINT1 XCT "(",CTY PRINT3: MOVE A,TT ;[if 0 --> NIL's 777777 --> ill mem ref]. PCALL PRINT4 CDRA A,@(P) JUMPE A,PRINT2 MOVEM A,(P) XCT " ",CTY JSP D,PATMTP JRST .+2 JRST PRINT3 XCT ".",CTY XCT " ",CTY PCALL PRIN1A PRINT2: XCT ")",CTY JRST POPAJ PAGE PRINT1: PSAVE CPOPAJ PRIN1A: JUMPE TT,PRINIC ;inum JUMPL TT,PRINL ;not a Lisp expression CDRA A,(A) CAIN TT,ID JUMPN A,PRINN CAIL TT,CODMIN JRST PCODE JUMPN A,@PRITAB-ATMIN-1(TT) ;go to print routine for the given type PRINL: XCT "#",CTY HLRZ A,-1(P) JUMPE A,.+3 ;usually there is no left half PCALL PRINL1 XCT ",",CTY HRRZ A,-1(P) PRINL1: MOVEI C,8 PRINI3: JUMPL A,[MOVE B,0 ;case of -2^35 MOVEI A,1 DIVI A,(C) JRST .+2] IDIVI A,0(C) HRLM B,(P) SKIPE A PCALL .-3 JRST FP7A1 PRITAB: BPRI ;negative bignum BPRI+1 ;positive bignum PRINI1 ;integer PRINO ;floating point number PSTR ;string PVEC ;vector PAGE PRINL2: MOVEI R,TYO JRST PRINL1 PRINI1: SKIPA A,(A) PRINIC: SUBI A,INUM0 FOO CDRA C,VBASE SUBI C,INUM0 JUMPGE A,PRINI2 XCT "-",CTY MOVNS A PRINI2: PCALL PRINI3 PRINI4: IFN ROCT,<CAIN C,10 JRST POCTNM> CAIN C,TEN FOO SKIPE %NOPOINT PRET MOVEI A,"." JRST (R) IFN ROCT,< POCTNM: JUMPL R,CPOPJ MOVEI A,"L" JRST (R) > PVEC: PSAVE -1(A) HRLI A,(POINT 18) PSAVE A MOVEI A,"[" PCALL (R) JRST PVECL+1 PVECL: XCT ",",CTY ILDB A,(P) PCALL PRINT4 SOSL -1(P) JRST PVECL MOVEI A,"]" P2DROP JRST (R) PCODE: XCT "#",CTY XCT "#",CTY JRST PRINL1 CTY: JSA A,TYOI TYOI: X PSAVE A LDB A,[POINT 6,-1(A),ACFLD] PCALL (R) PREST A JRA A,(A) PAGE PRINN: FOO MOVEI B,PNAME PCALL GET4 JUMPE A,PRINL CARA A,D PCALL PRIDST ILDB A,C JUMPE A,CPOPJ ;special case of null character PRIN2X: JUMPL R,PRIN4 ;never slash LDB B,SL1FLD JRST PRIN2N(B) ;1 for no slash PRIN3: SKIPL CHRTAB(A) ;<0 for no slash PRIN2N: PCALL SLSHPR ;slashify PRIN4: PCALL (R) ILDB A,C PRIN5: JUMPN A,PRIN3+X ;prin4 for never slash PRET PSTR: PCALL PRIDST MOVE A,STRBEG JRST PSTR3 PSTREC: PCALL (R) MOVE A,STREND PSTR3: SKIPL R ;dont print " if no slashify PSTR2: PCALL (R) ILDB A,C CAMN A,STREND JRST PSTREC JUMPN A,PSTR2 MOVE A,STREND JUMPGE R,(R) PRET PRIDST: MOVEI C,2(SP) PCALL PNAMU3 PUSH C,[0] HRLI C,(POINT 7,0,35) HRRI C,2(SP) PRET SLSHPR: PSAVE A HRRZ A,SLSH PCALL (R) JRST POPAJ PAGE PRINO: MOVE A,(A) SETZB B,C JUMPG A,FP1 JUMPE A,FP3 MOVNS A XCT "-",CTY FP1: CAMGE A,FT01 JRST FP4 CAML A,FT8 AOJA B,FP4 FP3: MULI A,400 ASHC B,-243(A) MOVE A,B SETZM FPTEM# PCALL FP7 XCT ".",CTY MOVNI T,8 ADD T,FPTEM MOVE B,C FP3A: MOVE A,B MULI A,TEN PCALL FP7B SKIPE B AOJL T,FP3A PRET FP4: MOVNI C,6 MOVEI TT,0 FP4A: ADDI TT,1(TT) XCT FCP(B) TRZA TT,1 FMPR A,@FCP+1(B) AOJN C,FP4A PSAVE TT MOVNI B,-2(B) DPB B,[POINT 2,FP4C,11] PCALL FP3 MOVEI A,"E" PCALL (R) FP4C: XCT "+"+X,CTY PREST A FP7: JUMPE A,FP7B IDIVI A,TEN AOS FPTEM HRLM B,(P) JUMPE A,FP7A1 PCALL FP7 FP7A1: HLRE A,(P) FP7B: ADDI A,"0" JRST (R) PAGE 353473426555 ;1e32 266434157116 ;1e16 FT8: 1.0E8 1.0E4 1.0E2 1.0E1 FT: 1.0E0 026637304365 ;1e-32 113715126246 ;1e-16 146527461671 ;1e-8 163643334273 ;1e-4 172507534122 ;1e-2 FT01: 175631463146 ;1e-1 FT0: FCP: CAMLE A,FT0(C) CAMGE A,FT(C) XWD C,FT0 SUBTTL SUPER FAST TABLE DRIVEN READ --- PAGE 10 ;magic scanner table bit definitions ;bit 0=0 iff slashified as nth id character ;bit 1=0 iff slashified as 1st id character ;bits 2-5 ratab index ;bits 6-8 dotab index ;bits 9-10 strtab index ;bits 11-13 idtab index ;bits 14-16 exptab index ;bits 17-19 rdtab index ;bits 20-25 ascii to radix 50 conversion ;bits used by the alternative SCANner ;bits 26-29 ratab index ;bits 30-31 strtab index ;bits 32-34 idtab index ;bit 35=0 iff slashified as 1st id character ;bit 32=0 iff slashified as nth id character ;The following 8 words are modified by SCANSET and SCANRESET IGEND: CRLF STRBEG: DBLQT ;string start STREND: DBLQT ;string end SLSH: XWD PRIN3,"!" ;slashtest,slashifier SL1FLD: POINT 1,CHRTAB(A),1 RATFLD: POINT 4,CHRTAB(A),5 STRFLD: POINT 2,CHRTAB(A),10 IDFLD: POINT 3,CHRTAB(A),13 DOTFLD: NUMFLD: POINT 3,CHRTAB(A),8 EXPFLD: POINT 3,CHRTAB(A),16 RDFLD: POINT 3,CHRTAB(A),19 R50FLD: POINT 6,CHRTAB(A),25 ;magic state flags in t EXP==1 ;exponent NEXP==2 ;negative exponent SAWDOT==4 ;saw a dot (.) MINSGN==10 ;negative number IFN ROCT,<OCTNM==20 ;octal number (saw a L) RDIG==6 > IFE ROCT,RDIG==5 ;atom type in R for SCAN IDCLS==0 ;identifier STRCLS==1 ;string NUMCLS==2 ;number DELCLS==3 ;delimiter PAGE ;macros for scanner table DEFINE RAD50 (X)< IFB <X>,<R50VAL=0> IFLE <"X"-"9">,<IFGE <"X"-"0">,<R50VAL="X"-"0"+1>> IFIDN <"X"><".">,<R50VAL=45> IFIDN <"X"><"$">,<R50VAL=46> IFIDN <"X"><"%">,<R50VAL=47> IFGE <"X"-"A">,<R50VAL="X"-"A"+13>> DEFINE TABIN (SN,S1,R,D,S,I,E,RD,R50,RE<2>,SE<3>,IE<2>,S1E<0>)< XLIST IRPC R50< RAD50 (R50) BYTE (1)SN,S1(4)R(3)D(2)S(3)I,E,RD(6)R50VAL(4)RE(2)SE(3)IE(1)S1E> LIST> DEFINE LET (X)< TABIN (0,0,5,2,3,4,2,0,X)> DEFINE SCNLET (X)< TABIN (1,1,5,2,3,4,2,0,X,5,3,4,1)> DEFINE DELIMIT (X,Y)< TABIN (0,0,2,2,3,2,2,Y,X)> DEFINE IGNORE (X)< TABIN (0,0,3,2,3,2,2,0,X,3)> PAGE CHRTAB: TABIN (0,0,1,1,1,1,1,0,< >,1,1,1) ;null LET (< >) IGNORE (< >) ;tab,lf,vtab,ff,cr LET (< >) ;16 to 31 TABIN (0,0,0,0,0,0,0,0,< >,0,0,0) ;igmrk LET (< >) ;33 -- <ESC> JUST A LETTER WHEN IN A FILE. LET (< >) ;34 to 36 IGNORE (< >) ;37 (EOL) and space TABIN (0,0,4,2,3,3,2,0,< >,4,3,3) ;! the new slashifier TABIN (0,0,9,2,2,2,2,0,< >,9,2) ;" LET (< $>) ;#$ TABIN (0,0,0,0,3,0,0,0,<%>,0,3,0) ;% is comment start LET (< >) ;& TABIN (0,0,2,2,3,4,2,5,< >) ;' the new quote character DELIMIT (< >,0) DELIMIT (< >,1) ;() LET (< >) ;* TABIN (0,0,3,2,3,4,2,0,< >) ;+ TABIN (0,0,3,2,3,2,2,0,< >) ;, ignored for READ, delimit for SCAN TABIN (0,0,6,2,3,4,2,0,< >) ;- TABIN (0,0,7,3,3,2,2,4,<.>,7) LET (< >) ;/ old slashifyer is just a letter now TABIN (1,0,8,RDIG,3,4,3,0,<0123456789>,8,3,4) LET (< >) ;:; DELIMIT (< >,2) ;< super paranthesis LET (< >) ;= DELIMIT (< >,3) ;> super paranthesis LET (< >) ;? LET (< >) ;@ old quote character is just a letter now SCNLET (<ABCD>) TABIN (1,1,5,4,3,4,2,0,<E>,5,3,4,1) ;E exponent for floating point number SCNLET (<FGHIJK>) IFE ROCT,SCNLET(<L>) IFN ROCT,< TABIN (1,1,5,5,3,4,2,0,<L>,5,3,4,1) ;L ends an octal number > SCNLET (<MNOPQRSTUVWXYZ>) DELIMIT (< >,6) ;[ vector start LET (< >) ;\ DELIMIT (< >,3) ;] vector end LET (< >) ;^_` SCNLET (<ABCDEFGHIJKLMNOPQRSTUVWXYZ>) ;lower case LET (< >) ;{ DELIMIT (< >,3) ;175 -- ALTMODE (ALSO DECUS' 33 CONVERTED DURING TTI INPUT). LET (< >) ;~ DELIMIT (< >,6) ;rubout PAGE IDCHTAB:BLOCK "?" ;table of character ids. updated by INTERN and FOO XWD 0,QST BLOCK 100-"?"-1 ; REMOB. refered to by READCH and EXPLODE. READCH: PCALL TYI RECH1: TRNN A,100 SKIPA C,IDCHTAB(A) HLRZ C,IDCHTAB-100(A) TRNE C,-1 ;is it in character id table ? JRST RETC ;yes! return it PSAVE TT ;save TT and PSAVE T ; T for EXPLODE LSH A,35 MOVE C,SP PUSH C,A PCALL INTER0 PREST T PREST TT PRET READP1: SETZM NOINFG READ0: PSAVE TYID PSAVE OLDCH SETZM OLDCH# HRLI A,(JRST) MOVEM A,TYID PCALL READ+1 PREST OLDCH PREST TYID PRET RDRUB: MOVEI A,CR PCALL TTYO MOVEI A,LF PCALL TTYO SKIPA P,PSAV# READ: SETZM NOINFG# ;0 means intern SKIPN OLSCNV JRST READD SETZ A, PCALL SCANSET PSAVE A PCALL READD EXCH A,(P) PCALL SCANSET JRST POPAJ READD: MOVEM P,PSAV PCALL READ1 SETZM PSAV PRET READ1: PCALL RATOM PRET ;atom XCT RDTAB2(B) JRST READ1 ;try again RDTAB2: JRST READ2 ;0 ( JFCL ;1 ) JRST READ4 ;2 < JFCL ;3 ],>,$ JFCL ;4 . JRST RDQT ;5 ' JRST READVC ;6 [ READ2: PCALL RATOM JRST READ2A ;atom XCT RDTAB(B) READ2A: PSAVE A PCALL READ2 PREST B JRST XCONS RDTAB: PCALL READ2 ;0 ( JRST FALSE ;1 ) PCALL READ4 ;2 < JRST READ5 ;3 ],>,$ JRST RDT ;4 . PCALL RDQT ;5 ' PCALL READVC ;6 [ RDTX: PCALL RATOM PRET ;atom XCT RDTAB2(B) DOTERR: SETZM OLDCH ERRL0 ^D133,[SIXBIT /DOT CONTEXT ERROR!/] RDT: PCALL RDTX PSAVE A PCALL RATOM JRST DOTERR CAIN B,1 JRST POPAJ CAIE B,3 JRST DOTERR MOVEM A,OLDCH JRST POPAJ READ4: PCALL READ2 MOVE B,OLDCH CAIE B,ALTMOD TYI1: SETZM OLDCH ;kill the > or ] PRET READ5: MOVEM A,OLDCH ;save > or ] or $ JRST FALSE ;and return nil RDQT: PCALL READ1 QTIFY: PCALL NCONS FOO HRLI A,CQUOTE JRST DCONSA ;skip a comment COMENT: CAIN A,IGCRLF ;^Z ? JRST COMIGN ;yes. end on CRLF MOVE A,IGEND ;no. end on IGEND HRRM A,COMM+1 ;set end char COMM: PCALL TYIC ;AR4 must contain 1 here CAIE A,CRLF+X JRST COMM PRET ;skip a super (^Z) comment COMIGN: PCALL TYID1 ;AR4 must contain 1 here CAIE A,CRLF JRST COMIGN PRET PAGE READVC: PCALL READ2 MOVE B,OLDCH ENDVC: CAIN B,"]" SETZM OLDCH LTOVEC: JUMPE A,CPOPJ PSAVE A ;save list CDRA A,(A) PCALL LENGTH PCALL MKVECT ;make a vector CDRA B,(A) EXCH A,(P) MOVSI C,(POINT 18,(B)) MOVS A,(A) IDPB A,C CARA A,A JUMPN A,.-3 JRST POPAJ PAGE ;atom parser RATOM: SETZB T,R ;IDCLS in R HRLI C,(POINT 7,0,35) HRRI C,(SP) SETZM 1(C) ;clear first word MOVEI AR4,1 RATOM2: PCALL TYID1 LDB B,RATFLD JRST RATAB(B) RATAB: PCALL COMENT ;0 comment JRST RATOM2 ;1 null JRST RATOM3 ;2 delimit JRST RATOM2 ;3 ignore PCALL TYIC ;4 ! JRST RDID ;5 letter JRST RDNMIN ;6 - JRST RDOT ;7 . JRST RDNUM ;8 digit JRST RDSTR ;9 string ;a real dotted pair RDOT2: MOVEM A,OLDCH MOVEI A,"." RATOM3: LDB B,RDFLD HRRI R,DELCLS ;delimiter CPOPJ1: PSKPRT ;non-atom (ie a delimiter) PRET ;dot handler RDOT: PCALL TYID1 LDB B,DOTFLD JRST DOTAB(B) DOTAB: PCALL COMENT ;0 comment JRST RDOT ;1 null JRST RDOT2 ;2 delimit JRST RDOT2 ;3 dot JRST RDOT2 ;4 E IFN ROCT,JRST RDOT2 ;5 L MOVEI B,0 ;6 (5) digit IDPB B,C TLO T,SAWDOT JRST RDNUM PAGE ;string scanner STRTAB: PCALL COMENT ;0 comment JRST RDSTR ;1 null JRST STR2 ;2 delimit IDPB A,C ;3 string element RDSTR: PCALL TYID1 LDB B,STRFLD ;A huge string (e.g. missing close-quote) JRST STRTAB(B) ; will overflow SPDL and clobber I/O bufs. STR2: PCALL TYID1 LDB B,STRFLD CAIN B,2 JRST RDSTR-1 MOVEM A,OLDCH HRRI R,STRCLS ;string LMKSTR: PCALL IDEND MSTR1: PCALL IDSUB PCALL PNAMAK HRLI A,STRNG JRST DCONSA ;identifier scanner IDTAB: PCALL COMENT ;0 JRST RDID+1 ;1 null JRST MAKID ;2 delimit PCALL TYIC ;3 ! RDID: IDPB A,C ;4 letter or digit PCALL TYID1 LDB B,IDFLD JRST IDTAB(B) PAGE ;number scanner NUMTAB: PCALL COMENT ;0 comment JRST RDNUM+1 ;1 null JRST NUMAK ;2 delimit JRST RDNDOT ;3 dot JRST RDE ;4 e IFN ROCT,JRST OCTNUM ;5 L RDNUM: IDPB A,C ;6 (5) digit PCALL TYID1 LDB B,NUMFLD JRST NUMTAB(B) RDNDOT: TLOE T,SAWDOT JRST NUMAK ;two dots - delimit MOVEI A,0 JRST RDNUM RDNMIN: TLO T,MINSGN JRST RDNUM+1 ;exponent scanner RDE: TLO T,EXP MOVEI A,0 IDPB A,C PCALL TYID1 CAIN A,"-" TLOA T,NEXP CAIN A,"+" JRST RDE2+1 JRST RDE2+2 EXPTAB: PCALL COMENT ;0 JRST RDE2+1 ;1 null JRST NUMAK ;2 delimit RDE2: IDPB A,C ;3 digit PCALL TYID1 LDB B,EXPFLD JRST EXPTAB(B) IFN ROCT,< OCTNUM: TLO T,OCTNM PCALL TYID1 LDB B,NUMFLD SOJG B,NUMAK JUMPL B,OCTNUM+1 PCALL COMENT JRST B,OCTNUM+1 > PAGE ;semantic routines ;identifier interner and builder IDEND: TDZA A,A IDEND1: IDPB A,C TLNE C,760000 JRST IDEND1 PRET MAKID: MOVEM A,OLDCH PCALL IDEND SKIPE NOINFG JRST NOINTR ;dont intern it INTER0: PCALL INTER2 ;is it in oblist PRET ;found PCALL PNAIMK ;not there MAKID2: SKIPGE C,IDCHPO# ;character id ? JRST MKID2 ;no! TRNN C,100 JRST .+3 HRLM A,IDCHTAB-100(C) JRST MKID2 HRRM A,IDCHTAB(C) MKID2: MOVE C,CURBUC HLRZ B,@RHX2 PCALL CONS ;cons it into the oblist HRLM A,@RHX2 JRST CAR CURBUC: 0 ;pname unmaker PNAMUK: MOVE C,SP PNAMUD: PCALL GETPNM PNAMU3: CARA B,(A) PUSH C,(B) CDRA A,(A) JUMPN A,PNAMU3 PRET ;idsub constructs a iowd pointer for a print name IDSUB: HRRZS C CAML C,JRELO ;top of spec pdl JRST SPDLOV MOVNS C ADDI C,(SP) HRLZS C HRRI C,1(SP) MOVEM C,IDPTR# MOVEI B,1 ANDCAM B,(C) ;clear low bit AOBJN C,.-1 PRET NOINTR: PCALL IDSUB PNAIMK: PCALL PNAMAK JRST PNGNK1 PAGE ;identifier interner INTERT: PCALL PNAMUK INTER2: PCALL IDSUB INTER1: MOVE B,1(SP) ;get first word of pname LSH B,-1 ;right justify it SETOM IDCHPO ;indicate no character id TDNE B,[1777,,777777] ;character id ? JRST INT1 ;no! MOVE T,B LSH T,-12 HLRZM T,IDCHPO ;is a character id INT1: IDIVI B,BCKETS+X ;compute hash code RHX2: FOO HLRZ T,OBTBL(B+1) ;get bucket MOVEM B+1,CURBUC ;save bucket number MOVE C,T JRST MAKID1 MAKID3: MOVE C,T ;save previous atom CDRA T,(T) ;get next atom MAKID1: JUMPE T,CPOPJ1 ;not in oblist CARA A,(T) ;next id in oblist FOO MOVEI B,PNAME PCALL IGET JUMPE A,[ERRL2 ^D167,[SIXBIT \MISSING PRINT NAME IN OBLIST!\]] MOVE D,IDPTR ;found pname MAKID5: JUMPE A,MAKID3 ;not the one MOVS A,(A) MOVE B,(A) CAME B,(D) JRST MAKID3 ;not the one CARA A,A ;ok so far AOBJN D,MAKID5 JUMPN A,MAKID3 ;not the one CARA A,(T) ;this is it CARA B,(C) RPLCA A,(C) RPLCA B,(T) PRET ;pname builder PNAMAK: MOVE T,IDPTR MOVEI TT,C PNAMB: MOVE A,(T) PCALL FWCONS PCALL NCONS RPLCD A,(TT) MOVE TT,A AOBJN T,PNAMB RETC: HRRZ A,C PRET PAGE ;number builder NUMAK: MOVEM A,OLDCH HRRI R,NUMCLS ;number MOVEI A,0 IDPB A,C IDPB A,C HRRZS C CAML C,JRELO ;top of spec pdl JRST SPDLOV MOVSI C,(POINT 7,0,35) HRRI C,(SP) TLNE T,SAWDOT+EXP JRST NUMAK2 ;decimal number or flt pt FOO MOVE A,VIBASE ;ibase integrer SUBI A,INUM0 IFN ROCT,<TLNE T,OCTNM MOVEI A,10 ;octal number > PCALL NUM NUMAK4: MOVEI B,FIXNU NUMAK6: TLNE T,MINSGN MOVNS A JRST MAKNUM NUMAK2: PCALL NUM10 MOVEM A,TT TLNN T,SAWDOT JRST [PCALL FLOAT1 ;flt pt without fraction MOVE TT,A JRST NUMAK3] PCALL NUM10 ;fraction part EXCH A,TT TLNN T,EXP JUMPE AR5,NUMAK4 ;no exponent and no fraction PCALL FLOAT1 EXCH A,TT PCALL FLOAT1 MOVEI AR4,FT01 PCALL FLOSUB FMPR A,B FADRM A,TT NUMAK3: PCALL NUM10 ;exponent part MOVE AR5,A MOVEI AR4,FT-1 TLNE T,NEXP MOVEI AR4,FT01 ;-exponent PCALL FLOSUB FMPR TT,B ;positive exponent MOVEI B,FLONU MOVE A,TT JFCL 10,FLOOV JRST NUMAK6 PAGE FLOSUB: MOVSI B,(1.0) TRZE AR5,1 FMPR B,(AR4) JUMPE AR5,CPOPJ LSH AR5,-1 SOJA AR4,FLOSUB+1 ;variable radix integer builder NUM10: MOVEI A,TEN NUM: HRRM A,NUM1 JFCL 10,.+1 ;clear carry0 flag SETZB A,AR5 NUM2: ILDB B,C JUMPE B,CPOPJ ;done NUM1: IMULI A,X ADDI A,-"0"(B) NUM3: JFCL 10,RDBNM AOJA AR5,NUM2 PAGE INTERN: MOVEM A,AR5 PCALL INTERT ;is it in oblist PRET ;found it MOVE A,AR5 ;not there CARA B,(A) CAIE B,STRNG JRST MAKID2 ;put it there CDRA A,(A) PCALL PNGNK1 ;make an id of it JRST MAKID2 REMOB: JUMPE A,CPOPJ ;never remove NIL JSP D,NILID ;return NIL if not an id PSAVE A PCALL INTERT SKIPA B,CURBUC JRST POPAJ ;not on oblist RHX5: FOO HLRZ C,OBTBL+X(B) CARA T,(C) CAMN T,A JRST [CDRA TT,(C) HRLM TT,@RHX5 JRST POPAJ] REMOB3: MOVE TT,C CDRA C,(C) CARA T,(C) CAME T,A JRST REMOB3 CDRA T,(C) RPLCD T,(TT) SKIPGE C,IDCHPO ;character id ? JRST POPAJ ;no! TRNN C,100 JRST .+3 HRRZM IDCHTAB-100(C) JRST POPAJ HLLZM IDCHTAB(C) POPAJ: PREST A PRET ;Get print name for identifier or string. Return with skip if sucessful. GETPNM: JSP D,ATMTYP JRST .+2 NOPNAM: ERRL0 ^D134,[SIXBIT /NO PRINT NAME!/] CDRA A,(A) CAIN TT,STRNG ;is it a string? JUMPN A,CPOPJ ;yes CAIE TT,ID JRST NOPNAM FOO MOVEI B,PNAME PCALL GET4 JUMPE A,NOPNAM ;didn't find it CARA A,D PRET PAGE ;return NIL if argument is not on the oblist .INTERNP:JSP D,NILID ;return NIL if not an id MOVE AR5,A PCALL GT1PNM ;get first word of pname MOVE B,A LSH B,-1 XCT INT1 ;compute hash code XCT INT1+1 ;get bucket EXCH A,T MOVE B,AR5 JRST FLAGP1 ;SKIPTO subr 1 arg. Skips reading until found character that matches ; first character in the argument SKIPTO: MOVEI AR4,1 PSAVE A PCALL GTFCH PCALL COMM-1 ;read as comment JRST POPAJ RDSLSH: MOVE D,[POINT 18,NQUOT] MOVE R,[POINT 7,[ASCIZ "%'!@/<>["]] MOVEI B,(5B3+2B6+3B8+4B11+2B14) ;Letter JUMPN A,RDSL2 MOVEI B,(3B8) ;Comment AOJA D,RDSL2 RDSL1: DPB B,[POINT 18,CHRTAB(A),19] ILDB B,D RDSL2: ILDB A,R JUMPN A,RDSL1 JRST SCANSET NQUOT: <5B3+2B6+3B8+4B11+2B14+0B17>+<5B21+2B24+3B26+4B29+2B32+0B35> <2B3+2B6+3B8+4B11+2B14+5B17>+<4B21+2B24+3B26+3B29+2B32+0B35> <5B3+2B6+3B8+4B11+2B14+0B17>+<5B21+2B24+3B26+4B29+2B32+0B35> <2B3+2B6+3B8+2B11+2B14+2B17>+<2B21+2B24+3B26+2B29+2B32+3B35> <2B3+2B6+3B8+2B11+2B14+6B17> PAGE ; SCAN -- GENERAL PURPOSE ADAPTER FOR LISP SCANNER OLDSCN: CRLF ;IGEND DBLQT ;STRBEG DBLQT ;STREND XWD PRIN3,"!" ;SLSH POINT 1,CHRTAB(A),1 ;SL1FLD POINT 4,CHRTAB(A),5 ;RATFLD POINT 2,CHRTAB(A),10 ;STRFLD POINT 3,CHRTAB(A),13 ;IDFLD IGEND2: CRLF+X ;IGEND STRBE2: DBLQT ;STRBEG STREN2: DBLQT ;STREND SLSH2: XWD PRIN3C,"!"+X ;SLSH SL1F2: POINT 1,CHRTAB(A),35 ;SL1FLD RATF2: POINT 4,CHRTAB(A),29 ;RATFLD STRF2: POINT 2,CHRTAB(A),31 ;STRFLD IDF2: POINT 3,CHRTAB(A),34 ;IDFLD LETFLD: POINT 1,CHRTAB(A),32 ;ON IF LETTER OR DIGIT ALLFLD: POINT 10,CHRTAB(A),35 ;ALL NEW FIELDS SCANSET:JUMPN A,.+2 SKIPA B,[XWD OLDSCN,IGEND] MOVE B,[XWD IGEND2,IGEND] BLT B,IDFLD EXCH A,OLSCNV# ;Get previous setting PRET PRIN3C: LDB B,LETFLD JRST PRIN2N(B) PAGE SCAN: SETOM NOINFG PCALL RATOM SKIPA PCALL READCH+1 FOO MOVEM A,SCNV MOVEI A,INUM0(R) PRET UNREADCH: PSAVE A PCALL GTFCH MOVEM A,OLDCH JRST POPAJ LETTER: MOVEI B,5B29+3B31+4B34+1B35 LET2: SUBI A,INUM0 DPB B,ALLFLD JRST FALSE DELIMITER: SKIPA B,[2B29+3B31+2B34+0B35] ;A DELIMITER, NOT A LETTER. IGNORE: MOVEI B,3B29+3B31+2B34+0B35 JRST LET2 PAGE SCANINIT: SUBI A,INUM0 SUBI B,INUM0 HRRM A,IGST2 ;IGSTRT MOVEM B,IGEND2 ;IGEND MOVEI B,2B29+3B31+2B34+0B35 ;DELIMITER MOVEI A,177 DPB B,ALLFLD SOJG A,.-1 MOVE A,[XWD "A"-"Z"-1,"A"] MOVEI B,5B29+3B31+4B34+1B35 ;LETTER DPB B,ALLFLD AOBJN A,.-1 MOVE A,[XWD "a"-"z"-1,"a"] DPB B,ALLFLD AOBJN A,.-1 MOVE A,[XWD "0"-"9"-1,"0"] MOVEI B,8B29+3B31+4B34+0B35 ;DIGIT DPB B,ALLFLD AOBJN A,.-1 IGST2: MOVEI A,X MOVEI B,0 ;IGSTRT DPB B,ALLFLD MOVEI A,-INUM0(AR4) ;STREND MOVEM A,STREN2 MOVEI B,2 DPB B,STRF2 MOVEI A,-INUM0(C) ;STRBEG MOVEM A,STRBE2 MOVEI B,9 DPB B,RATF2 MOVEI A,-INUM0(AR5) HRRM AR5,SLSH2 ;SLASHIFIER MOVEI B,4B29+3B31+3B34+0B35 ;SLASHIFIER DPB B,ALLFLD MOVEI A,0 ;NULL MOVEI B,1B29+1B31+1B34+0B35 ;NULL DPB B,ALLFLD MOVEI A,"." MOVEI B,7 DPB B,RATF2 SETZM CHRTAB+IGCRLF ;^Z IS ALWAYS A COMMENT-CHAR. JRST FALSE SUBTTL LISP INTERPRETER SUBROUTINES --- PAGE 11 IF1,PURGE CDR CADDDR: SKIPA A,(A) CADDAR: CARA A,(A) CADDR: SKIPA A,(A) CADAR: CARA A,(A) CADR: SKIPA A,(A) CAAR: CARA A,(A) CAR: CARA A,(A) PRET CDDDDR: SKIPA A,(A) CDDDAR: CARA A,(A) CDDDR: SKIPA A,(A) CDDAR: CARA A,(A) CDDR: SKIPA A,(A) CDAR: CARA A,(A) CDR: CDRA A,(A) PRET CAADDR: SKIPA A,(A) CAADAR: CARA A,(A) CAADR: SKIPA A,(A) CAAAR: CARA A,(A) JRST CAAR CDADDR: SKIPA A,(A) CDADAR: CARA A,(A) CDADR: SKIPA A,(A) CDAAR: CARA A,(A) JRST CDAR CAAADR: SKIPA A,(A) CAAAAR: CARA A,(A) JRST CAAAR CDDADR: SKIPA A,(A) CDDAAR: CARA A,(A) JRST CDDAR CDAADR: SKIPA A,(A) CDAAAR: CARA A,(A) JRST CDAAR CADADR: SKIPA A,(A) CADAAR: CARA A,(A) JRST CADAR RPLACA: RPLCA B,(A) PRET RPLACD: RPLCD B,(A) PRET PAGE QUOTE: CARA A,(A) ;car and quote duplicated for backtrace PRET AASCII: PCALL NUMVAL LSH A,^D29 PNGNK2: PCALL BNCONS PNGNK1: FOO HRLI A,PNAME PCALL DCONSA PCALL NCONS IDCONS: HRLI A,ID JRST DCONSA NCONS: HRLZS A JRST DCONSA CONS: EXCH B,A XCONS: HRL A,B DCONSA: IFN CNSPRB,< CAIN F,ILLAD PCALL AGC> EXCH A,(F) EXCH A,F AOS CONSVAL PRET FW0CNS: MOVEI A,0 FWCONS: JUMPN FF,FWC1 EXCH A,FWC0# PCALL AGC EXCH A,FWC0 FWC1: EXCH A,(FF) EXCH A,FF PRET PAGE IFE STL,< SASSOC: PCALL SAS1 JCALLF 0,(C) PRET SAS0: CARA B,T SAS1: JUMPE B,CPOPJ MOVS T,(B) MOVS TT,(T) CAIE A,(TT) JRST SAS0 CDRA A,T JRST CPOPJ1 ATSOC: PCALL SAS1 JRST FALSE > ;end of IFE STL IFN STL,< ATSOC: EXCH A,B PCALL GET4 SKIPE A CDRA A,TT > PRET REVERSE:SKIPN T,A PRET MOVEI A,NIL HLL A,(T) CDRA T,(T) PCALL DCONSA JUMPN T,.-3 CPOPJ: PRET LENGTH: MOVEI B,0 LNGTH1: JSP D,ATMTYP JRST FIX1 CDRA A,(A) AOJA B,LNGTH1 LAST: MOVE C,A CDRA A,(A) JSP D,NATMTYP JRST LAST JRST RETC NATMTYP:SETZ TT, CAILE A,INUMIN JRST 1(D) CARA TT,(A) CAILE TT,ATMIN JRST 1(D) JRST (D) PAGE PATOM: MOVEI D,TRFA PATMTP: JUMPE A,NILIN SETZ TT, CAILE A,INUMIN JRST (D) ;inum CAIGE A,@GCP1 ;Base of FWS CAIGE A,@GCPP1 ;Base of FS SOJA TT,(D) ;not a Lisp cell NILIN: CARA TT,(A) CAILE TT,ATMIN JRST (D) ;atom JRST 1(D) ATOM: MOVEI D,TRFA ATMTYP: SETZ TT, CAILE A,INUMIN JRST (D) ;inum CARA TT,(A) CAILE TT,ATMIN JRST (D) ;atom JRST 1(D) PAIRP: JSP D,ATMTYP MOVEI A,NIL PRET CONSTANTP:JSP D,ATMTYP CAIN TT,ID MOVEI A,NIL PRET STRINGP:JSP D,ATMTYP CAIE TT,STRNG MOVEI A,NIL PRET NUMBERP:JSP D,ATMTYP CAILE TT,FLONU FALSE: MOVEI A,NIL PRET FIXP: JSP D,ATMTYP CAILE TT,FIXNU MOVEI A,NIL PRET FLOATP: JSP D,ATMTYP CAIE TT,FLONU MOVEI A,NIL PRET INUMP: CAIG A,INUMIN MOVEI A,NIL PRET PAGE BIGP: JSP D,ATMTYP CPOSNU: CAILE TT,POSNU JRST FALSE JUMPE TT,FALSE PRET IDP: MOVEI D,TRUE NILID: CAILE A,INUMIN JRST FALSE HLLE TT,(A) AOJE TT,(D) JRST FALSE ;return NIL if not an id ;give error if not id CHKID: CAILE A,INUMIN JRST NOID HLLE TT,(A) AOJE TT,(D) NOID: ERRE1 ^D25,[SIXBIT /IS NOT AN IDENTIFIER!/] EQ: CAMN A,B TRFA: JRST TRUE JRST FALSE ZEROP: JSP D,ONUMV JRST FALSE ;BIGNUM CAN'T BE ZERO NOT: NULL: JUMPN A,FALSE TRUE: FOO MOVEI A,TRUTH PRET LITER: PCALL .INTERNP JUMPE A,CPOPJ ROT T,7 CAIL T,"A" CAILE T,"z" JRST FALSE CAILE T,"Z" CAIL T,"a" JRST RETB JRST FALSE DIGIT: PCALL .INTERNP JUMPE A,CPOPJ ROT T,7 CAIL T,"0" CAILE T,"9" JRST FALSE JRST RETB PAGE IF1,<PURGE GET> ;MONSYM has defined GET, so purge it. GETD: FOO MOVEI B,FUNCELL GET: JSP D,NILID ;return NIL if not id IGET: PCALL GET1 SKIPE A GET2: CARA A,D PRET GET1: CDRA A,(A) GET4: JUMPE A,CPOPJ GET0: MOVS TT,(A) MOVS D,(TT) CAIN B,(D) PRET CARA A,TT JUMPN A,GET0 PRET IFE STL,< GETL: CDRA A,(A) GETL0: CARA T,(A) CARA T,(T) MOVE C,B GETL1: MOVS TT,(C) CAIN T,(TT) JRST CAR CARA C,TT JUMPN C,GETL1 CDRA A,(A) JUMPN A,GETL0 PRET > REMD: FOO MOVEI B,FUNCELL REMPROP:JSP D,NILID ;return NIL if not id REMP1: MOVE T,A CDRA A,(T) JUMPE A,CPOPJ ;we are done if it is not there MOVS TT,(A) MOVS D,(TT) CAIE B,(D) JRST REMP1 HLRM TT,(T) JUMPN T,GET2 HLROM TT,CNIL3 ;reset NIL JRST GET2 PAGE PUTD: EXCH A,C IPUTD: PCALL XCONS EXCH A,C FOO MOVEI B,FUNCELL PUT: JSP D,CHKID MOVE T,A MOVE A,B JSP D,CHKID MOVE A,T PCALL GET1 JUMPN A,CSET1 MOVE A,C PCALL XCONS CDRA B,(T) PCALL CONS RPLCD A,(T) JUMPN T,CDAR RPLCD A,CNIL3 ;set NIL JRST CDAR CSET1: FOO CAIN B,VALUE CARA TT,D RPLCD C,(TT) JRST RETC IFE STL,< DEFPROP: CDRA C,(A) CDRA B,(C) CARA A,(A) CARA B,(B) CARA C,(C) PSAVE A PCALL PUT JRST POPAJ > MKCODE: PCALL NUMVAL IMKCODE:HRLI A,CODE JRST DCONSA CODEP: JSP D,ATMTYP CAIGE TT,CODMIN JRST FALSE CAIL TT,ID MOVEI A,NIL PRET PAGE FLAGP: JSP D,NILID CDRA A,(A) FLAGP1: PCALL MEMQ+1 JUMPN A,TRUE PRET FLAG: MOVEI D,FLAG1 FLAGO: HRRM D,FLAGX MOVE T,A MOVE A,B JSP D,CHKID ;flag indicator must be id FLAGL: JUMPE T,FALSE CARA A,(T) FLAGX: PCALL X CDRA T,(T) JRST FLAGL FLAG1: JSP D,CHKID ;may only flag id CDRA A,(A) PCALL MEMQ+1 JUMPN A,CPOPJ CARA C,(T) CDRA A,(C) PCALL XCONS FLAG2: RPLCD A,(C) JUMPN C,CPOPJ RPLCD A,CNIL3 PRET REMFLAG:JSP D,FLAGO JSP D,NILID FLAG3: MOVE C,A CDRA A,(C) JUMPE A,CPOPJ CARA D,(A) CAIE B,(D) ;B is preserved by XCONS JRST FLAG3 CDRA A,(A) JRST FLAG2 PAGE EQUAL: MOVE C,P ;Unfortunately, if BIGNUMs are involved here, EQUAL1: CAMN A,B ; potential AGC so save your variables. JRST TRUE JSP D,PATMTP SKIPA T,TT ;ATOM HRROI T,(TT) EXCH A,B JSP D,PATMTP JRST EQLATM ;ATOM AOJGE T,NOEQL ;not atom but first arg was PSAVE A PSAVE B CDRA A,TT CARA B,(B) PCALL EQUAL1 PREST B PREST A CDRA A,(A) CDRA B,(B) JRST EQUAL1 EQLATM: CAME T,TT ;same atom type ? JRST NOEQL ;no, try for floating point JUMPLE TT,NOEQL ;Inum and non lisp cell adresses must be EQ CAILE TT,POSNU ;Bignum CAIN TT,STRNG JRST EQS CAIN TT,VECT JRST EQV CDRA A,(A) CDRA B,(B) MOVE A,(A) CAMN A,(B) JRST TRUE NOEQL: MOVE P,C JRST FALSE PAGE EQS: CDRA D,(A) CDRA TT,(B) EQS2: JUMPE D,NOEQL MOVS D,(D) MOVS TT,(TT) MOVE B,(TT) CAME B,(D) JRST NOEQL HLRZS D HLRZS TT JUMPN TT,EQS2 JUMPN D,NOEQL JRST TRUE EQV: CDRA TT,(A) CDRA D,(B) MOVE B,-1(TT) CAME B,-1(D) JRST NOEQL ;different size PSAVE B HRLI TT,(POINT 18) PSAVE TT HRLI D,(POINT 18) PSAVE D EQV2: ILDB A,(P) ILDB B,-1(P) PCALL EQUAL1 SOSL -2(P) JRST EQV2 P3DROP JRST TRUE PAGE SUBAS==EXARG SUBBS==EXARG+1 SUBST: MOVEM A,SUBAS# ;Recurse..find subportion in C =B, and MOVEM B,SUBBS# ; re-CONS with A instead. SUBS0: MOVE A,SUBAS MOVE B,SUBBS PSAVE C MOVE A,C PCALL EQUAL PREST C JUMPN A,SUBS3 CAILE C,INUMIN JRST SUBS1 CARA T,(C) CAILE T,ATMIN JRST SUBS1 PSAVE C CARA C,(C) PCALL SUBS0 EXCH A,(P) CDRA C,(A) PCALL SUBS0 PREST B JRST XCONS SUBS1: SKIPA A,C SUBS3: HRRZ A,SUBAS PRET PAGE NCONC: JUMPE A,PROG2 MOVE TT,A MOVE C,TT CDRA TT,(C) JUMPN TT,.-2 RPLCD B,(C) PRET APPEND: JUMPE A,PROG2 MOVEI C,AR4 MOVE TT,A APP1: CARA A,(TT) PSAVE B PCALL CONS ;saves b PREST B RPLCD A,(C) MOVE C,A CDRA TT,(TT) JUMPN TT,APP1 JRST RETAR4 PROGN: SKIPN B,A PRET PROGN1: PSAVE B CARA A,(B) PCALL EVAL PREST B COND2: SKIPL C,PA4 JRST RETC ;exit if a RETURN was found CDRA B,(B) SKIPL PA3 ;exit if a GO was found JUMPN B,PROGN1 PRET PAGE MEMBER: MOVEM A,SUBAS MEMB1: JUMPE B,FALSE MOVE A,SUBAS PSAVE B CARA B,(B) PCALL EQUAL AJMN: JUMPN A,POPAJ PREST B CDRA B,(B) JRST MEMB1 MEMQ: EXCH A,B JUMPE A,CPOPJ MOVS C,(A) CAIN B,(C) PRET CARA A,C JUMPN A,MEMQ+2 PRET AND: JUMPE A,TRUE SKIPA C,AJMN OR: MOVSI C,(JUMPE A,) JUMPE A,CPOPJ HRRI C,ANDOR PSAVE A PSAVE C JRST ANDORI ANDOR: EXCH A,-1(P) CDRA A,(A) JUMPE A,POP1AJ MOVEM A,-1(P) ANDORI: CARA A,(A) PCALL EVAL XCT (P) POP2J: P2DROP PRET POP1AJ: P1DROP JRST POPAJ PAGE GENSYM: MOVE B,[POINT 7,GNUM,34] MOVNI C,4 MOVEI TT,"0" GENSY2: LDB T,B AOS T DPB T,B CAIG T,"9" JRST GENSY1 DPB TT,B ADD B,[XWD 70000,0] AOJN C,GENSY2 GENSY1: MOVE A,GNUM PCALL FWCONS PCALL NCONS JRST PNGNK1 GNUM: ASCII /G0000/ ;* IFE STL,< CSYM: CARA A,(A) PSAVE A PCALL GT1PNM MOVEM A,GNUM JRST POPAJ > GT1PNM: PCALL GETPNM CARA A,(A) MOVE A,(A) PRET PAGE LIST: FOO MOVEI B,CEVAL JRST MAPCAR ILIST: MOVEI T,0 JUMPE A,ILIST2 ILIST1: PSAVE A ;Evals list, leaving on P, & neg # in T. CARA A,(A) PSAVE TT HRLM T,(P) PCALL EVAL ILIST3: PREST TT HLRE T,TT EXCH A,(P) CDRA A,(A) SOS T JUMPN A,ILIST1 ILIST2: JRST (TT) MAPCAN: TLO B,400000 MAPCON: TLOA B,100000 MAPCAR: TLO B,400000 MAPLIST:TLOA B,200000 MAPC: TLO B,400000 MAP: JUMPE A,FALSE PSAVE A HLLM B,(P) HRLI B,(FCALL 1,) PSAVE B PSAVE A HRLZM P,(P) MAPL2: SKIPGE -2(P) CARA A,(A) ;MAPC or MAPCAR. XCT -1(P) LDB C,[POINT 2,-2(P),2] JUMPE C,MAP1 TRNN C,1 PCALL NCONS JUMPE A,MAP1 ;Case of NIL returned in MAPCAN, MAPCON HLR B,(P) RPLCD A,(B) TRNE C,1 PCALL LAST HRLM A,(P) MAP1: CDRA A,@-2(P) HRRM A,-2(P) JUMPN A,MAPL2 PREST AR4 P2DROP JRST RETAR4 PAGE PA3: 0 ;lh=0=>rh =next prog statement * ;lh - =>rh = tag to go to PA4: -1,,0 ;lh=-1,rh=pntr to prog less bound var list * ;lh=+,rh return value PROG: PSAVE PA3 PSAVE PA4 CARA T,(A) CDRA A,(A) HRROM A,PA4 MOVEM A,PA3 PUSH SP,[0] ;mark for unbind JUMPE T,PG0 PG7A: CARA A,(T) MOVEI AR4,NIL PCALL BIND CDRA T,(T) JUMPN T,PG7A PG0: SKIPA T,PA3 PG5A: MOVE T,A PG1: JUMPE T,PG2 CARA A,(T) CDRA T,(T) CARA B,(A) CAILE B,ATMIN JRST PG1 MOVEM T,PA3 PCALL EVAL SKIPL A,PA4 JRST PG4 ;return SKIPL T,PA3 JRST PG1 PG5: JUMPE A,EG1 CARA TT,(A) CDRA A,(A) CAIN TT,(T) JRST PG5A ;found tag JRST PG5 PG2: TDZA A,A PG4: HRRZS A PCALL UNBIND ERRP4: PREST PA4 PREST PA3 PRET GO: CARA A,(A) HRROM A,PA3 IFE STL,<CARA B,(A) CAILE B,ATMIN> JRST FALSE IFE STL,<PCALL EVAL JRST GO+1> PAGE RETURN: HRRZM A,PA4 PRET SETQ: CARA B,(A) PSAVE B PCALL CADR PCALL EVAL MOVE B,A PREST A SET: MOVE AR4,B PCALL BIND SUB SP,[XWD 1,1] RETAR4: CDRA A,AR4 PRET CON2: CDRA A,(T) COND: JUMPE A,CPOPJ ;entry PSAVE A CARA A,(A) CARA A,(A) PCALL EVAL PREST T JUMPE A,CON2 CARA B,(T) JRST COND2 EG1: HRRZ A,T ERRE1 ^D26,[SIXBIT /UNDEFINED PROG TAG-GO!/] SUBTTL ARITHMETIC SUBROUTINES --- PAGE 12 IFE STL,< ;macro expander -- (foo a b c) is expanded into (*foo (*foo a b) c) EXPAND: MOVE C,B CDRA A,(A) PCALL REVERSE JRST EXPA1 EXPN1: MOVE C,B EXPA1: CDRA T,(A) CARA A,(A) JUMPE T,CPOPJ PSAVE A MOVE A,T PCALL EXPA1 EXCH A,(P) PCALL NCONS PREST B PCALL XCONS HRL A,C JRST DCONSA > PAGE ADD1: CAILE A,INUMIN CAILE A,ATMIN-1 SKIPA B,[INUM0+1] AOJA A,CPOPJ .PLUS: JSP C,OP ADD A,TT FADR A,TT JRST BPLUS SUB1: CAILE A,INUMIN+1 CAILE A,ATMIN SKIPA B,[INUM0+1] SOJA A,CPOPJ .DIF: JSP C,OP SUB A,TT FSBR A,TT JRST BDIF .TIMES: JSP C,OP IMUL A,TT FMPR A,TT JRST BTIMES .QUO: CAIN B,INUM0 JRST ZERODIV JSP C,OP IDIV A,TT FDVR A,TT JRST BQUO .GREAT: EXCH A,B JUMPE B,FALSE .LESS: JUMPE A,CPOPJ CAIN B,INUM0 JRST MINUSP JSP C,OP JRST COMP2 JRST COMP2 JRST BCMPR COMP2: CAML A,TT JRST FALSE JRST TRUE PAGE MAKNUM: CAIN B,FIXNU JRST FIX1A FLO1A: MOVEI B,FLONU JRST FQCONS FIX1B: SUBI A,INUM0 MOVEI B,FIXNU FQCONS: PCALL FWCONS JRST XCONS IF1,PURGE NUMVAL ;To avoid confusion with NUMVAL in STENEX NUMVLX: JFCL 17,.+1 ONUMV: MOVEI B,FIXNU CAILE A,INUMIN JRST ONUMV1 CARA B,(A) CAILE B,ATMIN CAILE B,FLONU NUMV2: ERRE1 ^D27,[SIXBIT /IS NOT A NUMBER!/] CDRA A,(A) CAIG B,POSNU JRST (D) ;Normal return if bignum SKIPA A,(A) ONUMV1: SUBI A,INUM0 JRST 1(D) ;Return with skip if fixnum or flonum NUMVAL: CAILE A,INUMIN JRST FIXV1 CARA D,(A) CAIE D,FIXNU ERRE2 ^D46,[SIXBIT /IS NOT A WORD SIZE INTEGER/] CDRA A,(A) FIXV2: SKIPA A,(A) FIXV1: SUBI A,INUM0 PRET PAGE FLOAT: PSAVE A JSP D,ONUMV JRST BFLOT CAIN B,FLONU JRST POPAJ MOVEI D,FLO1A MOVEM D,(P) FLOAT1: IDIVI A,400000 SKIPE A TLC A,254000 TLC B,233000 FADR A,B PRET FIX: PSAVE A JSP D,ONUMV JRST POPAJ ;BIGNUM CAIE B,FLONU JRST POPAJ MOVEM A,(P) MULI A,400 TSC A,A JFCL 17,.+1 ASH B,-243(A) FIX2: JFCL 10,BFIX P1DROP FIX1: MOVE A,B JRST FIX1A MINUSP: JSP D,ONUMV JRST MINSP2 ;BIGNUM JUMPGE A,FALSE JRST TRUE MINUS: JSP D,NUMVLX JRST MINS2 ;BIGNUM MOVNS A ABS2IN: JFCL 10,FIXOV3 JRST MAKNUM ABS: JSP D,NUMVLX JRST ABS2 MOVMS A JRST ABS2IN PAGE DIVIDE: CAIN B,INUM0 JRST ZERODIV JSP C,OP JRST RDIV JRST ILLNUM JRST BDIV RDIV: JFCL 17,.+1 IDIV A,TT JFCL 10,DIVMB ;FREAK CASE OF -2**35 IN A. PSAVE B PCALL FIX1A EXCH A,(P) PCALL FIX1A PREST B JRST XCONS REMAINDER: PCALL DIVIDE JRST CDR FIXOV: ERRL0 ^D135,[SIXBIT /INTEGER OVERFLOW!/] ZERODIV:ERRL0 ^D136,[SIXBIT /ZERO DIVISOR!/] FLOOV: ERRL0 ^D137,[SIXBIT /FLOATING OVERFLOW!/] ILLNUM: ERRL0 ^D138,[SIXBIT /NON-INTEGRAL OPERAND!/] GCD: JSP C,OP JRST GCD2 JRST ILLNUM JRST BGCD GCD2: JFCL 17,.+1 MOVMS A MOVMS TT JFCL 10,DIVMB ;FREAK CASE OF -2**35 IN A OR TT. ;euclid's algorithm GCD3: CAMG A,TT EXCH A,TT JUMPE TT,FIX1A IDIV A,TT MOVE A,B JRST GCD3 DIVMB: MOVEI B,FIXNU PCALL BIGTSB JRST @2(C) PAGE ;general arithmetic op code routine for mixed types OP: CAIG A,INUMIN JRST OPA1 SUBI A,INUM0 CAIG B,INUMIN JRST OPA2 HRREI TT,-INUM0(B) XCT (C) ;inum op (cannot cause overflow) FIX1A: ADDI A,INUM0 CAILE A,INUMIN CAILE A,ATMIN JRST FIX1B PRET NONUM1: MOVE A,TT OPA1: CARA T,(A) CAILE T,ATMIN CAILE T,FLONU JRST NUMV2 ;A is not a number CDRA A,(A) CAIE T,FIXNU JRST OPA6 SKIPA A,(A) OPA2: ;first arg is a FIXNUM MOVEI T,FIXNU CAILE B,INUMIN JRST OPB2 MOVE TT,B CARA B,(B) CAILE B,ATMIN CAILE B,FLONU JRST NONUM1 ;TT is not a number CDRA TT,(TT) CAIE B,FIXNU JRST OPA5 SKIPA TT,(TT) OPB2: HRREI TT,-INUM0(B) MOVE AR4,A ;<MOVEI B,FIXNU> supplied by DIVMB. JFCL 17,.+1 XCT (C) ;fixed pt op OPOV: JFCL 10,FIXOVL JRST FIX1A OPA6: CAILE B,INUMIN ;first arg is not FIXNUM JRST OPB7 CDRA TT,(B) CARA B,(B) CAIE B,FLONU JRST OPB3 ;second arg is not a FLONUM CAIN T,FLONU ;second arg is FLONUM; test first arg SKIPA A,(A) PCALL BFLT ;not a FLONUM, must be BIGNUM; float it MOVE TT,(TT) OPR: JFCL 17,.+1 XCT 1(C) ;flt pt op JFCL 10,FLOOV JRST FLO1A PAGE OPA5: ;first arg is FIXNUM but second arg is not CAIE B,FLONU ;is second arg a FLONUM JRST BIGOP ;no. it must be a bignum PCALL FLOAT1 JRST OPR-1 OPB3: ;first arg is not fixnum, second arg is not flonum CAIE B,FIXNU ;is second arg FIXNUM ? JRST OPB9 ;no. it must be bignum SKIPA TT,(TT) OPB7: HRREI TT,-INUM0(B) MOVEI B,FIXNU CAIE T,FLONU JRST BIGOP MOVE A,(A) EXCH A,TT PCALL FLOAT1 OPB8: EXCH A,TT JRST OPR OPB9: ;second arg is bignum CAIE T,FLONU ;is first arg a FLONUM ? JRST BIGOP ;no MOVE A,(A) EXCH A,TT EXCH B,T PCALL BFLT JRST OPB8 BIGOP: PCALL BIGTST JRST @2(C) SUBTTL BIGNUM ARITHMETIC ROUTINES --- PAGE 13 ;Power of ten PWR10: MOVEM B,BASEX# MOVE C,B IMUL B,B ;BASE^2 IMUL B,B ;BASE^4 IMUL B,C ;BASE^5 IMUL B,B ;BASE^ten MOVEM B,BASE10# PRET B0CONS: MOVEI A,0 BNCONS: MOVEI B,0 BCONS: PCALL FWCONS JRST CONS ;Bignum PRINT BPRI: XCT "-",CTY PCALL COPY FOO MOVE B,VBASE SUBI B,INUM0 PCALL PWR10 PCALL BPRJ MOVE C,BASEX JRST PRINI4 BPRJ: MOVE B,BASE10 PCALL Q1 JUMPE B,BPR2 ;zero quotient PSAVE A ;remainder MOVE A,B ;quotient PCALL BPRJ PREST A ;remainder BPR1: MOVEI C,TEN ;print ten digits SOJL C,CPOPJ IDIV A,BASEX HRLM B,(P) PCALL BPR1+1 JRST FP7A1 ;particular TYO for digit ;Ignore leading zero digits for first word BPR2: JUMPE A,CPOPJ IDIV A,BASEX HRLM B,(P) PCALL BPR2 JRST FP7A1 ;particular TYO for digit PAGE ;Divides bignum in A by integer in B ;Destroys original bignum ;Returns remainder in A, quotient in B .Q1: Q1: MOVEM B,Y# PSAVE A CDRA A,(A) JUMPE A,Q1A PCALL Q1+1 PREST C RPLCD B,(C) CARA T,(C) MOVE B,(T) DIV A,Y Q1B: MOVEM A,(T) ;replace old digit MOVE A,B MOVE B,C PRET Q1A: PREST C CARA T,(C) MOVE A,(T) IDIV A,Y JUMPN A,Q1B ;non-zero quotient - keep it HRRZM FF,(T) ;reclaim full word MOVE FF,T HRRZM F,(C) ;reclaim free word HRRZ F,C MOVEI C,0 JRST Q1B+1 PAGE ;Bignum READ RDBNM: PSAVE [NIL] ;initial value of bignum MOVSI C,700 HRRI C,(SP) ;byte pointer to spec pdl MOVEM T,TSAV# MOVEM C,RDPTR# HRRZ B,NUM1 ;base of number PCALL PWR10 RDNM1: MOVEI C,TEN ;ten digits at a time MOVEI A,0 ILDB B,RDPTR JUMPE B,RDNM2 ;end of bignum IMUL A,BASEX ADDI A,-"0"(B) SOJG C,.-4 MOVE B,BASE10 PCALL RDSUB JRST RDNM1 RDNM2: CAIN C,TEN ;no digits in last superdigit JRST RDNM3 HRREI C,-TEN(C) ;number of digits in last MOVEI B,1 IMUL B,BASEX AOJL C,.-1 ;compute basex^(number of digits) PCALL RDSUB RDNM3: LDB B,[POINT 1,TSAV,14] ;MINSGN TRC B,POSNU ;sign of bignum PREST A P1DROP JRST XCONS RDSUB: MOVE C,-1(P) PCALL BTIME1 ;bignum(C)*int(B)+int(A) MOVEM A,-1(P) PRET PAGE BTIME0: PSAVE B PCALL COPY MOVE C,A PREST B MOVEI A,0 ;big(C)*int(B)+int(A) BTIME1: JUMPE C,BNCONS ;end of bignum MOVEM B,MULR# ;multiplier PSAVE C ;bignum BT1B: MOVEM A,CARRY# MOVS T,(C) MOVE A,(T) MUL A,MULR ADD B,CARRY TLZE B,SIGN ADDI A,1 BT1E: MOVEM B,(T) ;store low order product+carry in bignum HLRZS T ;(CDR bignum) JUMPE T,BT1C ;end of bignum MOVE C,T JRST BT1B BT1C: JUMPE A,POPAJ ;no high order part PCALL BNCONS ;conses for remaining high order part RPLCD A,(C) ;RPLACD end of bignum JRST POPAJ PAGE ;Bignum copy .COPY: COPY: JUMPE A,CPOPJ CARA B,(A) PSAVE (B) CDRA A,(A) PCALL COPY MOVE B,A PREST A JRST BCONS ;Bignum reclaim RECLAIM:CAILE A,INUMIN PRET EXCH A,F EXCH A,(F) HLRZ B,A ;type HRRZS A CAIE B,POSNU CAIN B,NEGNU JRST UNCONS PRET ;BIGNUM UNCONS UNCONS: JUMPE A,CPOPJ CARA B,(A) MOVEM FF,(B) MOVE FF,B EXCH A,F EXCH A,(F) HRRZS A JRST UNCONS ;BIGNUM MINUSP MINSP2: CAIN B,POSNU JRST FALSE JRST TRUE ;BIGNUM MINUS MINS2: TRCA B,1 ABS2: MOVEI B,POSNU ;BIGNUM ABS JRST XCONS ;compare two bignums A<B BCMPR: PCALL BDIF PSAVE A PCALL MINUSP EXCH A,(P) PCALL RECLAIM JRST POPAJ PAGE ;DIFFERENCE of two bignums BDIF: TRC TT,1 ;complement sign of bignum in B ;sum of two bignums ;bignums in A and B; sign(A) in T, sign(B) in TT BPLUS: PSAVE B PCALL COPY EXCH A,(P) PCALL COPY PREST C MOVE B,A MOVEI A,0 CAME T,TT JRST BDIF1 ;signs different PSAVE T ;sign of result PCALL BADD PREST B JRST XCONS BDIF1: CAIN TT,POSNU EXCH B,C PCALL BSUB ;posnum in C, negnum in B JUMPL B,BDIF3 PCALL SUPRSS JRST MAKPOS BDIF3: PCALL COMPLM MOVEI B,NEGNU JRST MAKBIG BSUB: MOVNI TT,1 MOVSI T,(SUB TT,(B)) JRST BAS BADD: MOVEI TT,1 MOVSI T,(ADD TT,(B)) PAGE ;cry(A)(+ or -) big(B) + big(C) into A, sign into B. ;destroys both bignums BAS: HRRM TT,BCRY PSAVE B BP2A: HRRM B,BTMP MOVS B,(B) CARA TT,(C) EXCH TT,FF EXCH TT,(FF) ;reclaim full word EXCH C,F EXCH C,(F) ;reclaim free word ADD TT,A XCT T ;big(C) (+ or -) big (B) MOVEI A,0 TLZE TT,SIGN ;turn off high bit BCRY: HRREI A,. ;set carry if overflow or negative BP2B: MOVEM TT,(B) HLRZS B HRRZS C JUMPE B,BP2F ;end of B JUMPN C,BP2A JRST BP2D ;finish with carry (+ or -) big(B) BP2F: JUMPE C,BP2H ;end of C also EXCH B,C RPLCD B,@BTMP ;RPLACD end of big(B) with rest of C MOVSI T,(ADD TT,(B)) ;finish with big(C) + carry BP2D: HRRM B,BTMP MOVS B,(B) MOVE TT,A XCT T ;carry (+ or -) integer JUMPL TT,BP2K MOVEM TT,(B) CAME T,[SUB TT,(B)] JRST POSXIT ;can quit now MOVEI A,0 ;turn off carry JRST BP2L ;continue to negate BP2K: HRRE A,BCRY TLZ TT,SIGN ;make high bit zero MOVEM TT,(B) BP2L: HLRZS B JUMPN B,BP2D BP2H: JUMPLE A,XIT ;no carry PCALL BNCONS BTMP: HRRM A,. ;RPLACD end of bignum with carry POSXIT: MOVEI B,0 ;sign positive JRST POPAJ XIT: MOVE B,A ;sign in B JRST POPAJ PAGE ;suppress leading zeros from bignum SUPRSS: SKIPA C,[JRST COMPL7] ;complement bignum (2^35 complement) COMPLM: MOVSI C,(SUBM T,(B)) JUMPE A,CPOPJ PSAVE A HRLZI T,SIGN MOVEI TT,0 COMPL4: MOVS B,(A) SKIPN (B) JUMPE TT,COMPL3 XCT C HRLOI T,SIGN-1 COMPL7: SKIPE (B) MOVEM A,TT COMPL3: HLRZ A,B JUMPN A,COMPL4 ;continue JUMPE TT,COMPL5 ;all zeros CDRA A,(TT) HLLZS (TT) ;RPLACD high order non-zero with NIL COMPL6: PCALL UNCONS ;UNCONS leading zeros JRST POPAJ COMPL5: EXCH A,(P) JRST COMPL6 ;sign(TT)*sign(T) into TT MQSIGN: CAIE T,POSNU TRC TT,1 PRET PAGE ;bignum multiply ;big (A) * big (B) into A, signs in T,TT BTIMES: PCALL MQSIGN PSAVE TT ;save sign of result PCALL BMUL PREST B JRST MAKBIG ;0(P) is partial result ;-1(P) is remaining reversed multiplier ;-2(P) is multiplicand BMUL: PSAVE B PCALL REVERSE PSAVE A MOVEI A,0 PSAVE A BTLOOP: SKIPN C,-1(P) JRST BTEND ;end of multiplier JUMPE A,BTLP2 ;first time MOVE B,A PCALL FWCONS-1 PCALL CONS ;increase length of product BTLP2: MOVEM A,(P) MOVE A,-2(P) PCALL COPY MOVS B,(C) ;next multiplier digit MOVE C,A HLRZM B,-1(P) MOVE B,(B) MOVEI A,0 PCALL BTIME1 MOVE C,(P) JUMPE C,BTLOOP ;no add needed on first time MOVE B,A MOVEI A,0 PCALL BADD JRST BTLOOP BTEND: P3DROP JRST SUPRSS PAGE ;extensions of interpreter routines and tests REPEAT 0,< ;ONUMVAL for bignums goes here NUMVD2: HRRZ C,0(P) ;address of <PCALL ONUMVAL> +1 FOO CAIL C,FS ;LISP-system area of code? PRET ; No, user or BPS gets a BIGNUM-pntr back. P1DROP CAIN C,ZEROP+1 JRST FALSE CAIN C,MINUSP+1 JRST MINSP2 CAIN C,MINUS+1 JRST MINS2 CAIN C,ABS+1 JRST ABS2 CAIN C,FIX+2 JRST POPAJ CAIN C,FLOAT+2 JRST BFLOT IFN MOD,<CAIN C,CMOD+1 JRST CMOD1 > PAGE > ;number overflow, use bignums FIXOVL: MOVEI C,(C) CAIN C,.TIMES+1 JRST REMUL ;TIMES overflowed. Recompute. JUMPE A,FIXOV2 ;PLUS(mbeta mbeta) overflows 2 bits. FIXOV3: TLC A,SIGN ;all other cases just overflowed 1 bit MOVM B,A MOVE TT,A MOVEI A,1 FIXOVX: PCALL MKBG JRST XCONS FIXOV2: SETZ B, SETO TT, ;(NEGATIVE). MOVEI A,2 ;== -2*beta. JRST FIXOVX REMUL: MOVE A,AR4 MOVEI T,FIXNU PCALL BIGTSB JRST BTIMES ;use the bignum multiplication MAKPOS: MOVEI B,POSNU ;Make a LISP number from bignum -- A is list, B is sign MAKBIG: JUMPE A,FIX1A ;NULL list produces zero CDRA C,(A) JUMPN C,XCONS ;a real bignum CARA C,(A) ;only one word of precision MOVE C,(C) CAIE B,POSNU MOVNS C ;negative PCALL UNCONS MOVE A,C JRST FIX1A PAGE BIGTSB: MOVEI B,FIXNU ;Transforms general numbers in (A,T),(TT,B) ;into bignums in (A,T),(B,TT), values in A,B; signs in T,TT. BIGTST: EXCH B,T ;funny ac usage in lisp PSAVE T PSAVE TT PCALL BIGSUB ;convert number originally in A,T EXCH B,-1(P) EXCH A,(P) PCALL BIGSUB ;convert number originally in TT,B MOVE TT,B MOVE B,A PREST A PREST T PRET BIGSUB: CAIE B,POSNU CAIN B,NEGNU PRET ;no conversion necessary CAIE B,FIXNU JRST NUMV2 ;already checked for flonum MOVEI B,0 MOVE TT,A ;get value of number MOVM A,TT JUMPGE A,BIGSRT MOVEI A,1 ;bastard case of -2^35 MKBG: PCALL MKBIG JRST BIGSND BIGSRT: PCALL BCONS BIGSND: SKIPGE TT SKIPA B,[NEGNU] MOVEI B,POSNU PRET MKBIG: PSAVE B PCALL BNCONS MOVE B,A PREST A JRST BCONS PAGE BFLOT: MOVEI T,FLO1A MOVEM T,(P) MOVE T,B ;Make a floating pt number out of a bignum BFLT: PSAVE C PSAVE T CAIE T,POSNU CAIN T,NEGNU SKIPA T,[-200] JRST NUMV2 BFLT2: MOVE C,B CARA B,(A) CDRA A,(A) ADDI T,43 JUMPN A,BFLT2 ;find last two words of bignum MOVE B,(B) MOVE C,(C) BFLT3: TLNE B,SIGN/2 JRST BFLT4 ASHC B,1 SOJA T,BFLT3 ;normalize B,C BFLT4: JUMPGE T,FLOOV ASH B,-10 DPB T,[POINT 8,B,8] MOVE A,B PREST T PREST C CAIE T,POSNU MOVNS A PRET ;Make a bignum from a flt pt number BFIX: MOVM A,(P) MULI A,400 MOVEI C,-243(A) ;#left shifts needed IDIVI C,43 ;C_#extra words-1, D_#shifts MOVEI A,0 ASHC A,(C+1) PSAVE B PCALL BNCONS MOVE B,A PREST A PCALL BCONS SOJL C,BFIX2 MOVE B,A MOVEI A,0 PCALL BCONS SOJGE C,.-3 BFIX2: PREST TT PCALL BIGSND JRST XCONS PAGE ;Bignum divide BDIV: PCALL MQSIGN ;complement sign of TT if T is negnum PSAVE T ;sign of remainder PSAVE TT ;sign of quotient PCALL DIVSUB BDIV2: EXCH B,(P) PCALL MAKBIG ;quotient MOVE B,-1(P) MOVEM A,-1(P) PREST A PCALL MAKBIG ;remainder PREST B JRST XCONS BQUO: PCALL MQSIGN PSAVE TT PCALL DIVSUB PSAVE A MOVE A,B PCALL UNCONS PREST A PREST B JRST MAKBIG DIVSUB: CDRA C,(B) JUMPN C,DIV1 ;NULL(CDR B) means single length divisor BQUO1: PSAVE B PCALL COPY PREST B CARA B,(B) MOVE B,(B) PCALL Q1 PSAVE B ;quotient PCALL BNCONS MOVE B,A JRST POPAJ PAGE ;DIV1 does long division of X/Y ;enter with x in A, Y in B. DIV1: PSAVE A ;X PSAVE B ;Y MOVE A,B PCALL HIDIG HRLOI A,SIGN/2-1 IDIV A,(C) ;(beta/2-1)/Y[N-1]+1 ADDI A,1 MOVEM A,SCALE# MOVE B,A MOVE A,(P) ;Y - divisor PCALL BTIME0 ;SCALE*Y MOVEM A,V ;scaled divisor MOVEM A,(P) ;protect V from GC PCALL HIDIG POP C,VH ;V[N-1] POP C,VH1 ;V[N-2] MOVE A,-1(P) ;X - numerator PCALL COPY PCALL EXTND MOVE B,SCALE MOVE C,A PCALL BTIME1-1 ;SCALE*X -- scaled numerator MOVEM A,-1(P) ;U PSAVE [NIL] HRRZM P,QUO# ;pointer to quotient list PCALL LENGTH PSAVE A MOVE A,V# PCALL LENGTH PREST B SUB B,A ;LENGTH(U)-LENGTH(V) MOVE A,-2(P) ;U JUMPLE B,DIV1X ;special case of U<V PCALL DIV2 ;carry out division with parameters DIV1X: PCALL SUPRSS ;suppress leading zeros of remainder JUMPE A,DIV1Y ;zero remainder MOVE B,SCALE PCALL Q1 ;U/SCALE - final remainder in B MOVE A,B DIV1Y: EXCH A,(P) PCALL SUPRSS ;suppress leading zeros in quotient PREST B JRST POP2J PAGE ;Recursive function to position V properly with respect to U. ; on successive calls to DIV3 which calculates quotient digits. ;Enter DIV2 with U in A, N in B. N= LENGTH(U)-LENGTH(V)-1. DIV2: SOJLE B,DIV3 PSAVE A ;U CDRA A,(A) PCALL DIV2 RPLCD A,@(P) ;(RPLACD U,(DIV3(CDR U))) PREST A JRST DIV3 ;Enter with U[J] in A DIV3: PSAVE A ;UJ PCALL HIDIG POP C,A ;UH CAML A,VH# JRST DIVCS1 ;strange case when UH>=VH POP C,B ;UH1 DIV A,VH ;(UH*beta+UH1)/VH PSAVE A ;quotient digit L1: MOVEM B,REM# ;remainder MUL A,VH1# SUB A,REM ;(VH1*QUO)-beta*REM CAMGE B,(C) ;UH2 SUBI A,1 JUMPG A,DIVCS2 ;quotient too big L4: MOVE A,V MOVE B,(P) ;quotient digit PCALL BTIME0 ;Q*V MOVE C,-1(P) ;UJ MOVE B,A MOVEI A,0 PCALL BSUB ;UJ-Q*V JUMPL B,DIVCS3 ;quotient too big L3: MOVEM A,-1(P) ;new UJ PREST A ;quotient digit MOVE B,@QUO PCALL BCONS MOVEM A,@QUO ;new quotient list MOVE A,(P) PCALL DIVSRT ;shorten UJ by one digit JRST POPAJ PAGE ;Special case of UH>=VH DIVCS1: HRLOI A,SIGN-1 ;BETA-1 PSAVE A POP C,B ;UH1 JRST DIVC2A ;R_UH1+VH ;Special case correction for quotient DIVCS2: SOS A,(P) ;quotient_quotient-1 MOVE B,REM DIVC2A: ADD B,VH ;R_R+VH JUMPL B,L4 ;overflow ... R >= beta. JRST L1 ;Special case of quotient too large DIVCS3: SOS (P) ;quotient_quotient-1 PSAVE A MOVE A,V PCALL COPY MOVE C,A PREST B MOVEI A,0 PCALL BADD ;U_U+V MOVEM A,-1(P) PCALL DIVSRT ;shorten overflowed digit JRST L3+1 PAGE ;Pushes successive digits of list in A onto pdl ;Returns C pointing to pdl location of last digit HIDIG: MOVE C,P MOVS B,(A) PSAVE (B) HLRZ A,B JUMPN A,HIDIG+1 EXCH C,P PRET ;Shorten list by one DIVSRT: MOVE C,A CDRA A,(A) CDRA B,(A) ;CDDR JUMPN B,.-3 HLLZS (C) ;NULL (CDDR C) => RPLACD(C NIL) CARA B,(A) JRST UNCONS ;Lengthen list by one EXTND: PSAVE A PCALL LAST MOVE T,A PCALL B0CONS RPLCD A,(T) JRST POPAJ PAGE TA==4 TB==5 TC==6 TD==7 UP==10 VP==11 Q==12 ;Bignum GCD BGCD: PSAVE B PCALL COPY EXCH A,(P) ;V PCALL COPY PSAVE A ;U PCALL COPY MOVE C,A MOVE A,-1(P) PCALL COPY MOVE B,A ;U MOVEI A,0 PCALL BSUB ;V-U PSAVE B PCALL BSUBND JUMPE A,GCDSC1 ;U=V PCALL UNCONS PREST B JUMPGE B,BGCD2 ;U>=V MOVE A,(P) EXCH A,-1(P) MOVEM A,(P) PAGE ;Now V<U V in -1(P), U in (P) BGCD2: MOVE A,-1(P) JUMPE A,GCDEND ;V is zero CDRA B,(A) JUMPE B,GCDSING ;V is single precision PCALL LENGTH ;LENGTH (V) MOVE T,A MOVE A,(P) ;U PCALL LENGTH SUB A,T ;L(U)-L(V) JUMPE A,GCD4 SOJN A,GCD7A ;>1 MOVE A,-1(P) ;V PCALL EXTND ;lengthen V by one high order zero GCD4: MOVE A,(P) ;U PCALL HIDIG HRLOI A,SIGN/2-1 ;BETA/2-1 IDIV A,(C) ;(BETA/2-1)/U[N-1]+1 ADDI A,1 MOVEM A,SCALE PCALL GCSB MOVE UP,A ;SCALE*UH MOVE A,-1(P) ;V PCALL HIDIG PCALL GCSB MOVE VP,A ;SCALE*VH MOVEI TA,1 MOVEI TD,1 SETZB TC,TB PAGE GCD5: MOVE A,UP ADD A,TA MOVE B,VP ADD B,TC JUMPE B,GCD7 JUMPL A,GCD5X ;overflow case IDIV A,B ;(U'+A)/(V'+C) GCD5A: MOVE Q,A MOVE A,UP ADD A,TB MOVE B,VP ADD B,TD JUMPE B,GCD7 SKIPG B TDZA A,A ;special case of V'+D = BETA IDIV A,B ;(U'+B)/(V'+D) CAME A,Q JRST GCD7 MOVE A,TC EXCH TA,TC ;A'_C IMUL A,Q SUB TC,A ;C'_A-Q*C MOVE A,TD EXCH TB,TD ;B'_D IMUL A,Q SUB TD,A ;D'_B-Q*D MOVE A,VP EXCH UP,VP ;UP'_VP IMUL A,Q SUB VP,A ;VP'_UP-Q*VP JRST GCD5 PAGE ;Special case when U'+A=BETA GCD5X: MOVEI A,1 MOVE C,B MOVEI B,0 DIV A,C JRST GCD5A GCD7: JUMPE TB,GCD7A MOVE A,(P) ;U MOVE B,-1(P) ;V PSAVE TC PSAVE TD PCALL GCDSB ;A*U+B*V PREST TB PREST TA EXCH A,(P) ;U MOVE B,-1(P) PCALL GCDSB ;C*U+D*V MOVEM A,-1(P) ;V JRST BGCD2 GCDSB: PSAVE TA PSAVE TB PSAVE B MOVM B,TA PCALL BTIME0 EXCH A,(P) ;B MOVM B,-1(P) ;TB PCALL BTIME0 PREST B ;A*TA PREST TA PREST TB XOR TA,TB MOVE C,A MOVEI A,0 JUMPGE TA,BADD ;signs same PCALL BSUB ;signs different BSUBND: JUMPGE B,SUPRSS JRST COMPLM GCD7A: MOVE A,-1(P) PCALL SUPRSS MOVE B,A MOVE A,(P) PCALL DIV1 ;U/V EXCH B,-1(P) ;V_REMAINDER MOVEM B,(P) ;U_V PCALL UNCONS ;dont need quotient JRST BGCD2 PAGE GCDSING: PREST A ;U MOVE B,(P) ;V - single precision CARA B,(B) MOVE B,(B) MOVEM B,(P) PCALL Q1 ;U MOD V into A PREST B ;A < B JUMPE A,GCDS2 ;Single precision GCD IDIV B,A MOVE B,A MOVE A,C JUMPN A,.-3 GCDS2: MOVE A,B JRST FIX1A GCSB: MOVE A,-1(C) MUL A,SCALE MOVE B,A MOVE A,(C) IMUL A,SCALE ADD A,B PRET GCDSC1: P2DROP PREST A JRST MAKPOS GCDEND: PREST A ;U is result P1DROP JRST MAKPOS SUBTTL GENERALIZED GFPAK, FOR BIGNUMS --- PAGE 14 IFN MOD,< ;THE REST OF THIS PAGE IS UNDER THIS SWITCH ;TITLE GFPAK4 -- GALOIS FIELD PACKAGE ; THE MODULUS CANNOT BE A BIGNUM, WITH THIS VERSION OF GFPAK; ; THE ARG TO CMOD CAN BE, THOUGH. ; Every other arg is assumed to be FIXNUM or INUM !!! ; THE MODULUS SHOULD ALWAYS BE SET OR RESET BY THE FUNCTION SETMOD; ; IT SHOULD NOT BE SET BY A SETQ IN LISP/REDUCE. ; THE MODULUS CAN BE INTERROGATED FOR ITS CURRENT VALUE BY: ; 1) THE VALUE RETURNED FROM THE FUNCTION (SETMOD 0), ; WHICH DOESN'T ALTER THE CURRENT VALUE; OR BY ; 2) THE VALUE OF THE EXTERNAL VARIABLE MOD*. ; (SETMOD NIL) IS LEGITIMATE, AND IS == (SETQ MOD* NIL). GFP: 0 ;STRICTLY LOCAL: THE SINGLE-PRECISION MODULUS. ;VBIGP IS THE VALUE-CELL OF THE VARIABLE MOD*, ; AND PERMITS EXTERNAL-INTERROGATION. ;VBIGP IS ALSO USED IN CMOD, AS A FIXNUM, ; (TO AVOID RE-FIX1A-ING GFP EACH TIME). ; IT IS THUS PROTECTED DURING A GC. PAGE ;(SETMOD A) SETS P, THE NUMBER OF ELEMENTS OF THE FIELD, TO A IF A.NE.0 ; AND RETURNS P AS A RESULT IN ANY CASE. ; DOES NOT CHECK TO SEE IF P IS PRIME, WHICH IT SHOULD BE. INTERNAL SETMOD SETMOD: MOVE C,A ;Preserve pntr around NUMVAL. JUMPE A,SETM2 ;If NIL, just reset cells. PCALL NUMVAL JUMPE A,SETM3 ;If "0", interrogate old value. SETM2: MOVMM A,GFP ;Internal cell (for local use). FOO MOVEM C,VBIGP ;External pntr (for users and CMOD). SETM3: FOO MOVE A,VBIGP ;Return current value. PRET ;(CMOD A) NORMALIZES A MOD P, REGARDLESS +/- SIZE INTERNAL CMOD CMOD: JSP D,ONUMV JRST CMOD1 CAIN B,FLONU JRST ILLNUM ;FLOATING POINT NUMBERS ARE ILLEGAL IDIV A,GFP SKIPGE A,B ;IF A WAS NEG, REMAINDER IS NEG ADD A,GFP JRST FIX1A ;CONVERT & EXIT CMOD1: PSAVE B PCALL COPY MOVE B,GFP PCALL Q1 PREST B CAIE B,POSNU MOVNS A JRST CDIF1 PAGE ;(CPLUS A B) RETURNS THE SUM OF A AND B IN THE CURRENT GALOIS FIELD ; ASSUMES A & B ALREADY NORMALIZED. INTERNAL CPLUS CPLUS: MOVEM B,TMP ;SAVE B PCALL NUMVAL ;CONVERT A EXCH A,TMP ;SAVE A PCALL NUMVAL ;CONVERT B ADD A,TMP ;ADD CAML A,GFP ;SKIP IF LESS, ELSE SUB A,GFP ; NORMALIZE JRST FIX1A ;CONVERT AND EXIT TMP: 0 ;CDIF(A,B) RETURNS A-B MOD P, A,B ARE ELEMENTS OF GF(P) INTERNAL CDIF CDIF: MOVEM B,TMP ;SAVE B PCALL NUMVAL ;CONVERT A EXCH A,TMP ;SAVE A PCALL NUMVAL ;CONVERT B EXCH A,TMP SUB A,TMP ;SUBTRACT CDIF1: SKIPGE A ; SKIP IF GREATEQ 0,ELSE ADD A,GFP ; NORMALIZE JRST FIX1A ;CONVERT AND EXIT ;(CTIMES A B) RETURNS THE PRODUCT OF A AND B IN THE CURRENT GALOIS FIELD ; ASSUMES A & B NON-NEG ... NORMALIZED. INTERNAL CTIMES CTIMES: MOVEM B,TMP ;SAVE B PCALL NUMVAL ;CONVERT A EXCH A,TMP ;SAVE A PCALL NUMVAL ;CONVERT B MUL A,TMP ;MULTIPLY DIV A,GFP ;DIVIDE BY P TO GET IN RANGE MOVE A,B ;MOVE REMAINDER JRST FIX1A ;WHICH WE CONVERT AND EXIT PAGE ;(CRECIP A) RETURNS THE INVERSE OF A IN THE CURRENT GALOIS FIELD. ; COMPUTATION USES EXTENDED EUCLIDEAN ALGORITHM, WHEREBY ; (GCD P A) IS COMPUTED, AND NUMBERS X AND Y ARE FOUND SUCH THAT ; P*X + A*Y = (GCD P A) = 1 BECAUSE P IS PRIME (WE HOPE). ; SINCE P*X O (MOD P) WE DO NOT IN FACT COMPUTE X. ; Y IS OF COURSE THE MULTIPLICATIVE INVERSE OF A. ;ALGORITHM: ; A(I)=A(I+1)*Q(I)+A(I+2) ; Y(I+2)=Y(I)-Q(I)*Y(I+1) ; A(1)=P, A(2)=A, Y(1)=0, Y(2)=1 ; A(N+2)=0, Y(N+1)=Y ;STORAGE ALLOCATION: ; A: A(I+1) ; B: A(I) ; C: A(I+2) (BECAUSE OF THE WAY IDIV WORKS) ; AR4: Y(I) ; AR5: Y(I+1) INTERNAL CRECIP CRECIP: PCALL NUMVAL ;GET VALUE OF ARGUMENT IN A(2) SETZM AR4 ;Y(1)=0 MOVEI AR5,1 ;Y(2)=1 MOVE B,GFP ;A(1)=P LOOP: IDIV B,A ;C=A(I+2), B=Q(I) JUMPE C,EXIT ;IF A(I+2)=0, WE ARE THROUGH IMUL B,AR5 ;Q(I)*Y(I+1) EXCH AR4,AR5 SUB AR5,B ;Y(I+2) MOVE B,A MOVE A,C JRST LOOP ;NEXT ITERATION EXIT: SKIPGE A,AR5 ;A_Y(N+1). IF NEGATIVE ADD A,GFP ;ADD P TO GET 0.LT.Y.LT.P JRST FIX1A ;CONVERT TO LISP NUMBER AND EXIT > ;END OF IFN MOD SUBTTL EXPLODE, COMPRESS AND FRIENDS --- PAGE 15 IFE STL,< FLATSIZE:HLLZS FLAT1 MOVEI R,FLAT2 PCALL PRINTA FLAT1: MOVEI A,X ;* JRST FIX1A FLAT2: AOS FLAT1 PRET > %EXPLODE:SKIPA R,.+1 ;LIKE PRIN2 & PRIN1, EXPLODE: HRRZI R,EXPL1 ; <HRRZI>=551, negative R trick. SKIPN OLSCNV ;READ scanner? JRST EXPLO1 ;Yes! PSAVE A MOVEI A,NIL PCALL SCANSET EXCH A,(P) PCALL EXPLO1 EXCH A,(P) PCALL SCANSET JRST POPAJ EXPLO1: MOVSI AR4,AR4 PCALL PRINTA JRST RETAR4 EXPL1: PSAVE B PSAVE C ANDI A,177 PCALL RECH1 PCALL NCONS HLR B,AR4 RPLCD A,(B) RPLCA A,AR4 PREST C JRST POPBJ PAGE IFE STL,< READLIST:TDZA T,T COMPRESS:MOVNI T,1 MOVEM T,NOINFG > IFN STL,< COMPRESS:SETOM NOINFG > PSAVE OLDCH SETZM OLDCH JUMPE A,[ERRL0 ^D141,[SIXBIT /NO LIST-COMPRESS!/]] HRRM A,MKNAM3 MOVEI A,MKNAM2 PCALL READ0 CDRA T,MKNAM3 CAIE T,-1 JUMPN T,[ERRL0 ^D142,[SIXBIT /MORE THAN ONE S-EXPRESSION-COMPRESS!/]] PREST OLDCH PRET MKNAM2: PSAVE B PSAVE TT MKNAM3: MOVEI TT,X JUMPE TT,MKNAM6 CAIN TT,-1 ERRL0 ^D143,[SIXBIT /READ UNHAPPY-COMPRESS!/] CDRA B,(TT) HRRM B,MKNAM3 CARA A,(TT) PCALL GTFCH MKNAM4: PREST TT JRST POPBJ MKNAM6: MOVEI A," " HLLOS MKNAM3 JRST MKNAM4 GTFCH: CAILE A,INUMIN JRST GTFINV GTFCH2: PCALL GETPNM CARA A,(A) LDB A,[POINT 7,(A),6] PRET GTFINV: SUBI A,INUM0-"0" CAIG A,"9" CAIGE A,"0" ERRL1 ^D144,[SIXBIT /NUMBER NOT DIGIT!/] PRET SUBTTL EVAL APPLY -- THE INTERPRETER --- PAGE 16 EV3: CARA A,(AR4) FOO MOVEI B,VALUE PCALL GET+1 ;don't need to check for id JUMPE A,UNDFUN ;function object has no definition CDRA A,(A) CARA B,(AR4) CAIE A,(B) ;Error if same id UBDPTR: FOO CAIN A,UNBOUND JRST UNDFUN CDRA B,(AR4) ;eval (cons a (cdr AR4)) PCALL CONS EVAL: HRRZM A,AR4 CAILE A,INUMIN JRST CPOPJ CARA T,(A) CAILE T,ATMIN JRST EE1 ;x is atomic CAILE T,INUMIN JRST UNDFUN CARA TT,(T) CAIN TT,ID JRST EE2 ;car (x) is an id CAIL TT,CODMIN JRST EVCOD CAIG TT,ATMIN JRST EXP3 IFE APPL,< UNDFUN: CARA A,(AR4) ERRE1 ^D28,[SIXBIT /UNDEFINED FUNCTION - EVAL!/] > IFN APPL,< JRST RETAR4 UNDFUN==RETAR4 > EE1: CAIE T,ID PRET ;constant FOO MOVEI B,VALUE PCALL IGET EXCH A,AR4 JUMPE AR4,UNBVAR CDRA AR4,(AR4) IFE APPL,< FOO CAIN AR4,UNBOUND UNBVAR: ERRE1 ^D29,[SIXBIT /UNBOUND VARIABLE - EVAL!/] > IFN APPL,< FOO CAIE AR4,UNBOUND UNBVAR==CPOPJ > MOVEM AR4,A PRET PAGE IFN FNRG,< ALIST: SKIPE A,-1(P) PCALL NUMBERP PUSH SP,[0] ;mark for unbind JUMPN A,AEVAL7 ;number MOVE C,SC2 ;bottom of spec pdl MOVEM C,AEVAL5# SETOM AEVAL2 AEVAL8: MOVE C,SP AEVAL6: CAMN C,AEVAL5 ;bottom spec pdl JRST AEVAL1 ;done AEVAL4: POP C,AR4 JUMPE AR4,AEVAL6 ;thru with block MOVSS AR4 PUSH SP,(AR4) ;save value cell HLRZM AR4,(AR4) ;store previous value in value cell HRLM AR4,(SP) ;save pointer to spec pdl loc JRST AEVAL4 FNGUBD: EXCH A,(P) ;spec pdl pointer PCALL NUMVAL MOVE D,A FNGUB2: POP SP,T JUMPE T,POPAJ ;done MOVSS T ;pointer to value cell RPLCA T,(T) SKIPN 1(D) AOBJN D,.-1 ;skip over spec pdl marker PUSH D,(T) ;put value cell in spec pdl HLRZM T,(T) ;restore value cell JRST FNGUB2 %EVAL: PSAVE A PSAVE B PCALL ALIST PREST A MOVEI A,UNBIND EXCH A,(P) JRST EVAL PAGE AEVAL1: SKIPGE AEVAL2 SKIPN B,-1(P) PRET ;done with binding MOVE A,B ;ALIST binding... PCALL REVERSE SKIPA ABIND2: MOVE A,B CDRA B,(A) CARA A,(A) CDRA AR4,(A) CARA A,(A) PCALL BIND JUMPN B,ABIND2 PRET ;spec pdl binding AEVAL7: MOVE A,-1(P) PCALL NUMVAL SETZM AEVAL2 MOVEM A,AEVAL5 ;point to unbind to JRST AEVAL8 AEVAL2: 0 ;0 for number, -1 for a-list * > ;end of IFN FNRG PAGE EE2: CDRA T,(T) FOO MOVEI D,FUNCELL EE21: JUMPE T,EV3 MOVS TT,(T) MOVS T,(TT) CAIN D,(T) JRA T,EE3 CARA T,TT JRST EE21 EE3: CARA TT,T CARA D,(T) ;FOO CAIN TT,SUBR ; JRST EVCOD FOO CAIN TT,EXPR JRST AEXPQ ;FOO CAIN TT,FSUBR ; JRST EFS FOO CAIN TT,MACRO JRST EFM FOO CAIE TT,FEXPR JRST UNDFUN CAIE D,ID CAIGE D,CODMIN JRST AFEXP EFS: CDRA T,(T) CDRA A,(AR4) JRST (T) AFEXP: HLL T,(AR4) PSAVE T CDRA A,(A) UUOS3I: TLO A,400000 PSAVE A MOVNI T,1 JRST IAPPLY AEXP: HLL T,(AR4) EXP3: CDRA A,(AR4) UUOS6: PSAVE T CILIST: JSP TT,ILIST EXP2: JRST IAPPLY PAGE AEXPQ: CAIE D,ID CAIGE D,CODMIN JRST AEXP EVCOD: CDRA A,(AR4) HLL T,(AR4) UUOS2: CDRA T,(T) PSAVE T ;For POPJ below --> call this addr. JSP TT,ILIST ESB1: MOVEI TT,CPOPJ PDLARG: HRREI R,NACS(T) JUMPGE R,PDLA1(R) MOVMS R CAILE R,NSUA-NACS ERRL1 ^D145,[SIXBIT /TOO MANY ARGS FOR EXPR!/] HRLI R,(R) PXDROP R MOVEI A,EXARG HRLI A,1(P) BLT A,EXARG-1(R) PDLA1: PREST A+4 PREST A+3 PREST A+2 PREST A+1 PREST A JRST (TT) EFM: CALLF 1,(T) JRST EVAL PAGE IFN FNRG,< %APPLY: MOVEI R,3 JSP TT,ARGP1 MOVEM T,APFNG1# PCALL ALIST MOVE T,APFNG1 JSP TT,PDLARG PSAVE C ;spec pdl pointer PSAVE [FNGUBD] > APPLY: PSAVE A MOVEI T,0 AP3: JUMPE B,IAPPLY ;all args pushed; b has arg list CARA C,(B) PSAVE C ;push arg CDRA B,(B) SOJA T,AP3 IFN FNRG,< IAP4: JUMPGE D,TOOFEW ;special case for fexprs AOJN R,TOOFEW PSAVE B MOVE A,SP PCALL FIX1A EXCH A,(P) MOVE B,A MOVNI R,2 SOJA T,IAP5 FUNCT: PSAVE A MOVE A,SP PCALL FIX1A PREST B HLL A,(B) PCALL DCONSA FOO HRLI A,FUNARG JRST DCONSA PAGE APFNG: SOS T MOVEM T,APFNG1 JSP TT,PDLARG ;get args and funarg list CDRA A,(A) CDRA D,(A) ;a-list pointer CARA A,(A) ;function MOVN R,APFNG1 ;Positive no. of args PSAVE D PSAVE [FNGUBD] JSP TT,ARGP1 ;replace args and fn name PSAVE D ;a-list pointer PCALL ALIST ;set up spec pdl PREST D AOS T,APFNG1 > ;end of IFN FNRG IAPPLY: MOVE C,T ;state of world at entrance ADDI C,(P) ;t has - number of args on pdl ILP1A: CDRA B,(C) ;next pdl slot has function- poss fun name in lh CAILE B,INUMIN JRST UNDTAG CARA TT,(B) CAILE TT,ATMIN JRST IAP1 ;fn is atomic FOO CAIN TT,LAMBDA JRST IAPLMB IFN FNRG,< FOO CAIN TT,FUNARG JRST APFNG > FOO CAIN TT,LABEL JRST APLBL PSAVE T MOVE A,B PCALL EVAL PREST T MOVE C,T ADDI C,(P) ILP1B: MOVEM A,(C) JRST ILP1A UNDTAG: MOVE A,(C) ;FN NAME,,FN TLNE A,-1 ;Any function name ? HLRZS A ;Yes! ERRE1 ^D30,[SIXBIT /UNDEFINED FUNCTION - APPLY!/] PAGE IAP1: CAIGE TT,CODMIN JRST UNDTAG CAIE TT,ID JRST APCOD FOO MOVEI D,FUNCELL CDRA B,(B) IAPL1: JUMPE B,IAP2 MOVS TT,(B) MOVS B,(TT) CAIN D,(B) JRA B,IAPL2 CARA B,TT JRST IAPL1 IAPL2: CARA TT,B ;FOO CAIN TT,SUBR ; JRST APCOD FOO CAIE TT,EXPR ERRE1 ^D31,[SIXBIT /NOT EXPR - APPLY!/] CARA D,(B) CAIE D,ID CAIGE D,CODMIN JRST IAPXPR APCOD: CDRA B,(B) HRRZM B,(C) JRST ESB1 IAPXPR: CDRA A,B JRST ILP1B PAGE IAPLMB: CDRA B,(B) CARA TT,(B) CDRA B,(B) CARA D,(TT) CAIN D,ID JUMPN TT,[ERRL1 ^D146,[SIXBIT /ILLEGAL LAMBDA FORMAT!/]] MOVE R,T IPLMB1: JUMPE T,IPLMB2 ;no more args JUMPE TT,TOMANY ;too many args supplied IAP5: CARA A,(TT) MOVEI AR4,1(T) ADD AR4,P HLLZ D,(AR4) ;tested in IAP4 RPLCA A,(AR4) CDRA TT,(TT) AOJA T,IPLMB1 IFE FNRG,IAP4==TOFEW IPLMB2: JUMPN TT,IAP4 ;too few args supplied PUSH SP,[0] ;mark for unbind JUMPE R,IAP69 IPLMB4: PREST AR4 CARA A,AR4 PCALL BIND AOJL R,IPLMB4 IAP69: PREST AR4 TLNE AR4,-1 FOO SKIPN BACTRF JRST .+3 HRRI AR4,CPOPJ PSAVE AR4 PCALL PROGN1 JRST UNBIND TOMANY: ERRL1 ^D147,[SIXBIT /TOO MANY ARGUMENTS SUPPLIED - APPLY!/] TOOFEW: ERRL1 ^D148,[SIXBIT /TOO FEW ARGUMENTS SUPPLIED - APPLY!/] PAGE APLBL: PUSH SP,[0] ;mark for unbind CDRA B,(B) CARA A,(B) CDRA B,(B) CARA AR4,(B) MOVEM AR4,(C) PCALL BIND MOVEI A,APLBL1 EXCH A,-1(C) EXCH A,LBLAD# HRLI A,LBLAD PUSH SP,A JRST IAPPLY APLBL1: PSAVE LBLAD JRST SPECSTR IAP2: CDRA A,(C) FOO MOVEI B,VALUE PCALL GET+1 ;don't need to check for id JUMPE A,UNDTAG CDRA A,(A) CDRA B,(C) CAIE A,(B) FOO CAIN A,UNBOUND JRST UNDTAG JRST ILP1B RETB: PROG2: HRRZ A,B PRET PAGE BIND: JSP D,CHKID FOO CAIE A,TRUTH JUMPN A,BIND4 ERRE2 ^D32,[SIXBIT /MAY NOT BE CHANGED!/] BIND4: PSAVE B PCALL BIND1 ;get value cell PUSH SP,(A) RPLCA A,(SP) HRRZM AR4,(A) POPBJ: PREST B PRET BIND1: HRRZM A,BIND3# FOO MOVEI B,VALUE PCALL GET+1 JUMPN A,CPOPJ FOO MOVEI A,UNBOUND PCALL DCONSA MOVE TT,A FOO HRLI A,VALUE PCALL DCONSA CDRA B,@BIND3 PCALL CONS RPLCD A,@BIND3 MOVE A,TT PRET TUNBIND:SETZM SPSAV MOVE B,SC2 UBD: CAMN SP,B PRET PCALL UNBIND JRST UBD SPECSTR: ;LAP...<PCALL SPECSTR> UNBIND: POP SP,T JUMPE T,CPOPJ MOVSS T HLRZM T,(T) JRST UNBIND PAGE PROGBIND:MOVEI D,PROGB1 ;LAP...<CALL 0,PROGBIND><0 0 (FLUID --)> SPEC1: PREST T PUSH SP,[0] ;mark for unbind SPEC2: LDB R,[POINT 13,(T),ACFLD] CAIG R,377 JRST (D) ;prog- or lam-bind JRST (T) ;next is opcode, so quit. LAMBIND:JSP D,SPEC1 ;LAP...<CALL 0,LAMBIND><0 x (FLUID --)> JUMPE R,SPEC3 ;Init = NIL CAIG R,NACS JRST LAMB1 CAIG R,NSUA ;Extended regs. JRST LAMB2 ;Yes MOVNI R,(R) ;From pdl ADDI R,NSUA+1(P) LAMB1: SKIPA R,(R) PROGB1: SETZ R, SPEC3: EXCH R,@(T) HRL R,(T) PUSH SP,R ;<address,,old-value>. AOJA T,SPEC2 LAMB2: MOVE R,EXARG-NACS-1(R) JRST SPEC3 ;Miscellaneous special case compiler run time routines %AMAKE: PSAVE A ;make alist for fsubr that requires it MOVE A,SP PCALL FIX1A MOVE B,A JRST POPAJ IFE STL,< %UDT: PCALL ERHED ;error print for undefined computed go tag PCALL PRIN1 STRTIP [SIXBIT / UNDEFINED COMPUTED GO TAG IN !/] MOVEI R,INUM0+17 HRRM R,ERRX CDRA R,(P) PCALL ERSUB3 JRST ERREND-1 %LCALL: MOVN A,T ;set up routine for compile lsubr ADDI A,INUM0 ADDI T,(P) PSAVE T PCALL (3) PREST T SUBI T,(P) HRLI T,-1(T) ADD P,T PRET > SUBTTL ARRAY SUBROUTINES --- PAGE 17 IFN ASARY,< ARRERR=-1 ARRAY: PCALL ARRAYS HRRI AR5,1(R) MOVE A,AR5 PUSH R,[0] AOBJN A,.-1 ARREND: MOVE A,BPPNR# MOVEM AR5,-1(A) MOVEI A,1(R) PCALL FIX1A ;MOVEI A,INUM0+1(R) FOO MOVEM A,VBPORG PRET ARRAYS: PSAVE A FOO MOVE A,VBPORG PCALL NUMVAL ;SUBI A,INUM0 MOVEM A,BPPNR FOO MOVE A,VBPEND PCALL NUMVAL ;MOVNI A,-INUM0-2(A) MOVN A,A ADDI A,2 ADD A,BPPNR ;bporg-bpend+2 HRLM A,BPPNR HRRZ A,BPPNR ADDI A,2 PCALL IMKCODE FOO MOVEI B,EXPR PREST A CDRA AR4,(A) ;(cdr l) CARA A,(A) ;(car l)name PCALL IPUTD CARA A,(AR4) ;(cadr l)mode PSAVE AR4 PCALL EVAL ;eval mode PREST AR4 MOVEM A,AMODE# MOVEI C,44 JUMPE A,ARRY1 MOVEI C,-INUM0(A) CAILE A,INUMIN JRST ARRY1 MOVEI C,22 MOVE A,GCMKL HRL A,BPPNR PCALL DCONSA ;IFF Lisp-pntrs requested, MOVEM A,GCMKL ;record for GC marking of arrays. ARRY1: MOVEM C,BSIZE# MOVEI A,44 IDIV A,C MOVEM A,NBYTES# CDRA A,(AR4) ;(cddr l)bound pair list JSP TT,ILIST AOS R,BPPNR MOVEI AR4,1 ;AR4 is array size MOVEI AR5,0 ;AR5 is cumulative residue AOJGE T,ARRYS ;single dimension MOVEI D,A-1 SUB D,T ;D is next ac for array code generation ARRY2: PCALL ARRB0 TLC TT,(IMULI) DPB D,[POINT 4,TT,ACFLD] PUSH R,TT CAIN D,A JRST ARRY3 MOVSI TT,(ADD) ADDI TT,1(D) DPB D,[POINT 4,TT,ACFLD] PUSH R,TT SOJA D,ARRY2 ARRB0: PREST TT ;E.G., after ARRAY XX(5,6), EXCH TT,(P) ; extents= (0:5,0:6), =42, = 0:41, CAILE TT,INUMIN ; generates SUBR #22002, say, and JRST ARRB1 ;22000/ -25,,22016 ;-N/2,,data CARA A,(TT) ; 001/ 5,,-10 ;INUM0*8 CDRA TT,(TT) ; 002/ IMULI A,7 SUBI TT,(A) ; 003/ ADD A,B ADDI TT,1 ; 004/ SUB A,22001 JRST ARRB2 ; 005/ JUMPL A,ARRERR;indexing .LT. (0,0) ; 006/ CAIL A,^D42 ARRB1: MOVEI A,INUM0 ; 007/ JRST ARRERR SUB TT,A ; 010/ IDIVI A,2 ;half-word pntrs. ARRB2: IMUL A,AR4 ; 011/ IMULI B,-^D18_12 ;bytesize. IMULB AR4,TT ; 012/ HRLZI C,(POINT 18,0(B),17) ADDM A,AR5 ; 013/ ADDI C,22016(A) PRET ; 014/ LDB A,C ;proper halfword. ; 015/ PRET ;returning pntr, etc. ARRY3: PUSH R,[ADD A,B] ; 016/ ...,,... ;INITIALLY 0 or NIL. ARRYS: PCALL ARRB0 HRRZ TT,BPPNR MOVEM AR5,(TT) ;SUBR-1, e.g. 22001. HRLI TT,(SUB A,) PUSH R,TT PUSH R,[JUMPL A,ARRERR] MOVE TT,AR4 HRLI TT,(CAIL A,) PUSH R,TT PUSH R,[JRST ARRERR] IDIV AR4,NBYTES ;calc #words in array SKIPE AR5 ;correct for remainder non-zero ADDI AR4,1 MOVE TT,NBYTES SOJE TT,ARRY6 ADDI TT,1 HRLI TT,(IDIVI A,) PUSH R,TT MOVN TT,BSIZE LSH TT,14 HRLI TT,(IMULI B,) PUSH R,TT MOVEI TT,44+200 SUB TT,BSIZE LSH TT,6 ARRY6: ADD TT,BSIZE LSH TT,6 SKIPE AR5,AMODE CAIL AR5,INUMIN ADDI TT,40 ;mode not = T TLC TT,(MOVSI C,) PUSH R,TT MOVEI TT,4(R) HRLI TT,(ADDI C,(A)) PUSH R,TT PUSH R,[LDB A,C] MOVSI AR5,(PRET) SKIPN TT,AMODE MOVE AR5,[JRST FLO1A] CAIL TT,INUMIN MOVE AR5,[JRST FIX1A] PUSH R,AR5 MOVS AR5,AR4 MOVNS AR5 PRET STORE: PSAVE A PCALL CADR PCALL EVAL ;value to store EXCH A,(P) CARA A,(A) PCALL EVAL ;byte pointer returned in c PREST A NSTR: PSAVE A TLNE C,40 JSP D,ONUMV ;numerical array JRST BIGNER ;BIGNUM IS ERROR DPB A,C PREST A PRET > ;end of IFN ASARY from line 300 PAGE IFN ALOD&ASARY,< EXARRAY:PSAVE A CARA A,(A) PCALL GETSYM JUMPE A,POPAJ PCALL NUMVAL EXCH A,(P) PCALL ARRAYS PREST A HRRM A,-2(R) HRR AR5,A JRST ARREND > ;end of IFN ALOD&ASARY DLVECT: IFN ASARY,SETZ AR4, ;To reduce GC overhead, or GCing of JSP D,ATMTYP CAIE TT,VECT IFN ASARY,< JRST .+2 JRST ISVC ; obsolete array in BPS overlays, e.g. MOVE AR4,A PCALL GETD JUMPE A,FALSE ;Gone. CARA D,(A) FOO CAIE D,EXPR > JRST FALSE ISVC: CDRA A,(A) MOVEI TT,GCMKL ;Delete a Lisp array from the GC list, DLARRLP:CDRA T,(TT) ; If done with it, tho can't reclaim core yet. CARA C,(T) CAIN C,-2(A) JRST DLFOUND CDRA TT,(TT) JUMPN TT,DLARRLP JRST FALSE ;Not found. DLFOUND:CDRA T,(T) RPLCD T,(TT) ;Cut out of list. IFN ASARY,<SKIPE A,AR4 PCALL REMD> ;Delete the SUBR pointer from the Lisp array JRST TRUE PAGE MKVECT: PCALL NUMVAL JUMPL A,VECOV+1 PSAVE A LSH A,-1 PSAVE A FOO MOVE A,VBPORG PCALL NUMVAL EXCH A,(P) ADD A,(P) ADDI A,3 PCALL FIX1A PSAVE A FOO MOVE B,VBPEND PCALL .GREAT JUMPN A,VECOV FOO PREST VBPORG ;set new bporg MOVE A,GCMKL HRL A,(P) PCALL DCONSA HRRM A,GCMKL PREST A ;old bporg, i.e. beginning of vector MOVE B,(P) LSH B,-1 ADDI B,1 MOVNS B HRLM B,(A) ADDI A,2 HRRM A,-2(A) MOVE B,-2(A) SETZM (B) ;fill vector with NIL AOBJN B,.-1 PREST -1(A) ;Upper limit for vector HRLI A,VECT JRST DCONSA PAGE GETV: JSP T,OPV CARA A,(B) CDRA A,(B) PUTV: JSP T,OPV RPLCA A,(B) RPLCD A,(B) OPV: JSP D,ATMTYP CAIE TT,VECT ERRE2 ^D33,[SIXBIT /IS NOT A VECTOR!/] CDRA TT,(A) MOVE A,C SUBI B,INUM0 JUMPL B,INXOV CAMLE B,-1(TT) ;compare with upper limit JRST INXOV ;too big TRNE B,1 ;odd or eaven ADDI T,1 ;odd LSH B,-1 ADDI B,(TT) XCT (T) PRET VECTORP: UPBV: JSP D,ATMTYP CAIE TT,VECT JRST FALSE CDRA A,(A) MOVE A,-1(A) JRST FIX1A INXOV: MOVEI A,INUM0(B) ERRE2 ^D34,[SIXBIT /SUBSCRIPT IS OUT OF RANGE!/] VECOV: MOVE A,-2(P) ADDI A,INUM0 ERRE2 ^D35,[SIXBIT /TOO BIG VECTOR!/] SUBTTL EXAMINE, DEPOSIT , ETC --- PAGE 18 BOOLE: SUBI A,INUM0 DPB A,[POINT 4,BOOLI,OPFLD-2] MOVE A,B PCALL NUMVAL EXCH C,A BOOLL: PCALL NUMVAL BOOLI: SETZB C,A JRST FIX1A EXAMINE:PCALL NUMVAL ;<MOVE A,-INUM0(A)> MOVE A,(A) JRST FIX1A DEPOSIT:MOVE C,B PCALL NUMVAL ;<MOVEI C,-INUM0(A) EXCH A,C ; MOVE A,B > JSP D,ONUMV BIGNER: ERRL0 ^D139,[SIXBIT /BIGNUM UNSUITABLE AS ARG!/] ;AASCII,BOOLE,etc. MOVEM A,(C) JRST MAKNUM LSH: MOVEI C,-INUM0(B) PCALL NUMVAL LSH A,(C) JRST FIX1A SUBTTL GARBAGE COLLECTOR --- PAGE 19 GC: PCALL AGC JRST FALSE AGC2: SKIPE GCFFLG ;did we just do a GC from top ? PRET ;yes, don't do it again SETOM GCFFLG ;indicate GC from top AGC: MOVEM R,ACSAV+R AGC1: MOVEM SP,SPSAV ;save in case of ^C MOVE NIL,CNIL3 ;set NIL PSAVE .JBUUO PSAVE UUOH GCPK1: PSAVE PA3 PSAVE PA4 PSAVE UBDPTR ;special atom UNBOUND; not on OBLIST PSAVE MKNAM3 PSAVE GCMKL ;i/o channel input lists and arrays PSAVE BIND3 GCPK2: PSAVE [XWD 0,GCP6] ;this is a return address MOVEI D,ACSAV BLT D,ACSAV+11 ;save ACs 0 through 11 GCP2: SETZB NIL,X ;gc indicator, init. for bit table zero MOVE A,C3GC GCP5: BLT A,X ;zero bit tables, .=top of bit tables FOO SKIPN GCGAGV JRST GCP5A CAIN F,ILLAD STRTIP [SIXBIT /_*** FREE STG EXHAUSTED_!/] SKIPN FF STRTIP [SIXBIT /_*** FULL WORD SPACE EXHAUSTED_!/] GCP5A: MOVEI TT,1 MOVEI A,0 CALLI A,STIME ;time MOVEM A,GCTIMT# GCP3: MOVEI C,X ;.=bottom of reg pdl GCP6B: MOVE S,P HLL C,P MOVEI B,0 GC1: CAMN C,S PRET HRRZ A,(C) GCP: CAIGE A,X ;.=bottom of bit tables GCPP1: FOO CAIGE A,FS JRST GCEND GCP1: CAIL A,X ;.=bottom of full word space (fws) JRST GCMFWS MOVE F,(A) LSHC A,-5 ROT B,5 MOVE AR4,GCBT(B) GCBTP2: TDOE AR4,X(A) ;bit tab- (fs_-5), .=magic number for sync JRST GCEND GCBTP1: MOVEM AR4,X(A) ;bit tab- (fs_-5) PSAVE F CARA A,F JRST GCP GCMFWS: MOVEI AR4,X(A) ;.=- bottom of fws IDIVI AR4,44 MOVNS AR5 LSH AR5,36 ADD AR5,C2GC DPB TT,AR5 GCEND: CAMN P,S AOJA C,GC1 PREST A HRRZS A JRST GCP CNIL3: FOO XWD ID,CNIL2 ;NIL header to refresh ac 0 GCMKL: XWD 0,.+1+X ;Appended to, for each Lisp-pntr array. XWD .+1,.+2 XWD -NSUA+NACS-1,EXARG XWD .+1,.+2 XWD -11,ACSAV ;Reg 0 - 10 are saved from gc this way XWD .+1,NIL XWD -NIOCH,CHTAB+FSTCH C2GC: XWD 430100+AR4,X ;.=bottom of fws bit table C3GC: 0 ;<bottom bit table,,bottom bit table+1> GCBT: XWD 400000,0 ZZ==1B1 XLIST REPEAT ^D31,<ZZ ZZ==ZZ/2> LIST PAGE GCP6: HRRZ R,SC2 GCP6C: CAILE R,(SP) ;mark sp JRST GCP6A PSAVE (R) HRRZ C,P PCALL GCP6B P1DROP AOJA R,GCP6C GCP6A: HRRZ R,GCMKL ;mark arrays GCP6D: JUMPE R,GCSWP CARA A,(R) MOVE D,(A) ;<-N,,ADDR> GCP6E: PSAVE (D) CDRA C,P PSAVE (D) MOVSS (P) PCALL GCP6B P2DROP AOBJN D,GCP6E CDRA R,(R) JRST GCP6D GFSWPP: PHASE 0 GFSP1==. JUMPL S,.+3 HRRZM F,(R) HRRZ F,R ROT S,1 AOBJN R,.-4 MOVE S,(D) HRLI R,-40 AOBJN D,GFSP1 LPROG==. JRST GFSPR DEPHASE PAGE ;garbage collector sweep GCSWP: MOVSI R,GFSWPP BLT R,LPROG MOVEI F,ILLAD MOVE D,C3GCS FOO MOVEI R,FS GCBTL1: HRLI R,X ;-(32-<fs&37> MOVE S,(D) GCBTL2: ROT S,X ;fs&37 AOBJN D,GFSP1 GFSPR: MOVE A,C1GCS MOVE B,C2GCS PCALL GCS0 FOO SKIPN GCGAGV JRST GCSP1 PCALL WHEAD MOVE A,F PCALL GCPNT STRTIP [SIXBIT / FREE STG,!/] MOVE A,FF PCALL GCPNT1 STRTIP [SIXBIT / FULL WORDS AVAILABLE!/] PCALL TOURET GCSP1: PXDROP [XWD GCPK2-GCPK1,GCPK2-GCPK1] ;restore p PREST UUOH PREST .JBUUO MOVE NIL,ACSAV SETZM SPSAV CAIN F,ILLAD ERRG ^D260,[SIXBIT /NO FREE STG LEFT!/] JUMPE FF,[ERRG ^D261,[SIXBIT /NO FULL WORDS LEFT!/]] MOVEI A,0 CALLI A,STIME ;time SUB A,GCTIMT ADDM A,GCTIM# MOVSI D,ACSAV BLT D,S ;reload ac's MOVE R,ACSAV+R IFN OPSYS,< SKIPE KBINTF ;Any user ^char interrupts from KB? JRST KBINTH > ; Yes, process. PRET PAGE GCS0: MOVEI FF,0 GCS1: ILDB C,B JUMPN C,GCS2 HRRZM FF,(A) HRRZ FF,A GCS2: AOBJN A,GCS1 PRET C1GCS: 0 ;<- length of fws,,bottom of fws> C2GCS: POINT 1,X,35 ;.=bottom of fws bit table C3GCS: 0 ;-n wds in bt,,bt GCTIME: MOVE A,GCTIM JRST FIX1A TIME: MOVEI A,0 CALLI A,STIME JRST FIX1A SPEAK: MOVE A,CONSVAL# JRST FIX1A GCPNT1: MOVEI B,0 JUMPE A,LOOP0 HRRZ A,(A) AOJA B,.-2 ; B:=LENGTH(A) GCPNT: MOVEI B,0 JRST .+2 HRRZ A,(A) CAIE A,ILLAD AOJA B,.-2 LOOP0: PCALL FIX1 JRST PRIN1 SUBTTL GETSYM,PUTSYM --- PAGE 20 IFN ALOD,< ;this entire page R50MAK: PCALL PNAMUK PUSH C,[0] HRLI C,700 HRRI C,(SP) MOVEI B,0 MK3: ILDB A,C LDB A,R50FLD CAMGE B,[50*50*50*50*50] SKIPN A PRET IMULI B,50 ADD B,A JRST MK3 GETSYM: PCALL R50MAK TLO B,040000 ;04 for globals MOVE C,.JBSYM MK7: CAMN B,(C) JRST MK10 ;found AOBJP C,.+2 AOBJN C,MK7 TLC B,140000 ;10 for locals TLNN B,100000 TLON B,400000 ;Suppressed to DDT JRST MK7-1 JRST FALSE MK10: MOVE A,1(C) ;value JRST FIX1A PUTSYM: PSAVE B PCALL R50MAK MOVE A,B TLO A,040000 ;make global SKIPL .JBSYM AOS .JBSYM ;increment initial symbol table pointer PSAVE A MOVEI A,2 PCALL EXPND2 MOVN B,[XWD 2,2] ADDB B,.JBSYM PREST (B) ;Name PREST 1(B) ;value JRST FALSE > ;end of IFN ALOD SUBTTL FASLOAD --- PAGE 21 ;From MIT-ML, converted to LISP 1.6 of Utah ;By KRK, Last edit: 09 Aug 76 IFN OFLD,< LDFNM2==137 ;Address of Lisp version number (if any). LDGPRO==0 ;Address (relative to reg P) of internal QLIST LDPRLS==-1 ; - " - P.URCLOBRL LDAAOB: 0 ;Currently highest index in Atomtable LDAGCM: 0 ;Address of GCMKL word for Atomtable LDAPTR: 0(TT) ;Base address for Atomtable. Index in TT LDBYTS: 0 ;Holds word being unpacked into bytes LDEOFJ: 0 ;Error index LDF2DP: 0 ;XOR between current and file version number LDGROW: 0 ;For extended Atomtable. Not used LDHLOC: 0 ;Not used LDOFST: 0(TT) ;Start of currently loaded routine. Relocation base ;LDPRDF: 0 ;Internal !*PREDEF flag ;Error indices LOOK==-1 EMPTYF==0 FORMAT==1 GCPROT==2 BPFULL==3 FTFULL==4 PAGE ; FASLOD('ArrayForFisl); FASLOD: ;MOVEM B,LDPRDF ;"Print redefined funcs". FOO SKIPN C,VPURIFY TLOA C,(1B0) FOO CDRA C,VP.URCLOBRL PSAVE C ;- to omit; 0 or old-addr to purify. PSAVE C ;LDGPRO zeroed below. SETZM LDEOFJ ;An EOF is erroneous until LDBEND byte. JSP D,ATMTYP CAIE TT,VECT JRST LDFERR CDRA A,(A) ;Lookup ATOMTABLE's access addr... MOVEI B,-2(A) MOVEM B,LDAGCM ;Addr of array's allocation-wd (GCMKL). MOVE B,-2(A) HRRM B,LDAPTR ;Addr of array's data base-wd. SETZ TT, SETZM @LDAPTR ;0th is NIL [N.B. indirection-addr uses TT]. LDMORE: JSP T,LDGTWD ; ...except that can get empty file. JUMPE TT,.-1 ;Sluff leading/trailing 0 words. SETZM LDEOFJ ;(Reset after a new file's LDMORE). AOS LDEOFJ ;Now 1 for "Format error". CAME TT,[ASCII /FASLP/] JSP D,LDFERR ;Improper format for FASL file. JSP T,LDGTWD ;Get 2nd word of each file. XOR TT,LDFNM2 ;Compare to Lisp's version&flags. MOVEM TT,LDF2DP ;Nonzero if different. SETZM FFFSUB# SETZM LDGPRO(P) ;Internal QLIST effectively. HLLZ A,@LDAGCM ;[-length,,0] AOBJN A,.+1 MOVEM A,LDAAOB ;Commence with 1th cell; NIL is 0th. FOO MOVE A,VBPORG PCALL NUMVAL HRRM A,LDOFST ;Also a TT indirection pntr. HRRZM A,R ;Form AOBJP wd in R for BPS storage... MOVE B,LDAGCM ; [Use this rather than BPEND1]. SUBI A,-1(B) JUMPL A,USE.IT FOO MOVE A,VBPEND PCALL NUMVAL MOVE B,A MOVE A,R SUBI A,(B) JUMPGE A,FASLNC USE.IT: HRLI R,(A) ; [-<available BPS>,,<starting BPORG>] SETZM LDHLOC ;Initialize for the BPS section. MOVE AR4,[000400,,LDBYTS] ;Initialize for accessing each JRST LDBIN ; 9*4 series of bytes. PAGE ;;; FROM THIS POINT ON, UNTIL A FATAL ERROR OCCURS OR LOCATION LDFEND IS REACHED, ;;; THESE ACCUMULATORS ARE DEDICATED TO THE FOLLOWING PURPOSES: ;;; AR4 BYTE POINTER FOR GETTING SUCCESSIVE RELOCATION TYPES ;;; R AOBJN POINTER FOR PUTTING WORDS INTO BINARY PROGRAM SPACE LDREL: HRRI TT,@LDOFST ;[RELOCATABLE WORD] LDABS: MOVEM TT,(R) ;[ABSOLUTE WORD] LDABS1: AOBJP R,FASLNC ;EXCEEDED AVAILABLE BPS -- NO CORE. LDBIN: TLNN AR4,770000 JRST LDBIN2 ;OUT OF RELOCATION BYTES - GET MORE. LDBIN1: JSP T,LDGTWD ;GET WORD FROM INPUT FILE ILDB T,AR4 ;GET CORRESPONDING RELOCATION BYTE JSP D,@LDTTBL(T) ; - IT TELLS US WHERE TO GO LDTTBL: LDABS ; 0 ABSOLUTE LDREL ; 1 RELOCATABLE LDSPC ; 2 SPECIAL LDPRC ; 3 PURIFIABLE CALL LDQAT ; 4 QUOTED ATOM LDQLS ; 5 QUOTED LIST LDGLB ; 6 GLOBALSYM PATCH LDGET ; 7 GET DDT SYMBOL PATCH LDAREF ; 10 ARRAY REFERENCE LDPEN ; 11 PUT ENTRY POINT LDATM ; 12 ATOMTABLE ENTRY LDENT ; 13 ENTRY POINT INFO LDLOC ; 14 LOC TO ANOTHER PLACE LDPUT ; 15 PUT DDT SYMBOL LDEVAL ; 16 EVALUATE MUNGEABLE LDBEND ; 17 END OF BINARY LDBIN2: JSP T,LDGTWD ;GET WORD OF RELOCATION BYTES MOVEM TT,LDBYTS SOJA AR4,LDBIN1 ;INIT BYTE POINTER AND GO GET DATA WORD PAGE LDSPC: MOVE T,TT ;[SPECIAL] MOVE A,@LDAPTR HLR TT,A ;GET ADDRESS OF SPECIAL CELL TRNE TT,777000 ;WAS SUCH AN ADDRESS REALLY THERE? JRST LDABS ; YES, WIN TRNE TT,6 ; NO, IS THIS ATOM A NUMBER? JSP D,LDFERR ; YES - LOSE!!! TRZE TT,20 ;IS IT NON INTERNED ID ? PCALL %GCPRO ;YES. PROTECT IT MOVE TT,T HRRZ A,@LDAPTR SKIPN A JSP D,LDFERR ;NO, LOSE IF NIL...ELSE PCALL BIND1 ;GET VALUE CELL MOVE TT,T HRLM A,@LDAPTR ;SAVE VC ADDR IN ATOMTABLE (LH). HRR TT,A ;AT LAST WE WIN JRST LDABS LDQAT: MOVE D,@LDAPTR ;[QUOTED ATOM] TLNN D,777001 ;SKIP IF SPECIAL OR ALREADY USED TLO D,1 ;ELSE TURN ON REFERENCE BIT MOVEM D,@LDAPTR HRRI TT,(D) ;GET ADDRESS OF ATOM JRST LDABS LDGLB: JSP D,LDFERR REPEAT 0,< SKIPL TT ;[GLOBALSYM PATCH] SKIPA TT,LSYMS(TT) ;GET VALUE OF GLOBAL SYMBOL MOVN TT,LSYMS(TT) ;OR MAYBE NEGATIVE THEREOF ADD TT,-1(R) ;ADD TO ADDRESS FIELD OF HRRM TT,-1(R) ; LAST WORD LOADED JRST LDBIN > PAGE LDQLS: MOVSI C,11 ;[QUOTED LIST] PCALL LDLIST ;GOBBLE UP A LIST JUMPE C,.+2 MOVEM TT,(R) ;PUT WORD IN BPS PSAVE A JSP T,LDGTWD ;GET HASH KEY FOR LIST PREST A PCALL %GCPRO ;PROTECT NEW LIST FROM GC. JUMPE C,LDEVL7 ;IF -2, THIS LIST GOES INTO ATOMTABLE. JRST LDABS1 ;OR -1, JUST INTO BPS. LDLIS0: JSP T,LDGTWD LDLIST: LDB T,[POINT 2,TT,2] ;[CONSTRUCT LIST] JRST @LDLTBL(T) LDLTBL: LDLATM ;ATOM LDLLST ;LIST LDLDLS ;DOTTED LIST LDLEND ;END OF LIST LDLATM: MOVE A,@LDAPTR TLNN A,777011 IOR A,C MOVEM A,@LDAPTR PSAVE A JRST LDLIS0 LDLLST: TDZA A,A LDLDLS: PREST A HRRZS TT JUMPE TT,LDLLS3 LDLLS1: PREST B PCALL XCONS SOJG TT,LDLLS1 LDLLS3: PSAVE A JRST LDLIS0 LDLEND: HLRZ C,TT TRC C,777776 ;-1 to 1, -2 to 0. TRNE C,777776 ;Any other? JSP D,LDFERR ; is error. PREST A MOVSS TT HRRI TT,(A) PRET PAGE LDPRC: MOVE D,@LDAPTR ;[PURIFIABLE CALL] TLNE D,777000 JRST LDPRC1 ;JUMP IF ATOM HAS SPECIAL CELL TLNE D,6 JSP D,LDFERR ;LOSE IF NUMBER TLO D,1 ;ELSE TURN ON REFERENCE BIT MOVEM D,@LDAPTR LDPRC1: TRNN D,-1 ;MUST HAVE NON-NIL ATOM TO CALL JSP D,LDFERR HRR TT,D ;PUT ADDRESS OF ATOM IN CALL SKIPGE T,LDPRLS(P) ;SKIP FOR PURIFYING HACKERY JRST LDABS ; Not active...DONE. MOVEM TT,(R) ;Store the call-word, HRRZ C,R ; and get its address... JSP AR5,TRYSMSH ;NOW TRY TO SMASH IT JRST LDABS1 ;SMASHED HRLI A,(R) ;NOT SMASHED ... HRR A,LDPRLS(P) ; APPEND ADDR TO PURE LIST PCALL DCONSA ; TO RE-TRY AT LDFEND. MOVEM A,LDPRLS(P) JRST LDABS1 IFN 0,< LDSMSH: LDB T,[POINT 9,(AR5),8] CAIL T,34 ;CALL CAILE T,35 ;JCALL PRET HRRZ A,(AR5) ;Pntr to atomhead. PCALL GETD ;TRY TO GET EXPR, FEXPR PROP LDB D,[POINT 4,(AR5),12] ;Destroys A,B,C,T,TT JUMPE A,CPOPJ1 ;Can't be smashed since undefined yet. CARA B,(A) MOVE T,APOPJ1 FOO CAIN B,EXPR MOVE T,[CAILE D,NSUA] FOO CAIN B,FEXPR MOVE T,[CAIE D,17] XCT T APOPJ1: JRST CPOPJ1 ;Don't smash if wrong # args wanted. CDRA A,(A) ;ELSE WIN - SMASH THE CALL CARA TT,(A) CAIE TT,ID CAIGE TT,CODMIN JRST CPOPJ1 CDRA A,(A) MOVE TT,(AR5) MOVSI T,(PCALL) ;FCALL BECOMES PCALL TLNE TT,1000 MOVSI T,(JRST) ;JCALL BECOMES JRST IOR T,A MOVEM T,(AR5) ;***SMASH!*** PRET > ;End of IFN 0 PAGE LDGET: JSP D,LDFERR REPEAT 0,< CAMN TT,XC-1 JRST LDLHRL MOVE D,TT ;[GET DDT SYMBOL PATCH] TLNN D,200000 ;MAYBE THE ASSEMBLER LEFT US A VALUE? JRST LDGET2 JSP T,LDGTWD ;FETCH IT THEN SKIPE LDF2DP JRST LDGET2 ;CAN'T USE IT IF VERSIONS DIFFER LDGET1: TLNE D,400000 ;MAYBE NEGATE SYMBOL? MOVNS TT LDB D,[400200,,D] ;GET FIELD NUMBER XCT LDXCT(D) ;HASH UP VALUE FOR FIELD MOVE T,LDMASK(D) ;ADD INTO FIELD ADD TT,-1(R) ; MASKED APPROPRIATELY AND TT,T ANDCAM T,-1(R) IORM TT,-1(R) JRST LDBIN LDGET2: PSAVE . ;RANDOM P SLOT PSAVE AR4 ;SAVE UP ACS PSAVE D PSAVE R PSAVE F MOVEI R,0 TLZ D,740000 CAME D,LAPFIV(R) ;IF DDTSYM REQUEST IS FOR A GLOBAL SYM JRST LDGT5A ;THEN FIND IT IN THE LAPFIV TABLE, AND GET ITS LSHC R,-2 ;GLOBALSYM INDEX FROM THE PERMUTATION TABLE LSH F,-42 LDB TT,LDGET6(F) MOVE TT,LSYMS(TT) JRST LDGT5B LDGT5A: MOVEI TT,R70 CAMN D,[SQUOZE 0,R70] JRST LDGT5B PCALL UNSQOZ ;CONVERT SQUOZE TO A LISP SYMBOL MOVEI C,(A) MOVEI B,QSYM ;TRY TO FIND SYM PROPERTY PCALL GET JUMPN A,LDGETJ ;WIN SKIPN JOBSYM JRST LDGETX LDB D,[004000,,-2(P)] LDGET4: MOVE TT,D IDIVI D,50 JUMPE R,LDGET4 PCALL GETDD0 JRST LDGETX PAGE LDGT5B: MOVEM TT,-4(P) ;WIN, WIN - USE RANDOM P SLOT MOVEI A,-4(P) ; TO FAKE UP A FIXNUM JRST LDGETJ LDGETX: MOVEI A,(C) PCALL NCONS MOVEI B,QGETDDTSYM ;DO A FAIL-ACT PCALL XCONS PCALL LDGETQ LDGETJ: PREST F ;RESTORE ACS PREST R PREST D PREST AR4 MOVE TT,(A) PCALL TYPEP ;FIGURE OUT WHAT WE GOT BACK PREST -1(P) ;POP RANDOM SLOT (REMEMBER THE LOCKI!) CAIN A,FIXNU JRST LDGET1 LDGETV: CAIN A,FLONU ;USE A FLONUM IF WE GET ONE JRST LDGET1 LDGETW: SKIPE TT,JOBSYM MOVSI TT,1 MOVEM TT,LDDDTP(P) JRST LDGET2 LDGETQ:; FAC [CAN'T GET DDT SYMBOL - FASLOAD!] LDGET6: REPEAT 4,<<11_^D24>+<<<3-.RPCNT>*11>_^D30> LAP5P(R) > LDXCT: MOVSS TT ;INDEX FIELD HRRZS TT ;ADDRESS FIELD LSH TT,^D23 ;AC FIELD JFCL ;OPCODE FIELD LDMASK: -1 ;INDEX FIELD 0,,-1 ;ADDRESS FIELD 0 17, ;AC FIELD -1 ;OPCODE FIELD LDLHRL: HRLZ TT,LDOFST ADDM TT,-1(R) JRST LDBIN > PAGE LDAREF: JSP D,LDFERR REPEAT 0,< PSAVE TT ;[ARRAY REFERENCE] MOVE D,@LDAPTR TLNN D,777001 TLO D,11 MOVEM D,@LDAPTR MOVEI A,(D) PCALL TTSR+1 ;NCALL TO TTSR HLL TT,(P) PXDROP R70+1 JRST LDABS > LDATM: LDB T,[POINT 3,TT,3] ;[ATOMTABLE ENTRY] JRST @LDATBL(T) LDATBL: LDATPN ;INTERNED ID LDATPI ;NON INTERNED ID LDATPS ;STRING LDATFX ;FIXNUM LDATFL ;FLONUM LDATBP ;POSNUM (POSITIVE BIGNUM) LDATBN ;NEGNUM (NEGATIVE BIGNUM) LDAREF ;TO GET ERROR LDATPB: MOVSI C,(TT) MOVN C,C HRRI C,0(SP) JSP T,LDGTWD MOVEM TT,1(C) AOBJN C,LDGTWD ; T still has return address PRET LDATPN: PCALL LDATPB ;[ATOMTABLE INTERNED ID ENTRY] PCALL INTER0 LDATP8: MOVE TT,LDAAOB MOVEM A,@LDAPTR AOBJP TT,LDAEXT MOVEM TT,LDAAOB JRST LDBIN LDATPI: PCALL LDATPB ;[ATOMTABLE NON INTERNED ID ENTRY] PCALL NOINTR TLO A,20 ;Mark for saving JRST LDATB2 PAGE LDATPS: PCALL LDATPB ;[ATOMTABLE STRING ENTRY] PCALL MSTR1 JRST LDATB2 LDATFX: JSP T,LDGTWD ;[ATOMTABLE FIXNUM ENTRY] PCALL FIX1A CAILE A,INUMIN TLOA A,12 ;INUM -- doesn't need GC pro. TLO A,2 JRST LDATP8 LDATFL: JSP T,LDGTWD ;[ATOMTABLE FLONUM ENTRY] PCALL FLO1A TLO A,4 JRST LDATP8 LDATBN: SKIPA C,[NEGNU] ;[ATOMTABLE NEGNUM ENTRY] LDATBP: MOVEI C,POSNU ;[ATOMTABLE POSNUM ENTRY] PSAVE C MOVEI C,(TT) MOVEI B,NIL LDATB1: JSP T,LDGTWD PCALL FWCONS PCALL CONS MOVE B,A SOJG C,LDGTWD ;T STILL HAS RETURN ADDRESS PREST B PCALL XCONS LDATB2: TLO A,6 JRST LDATP8 LDAEXT: MOVEI T,FTFULL JRST LDERRT REPEAT 0,< MOVM T,LDGROW ;[ATOMTABLE EXTEND] MOVNS T HRL TT,T MOVEM TT,LDAAOB ; Another page or so. MOVS TT,@LDAGCM ADD TT,T ; and protect the extension. MOVSM TT,@LDAGCM JRST LDBIN > PAGE LDENT: PCALL LDEPIN ;[ENTRY POINT INFO] FOO SKIPN VPREDEF JRST LDNRDF MOVE A,-1(P) PCALL GETD JUMPE A,LDNRDF MOVE A,-1(P) PSAVE R PSAVE AR4 PCALL WHEAD PCALL PRIN1 STRTIP [SIXBIT / REDEFINED!/] PCALL TOURET PREST AR4 PREST R LDNRDF: PREST B PREST C PREST A FOO CAIE B,SUBR JRST .+3 FOO MOVEI B,EXPR JRST .+4 FOO CAIE B,FSUBR JRST .+3 FOO MOVEI B,FEXPR SETOM FFFSUB PCALL IPUTD ;USES T,TT JRST LDBIN LDPEN: PCALL LDEPIN ;[PUT ENTRY POINT] PREST B PREST A PREST C PCALL PUT JRST LDBIN LDEPIN: HRRZ C,@LDAPTR ;[ENTRY POINT INFO] MOVSS TT HRRZ A,@LDAPTR PSAVE A ;ENTRY NAME. PSAVE C ;SUBR TYPE. JSP T,LDGTWD ;TT_<ARGS,,ENTRY-RELOC>... MOVEI A,@LDOFST CAILE A,(R) JSP D,LDFERR PCALL IMKCODE EXCH A,-2(P) JRST (A) PAGE LDLOC: JSP D,LDFERR REPEAT 0,< MOVEI TT,@LDOFST MOVEI D,(R) CAMLE D,LDHLOC MOVEM D,LDHLOC CAMG TT,LDHLOC JRST LDLOC5 MOVE D,LDHLOC SUBI D,(R) MOVSI D,(D) ADD R,D HRR R,LDHLOC SETZ TT, ADD AR4,[040000,,] JRST LDABS LDLOC5: HRRZ D,LDOFST CAIGE TT,(D) JSP D,LDFERR MOVEI D,(TT) SUBI D,(R) MOVSI D,(D) ADD R,D HRRI R,(TT) JRST LDBIN > PAGE LDPUT: JSP D,LDFERR REPEAT 0,< SKIPN A,V$SYMBOLS ;[PUT DDT SYMBOLS] JRST LDPUT3 CAIE A,SYMBOLS JRST LDPUT7 TLNN TT,40000 JRST LDPUT3 LDPUT7: SKIPN JOBSYM JRST LDPUT3 PSAVE AR4 JUMPL TT,LDPUT2 MOVE D,R LDPUT0: PSAVE D PSAVE F TLZ TT,740000 LDPUT1: MOVE T,TT IDIVI TT,50 JUMPE D,LDPUT1 MOVEI B,-1(P) MOVSI R,400000 PCALL PUTDD0 JRST LDRSTX LDPUT2: MOVE D,TT JSP T,LDGTWD EXCH TT,D TLNN TT,100000 JRST LDPT2A MOVE T,LDOFST ADD T,D HRRM T,D LDPT2A: TLNN TT,200000 JRST LDPUT0 HRLZ T,LDOFST ADD D,T JRST LDPUT0 LDPUT3: JUMPGE TT,LDBIN ;DON'T WANT TO PUT DDT SYM, BUT JSP T,LDGTWD ; MAYBE NEED TO FLUSH EXTRA WORD JRST LDBIN > PAGE LDEVAL: SETZ C, ;[EVALUATE MUNGEABLE] PCALL LDLIST PSAVE A PSAVE C PSAVE AR4 PSAVE R MOVEI A,(R) PCALL FIX1A FOO MOVEM A,VBPORG ;Permit the mungeable to alter BPORG. SKIPL A,LDPRLS-4(P) FOO HRRZM A,VP.URCLOBRL ;Save us in case of ERR. MOVE A,-3(P) PCALL EVAL EXCH A,-3(P) ;Save value, retrieve S-expr. PSAVE A FOO CDRA A,VP.URCLOBRL HRRM A,LDPRLS-5(P) FOO MOVE A,VBPORG PCALL NUMVAL PREST B PREST R SUBI A,(R) ;If BPORG unchanged, JUMPE A,LDEVL5 ; then leave R & FARRAY alone. JUMPLE A,LDEVL4 ; If lowered, keep R, just fix FARRAY. ADDM A,LDOFST ;Hence can't do future LDLOC ********** HRLI A,(A) ADD R,A ;Else decrease space-avail left. LDEVL4: FOO MOVE A,VFARRY ;Save S-exprs which change BPORG. PCALL XCONS FOO HRRZM A,VFARRY LDEVL5: PREST AR4 PREST C PREST A JUMPN C,LDBIN ;IF -1, THROW AWAY VALUE; PCALL %GCPRO ;OR -2, PROTECT & ENTER IN ATOMTABLE. LDEVL7: TLO A,16 ;FROM LDQLS, IS ALREADY PROTECTED JRST LDATP8 %GCPRO: HRRZ B,LDGPRO-1(P) PCALL CONS HRRM A,LDGPRO-1(P) CARA A,(A) ;RETURN WHAT WE JUST APPENDED. PRET PAGE LDBEND: CAME TT,[ASCII \FASLP\] ;[END OF BINARY] JSP D,LDFERR AOS LDEOFJ ;Now have seen End-of-Data in a file... ; Update BPS bounds and protect atoms ; from GC, then try for next file. LDFEND: ;[END OF FILE] HRRZ A,R CAMGE A,LDHLOC MOVE A,LDHLOC PCALL FIX1A FOO MOVEM A,VBPORG ;UPDATE BPORG HRRZ R,LDAAOB LDGCPR: SOJLE R,LDSDPL ;[GC PROTECT AS YET UNPROTECTED ATOMS] MOVEI TT,(R) MOVE AR5,@LDAPTR HRRZ A,AR5 TLNN AR5,777010 ;IF VALUE-CELL OR ALREADY PROTECTED, TLNN AR5,1 ;OR NO NEED (NEVER REF'D), JRST LDGCPR ; PASS BY. TLNE AR5,26 JRST LDGCP1 ;FIX,FLO,BIG,string or non-interned id JRST LDGCPR LDGCP1: HRRZ A,AR5 PCALL %GCPRO JRST LDGCPR LDSDPL: SKIPGE TT,LDPRLS(P) ;[RE-TRY SMASHING DOWN PURE LIST] JRST LDEOMM FOO MOVEM TT,VP.URCLOBRL ;Following retains locs unsmashed. FOO MOVEI R,VP.URCLOBRL LDSDP1: SKIPN TT,LDPRLS(P) JRST LDEOMM LDSDP2: CDRA T,(TT) MOVEM T,LDPRLS(P) CARA C,(TT) JSP AR5,TRYSMSH JRST LDSDP3 CDRA R,(R) JRST LDSDP1 LDSDP3: MOVE TT,LDPRLS(P) RPLCD TT,(R) JRST LDSDP1 PAGE LDEOMM: SKIPN A,LDGPRO(P) ;Have processed a FASL file completely, JRST LDFNIL FOO MOVE B,VF.LIST ; and protected internal Lisp node refs PCALL CONS ; off the PDL with this final save. FOO MOVEM A,VF.LIST LDFNIL: MOVE A,LDAGCM MOVE A,(A) ;Now clear array (so won't be SSAVEd), SETZM 0(A) ; and read til true EOF does ERR $EOF$ AOBJN A,.-1 ; or see start of next FASL in series. ;However, doesn't clear access routine. SETOM LDEOFJ ;EOF will be okay, or start of next file. JRST LDMORE ;Continue, with the extra PDL cells. LDGTWD: PCALL TYID ;This is BINI w/o Lisp # conversion... MOVE TT,A ; so inputting a 36-bit word or $EOF$. JRST 0(T) FASLNC: MOVEI T,BPFULL JRST LDERRT LDFERR: SKIPGE T,LDEOFJ ;Externally invoked after any ERRSET. JRST LDFSUB ; OK - return after proper EOF. MOVE T,LDEOFJ LDERRT: MOVEI A,LDERRN ;Change... MOVEM A,LDEOFJ ; Avoid doubly-printed LERRs. CAILE T,LDERRN ERRL1 ^D149,[SIXBIT \FASLOAD BUG!\] JRST .+1(T) ;Else dispatch to the various errs... LDERR0: ERRL1 ^D150,[SIXBIT \FASLOAD EMPTY FILE!\] ERRL1 ^D151,[SIXBIT \FASLOAD FORMAT ERR!\] ERRL1 ^D152,[SIXBIT \FASLOAD GC-PRO ERR!\] ERRL1 ^D153,[SIXBIT \FASLOAD EXCEEDS BPS!\] ERRL1 ^D154,[SIXBIT \FISLTABLE FULL!\] LDERRN==.-LDERR0 ERRL1 ^D155,[SIXBIT \NOGO!\] LDFSUB: SKIPN FFFSUB PRET SETZM FFFSUB FOO SKIPE %MSG STRTIP [SIXBIT /_*** (F)SUBR CONVERTED TO (F)EXPR_!/] PRET > ;End of IFN OFLD IFN OFLD!NFLD,< ;Try convert slow link to fast link TRYSMSH:HRRZ A,(C) ;right half of instruction HLRZ T,(C) ;left half CAIL T,(FCALL) ;is it FCALL or CAILE T,777(JCALL) ; JCALL JRST (AR5) ;No! Treat as sucessful, i.e. never smash PCALL GETD ;get function definition JUMPE A,1(AR5) ; unsucessful if wasn't there MOVSI TT,(PCALL) ; replacement FCALL - PCALL TRNE T,1000 MOVSI TT,(JRST) ; JCALL - JRST ANDI T,740 ;Now check EXPR - FEXPR FOO MOVEI D,EXPR CAIN T,740 FOO MOVEI D,FEXPR ;argcount 17 means call a FEXPR CARA B,(A) ;get function type CAIE B,(D) ;is it right type for the call? JRST 1(AR5) ;No! unsucessful CDRA A,(A) ;code part CARA D,(A) ;check tag CAIE D,ID CAIGE D,CODMIN JRST 1(AR5) ;not a code pointer! unsucessful HRR TT,(A) ;get code address into new instruction MOVEM TT,(C) ;change instruction JRST (AR5) ;sucessful > ;End of IFN OFLD!NFLD IFN NFLD,< ;New version of FASLOD FASLOAD:PSAVE [0] ;internal F.LIST HRRM P,LDQLIS ;save its pointer FOO SKIPE VPURIFY ;want to try converting slow links to fast? TDZA B,B ;yes SETO B, ;no! make negative to indicate that PSAVE B ;internal P.URCLOBRL HRRM P,LDPURC ;save its pointer MOVEM P,LDSTCK# ;save for stack check at end JSP D,ATMTYP ;check F.ISLTABLE CAIE TT,VECT ;is it a vector? ERRL2 ^D168,[SIXBIT /NO TABLE FOR FASL!/] ;no! error CDRA A,(A) ;get its base address SETZM (A) ;first element is NIL HRRM A,CTOPAT ;current top of table HRRM A,LDATBAS ;base of table JSP T,RSTBPO ;set internal BPORG and BPEND SETZM CALHLF ;indicate need new word in half word buffer MOVEI D,LDLOP+1 ;return address for LDBYT LDNWD: PCALL TYID ;byte buffer is empty. get new word MOVEM A,LDBTWD ;save word in buffer MOVE A,[POINT 6,LDBTWD] ;get byte pointer MOVEM A,LDBTPO# ;save it LDBYT: ILDB A,LDBTPO ;get a byte JUMPN A,(D) ;not 0 means not empty buffer HRRZ TT,LDBTPO ;buffer might be empty CAIN TT,LDBTWD ;does pointer still point to buffer? JRST (D) ;yes! 0 byte JRST LDNWD ;no! buffer empty LDID: JSP D,LDHLF ;Get length of id PCALL %FSLID+1 ;make interned id LDPUTA: AOS .+1 ;update top of table CTOPAT: MOVEM A,X ;move object into table ;this is the loader loop LDLOP: JSP D,LDBYT ;get new loader code byte CAIG A,LDBTMX ;is it a legal code JRST @LDJTAB(A) ;Yes! Dispatch ERRL2 ^D169,[SIXBIT /FASL FORMAT ERROR!/] ;No! Error LDJTAB: LDEND LDID LDGENSYM LDSTRNG LDPOSN LDNEGN LDFIXN LDFLON LDQUO LDCAL LDRLO LDAXCON LDXCON LDOFFSET LDENTRY LDXPR LDLAPBLOCK LDNCON LDPUTV LDMKVCT .LDABS LDPUSH .LDEVAL LDFLUID LDSYM LDEVID LDSETQ LDIPUT .LDPUT LDIPTD LDPUTD LDNUMP LDXPRS LDPOP LDEVIX .LDLIST LDPOPN LDPROTECT LDBTMX==.-LDJTAB-1 LDGENSYM: ;make non interned id FOO MOVEI C,PNAME PCALL MKFWLIS ;make print name list PCALL IDCONS-1 ;make into id JRST LDPUTA ;put into table LDPOSN: SKIPA C,CPOSNU ;positive bignum LDNEGN: MOVEI C,NEGNU ;negative bignum JRST LDSTRNG+1 LDSTRNG:MOVEI C,STRNG ;string PCALL MKFWLIS ;read and make full word list JRST LDPUTA ;put into table MKFWLIS:JSP D,LDHLF ;read length of list MOVE TT,A ;save count SKIPA B,[0] ;start with NIL MOVE B,A ;current list PCALL TYID ;read a word PCALL BCONS ;cons into list SOJG TT,.-3 ;go back for more HRL A,C ;get tag JRST DCONSA ;cons it LDFIXN: PCALL BINI ;read a fixnum JRST LDPUTA ;put into table LDFLON: PCALL TYID ;read a word PCALL FLO1A ;tag as floating point number JRST LDPUTA ;put into table LDMKVCT:JSP T,SAVBPO ;allow BPORG to be changed JSP D,LDHLF ;get uplim for vector PCALL MKVECT+1 ;make vector HRRZ C,(A) ;vector address HRRM C,CLIPTV ;update "current vector base" MOVE C,A JSP T,RSTBPO ;update internal BPORG MOVE A,C JRST LDPUTA ;put vector into table LDPUSH: MOVEI T,LDPU1 ;return address, push on stack LGETVX: JSP D,LDHLF ;get table index HRRZ A,@LDATBAS ;get element from table JRST (T) .LDABS: MOVEI D,LDPU1 ;push on stack LDHLF: SETZ A, EXCH A,CALHLF# JUMPN A,.+3 PCALL TYID ;half word buffer empty. read new word HLROM A,CALHLF ;save in buffer, -1 in lh make non-zero MOVEI A,(A) ;get right half (get rid of -1) JRST (D) ;return LDAXCON:MOVEI D,.+3 ;make list ending with absolute JRST LDHLF LDXCON: JSP T,LGETVX ;make list ending with table element SKIPA TT,A ;save table element in TT LDNCON: SETZ TT, ;end with NIL (ordinary list) JSP D,LDHLF ;length of list EXCH A,TT ;get end into A PREST B ;get element from stack PCALL XCONS ;cons into list SOJG TT,.-2 ;maybee more LDPU1: PSAVE A ;save on stack JRST LDLOP ;return to loop ;execute EXPR, arguments are on stack. put result on stack LDXPR: JSP T,LGETVX ;get function id from table PSAVE A ;save it LDXPRS: JSP T,SAVBPO ;function is on stack JSP D,LDBYT ;number of args PREST REL ;function DPB A,[POINT 4,LDCALL,ACFLD] ;update call instruction MOVN T,A JSP TT,PDLARG ;put args into regs LDCALL: CALLF X,(REL) ;call function PSAVE A ;save result on stack MOVEI T,LDLOP ;return address RSTBPO: ;Update internal BPORG and BPEND as the might have been changed FOO HRRZ A,VBPEND PCALL NUMVAL HRRM A,LDBPEN ;update internal BPEND FOO HRRZ A,VBPORG PCALL NUMVAL HRRM A,LDBPOR ;update internal BPORG JRST (T) .LDEVAL:JSP T,SAVBPO JSP T,LGETVX ;get fexpr id PREST B ;argument list PCALL CONS PCALL EVAL ;evaluate fexpr JRST LDCALL+1 LDPOP: P1DROP ;remove top of stack JRST LDLOP LDEVID: JSP T,LGETVX ;get id from table PCALL EVAL ;get its value JRST LDPU1 ;push it on stack LDSETQ: JSP T,LGETVX ;get id from table PCALL BIND1 ;get its value cell PREST (A) ;update value cell from stack JRST LDLOP LDIPUT: JSP T,LGETVX ;get id from table HRRM A,CLIPUT ;update "current property indicator" JRST LDLOP LDIPTD: JSP T,LGETVX HRRM A,CLIPTD ;update "current function type" JRST LDLOP .LDPUT: JSP T,LGETVX PREST C ;property value CLIPUT: MOVEI B,X ;property indicator PCALL PUT JRST LDLOP LDPUTD: JSP T,LGETVX PSAVE A ;save function id FOO MOVEI B,TRACE ;remove TRACE property PCALL REMP1 FOO SKIPN VPREDEF ;want to warn for redefined function JRST NOPRDF ;no! MOVE A,(P) ;is function PCALL GETD ; already defined JUMPE A,NOPRDF MOVE A,(P) ;yes! PCALL WHEAD ;warning header PCALL PRIN1 ;print function name STRTIP [SIXBIT / REDEFINED!/] PCALL TOURET ;return to current output NOPRDF: PREST C ;function id PREST A ;function body CLIPTD: MOVEI B,X ;function type PCALL IPUTD ;define it JRST LDLOP LDPUTV: JSP D,LDHLF ;get vector index PREST C ;value to put into vector SETZ B, LSHC A,-1 JUMPN B,.+3 ;B = 0 means even index CLIPTV: HRLM C,X(A) ;X is current vector base. updated by LDMKVCT JRST LDLOP HRRM C,@CLIPTV ;odd index. value goes into right half JRST LDLOP LDLAPBLOCK: ;load a block of code JSP D,LDHLF ;no of words to load LDBPORG:MOVEI R,X ;internal BPORG MOVEI C,(R) ADDI C,(A) ;new BPORG LDBPEND:CAILE C,X ;compare with internal BPEND JRST BINER2 ;error if bigger HRRM C,LDBPOR ;update BPORG HRRM R,LDRLBAS ;set block base addres for relocation SOJ R, HRRM R,LDRSTRT ;set patch address base HLLZS MPAFUN ;no patch function seen MOVNI C,(A) ;make HRL R,C ; iowd PCALL TYID ;read a word MOVEM A,1(R) ;deposit in BPS AOBJN R,.-2 ;maybee more JRST LDLOP MAPAT: MOVEI C,X ;old patch address ADDI C,77 MOVEI T,(T) ;patching function CAIE T,@MPAFUN ;same as old LDRSTRT: MOVEI C,X ;no! use patch base address. set by LDLAPBLOCK HRRM T,MPAFUN ;set current patch function MPARET: JSP D,LDBYT ;Get relative patch address. Patch funs return here JUMPE A,[HRRM C,MAPAT ;0 byte means save patch address JRST LDLOP] ; and end patching ADDI C,(A) ;update patch address HRRZ A,(C) ;get index or address MPAFUN: JRST X ;go patch LDRLO: JSP T,MAPAT ;enter patch loop LDRLBAS:ADDI A,X ;relocation base HRRM A,(C) ;put into instruction JRST MPARET ;return to patch loop LDQUO: JSP T,MAPAT ;enter patch loop HRRZ A,@LDATBAS ;get element from table HRRM A,(C) ;put in instruction JRST MPARET LDCAL: JSP T,MAPAT ;enter patch loop HRRZ A,@LDATBAS ;get table element HRRM A,(C) ;put in instruction LDPURC: SKIPL REL,X ;If iternal PURIFY switch is on JSP AR5,TRYSMSH+1 ; try to convert slow link to fast JRST MPARET ;did it or no PURIFY! return to patch loop MOVE A,REL ;couldn't do it. get internal P.URCLOBRL HRLI A,(C) ;cons instruction address PCALL DCONSA ; into list MOVEM A,@LDPURC ; and move into P.URCLOBRL JRST MPARET ;return to loop LDFLUID:JSP T,LGETVX ;get id from table PCALL BIND1 ;get its value cell JRST LDPUTA ;put it into table LDEVIX: MOVE A,(P) ;top of stack JSP D,NATMTYP ;check if it needs to be gc-protected JRST LDEPRO ;not atom! needs protection JUMPE TT,.LDLIST ;INUM doesn't need potection CAIE TT,ID ;is an id? JRST LDEPRO ;no! protect PCALL .INTERNP ;is it interned JUMPN A,.LDLIST ;if yes, don't protect MOVE A,(P) ;get top of stack LDEPRO: CDRA B,@LDQLIS ;internal F.LIST PCALL CONS HRRM A,@LDQLIS ;update internal F.LIST .LDLIST:PREST A ;take top of stack JRST LDPUTA ;put it into table LDSYM: JSP T,LGETVX ;get id from table MOVE T,A ;save in case of error FOO MOVEI B,SYM ;get SYM PCALL GET ; property JUMPE A,[MOVE A,T ;if none ERRE2 ^D38,[SIXBIT / IS NOT A SYM!/]] ;error PCALL NUMVAL ;get address JRST LDPUTA ;put into table LDOFFSET: JSP T,LGETVX ;get address from table MOVE T,A ;save it JSP D,LDHLF ;get offset ADDI A,(T) ;update address JRST LDPUTA ;put it into table LDNUMP: JSP T,LGETVX ;get object from table PCALL FIX1A ;convert to number JRST LDPU1 ;put on stack LDPOPN: PREST A ;get top of stack PCALL NUMVAL ;convert to address JRST LDPUTA ;put into table LDPROTECT: ;protect objects by consing them into internal F.LIST LDQLIS: CDRA B,X ;get internal F.LIST JRST .+3 ;enter loop PCALL CONS ;cons object into list MOVE B,A ;save list JSP T,LGETVX ;get new object JUMPN A,.-3 ;if not NIL go back HRRM B,@LDQLIS ;update internal F.LIST JRST LDLOP LDENTRY:HRRZ C,LDRLBAS ;get start of lap block JSP D,LDHLF ;get relative address ADDI C,(A) ;get real address JSP D,LDBYT ;no of args EXCH A,C PCALL IMKCODE ;make code pointer JRST LDPU1 ;push on stack LDEND: CAME P,LDSTCK ;end of loading. check stack consistency ERRL2 ^D170,[SIXBIT /FASL STACK OUT OF SYNC!/] PREST B ;internal P.URCLOBRL JUMPL B,NOPURC ;negative if PURIFY is off FOO MOVEI A,VP.URCLOB PCALL NCONC ;concatenate to P.URCLOBRL MOVE REL,A ;try smash instructions on list CDRA AR4,(REL) JRST SMSHLE ;enter loop SMSHLP: CARA C,(AR4) ;get instruction address JSP AR5,TRYSMSH ;try smash instruction JRST .+2 ;Smashed! MOVE REL,AR4 ;Not smashed! keep address in list CDRA AR4,(AR4) ;next element HRRM AR4,(REL) ;this will remove address of smashed instruction SMSHLE: JUMPN AR4,SMSHLP ;if more go back NOPURC: PREST B ;internal F.LIST FOO HRRZ A,VF.LIST ;F.LIST PCALL XCONS ;save internal F.LIST on F.LIST FOO HRRM A,VF.LIST ;update F.LIST MOVEI T,CPOPJ ;return address SAVBPO: HRRZ A,LDBPEN PCALL FIX1A FOO HRRZM A,VBPEND HRRZ A,LDBPOR PCALL FIX1A FOO HRRZM A,VBPORG ;Allow change of BPORG JRST (T) LDBTWD: X LDATBAS:Z X(A) ;First six bits of this word must be 0 to make LDBYT correct ;%FSLID is an EXPR that reads an id from a FSL file, it is used by ; the PRELOAD device. %FSLID: PCALL TYID ;Get length of id MOVN C,A ;make HRLZI C,(C) ; HRRI C,(SP) ; iowd PCALL TYID ;get a word MOVEM A,1(C) ;put in buffer AOBJN C,.-2 ;get more if not finished JRST INTER0 ;intern it > ;End of IFN NFLD SUBTTL ALVINE AND LOADER INTERFACES --- PAGE 22 ;interface to alvine IFN AED,< ED: MOVEI REL,X ;Reset to EDP2 by: STRT, EXCISE, EXCORE. JRST (REL) EDP2: PSAVE A HRRZ A,CORUSE HRRM A,LST AOS A HRRM A,ED MOVSI A,(SIXBIT /ED/) PCALL SYSINI HRLM A,LST MOVNS A PCALL MORCOR PCALL SYSINQ PREST A JRST ED GRINDEF:PSAVE A PCALL ED PREST A JRST 2(REL) > ;end of IFN AED EXCISE: MOVE A,JRELO IFN AED,<MOVEI B,EDP2 HRRM B,ED> IFN ALOD,SETZM LDFLG ;initial loader symbol table flag CALLI A,CORE JRST .+1 JSR IOBRST IFE HCBPS,PCALL CHKVBP ;Ensure BPORG and BPEND in low BPS. JRST TRUE PAGE VAR LIT PAGE ; lisp loader interface IFN ALOD,< LOAD: AOS B,CORUSE MOVEM B,OLDCU# MOVEM A,LDPAR# JUMPE A,LOAD2 ;If NIL, @.JBREL+1 FOO MOVE A,VBPORG ; else into BPS @BPORG. PCALL NUMVAL MOVE B,A LOAD2: MOVEM B,RVAL ;final destination of loaded code MOVSI A,(SIXBIT /LOD/) PCALL SYSINI SUBI A,150 ;extra room for locations 0 to 137 and slop MOVNS A ;length(loader) = 5400 approx. HRRZM A,LODSIZ# ADDI A,10 ;Space for start of symbol table etc. PCALL MORCOR ;expand core for loader MOVEM A,LOWLSP# ;location of blt'ed low lisp MOVE B,LODSIZ ADD B,A MOVEM B,HVAL ;temporary destination of loaded code HRLI A,0 ;<0,,LOWLSP> -- HVAL. BLT A,(B) ;blt up low lisp HLL A,NAME+3 ;IOWD length(loader),137 . HRRI A,137-1 PCALL SYSINP SKIPE LDFLG# JRST LOAD3 ;If already have them, skip SYMs. MOVSI A,(SIXBIT /SYM/) PCALL SYSINI MOVNS A ;length symbols PCALL MORCOR ;expand core for symbols SKIPGE B,.JBSYM SOS B ;if no symbol table, use original jobsym. HLRZ A,NAME+3 ;-length(symbols) ADDB A,B HLL A,NAME+3 ;symbol table iowd PCALL SYSINP HRRM B,.JBSYM HLLZ A,NAME+3 ADDM A,.JBSYM SETOM LDFLG ;Lisp symbols loaded, until next EXCISE. SKIPA LOAD3: SOS .JBSYM ;want jobsym to point one below 1st symbol MOVE 3,HVAL ;h MOVE 5,RVAL ;r MOVE 2,3 SUB 2,5 ;x=h-r HRLI 5,12 ;(w) -- LH index needed because HRLI 2,11 ;(v) uses @X, etc. SETZB 1,4 ;(N,S) IFN SYDEV,<MOVE 4,SYSNUM> ;Tell Loader current SYS: used by Lisp. JSP 0,140 ;call the loader LOAD4: HRRZM 5,RLAST# ;last location loaded(in final area) MOVE T,OLDCU MOVE A,.JBSYM MOVEM A,.JBSYM(T) MOVE A,.JBREL MOVEM A,.JBREL(T) ;update jobrel HRLZ 0,LOWLSP SOS LODSIZ AOBJN 0,.+1 ;<LOWLSP+1,,A> -- LODSIZ. BLT 0,@LODSIZ ;blt down low lisp MOVE 0,@LOWLSP ;<LOWLSP,,NIL> -- all accs now restored. MOVE B,RLAST MOVE A,RVAL HRL A,HVAL ;<HVAL,,RVAL> -- RLAST. SKIPE LDPAR JRST BINLD ;If into BPS, check room first. MOVE C,RLAST ;new coruse LDRET2: BLT A,(B) ;blt down loaded code HRRZM C,CORUSE ;top of code loaded MOVEI B,1 ANDCAM B,.JBSYM SUB C,.JBSYM ;length of free core ORCMI C,776000 AOJGE C,START ;no contraction ADD C,.JBREL ;new top of core MOVE B,C PCALL MOVDWN HRLM C,.JBSA CALLI C,CORE ;contract core JRST .+1 JRST START BINLD: PSAVE A ;Check for BPS exceeded... PSAVE B ;<MOVEI C,INUM0(B) CDRA A,B ; CAML C,VBPEND PCALL FIX1A ; JRST BPSERR PSAVE A ; MOVEM C,VBPORG> FOO MOVE B,VBPEND PCALL .LESS JUMPE A,[SETOM BPSFLG ;Flag "BPS exceeded" for LISP2 check. JRST START ] FOO PREST VBPORG ;Update it; loading fits. PREST B PREST A SOS C,OLDCU ;old top of core JRST LDRET2 > ;end of IFN ALOD PAGE IFN AED!ALOD,< SYSINI: MOVEM A,NAME+1 IFLE <OPSYS+SYDEV-1>,<SETZM NAME+3 > IFN SYDEV,<PSAVE SYSNUM IFLE OPSYS,<PREST .+2> IFG OPSYS,<PREST NAME+3> > INIT 17 IFE SYDEV,<SIXBIT /SYS/ > IFN SYDEV,< IFLE OPSYS,< X > IFG OPSYS,<SIXBIT /DSK/ > > 0 JRST AIN.4+1 LOOKUP NAME JRST SYSINER ;error INPUT [IOWD 1,NAME+3 ;input size of file 0] HLRO A,NAME+3 PRET SYSINER:RELEASE IFE ALOD,<ERRL1 ^D156,[SIXBIT /LISP.ED MISSING!/]> IFN ALOD,< MOVSI B,(SIXBIT /SYM/) CAME A,B ;Are we in LOAD mode? IFN AED,ERRL1 ^D156,[SIXBIT /LISP.ED OR LOD MISSING!/] ;No, safe to use IFE AED,ERRL1 ^D156,[SIXBIT /LISP.LOD MISSING!/] ; low core routines. OUTSTR [ASCIZ / LISP.SYM not found!! No load. /] ; Yes -- Loader in low core, though, MOVE 5,RVAL ; so have to fake the BLT JRST LOAD4 ; with original RVAL. > ;end of IFN ALOD NAME: SIXBIT /LISP/ ;Filename of system, 0 ; .* auxiliaries (e.g. SYM, LOD, ED). 0 0 > ;end of IFN ALOD!AED PAGE IFN ALOD,< SYSINP: MOVEM A,LST> ;LOAD IFN ALOD!AED!RWB,< SYSINQ: ;ED, RBLK IFN OPSYS,< ;KLUDGE to circumvent bug in PA1050... MOVS A,LST ; to wit: uses SIN which plants a nul, SUB A,LST ; which clobbers wd after input-blk. HLRZ A,A IFN HCBPS,<CAIGE A,400000> CAMGE A,.JBREL PSAVE 1(A) INPUT LST IFN HCBPS,<CAIGE A,400000> CAMGE A,.JBREL PREST 1(A) > IFE OPSYS,<INPUT LST> ;ELSE just input it. STATZ 740000 ERRL1 ^D157,AIN.8 RELEASE PRET LST: 0 0 > ;end of IFN ALOD!AED!RWB AIN.8: SIXBIT /INPUT ERROR!/ PAGE IFN ALOD,< MOVDWN: HLRZ A,.JBSYM JUMPE A,MOVS1 ADDI A,1(B) HRL A,.JBSYM HRRM A,.JBSYM BLT A,(B) ;downward blt PRET MOVSYM: MOVE B,.JBREL HRLM B,.JBSA HLRE A,.JBSYM JUMPE A,MOVS1 ADDI B,1(A) ;new bottom of symbol table MOVNI A,1(A) ADD A,.JBSYM ;last loc of old symbol table HRRM B,.JBSYM PSAVE C MOVE B,.JBREL ;last loc of new symbol table MOVE C,(A) ;simulated upward blt MOVEM C,(B) SUBI B,1 ADDI A,-1 ;lf+1,rt-1 JUMPL A,.-4 PREST C PRET MOVS1: HRRZM B,.JBSYM PRET> ;end of IFN ALOD ;enter with size needed in a ;exit with pointer in a to core MORCOR: PSAVE B PCALL EXPND2 MOVE B,CORUSE# ADDM A,CORUSE MOVE A,B PREST B PRET EXPND2: HRRZ B,.JBSYM SUB B,CORUSE SUBM A,B JUMPL B,EXPND3 ADD B,.JBREL ;new core size CALLI B,CORE ;expand core TCORE3: ERRL1 ^D158,[SIXBIT /CAN'T EXPAND CORE!/] IFN ALOD,<PSAVE A PCALL MOVSYM PREST A> IFE ALOD,<MOVE B,.JBREL HRRZM B,.JBSYM HRLM B,.JBSA> EXPND3: PRET SUBTTL SOSLINK INLINE WITH LISP MAIN --- PAGE 23 %FPAGE: SUBI A,INUM0 ;FIND-PAGE N, IN THE FILE. PSAVE A %FP.LP: SOSG A,0(P) JRST POPAJ ;Stop when get there, returning 0=NIL. PCALL TYI ;(ERR $EOF$) if too few <ff>. CAIE A,14 JRST .-2 JRST %FP.LP %NEXTTYI: PCALL TYI ;Doing a PEEKC(). MOVEM A,OLDCH JRST FIX1A FILEP: PCALL FILEPX RELEASE 0, PRET FILEPX: PSAVE A ;Test for a file's existence. MOVSI B,(SIXBIT /DSK/);Clear any left over. MOVEM B,DEV SETZM PPN JUMPE A,.+3 JSP D,ATMTYP PCALL NCONS MOVE T,A ;Permit @((F.E)) or full @(DIR: D F.E)) . PCALL IOSUB MOVEM A,LOOKIN IFN SYDEV,<PCALL SYSDEV > ;Change SYS: if necessary. MOVE A,DEV MOVEM A,DEV2 INIT 0,17 DEV2: X 0 JRST AIN.7 PREST A LOOKUP 0,LOOKIN ;Using chan 0 (no INC or INPUT needed). MOVEI A,NIL ; file not found. PRET PAGE IFN SOSSW,< %SOSSWAP: SUBI 2,INUM0 ;(PAGE # .LT. 2^16, OF COURSE). SUBI 4,INUM0 LSH 4,^D16 ;ERGO, 2 BECOMES 400000 PSAVE 4 PSAVE 2 PSAVE 1 ;FILE SPECIFICATION MOVE 1,3 PCALL NUMVAL ;(LINE # .LT. 99999). MOVE 4,[POINT 7,T,34] MKLIN1: IDIVI 1,^D10 ADDI 2,60 DPB 2,4 ADD 4,[XWD 70000,0] TLNN 4,400000 JRST MKLIN1 TRO T,1 EXCH T,(P) ;T WILL NOW CONTAIN FILE SPECIFICATION SETZM DEV PCALL IOSUB ;RETURNS FILENM IN A MOVEM 17,ACSAV+17 MOVEI 17,ACSAV BLT 17,ACSAV+16 ;SAVE ACCS 0-17 for return from subr. PREST 15 PREST 16 PREST 13 ;00/01/02 == GET,R-O,CREATE. MOVEM P,ACSAV+P MOVE 14,A HLL 13,EXT ;SET BY IOSUB IFGE OPSYS,<CALLI 11,24 ;GETPPN UUO SETZ 11, HRRZS 11 > IFL OPSYS,<GJINF MOVE 11,2 > SETZB 1,12 ;HIGH ACCS FOR SOS ARE NOW SET ... TO WIT: ; ;ACC 11 = PPN ; 12 = (UNUSED). ; 13 = EXT,,FLAGS ;BITS 18-19 = 0 (GET FILE), 1 (READ-ONLY), 2 (CREATE IT) ; 14 = FILENM ; 15 = LINE #, IN ASCID FORM (BIT 35 ON); ; 16 = PAGE #. PAGE IFE OPSYS, < ;USE LABORIOUS METHOD OF MAKING CORE-IMAGE. ; == FOR 10/50 SYSTEMS...VESTIGIAL. ;SWAP IS NOT DECLARED INTERNAL/SUBR (THO IT COULD BE). ;FIRST SAVES ALL ACCUMULATORS AS FILE 'QQSVAC.TMP' ;SAV -- SWAPS OUT (EFFECTIVELY) 116 THRU MIN(LH(E+2),.JBREL) ; -- MUST GO TO THE DISK (& WILL, REGARDLESS OF DEVICE). ; -- USES 1; DOES NOT SAVE ANY HIGH SEGMENT !!! ; -- THE FORMAT IS A NON-ZERO-COMPRESS (75--END). ; -- THE ACCS ARE RESTORED IF A RUN IS NOT DONE. ;RUN -- USES THE DEC RUN-UUO WHICH DESTROYS THE ACCUMULATORS ; -- THEREFORE, IF YOU WISH TO PASS ARGUMENTS (IN THE ACCS) ; -- TO THE NEW PROGRAM, PICK THEM UP FROM THE TMP FILE. EXTERNAL .JBCOR,.JBS41,.JBDDT SLOC==74 .JBSDD==114 SWAP: MOVEI 1,ACBLK BLT 1,ACBLK+17 ;CAN'T OUTPUT FROM BELOW LOC 115 MOVE 1,[XWD ACSAV,6] ;RESTORE UNCLOBBERED HI-ACCS BLT 1,17 CALLI 1,30 ;PJOB IDIVI 1,^D10 LSH 1,6 OR 1,2 LSH 1,^D24 OR 1,[SIXBIT/00SVAC/] MOVEM 1,ACHEAD ADDI 1,5460-4143 ;'LP' - 'AC' INIT 17 ;DUMP MODE SIXBIT /DSK/ 0 ;NO BUFFERS JRST AOUT.4+1 SETZM ACHEAD+2 SETZM ACHEAD+3 ENTER ACHEAD ERRL1 ^D159,SWOUT2 OUTPUT [IOWD 20,ACBLK 0] STATZ 740000 ERRL2 ^D160,SWOUT2 CLOSE STATZ 740000 ERRL2 ^D161,SWOUT2 MOVEM 1,IOFILE SETZM IOFILE+2 SETZM IOFILE+3 ENTER IOFILE ERRL2 ^D162,SWOUT2 HRRZ 2,.JBCOR MOVEM 2,OLDCOR MOVE 2,.JBREL HRRM 2,.JBCOR SUBI 2,SLOC ;NOT OUTPUTTING FIRST 0-SLOC LOCS MOVEM 2,1 ;N WORDS OF DATA MOVN 2,2 SUBI 2,1 ;-(N+1) == DATA + NULL HEADER WORD HRLM 2,OLIST MOVE 2,.JBREL HRRM 2,MVX+^D9 ;HIGHEST LOC BEFORE RELOC = DITTO BLT ADDI 2,2000 CALLI 2,CORE ;SPACE TO RELOCATE INTO ERRL2 ^D163,SWOUT2 MOVE 3,[XWD MVX,MV] BLT 3,MVE MOVE 3,[XWD 216,116] JRST MV MVX: PHASE 4 MV: MOVE 2,SLOC(1) MOVEM 2,SLOC+100(1) ;MOVE 100 UPWARD SOJG 1,MV SETZM SLOC+100 ;NULL HEADER WORD MOVE 2,.JBDDT MOVEM 2,.JBSDD+100 MOVE 2,.JB41 MOVEM 2,.JBS41+100 OUTPUT OLIST+100 ;AT RELOCATED IOWD BLT 3,0-0 ;MOVE BACK DOWN MVE: JRST MVY DEPHASE MVY: MOVE 2,[XWD ACSAV,6] BLT 2,17 ;RESTORE AGAIN OVER CODE HRRZ 2,MVX+^D10 CALLI 2,CORE ;REDUCE CORE BY 1K TO PREVIOUS STRTIP [SIXBIT /_*** WOULDN'T REDUCE CORE_!/] STATZ 740000 ;NOW CHECK FOR OUTPUT ERRORS ERRL2 ^D164,SWOUT2 CLOSE 0, STATZ 740000 ERRL2 ^D165,SWOUT2 RELEAS 0, MOVE 2,OLDCOR HRRM 2,.JBCOR RUNUUO: SETZM NEWCOR MOVSI 1,1 ;SA INC HRRI 1,DEVC2 CLRBFI ;DELETE CR,LF IF ANY...DISTURB SOS. CALLI 1,35 ;RUN UUO HALT ; POSSIBLY RECOVERABLE, BUT EXIT ANYWAY ACBLK: BLOCK 20 DEVC2: SIXBIT/SYS/ SIXBIT/SOS/ SIXBIT/SAV/ 0 0 NEWCOR: OLDCOR: 0-0 IOFILE: ACHEAD: SIXBIT/QQSVAC/ SIXBIT/TMP/ 0 0 OLIST: XWD 0-0,SLOC+100-1 0 SWOUT2: SIXBIT /COULDN'T SWAP SUCCESSFULLY_!/ > ;******** CLOSE OF IFE OPSYS, FROM SWAP: ********. PAGE IFN OPSYS, < ;EASIER WITH TENEX %SWAP: MOVSI 1,1 ;SET B17 MOVE 2,[POINT 7,FILSOS] GTJFN JRST SOSER1 HRRZ 3,1 ;AC1(RH) NOW HAS DESIRED JFN. MOVSI 1,(1B1+1B3) ;Spec. cap. & use AC2. MOVEI 2,0 ;VIRTUAL ADDRESS OF ACCS. CFORK ;CREATE INFERIOR FORK. JRST SOSER2 EXCH 1,3 HRL 1,3 ;SET UP (LH) WITH HANDLE JSYS 200 ;GET JSYS HRRZ 1,3 MOVEI 2,2 ;INDEX INTO ENTRY-VEC SFRKV ;START THAT FORK ;AC1 HAS INFERIOR-F HANDLE! WFORK ;CURRENT FORK WAITS UNTIL THE ; INFERIOR FORK TERMINATES. KFORK ;INF-FORK STILL EXISTS, SO! SWAPEX: MOVSI 17,ACSAV BLT 17,17 ;Restore accs PRET ; and return. FILSOS: ASCIZ /<SUBSYS>SOS.SAV/ SOSER1: OUTSTR FILSOS OUTSTR [ASCIZ / NOT FOUND /] SOSER2: OUTSTR [ASCIZ /COULDN'T SOSSWAP/] JRST SWAPEX > ;CLOSE OF IFN OPSYS. > ;******* Close of IFN SOSSW, from %SOSSWAP: **** %ACSAV: ACSAV: BLOCK 20 PAGE IFN JSYXEQ,< ;The rest of this page is under this switch COMMENT The JSYS function executes a JSYS and returns the result. It is called as JSYS(jsysno,arg1,arg2,arg3,retreg) where jsysno is the number of the JSYS, retreg is the number of the register in which the executed JSYS will return its value and argN is loaded into register N as argument to the JSYS. The value of the global variable JSYSAR4 is taken as arg4 (initial value is 0). If argN is a number then that number is converted to machine- representation and loaded into reg N. If argN is not the list (BUF) then it must be a string or an id. This string or id is written in a buffer as a ASCIZ string and a pointer to that string is loaded into reg N. If argN is (BUF) then a pointer to a stringbuffer is loaded into reg N. Only one of the argN may be (BUF). If there is a (BUF) this indicates that the JSYS will write a string into the string buffer, using retreg as updated string- pointer and return as value the string converted into a LISP string. If there is no (BUF) among the arguments, then the content of the retreg register is converted into a LISP number and returned as value of JSYS. %JSYS: PSAVE B ; A1 arg. PSAVE C ; A2 arg. PSAVE AR4 ; A3 arg. FOO PSAVE VJSYSAR4 ; A4 arg. CAIG A,INUM0+777 ; JSYS number CAIGE A,INUM0+1 ERRE2 ^D39,[SIXBIT /NOT A JSYS!/] SUBI A,INUM0 HRRM A,JSY ; Set which JSYS. MOVE A,AR5 CAIG A,INUM0+4 CAIGE A,INUM0+1 ERRE2 ^D40,[SIXBIT /NOT A RETURN REGISTER!/] SUBI A,INUM0 HRRM A,RETREG ; Set which register contains the value MOVEI AR5,1 HRRM AR5,RBUFAR ; No string returned. MOVEM SP,STRST# ;Start of string buffer. Special stack is used HRREI B,-3 JSARLP: HRRM B,NJSAR NJSAR: MOVE A,X(P) ; Get arg. JSP D,ATMTYP ; What type is it? CAIE TT,FIXNU ; If not a fixnum JUMPN TT,JSASTB ; or an Inum must be string or buffer PCALL NUMVAL ; A number. Convert to machine format MOVEM A,@NJSAR ; and set arg. JRST JSARLE JSASTB: CAIE TT,ID ; An id CAIN TT,STRNG ; or a string ? JRST JSASTR ; Yes! FOO CAIE TT,BUF ; Return string buffer? ERRE2 ^D41,[SIXBIT /ILLEGAL JSYS ARG!/] ; No! Error. HRRM B,RBUFAR ; Arg no for return string pointer. JRST JSARLE JSASTR: MOVE C,STRST ; String buffer position. MOVEI B,1(C) HRROM B,@NJSAR ; Set arg to string pointer. PCALL PNAMUD ; Unpack into buffer PUSH C,[0] ; Deposit zero at end of string. MOVEM C,STRST ; Update string buffer. JSARLE: HRRE B,NJSAR ; Next arg. AOJLE B,JSARLP HRRZ B,RBUFAR ; Return string? SOJE B,NORST ; No! MOVE B,STRST ; String buffer position. PUSH B,[0] ; Zero first word. RBUFAR: HRROM B,X(P) ; Set arg to string pointer for return string. NORST: HRRZM B,STRST ; 0 or address of output string. PREST 4 ; A4 arg. PREST 3 ; A3 arg. PREST 2 ; A2 arg. PREST 1 ; A1 arg. JSY: JSYS X ERJMP JSYERR ERJMP JSYERR RETREG: MOVE A,X ; Load return value into register 1. SKIPE B,STRST ; Return string? JRST MKSTR ; Yes! Convert to Lisp string. JRST FIX1A ;No! Convert to LISP number and return ;JSYS error return JSYERR: PCALL ERRSTR ERRE2 ^D42,[SIXBIT /JSYS ERROR!/] ; ERRSTR returns the last system error message as a Lisp string; ERRSTR: HRROI A,1(SP) ; Pointer to buffer for string. HRLOI B,400000 ; .FHSLF SETZ 3, ERSTR ERJMP EER ERJMP EER MKSTR1: MOVEI B,1(SP) MKSTR: SKIPG C,A ; Convert from ASCII string to LISP string. JRST FALSE ; Return NIL if no string. LDB AR4,A ; Last character. JUMPN AR4,NOBCKP ; O.k. if not null. CAIN B,(A) ; Only one word? JRST NOBCKP ; Yes! Never step back pointer. HLRZ AR4,A CAIN AR4,350700 ; Null in beginning of word? MOVEI C,-1(A) ; Yes! Step back pointer. NOBCKP: HRL A,B ; Start of string. SUBI B,1(SP) ; - expected start of string. JUMPE B,LMKSTR ; Don't need to move string if start is o.k.. HRRI A,1(SP) ; Expected start of string. SUBI C,(B) ; Updated end of string. BLT A,(C) ; Move string. JRST LMKSTR ; Make into LISP string. EER: FOO MOVEI A,QST ;Couldn't get error string return ? PRET GETAB$: PCALL NUMVAL HRRM A,GETALO HLLZ B,A MOVE C,SP GETALO: MOVEI A,X HRL A,B GETAB JRST GERR PUSH C,A AOBJN B,GETALO GERR: MOVSI A,700 HRR A,3 JRST MKSTR1 ; !%XEQ generates inferior forks %XEQ: MOVEM A,FORKH# ; FILENAME OR PREVIOUS FORK HANDLE #. MOVEM B,STAD# ; T=START, NIL=RESUME, 0-N = EVEC POS. MOVEM C,KILL# ; T=KFORK, NIL=KEEP FOR A RESUME-FORK. MOVEM AR4,ACSADR# ; NIL=NONE, N=ADDR OF ACCBLK MOVEM AR5,ARGSTR# ; NIL=NONE, RSCAN . TTYINP Tops20, TTYINP Tenex IFL OPSYS,< ;RSCAN not defined in TENEX JUMPE AR5,NORTYI CARA A,(AR5) JUMPE A,NRSCN ; NO RSCAN PCALL PNAMUK PUSH C,[0] ; Must end with 0 HRROI A,1(SP) RSCAN JRST FAIL6 NRSCN: MOVE A,FORKH > ;END OF IFL OPSYS NORTYI: PCALL NUMBERP ; IF NUMBERP FILE/FORKH JUMPN A,OLDFORK ; THEN GOTO OLDFORK; MOVE A,FORKH PCALL PNAMUK PUSH C,[0] ; Must end with 0 MOVSI A,100001 ; OLD FILES ONLY. HRROI B,1(SP) GTJFN ; GTJFN OF STRING ON SP STACK. JRST FAIL1 MOVEM A,SAVJFN# MOVSI A,200000 ; 1B1 SETZ B, ; SETUP ACS BELOW, IF ANY. CFORK JRST FAIL2 MOVEM A,FORKH HRRZ A,SAVJFN HRL A,FORKH JSYS 200 ; GET OF FORK,,JFN. SKIPN A,STAD FOO MOVEI A,TRUTH ; START, NOT RESUME. MOVEM A,STAD JRST TRYIT OLDFORK:MOVE A,FORKH PCALL NUMVAL CAIL A,400001 CAIL A,400035 ERRE2 ^D43,[SIXBIT /NOT A FORK HANDLE!/] MOVEM A,FORKH RFSTS TLNN A,777777 ERRL2 ^D168,[SIXBIT /DEAD FORK IN XEQ!/] MOVEM B,FORKPC# TRYIT: MOVEI A,100 ;PRIMARY INPUT CFIBF ;Flush buffer to be safe RFMOD MOVEM B,OTTMOD# SKIPN A,ACSADR JRST NOACS PCALL NUMVAL MOVE B,A MOVE A,FORKH SFACS NOACS: MOVE A,FORKH SKIPN C,STAD JRST DOSFORK ; IF NULL STAD THEN START FORK FOO CAIN C,TRUTH TDZA C,C ; IF STAD=T THEN START AT EVEC+0 SUBI C,INUM0 ; UNBOX NUMBER GEVEC ADD B,C MOVEM B,FORKPC HLRZ AR4,B ; CHECK LH LENGTH VERSUS STAD CAIE AR4,(JRST) JRST ITENEX CAIL C,2 JRST FAIL5 ; 10/50 CAN ONLY ST/REE 0/1. JRST DOSFORK ITENEX: CAIL C,(AR4) JRST FAIL5 DOSFORK:HRRZ B,FORKPC SFORK ; SFORK AT PC, RATHER THAN RFORK IFG OPSYS,<SKIPN A,ARGSTR JRST NTAR> IFL OPSYS,<SKIPN C,ARGSTR JRST DOWFORK CDRA A,(C) JUMPE A,NTAR> PCALL PNAMUK HRRZ C,SP HRLI C,700 MOVEI A,100 ;Primary output designator; XL1: MOVEI AR4,127 XL2: ILDB B,C JUMPE B,NTAR STI SOJG AR4,XL2 DIBE JRST XL1 NTAR: MOVE A,FORKH DOWFORK:WFORK MOVEI A,100 MOVE B,OTTMOD SFMOD MOVE A,FORKH SKIPN B,KILL JRST FIX1A ; RETURN FORKH# FOR FUTURE RESUME. KFORK ; KFORK IF NON-NIL FLAG. JRST FALSE FAIL1: PSAVE FORKH PCALL ERRSTR PCALL NCONS PRET B PCALL XCONS MOVE B,A MOVEI A,INUM0 JRST .ERROR FAIL6: CARA A,ARGSTR PSAVE A JRST FAIL1+1 FAIL2: MOVE A,SAVJFN RLJFN JFCL PCALL ERRSTR ERRE2 ^D44,[SIXBIT /ERROR IN XEQ!/] FAIL5: MOVE A,STAD ERRE2 ^D45,[SIXBIT /BAD ENTRY VECTOR IN XEQ!/] > ;End of IFN JSYXEQ SUBTTL BPS SWAPPING ROUTINES --- PAGE 24 IFN RWB,< ;to end of page INTERNAL RBLK, WBLK RBLK: PCALL FILEPX ; (RBLK <FILE>) no 2nd arg anymore. JUMPE A,RBLK0 ; Not found. INPUT [IOWD 1,LST 0] JRST SYSINQ RBLK0: RELEASE 0, JRST AIN.7 WBLK: INIT 17 ; (WBLK <file> <start-addr> <end-addr>) SIXBIT /DSK/ 0 JRST AOUT.4+1 HRLZM A,DEV MOVE A,B ;IN CASE ADDRESSES OVER 64K. PCALL NUMVAL EXCH A,C PCALL NUMVAL SUBI C,1 SUBM C,A ;A_ -(A-(C-1)) == ARG1:ARG2 INCLUSIVE HRL C,A MOVEM C,LST MOVEI T,DEV PCALL IOSUB MOVEM A,ENTR SETZM ENTR+2 ;CREATION DATE ENTER ENTR JRST OUTERR+1 OUTPUT [IOWD 1,LST 0] OUTPUT LST CLOSE STATZ 740000 JRST TYO2X+2 ;"OUTPUT ERROR". PRET > ;end of IFN RWB SUBTTL CORE EXPANDING ROUTINES --- PAGE 25 INTERNAL TCORE TCORE: SUBI A,INUM0 ;== ^C, CORE N, START EXCEPT FOR N =<0 JUMPL A,TCORE0 ;JUST RETURN CURRENT LISP-ALLOC SIZE JUMPE A,TCORE0+1 ;JUST RETURN CURRENT CORE SIZE CAILE A,MAXCORE ;LIMIT .LT. 124K OR SO, ALLOWING FOR I/O BUFFS JRST TCORE3 LSH A,^D10 SUBI A,1 CAMGE A,JRELO JRST TCORE1 ;Smaller than current Lisp area alloc. CAML A,.JBREL JRST TCORE2 ;LARGER THAN CURRENT CORE, SO EXPAND. IFE HCBPS,< SKIPN VXCORE JRST TCORE4 STRTIP [SIXBIT /_*** CAN'T EXCISE_!/] JRST TCORE0+1 > TCORE4: CAMG A,JRELO PCALL TCORE5 TCORE2: CALLI A,CORE JRST TCORE3 JRST LISPGO ;GO ALLOCATE CORE TCORE1: STRTIP [SIXBIT /_*** CAN'T CUT CORE INTO ALLOCATED SPACE_!/] TCORE0: SKIPA A,JRELO ;-1 GIVES CURRENT LISP-ALLOC AREA HRRZ A,.JBREL ; 0 GIVES CURRENT TOTAL CORE ASSIGNED ADDI A,1777 LSH A,-^D10 JRST FIXI TCORE5: MOVE B,JRELO CAME B,CORUSE FOO SKIPN %MSG PRET ; OUTSTR [ASCIZ / ;*** EXCISED ;/] PRET PAGE ; EXCORE( n ) permits arbitrary expansion of BPS above Lisp spaces, ; by: 1) flagging STRT allocator not to alloc extra core, ; 2) creating or extending a high BPS area of nK, ; 3) setting BPORG and BPEND up there appropriately, ; 4) doing an I/O reset, to get the buffers above BPS, ; permitting future LOADs, EDs, etc. ; EXCORE( 0 ) forces the BPORG and BPEND pntrs down to their last ; positions in low BPS, but doesn't clear the high...which ; is retained indefinitely or until an EXCISE. ; EXCORE(NIL) permits ALLOC() or ST to allocate extra core as usual. ; Has also the effect of EXCORE(0). IFN SZBPS,< ;Only defined when not maximal BPS. EXCORE: IFE HCBPS,< ;Only when BPS in low core MOVEM A,VXCORE# ;If NIL, flag for STRT allocation, JUMPE A,CHKVBP HRREI C,-INUM0(A) ;else JUMPL C,EXCORT LSH C,^D10 ; Convert nK to n*1024 words. JUMPE C,CHKVBP ; If arg=0, put BP pntrs back to low BPS. FOO MOVE A,VBPEND PCALL NUMVAL CAML A,FSO ;Are the pntrs in low BPS still? JRST EXCOR2 ; No, extend from this BPEND. MOVEM A,OBPEND# ; Yes, save positions for a later CHKVBP. FOO MOVE A,VBPORG PCALL NUMVAL MOVEM A,OBPORG# SKIPA A,JRELO ;Start BPS. [Could use CORUSE instead] EXCOR2: SETZ B, ;If 0, pntrs were already in high BPS. ADD A,C ;Extend by amt of arg. IORI A,777 ; End of page. CAIGE A,MAXCORE*^D1024 ;More than 124K requested, CALLI A,CORE ; or can't get it? JRST TCORE3 ; Say so. JUMPE B,EXCOR3 ;Got it -- set pntrs to it. MOVE A,JRELO ;[or CORUSE] ADDI A,1 PCALL FIX1A FOO MOVEM A,VBPORG EXCOR3: MOVE A,.JBREL PCALL FIX1A FOO MOVEM A,VBPEND JSR IOBRST ;Set JOBSA and clear I/O pntrs. CALLI RESET ;Set JOBFF. JSR APRSET PCALL TTYRET EXCORT: MOVE A,VXCORE PRET PAGE CHKVBP: FOO MOVE A,VBPEND ;Ensure BP pntrs to low BPS. PCALL NUMVAL CAMGE A,FSO JRST EXCORT ;Already low, no change needed. MOVE A,OBPEND PCALL FIX1A FOO MOVEM A,VBPEND MOVE A,OBPORG PCALL FIX1A FOO MOVEM A,VBPORG JRST EXCORT > IFN HCBPS,< JUMPE A,CPOPJ ;Do nothing if argument NIL. PCALL NUMVAL JUMPLE A,CPOPJ LSH A,^D10 MOVE AR5,A FOO MOVE A,VBPEND PCALL NUMVAL ADD AR5,A IORI AR5,777 HRLZ A,AR5 TLNN AR5,-1 CALLI A,CORE JRST TCORE3 MOVE A,AR5 PCALL FIX1A FOO MOVEM A,VBPEND PRET > > ;End of IFN SZBPS PAGE FREEZE: SKIPE A ;If going to toplevel, then PCALL TUNBIND ; unbind to toplevel MOVEM 17,ACSAV+17 ;This routine halts Lisp in a manner MOVEI 17,ACSAV ; that can be later re-started. BLT 17,ACSAV+16 IFL OPSYS,< MOVE 1,VBPORG PCALL NUMVAL MOVEM 1,.JBHRL > IFN OPSYS,< MOVEI 1,400000 MOVE 2,[2,,ENTFRZ] SEVEC > ;Tell it where to start or continue. MOVEI 1,NEWST ;Unfortunately, need to do this MOVEI 2,NEWREE ; in order to thwart PA1050, HRRM 1,.JBSA ; if ST or REE w/o clearing it. HRRM 2,.JBREN IFN OPSYS,< HALTF > IFE OPSYS,<EXIT 1,> NEWST: TDZA NIL,NIL NEWREE: SETO NIL, IFN OPSYS,< MOVEI 1,400000 ;Tell it the normal Lisp entries. MOVE 2,[2,,ENTVEC] SEVEC > IFL OPSYS,< MOVE 1,.JBREL HRLI 1,676777 CALLI 1,CORE JRST .+1 > MOVEI 1,LISPGO MOVEI 2,DEBUGO HRRM 1,.JBSA HRRM 2,.JBREN JSR IOBRST ;Clear I/O bufs. JUMPN NIL,[MOVE NIL,ACSAV SETZM RETFLG JRST START ] ;REE to get past INITFN. CALLI RESET JSR APRSET ;Reset 10/50 or Tenex interrupts. MOVSI 17,ACSAV BLT 17,17 PCALL TTYRET SKIPN A,ACSAV+1 ;Test arg of FREEZE... PRET ; NIL -- Return, no files open. MOVE A,.JBREL ; Non-NIL -- GOTO top-level INITFN. CAMN A,JRELO JRST LSPRET ;Unexpanded core. G.c. not necessary. JRST LISPGO IFN OPSYS,< ENTVEC: JRST LISPGO JRST DEBUGO ENTFRZ: JRST NEWST JRST NEWREE > SUBTTL AUXILIARY ROUTINES --- PAGE 26 IFN OPSYS,< LSSAVE: MOVEM 17,ACSAV+17 ;This routine SSAVEs Lisp in a manner MOVEI 17,ACSAV ; that can be later run, no files open. BLT 17,ACSAV+16 MOVE 17,ACSAV+17 ;Restore it. MOVEI 1,400000 MOVE 2,[2,,ENTFRZ] SEVEC MOVSI 1,(1B0+1B17) HRROI 2,LSSFIL GTJFN JRST LSSER1 HRLI 1,400000 MOVEI 2,LSSTBL SETZ 3, SSAVE HRRZS 1 RLJFN JRST LSSER1 MOVEI 1,400000 MOVE 2,[2,,ENTVEC] SEVEC JRST TRUE ;Distinguish from a NEWST's NIL! LSSER1: MOVEI 1,400000 MOVE 2,[2,,ENTVEC] SEVEC ERRL2 ^D166,[SIXBIT /COULDN'T SSAVE/] LSSFIL: IFL OPSYS,ASCIZ /LSSAVE.EXE/ IFG OPSYS,ASCIZ /LSSAVE.SAV/ LSSTBL: -700,,520B26+0 ;Pages 0-677 below PA1050. 0 > PAGE IFN SYDEV,< SETSYS: IFG OPSYS,<SUBI A,INUM0 ;CHANGE SYS: <DIR> NUMBER. CAIGE A,0 ; Permit 0 ... user's dir. SKIPA A,SYSNUM# MOVEM A,SYSNUM JRST FIXI> IFLE OPSYS,<MOVE T,A PCALL ATOM JUMPE A,GVDV MOVE A,T PCALL SIXMAK TRC A,":"-40 TRNE A,77 JRST GVDV HLLZM A,SYSNUM# MOVE A,T PRET GVDV: SETZB A,B SKIPA AR4,[POINT 6,SYSNUM] ADDI A,40(B) LSH A,7 ILDB B,AR4 JUMPN B,.-3 ADDI A,":" LSH A,1 SKIPA AR4,[1] LSH A,7 TLNN A,774000 JRST .-2 MOVEM A,1(SP) MOVEI C,1(SP) JRST MSTR1 > > SUBTTL REALLOC CODE --- PAGE 27 STRT: MOVE P,C2 SKIPE SP,SPSAV PCALL TUNBIND MOVE A,.JBREL ;New top of core -- becomes JRELO below. HRLM A,.JBSA SUB A,JRELO# ;length of extra core JUMPE A,RREL4 ;no expansion SKIPG A HALT ;smaller core -- bitch. IFN AED,<MOVEI B,EDP2 HRRM B,ED> IFE HCBPS,<SKIPE VXCORE ;If XCORE(Nil), go ahead and allocate, JRST RREL4 > ; else retain as is...usually expanded BPS. MOVE A,.JBREL TRO A,1777 CALLI A,CORE SKIPA A,.JBREL MOVE A,.JBREL HRLM A,.JBSA SUB A,JRELO PCALL TCORE5 IFN ALOD,SETZM LDFLG ;initial loader symbol table flag MOVE F,EFWSO# SUB F,FWSO# ;old length of fws HRRZS B,A ACHLOC: ASH A,-2+X ;1/4 of new core to fws * User-patchable * ADD A,F ;new length of fws MOVE C,B STKLOC: ASH C,-6 ;1/64 of new core to each pdl MOVE AR4,C HRL AR4,C HLRZ AR5,SC2 ;-old length of spec pdl ADD AR5,.JBREL ;new bottom of spec pdl HLL AR5,SC2 ;old length of spec pdl SUB AR5,AR4 ;new pointer for spec pdl MOVEM AR5,SC2 IFN EPDL,< HLRZ EP,EC2 ;-old length of exp pdl ADD AR5,EP ;new bottom of exp pdl HLL AR5,EC2 ;old length of exp pdl SUB AR5,AR4 ;new pointer for exp pdl MOVEM AR5,EC2 > MOVNS C2 ;old reg pdl pointer HLRZ AR4,C2 ;old length of reg pdl ADD C,AR4 ;new length of reg pdl HRRZ B,AR5 ;new bottom of reg pdl SUB B,FSO# MOVEI T,44 ;1/36 space for fws bit tables IDIVM A,T ;new length of fws bit tables AOS T SUB B,T ;B:=SPL-FSO-(FWS/36+1)-FWS-PL, then SUB B,A ;B:=B-(B/33+1)+FSO SUB B,C MOVEI TT,41 ;1/33 space for fs bit table IDIVM B,TT ;new length of fs bit table SUBI B,1(TT) ;new length of fs ADD B,FSO ;new bottom of fs HRRM B,GCP1 MOVN SP,B ;- new bottom of fws HRRM SP,GCMFWS HRLZM A,C1GCS MOVNS C1GCS ;- new length of fws HRRM B,C1GCS ADDI B,-1(A) ;new top of fws AOS B MOVE SP,FSO LSH SP,-5 SUBM B,SP HRRM SP,GCBTP2 ;magic number for bit table references HRRM SP,GCBTP1 HRLM B,C3GC ;bottom of bit tables --- for bit table zeroing HRRM B,GCP2 HRRM B,GCP MOVNI SP,-1(TT) HRLM SP,C3GCS HRRM B,C3GCS ;iowd for FS bit table sweep AOS B MOVE SP,FSO ANDI SP,37 HRRM SP,GCBTL2 ;magic number to position bit table word SUBI SP,^D32 HRRM SP,GCBTL1 HRRM B,C3GC ;bottom of bit table ADDI B,-1(TT) HRRM B,C2GCS ;bottom of fws bit table AOS B HRRM B,C2GC ADDI B,-1(T) HRRM B,GCP5 ;top of bit tables AOS B ;bottom of reg pdl HRRZ A,RHX2 ;oblist pointer MOVEM A,(B) HRRM B,GCP3 ;room for acs AOS B HRRM B,C2 ;reg pdl bottom MOVNI A,-10(C) HRLM A,C2 ;reg pdl size HRRZ A,.JBREL HRRZM A,JRELO ;new top of core MOVE A,GCP1 HRRM A,.+4 ;To... MOVE A,FWSO HRRM A,.+1 ;From... MOVE A,.(F) ;old bottom of fws * MOVEM A,.(F) ;new bottom of fws * SOJGE F,.-2 ;f has length (old) of fws HRRZ AR4,GCP1 SUB AR4,FWSO ;displacement for fws MOVE AR5,FSO ;bottom of fs RREL1: CARA A,(AR5) ;Adjust pntrs in new FS to new FWS... CAMG A,EFWSO CAMGE A,FWSO JRST RREL2 ADD A,AR4 RPLCA A,(AR5) ;fix car pointer RREL2: CDRA A,(AR5) CAMG A,EFWSO CAMGE A,FWSO JRST RREL3 ADD A,AR4 RPLCD A,(AR5) ;fix cdr pointer RREL3: CAMGE AR5,FWSO AOJA AR5,RREL1 MOVE A,GCP1 ;bottom of fws HRRZM A,FWSO MOVE A,C3GC ;bottom of bit table + 1 HRRZM A,EFWSO RREL4: FOO SETZB FF,DDTIFG ;Flag for AGC. JSR IOBRST JRST START ;-------------------------------------------------------------------- RLOCA: MOVE B,AR4 ;= FS+BPS LENGTHS. HRLI AR4,BFWS HRRI AR4,FS(B) MOVEI AR5,EFWS-BFWS(AR4) BLT AR4,(AR5) MOVEI AR4,FS-BFWS(B) MOVEI AR5,BFWS-1 REL1: CARA A,(AR5) CAILE A,EFWS JRST REL2 CAIGE A,BFWS JSP R,REL4 ADD A,AR4 REL2: RPLCA A,(F) CDRA A,(AR5) CAILE A,EFWS JRST REL3 CAIGE A,BFWS JSP R,REL4 ADD A,AR4 REL3: RPLCD A,(F) SOS F CAILE AR5,FS SOJA AR5,REL1 JRST RREL4 ;Now do the IOBRST and START. REL4: CAIL A,FS ADD A,FF JRST 1(R) PAGE REHASH: ;ONCE ONLY, per HASHFG. FOO MOVEI A,BFWS PSAVE A HRRM A,RHX2 HRRM A,RHX5 RH4: MOVSI B,X ;* FOO MOVEI A,BFWS+1(B) FOO MOVEM A,BFWS(B) AOBJN B,.-2 FOO SETZM BFWS(B) MOVSI AR5,-BCKETS RH1: FOO HLRZ C,OBTBL(AR5) RH3: JUMPE C,RH2 CARA A,(C) PSAVE C PSAVE AR5 PCALL INTERN PREST AR5 PREST C CDRA C,(C) JRST RH3 RH2: AOBJN AR5,RH1 SETZM HASHFG PREST A HRRM A,@GCP3 FOO MOVEM A,OBLIST JRST START SUBTTL LISP ATOMS AND OBLIST --- PAGE 28 RVAL: 0 HVAL: 0 VAR LIT PAGE FS: DEFINE MAKBUC (A,%B) <DEFINE OBT'A <%B=.> IFN <BCKETS-1-A>,<XWD %B,.+1> IFE <BCKETS-1-A>,<XWD %B,NIL> IF1 <%B=0>> DEFINE ADDOB (A,C,%B) <OBT'A DEFINE OBT'A<%B=.> IF1 <%B=0> XWD C,%B> DEFINE PUTOB (A,B) <ZZ==<ASCII /A/>_<-1> ZZ==-ZZ/BCKETS*BCKETS+ZZ ADDOB \ZZ,B> DEFINE PSTRCT (A) <ZZ==[ASCII /A/] LENGTH ZY,A REPEAT <ZY-1>/5,<XWD ZZ,.+1 ZZ==ZZ+1> XWD ZZ,0> DEFINE MKAT (A,B,C,D) <XLIST IRP A< PUTOB A,.+1 D XWD ID,.+1 XX==<B-EXPR>*<B-FEXPR> IFN XX,<XWD .+1,.+2 XWD B,C'A> IFE XX,<XWD .+1,.+4 XWD FUNCELL,.+1 XWD B,.+1 XWD CODE,C'A> XWD .+1,NIL XWD PNAME,.+1 PSTRCT A> LIST> PAGE DEFINE MKAT1 (A,B,C,D) <XLIST IRP C <PUTOB C,.+1 XWD ID,.+1 XX==<B-EXPR>*<B-FEXPR> IFN XX,<XWD .+1,.+2 XWD B,D'A> IFE XX,<XWD .+1,.+4 XWD FUNCELL,.+1 XWD B,.+1 XWD CODE,D'A> XWD .+1,NIL XWD PNAME,.+1 PSTRCT C> LIST> DEFINE LENGTH (A,B) <A==0 IRPC B,<A==A+1>> DEFINE ML1 (A)<XLIST IRP A,<XLIST INTERNAL A V'A= INUM0+A MKAT A,SYM,V> LIST> ;These SYMs are for direct access from LAP code (e.g. LISP.TNX) DEFINE ML (A)< XLIST IRP A,<PUTOB A,.+1 A: XWD ID,.+1 XWD .+1,NIL XWD PNAME,.+1 PSTRCT A> LIST> OBTBL: OBLIST: ZZ==0 ;Base of array or linear-list of hash buckets. XLIST ;REPEAT BCKETS,<MAKBUC \ZZ REPEAT BCKETS,<MAKBUC \ZZ ZZ==ZZ+1> LIST ; ZZ==ZZ+1> PAGE ML <LAMBDA,EXPR,FEXPR,SYM,FUNCELL,VALUE,PNAME,TRACE> ML <LABEL,MACRO,INPUT,OUTPUT,INBIN,OUTBIN> ML <SUBR,FSUBR> MKAT <RPLACA,RPLACD,MINUS,TERPRI,READ,CAR,CDR,CAAR>,EXPR MKAT <CADR,CDAR,CDDR,CAAAR,CAADR,CADAR,CADDR,CDAAR,CDADR,CDDAR,CDDDR>,EXPR MKAT <CAAAAR,CAAADR,CAADAR,CAADDR,CADAAR,CADADR,CADDAR,CADDDR,CDAAAR>,EXPR MKAT <CDAADR,CDADAR,CDADDR,CDDAAR,CDDADR,CDDDAR,CDDDDR,CONS>,EXPR MKAT <PROG2,ATOM,EQ,PRIN1,PRINT,RETURN,EXPLODE,ATSOC,PATOM>,EXPR MKAT <POSN,LINELENGTH,NUMBERP,EQUAL,SUBST,GET,INTERN,MEMBER>,EXPR MKAT <COMPRESS,READCH,NOT,NULL,GENSYM,ZEROP,DIVIDE,GCD>,EXPR IFN AED,<MKAT <ED,GRINDEF>,EXPR> MKAT <TIME,FIX,SET,LENGTH,ADD1,SUB1,LAST,WARNING>,EXPR MKAT <GCTIME,REVERSE,SPEAK,MAPLIST,MEMQ>,EXPR MKAT <PUT,PRIN2,ERR,MAPCAR,EXAMINE,DEPOSIT,LSH,MAPCAN,MAPCON>,EXPR MKAT <NCONS,XCONS,REMPROP,MINUSP,MAP,MAPC>,EXPR MKAT <WRS,RDS,OPEN,CLOSE,EXCISE,REMAINDER,ABS,BKTRA>,EXPR MKAT <PGLINE>,EXPR MKAT <%FSLID,%FPAGE,%NEXTTYI,SETPCHAR,DLVECT>,EXPR IFN SOSSW,MKAT %SOSSWAP,EXPR IFN RWB,<MKAT <RBLK,WBLK>,EXPR> MKAT <FILEP,FREEZE>,EXPR IFN SZBPS,MKAT <EXCORE>,EXPR MKAT <CORE>,EXPR,T MKAT <BINI,BINO,TYID,TYOD>,EXPR MKAT1 VINC,VALUE,INC* VINC:NIL MKAT1 VOUTC,VALUE,OUTC* VOUTC:NIL IFN OPSYS,MKAT LSSAVE,EXPR IFN JSYXEQ,<MKAT <%XEQ,GETAB$,ERRSTR>,EXPR MKAT1 VJSYSAR4,VALUE,JSYSAR4 VJSYSAR4: INUM0 ML BUF MKAT JSYS,EXPR,%> IFN SYDEV,<MKAT SETSYS,EXPR> MKAT EXPLODEC,EXPR,% MKAT TYO,EXPR,I MKAT TYI,EXPR,I MKAT EVAL,EXPR,,CEVAL: MKAT <LIST,COND,PROG,SETQ>,FEXPR MKAT1 LIST,EXPR,EVLIS MKAT <OR,AND,GO,PROGN>,FEXPR IFN ASARY,<MKAT <ARRAY,STORE>,FEXPR ML1 NSTR IFN ALOD,<MKAT EXARRAY,FEXPR> > MKAT1 QUOTE,FEXPR,FUNCTION IFN FNRG,< ML FUNARG MKAT1 FUNCT,FEXPR,*FUNCTION MKAT <%EVAL,%APPLY>,EXPR > MKAT <APPEND,NCONC,APPLY,REMOB,ERRORSET,FIXP,FLOATP,INUMP,BIGP>,EXPR MKAT <PUTD,GETD,REMD,PRINC,FLAG,FLAGP,REMFLAG,MKCODE,FLOAT,DIGIT>,EXPR MKAT <BOOLE,LITER,IDP,PAIRP,CONSTANTP,STRINGP,VECTORP,CODEP>,EXPR MKAT <MKVECT,UPBV,GETV,PUTV>,EXPR MKAT INTERNP,EXPR,. MKAT ASCII,EXPR,A MKAT QUOTE,FEXPR,,CQUOTE: MKAT1 FIX1A,EXPR,*BOX ML1 <EXARG,ATMTYP,NATMTYP,INTER0,FWCONS,ACHLOC,CHRTAB> MKAT INUM0,SYM,S INTERN INUM0 SINUM0: XWD FIXNU,VINUM0 IFN OPSYS,ML1 <READP1,PNAMUK,%ACSAV,LMKSTR> IFN OPSYS*SOSSW,ML1 %SWAP PUTOB T,.+1 TRUTH: XWD ID,.+1 XWD .+1,.+2 XWD VALUE,VTRUTH XWD .+1,NIL XWD PNAME,.+1 PSTRCT T VTRUTH: TRUTH PUTOB NIL,0 CNIL2: XWD .+1,.+2 XWD VALUE,VNIL XWD .+1,NIL XWD PNAME,.+1 PSTRCT NIL VNIL: NIL IFE STL,< MKAT <SASSOC,SETARG,GETL,ARG,READLIST,FLATSIZE>,EXPR MKAT <CSYM,DEFPROP>,FEXPR MKAT1 EXPN1,EXPR,*EXPAND1 MKAT1 EXPAND,EXPR,*EXPAND MKAT1 LCALL,SYM,*LCALL,INUM0+% MKAT1 UDT,SYM,*UDT,INUM0+% > MKAT1 AMAKE,SYM,*AMAKE,INUM0+% MKAT1 %NOPOINT,VALUE,*NOPOINT %NOPOINT: NIL MKAT1 BACTRF,VALUE,*BAKGAG BACTRF:NIL MKAT1 ERRSW,VALUE,*ERRMSG ERRSW:TRUTH MKAT1 V$EOF$,VALUE,$EOF$ V$EOF$: $EOF$ $EOF$: XWD ID,.+1 XWD .+1,NIL XWD PNAME,.+1 PSTRCT $EOF$ MKAT1 GCGAGV,VALUE,*GCGAG GCGAGV:NIL MKAT1 VFECHO,VALUE,*ECHO VFECHO:NIL MKAT1 VRAISE,VALUE,*RAISE VRAISE:NIL MKAT1 DDTIFG,VALUE,*DDTIN DDTIFG:TRUTH MKAT1 NOUUOF,VALUE,*NOUUO NOUUOF:NIL MKAT1 %MSG,VALUE,*MSG %MSG: TRUTH MKAT1 GC,EXPR,RECLAIM MKAT1 INITF,VALUE,INITFN* INITF:NIL MKAT1 %SYSTM,VALUE,SYSTEM* %SYSTM: OPSYS+INUM0 MKAT <SCANINIT,SCANSET,SCAN,UNREADCH>,EXPR MKAT <LETTER,DELIMITER,IGNORE,RDSLSH>,EXPR MKAT1 SCNV,VALUE,SCNVAL SCNV: NIL MKAT SKIPTO,EXPR MKAT <LPOSN,PAGELENGTH,EJECT,NUMVAL>,EXPR MKAT ERROR,EXPR,. MKAT1 VERMSG,VALUE,EMSG* VERMSG: NIL IFN OFLD!NFLD,< MKAT1 VPURIFY,VALUE,*PURIFY VPURIFY: NIL MKAT1 VPREDEF,VALUE,*PREDEF VPREDEF: NIL MKAT1 VF.LIST,VALUE,F.LIST VF.LIST: NIL MKAT1 VP.URCLOBRL,VALUE,P.URCLOBRL VP.URCLOBRL: NIL > IFN OFLD,< MKAT <FASLOD,LDFERR>,EXPR MKAT1 VFARRY,VALUE,FARRY VFARRY: NIL > IFN NFLD,MKAT FASLOAD,EXPR ;UNBOUND is a non-interned identifier UNBOUND:XWD ID,.+1 XWD .+1,NIL XWD PNAME,.+1 PSTRCT UNBOUND IFN MOD,< MKAT <SETMOD,CMOD,CPLUS,CDIF,CTIMES,CRECIP>,EXPR MKAT1 VBIGP,VALUE,MOD* VBIGP: NIL > MKAT1 LAMBIND,EXPR,*LAMBIND* MKAT1 PROGBIND,EXPR,*PROGBIND* MKAT1 SPECSTR,EXPR,*SPECRSTR* MKAT1 PLUS,EXPR,PLUS2,. MKAT1 DIF,EXPR,DIFFERENCE,. MKAT1 QUO,EXPR,QUOTIENT,. MKAT1 TIMES,EXPR,TIMES2,. MKAT1 RSTSW,VALUE,*RSET RSTSW:NIL MKAT1 GREAT,EXPR,GREATERP,. MKAT1 LESS,EXPR,LESSP,. IFN ALOD,<MKAT LOAD,EXPR MKAT1 PUTSYM,EXPR,*PUTSYM MKAT1 GETSYM,EXPR,*GETSYM> MKAT <OBLIST,BASE,IBASE,BPEND,BPORG>,VALUE,V VOBLIST: OBLIST VBASE: 8+INUM0 VIBASE: 8+INUM0 VBPORG: XWD 0,.+1 XWD FIXNU,VBPORX VBPEND: XWD 0,.+1 XWD FIXNU,VBPENX PUTOB ?,.+1 QST: XWD ID,.+1 XWD .+1,NIL XWD PNAME,.+1 PSTRCT ? BFWS: ;All the FWS LITerals from above atoms, etc. XLIST ; includes VBPORX,VBPENX datums. LIT VINUM0: INUM0 VBPORX: 400000 VBPENX: 700000-1000-2 ;676776 --> 1 for SYSINP and 1000 for slop. LIST EFWS: 0 SUBTTL LISP STORAGE ALLOCATOR (ONCE ONLY) --- PAGE 29 ALLOC:! CALLI RESET ;Later IOBRST & another RESET. MOVEI P,ALLPDL-1 IFN OPSYS, < ;LISP.EXE SIZE LT DESIRED STARTING SIZE. MOVEI A,INITCORE PCALL ALCORH > IFL OPSYS,<GETPPN A, HLRM A,SYSNU> IFN SYDEV, < IFG OPSYS, < MOVEI 1,1 ;MATCH EXACTLY HRROI 2,[ASCIZ /REDUCE/] STDIR JFCL GJINF ;IN DESPERATION, USE HIS LOGIN DIR #. HRRZM 1,SYSNUM > IFLE OPSYS,< MOVEI A,(SIXBIT /SYS/) HRLZM A,SYSNUM > > ;End of IFN SYDEV OUTSTR [ASCIZ / Allocate? /] INCHRW C CAIE C,"n" CAIGE C,"O" JRST ALLC00 IFN OPSYS,< OUTSTR [ASCIZ / Core (K): /] PCALL ALLNUM JUMPLE A,ALLTNX CAIG A,MAXCORE ;Asking for too much core ? JRST .+3 ;No OUTSTR [ASCIZ / Will give you maximum allowed/] MOVEI A,MAXCORE LSH A,^D10 SUBI A,1 PCALL ALCORE ALLTNX:! MOVEI A,^D8 HRRM A,ALLRDX ;Remaining inputs are octal. > IFN SYDEV, < IFG OPSYS, < OUTSTR [ASCIZ / SYS: dir# /] PCALL ALLNUM SKIPN A GJINF ;If user said "0", use his dir. SKIPL A HRRM A,SYSNUM > IFLE OPSYS,< OUTSTR [ASCIZ / SYS: /] SETZ A, SYLO:! INCHRW C CAILE C,"z" JRST SYLE CAIL C,"a" TRZ C,40 ;Convert lower case to upper CAIL C,"A" CAILE C,"Z" JRST SYLE LSH A,6 ADDI A,-40(C) JRST SYLO INCHRW C SYLE:! CAIN C,RUBOUT JRST [OUTSTR [ASCIZ /XXX /] JRST SYLO-1] CAILE C," " JRST SYLE-1 CAIN C,15 INCHRW C ;<lf> assumed. JUMPE A,.+2 HRLZM A,SYSNUM > > ;End of IFN SYDEV OUTSTR [ASCIZ / FWDS= /] PCALL ALLNUM JUMPL A,.+2 HRRM A,ALLC02 IFN SZBPS,< OUTSTR [ASCIZ / BPS.= /] PCALL ALLNUM JUMPL A,.+5 ;USE DEFAULT ? CAIGE A,MINFBPS MOVEI A,MINFBPS ADDI A,BOTBPS HRRZM A,SBPS > OUTSTR [ASCIZ / SPDL= /] PCALL ALLNUM JUMPL A,.+4 HRRM A,ALLC20 MOVNS A HRRM A,ALLC21 IFN EPDL,< OUTSTR [ASCIZ / EPDL= /] PCALL ALLNUM JUMPL A,.+4 HRRM A,ALLC40 MOVNS A HRRM A,ALLC41 > OUTSTR [ASCIZ / RPDL= /] PCALL ALLNUM JUMPL A,.+2 HRRM A,ALLC30 OUTSTR [ASCIZ / HASH= /] PCALL ALLNUM CAIG A,BCKETS JRST ALLC00 HRRM A,INT1 MOVNS A HRRM A,RH4 SETOM HASHFG ;ONCE ONLY. ALLC00:! MOVE A,.JBREL HRRZM A,JRELO HRLM A,.JBSA MOVEI A,DEBUGO HRRM A,.JBREN MOVEI A,LISPGO HRRM A,.JBSA IFN OPSYS,< MOVEI 1,400000 MOVE 2,[2,,ENTVEC] SEVEC > OUTSTR [ASCIZ / /] IFE HCBPS,< MOVEI A,FS PCALL FIX1A MOVEM A,VBPORG MOVEI A,FS ADD A,SBPS HRRZM A,FSO ;SET ONCE AND FOR EVER!!! SOS A PCALL FIX1A MOVEM A,VBPEND > IFN HCBPS,< MOVEI A,FS MOVEM A,FSO IFN OPSYS,MOVEI A,400000 ;First loc of high-segment. IFE OPSYS,< HRRZ B,.JBREL ;highest address in low core TRNN B,400000 ;is low core higher than 128k MOVEI B,377777 ;no, assume high core start at 400000 MOVE A,[XWD -2,.GTUPM] ;get high core orig. from monitor GETTAB A, ;.GTUPM indexed by current high core number HRLI A,1(B) ;table or call not present, use assumed value LSH A,-^D18 ;convert to address of high segment ANDI A,777000 ;clear any low bits ADDI A,.JBHDA> ;Add space for vestigial job data area MOVEM A,VBPORX IFE SZBPS,MOVEI A,700000-1000-2 ;PA1050 - 1 page. IFN SZBPS,ADD A,SBPS MOVEM A,VBPENX MOVSS A PCALL ALCORH SETZ A, CALLI A,SETUWP HALT > MOVE A,JRELO ALLC20:! SUBI A,1000+X ALLC21:! HRLI A,-1000+X MOVEM A,SC2 IFN EPDL,< ALLC40:! SUBI A,100+X ALLC41:! HRLI A,-100+X MOVEM A,EC2 > SUB A,FSO HRRZS B,A ASH A,-4 ALLC02:! ADDI A,400+X MOVE C,B ASH C,-6 ALLC30:! ADDI C,1000+X ;Stg order= prgm bps fs fws bt btf pdl epdl sp MOVEI T,44 IDIVM A,T AOS T ;size of btf SUB B,T SUB B,A SUB B,C ;remaining storage MOVEI TT,^D32+1 IDIVM B,TT ;bt size -1 SUBI B,1(TT) ;free storage size IFE HCBPS,<ADD B,SBPS> HRRZ AR4,B ADDI B,FS HRRZM B,FWSO HRRM B,GCP1 ;b hac top of fs MOVN SP,B HRRM SP,GCMFWS HRLZM A,C1GCS ;length of fws MOVNS C1GCS HRRM B,C1GCS ADDI B,-1(A) ;bottom of bt-1 AOS B MOVE SP,FSO LSH SP,-5 SUBM B,SP HRRM SP,GCBTP2 HRRM SP,GCBTP1 HRLM B,C3GC HRRM B,GCP2 HRRM B,GCP HRRZM B,EFWSO MOVNI SP,-1(TT) HRLM SP,C3GCS HRRM B,C3GCS AOS B MOVE SP,FSO ANDI SP,37 HRRM SP,GCBTL2 SUBI SP,^D32 HRRM SP,GCBTL1 HRRM B,C3GC ADDI B,-1(TT) HRRM B,C2GCS AOS B HRRM B,C2GC ADDI B,-1(T) HRRM B,GCP5 AOS B MOVEI A,OBTBL IFE HCBPS,<ADD A,SBPS> MOVEM A,(B) HRRM B,GCP3 AOS B HRRM B,C2 MOVNI A,-10(C) HRLM A,C2 IFE HCBPS,<MOVE FF,SBPS> IFN HCBPS,<SETZ FF, > MOVEI F,BFWS-1(FF) JUMPE FF,RLOCA MOVEI C,FOOLST REL5:! MOVE B,(C) ;Relocate all FS refs w/i system code, CDRA A,(B) ; by length of alloc'd BPS, iff HCBPS=0. ADD A,FF RPLCD A,(B) HLR B,B CDRA A,(B) ADD A,FF RPLCD A,(B) CAIGE C,EFOLST-1 AOJA C,REL5 MOVEI A,TRUTH ADD A,FF HRLM A,IDCHTAB+"T"-100 JRST RLOCA ;Uses values in AR4,F,FF. PAGE ALLNUM:! MOVSI A,400000 ;high bit on for no-digits-seen. INCHRW C CAIN C,15 INCHRW C ;<lf> assumed. CAIN C,RUBOUT JRST [OUTSTR [ASCIZ /XXX /] JRST ALLNUM] CAIL C,"0" CAILE C,"9" PRET TLZ A,400000 ;turn off hi bit on digit ALLRDX:! IFN OPSYS,IMULI A,^D10+X ;first a decimal number IFE OPSYS,IMULI A,^D8 ;only octal ADDI A,-"0"(C) JRST ALLNUM+1 ALCORE:! CAMG A,.JBREL PRET ;Already bigger. ALCORH:! CALLI A,CORE HALT PRET ALLPDL:! BLOCK 10 IFN SZBPS,<SBPS:! INITBPS+BOTBPS> PAGE I=0 DEFINE GARP (A,B) <XWD FOO'A,FOO'B> FOO 0 FOOLST:! XLIST REPEAT <FOOCNT/2>,< GARP (\I,\<I+1>) I=I+2> LIST EFOLST:! DEFINE MKENT (A)< INTERNAL A> ;These are for BIGNUMs (in ARITH)... MKENT <NUMV2,FLOOV,FS> MKENT <LAST,FIX1A,NUMVAL,REVERSE,LENGTH,XCONS,CONS,CTY,MINUSP> MKENT <NUM1,NUM3,FWCONS,FALSE,TRUE,NCONS,IDCONS> ;These are for GFPAK MKENT <.PLUS,REMAINDER,.COPY,.Q1,MAKBIG,POPAJ> ;These are for SCAN... MKENT <CHRTAB,RATOM,OLDCH,NOINFG,TYI> ;Most of the rest are for ALVINE... MKENT <READ,READP1,MAKNUM,PRIN1,PRINT,EXPLODE,EQUAL,SUBST> MKENT <LNCT,PAGL,CHCT,LINL,POSN,TYOD,TYID> MKENT <GET,INTERN,REMOB,COMPRESS,GENSYM,FIX,LENGTH,PATOM> MKENT <MAPLIST,GC,PUT,FIXP,FLOATP,ATMTYP,NATMTYP,IPUTD,IMKCODE> MKENT <ERR,MAPCAR,REMPROP,LIST,SETQ,ERRORSET,%APPLY> MKENT <SPECSTR,LAMBIND,PROGBIND,INTER0,ATOM,READCH,SET,PRIN2> MKENT <FP7A1,TERPRI,LSPRET,BKTRC> MKENT <TYO,ITYO,EVAL,APPLY,%EVAL,INPUT,OUTPUT> IFE STL,MKENT <READLIST,GETL,SASSOC,SAS1,FLATSIZE> IFN AED,MKENT PSAV1 ;SOME MORE FOR FRICK'S "SHEEP" SYSTEM... IFN ASARY,MKENT <ARRAY,ARRAYS,ARREND> MKENT <GCMKL,PRINT1,EJECT,OPEN,RDS,WRS,CLOSE,PRINC,GETD,PUTD,DCONSA> MKENT <PCHAR,FIXOV,ZERODIV,ILLNUM,STKLOC,ATSOC,EXARG,MKVECT> SUPPRESS FOOCNT,I END ALLOC