TITLE LISP INTERPRETER 3A(1)-2 SUBTTL NOTES TO SYSTEM PROGRAMMERS ;%% VERSION DEFINITIONS: LSPWHO==2 ;%% UCI LSPVER==3 ;%% MAJOR VERSION LSPMIN==1 ;%% MINOR VERSION LSPEDT==1 ;%% EDIT LEVEL ; ASSEMBLY SWITCHES OF INTEREST ; ; SWITCH EXPLANATION, COMMENTS ETC. ; ALTMOD FOR ALTMODE CHARACTER. OLD WAS 175 ; NOW IT'S 33 FOR 506 ; QALLOW ENABLES ACCESS TO QMANGR, ONLY IF YOUR ; SYSTEM SUPPORTS QUEUE. SEVERAL SWITCHES ; ASSOCIATED WITH THE CODE ; OLDNIL OLD STANFORD NIL. CODE TO MAKE CAR AND CDR ; OF NIL INCOMPLETE AS OF 8/30/73 ; NONUSE OLD STANFORD VERSIONS OF MEMQ, AND ETC. ; THAT RETURNED T OR NIL. ; REALLC PROGRAM-CONTROLLED DYNAMIC REALLOCATION ; ROUTINE AND RELATED FUNCTIONS ; SYSPRG PROJECT NUMBER IF NOT ON SYS:. ; SYSPN PROGRAMMER NUMBER IF NOT ON SYS: ; SYSDEV DEVICE LOCATION OF SYSTEM. ; NOTE THAT THE ABOVE THREE ARE WHERE LISP ; EXPECTS TO FIND THE LOADER,THE ; SYMBOL TABLE AND THE NORMAL HI-SEGMENT. ; THE FUNCTION (SETSYS ...) ONLY CHANGES THE ; EXPECTED LOCATION OF THE HI-SEG ;%% SYSNAM NAME OF EXPECTED HIGH SEGMENT ;%% AND LISP LOADER AND SYMBOL TABLE ;%% INUMIN LOWEST ADDRESS AVAILABLE FOR USE AS ;%% AN INUM ;%% BCKETS NUMBER OF HASH BUCKETS ;%% SHRST LOWEST ADDRESS IN HIGH SEGMENT ;%% SYSUNV SEARCH SYSTEM UNIVERSAL LIBRARIES ; **USE FOLLOWING AT OWN RISK** ; HASH NUMBER OF HASH BUCKETS WHEN STARTING ; ALVINE STANFORD EDITOR (WHO WOULD WANT IT?) ; 1 FOR ALVINE, 0 FOR NO ALVINE ; STPGAP ANOTHER STANFORD EDITOR ; COMMENTS: ; ; THERE ARE BASICALLY TWO SETS OF COMMENTS IN THE CODE: ; THOSE IN LOWER CASE ARE ORIGINAL STANFORD COMMENTS; ; THOSE OF A SEMI-COLON FOLLOWED BY TWO $'S, ; TWO #'S, OR TWO %'S ARE UCI ADDITIONS, ; CHANGES, OR ADDITIONAL COMMENTS ; ($'S ARE USUALLY DARYLE LEWIS, ; #'S ARE GENERALLY JEFF JACOBS, ; AND %'S ARE GENERALLY BILL EARL). PAGE SUBTTL AC DEFINITIONS AND EXTERNALS IFNDEF SYSUNV, ;[1] IFNDEF SHRST ;[1] TWOSEG SHRST ;[1] IFN SYSUNV,< ;[1] SEARCH MACTEN SEARCH UUOSYM ;[1] .JBVER==137 ;%% SYSTEM VERSION LOCATION ;[1] LOC .JBVER ;%% SET STANDARD SYSTEM VERSION ;[1] VRSN. (LSP) ;%% GENERATE VERSION> ;[1] RELOC SHRST ;[1] OLDNIL==1 ;## NOT COMPLETE IFNDEF NONUSE IFN SHRST-400000 IFNDEF QALLOW IFNDEF REALLC ;%% NORMALLY OFF TO SAVE SPACE ;%% CHANGE FOR EXTENDED SYSTEM ;SYSPRG==667 ;PPN OF LISP SYSTEM - SET TO 0 FOR SYS: ;SYSPN==2 ;SAME HERE IFNDEF SYSPRG, IFNDEF SYSPN, ;ALVINE==1 ;1 FOR ALVINE, 0 FOR NO ALVINE IFNDEF ALVINE, ;HASH==1 ;1 FOR SETTING # OF HASH BUCKETS AT SYS. INIT. TIME IFNDEF HASH, ;STPGAP==1 ;1 FOR STOPGAP, 0 TO DELETE IT IFNDEF STPGAP, IF1, MLON IFNDEF INUMIN, ;%% [1] INUM0=777777-<<777777-INUMIN>/2> ;%% [1] IFNDEF BCKETS, IFE SYSPRG,< IFNDEF SYSDEV> > IFN SYSPRG,< IFNDEF SYSDEV> > IFNDEF SYSNAM,> ;accumulator definitions ;`sacred' means sacred to the interpreter ;`marked' means marked from 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 AR1=4 ;marked, protected ;fourth arg of subrs AR2A=5 ;marked, protected ;fifth arg of subrs T=6 ;marked, protected ;minus number of args in LSUBR call TT=7 ;marked, protected REL=10 ;marked, protected S=11 ;$$NOW USED FOR ATOM RELOCATION AND GARBAGE COLLECTOR 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 X==0 ;X indicates impure (modified) code locations TEN==^D10 ;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 PUSHJ OPDEF JCALL [35B8] ;terminal function call-may be changed to JRST OPDEF CALLF [36B8] ;like call but may not be changed to PUSHJ OPDEF JCALLF [37B8] ;like jcall but may not be changed to JRST ;error UUOs OPDEF ERR1 [1B8] ;ordinary lisp error ;gives backtrace OPDEF ERR2 [2B8] ;space overflow error ;no backtrace OPDEF ERR3 [3B8] ;ill. mem. ref. OPDEF STRTIP [4B8] ;print error message and continue ;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 SKPINL [TTCALL 14,] ;## BETTER FOR TALK THAN SKPINC OPDEF TALK [PUSHJ P,TTYCLR] ;## TURN OF CONTROL O ;I/O bits and constants 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 ;channel data CHNAM==0 ;name of channel CHDEV==1 ;name of device CHPPN==2 ;ppn for input channel CHOCH==3 ;oldch for input channels IFN STPGAP,< 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 > IFE STPGAP,< CHDAT==4 POINTR==5 COUNT==6 > CHLL==2 ;linelength for output channel CHHP==3 ;hposit for output channels ;special ASCII characters IFNDEF ALTMOD, SPACE==40 ;space IGCRLF==31 ;ignored cr-lf RUBOUT==177 LF==12 CR==15 TAB==11 BELL==7 DBLQT==42 ;double quote " ;byte pointer field definitions ACFLD==14 ;ac field XFLD==21 ;index field OPFLD==10 ;opcode field ADRFLD==43 ;adress field ;external and internal symbols EXTERNAL JOB41 ;instruction to be executed on UUO EXTERNAL JOBAPR ;address of APR interupt routines EXTERNAL JOBCNI ;interupt condition flags EXTERNAL JOBFF ;first location beyond program EXTERNAL JOBREL ;address of last legal instruction in core image EXTERNAL JOBREN ;reentry address EXTERNAL JOBSA ;starting address EXTERNAL JOBSYM ;address of symbol table EXTERNAL JOBTPC ;program counter at time of interupt EXTERNAL JOBUUO ;uuo is put here with effective address computed EXTERNAL JOBOPC ;$$FOR NEW REENTER FEATURES EXTERNAL JOBHRL ;HIGH SEGMENT BOUNDARY ;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 ;RE-ENTER CONTROL CHARACTERS CNTLH==10 CNTLE==5 CNTLB==2 CNTLZ==32 CNTLG==7 CNTLR==22 ;CH TO RESTORE SYSTEM OBLIST 3/28/73 ;system uuos APRINI==16 RESET==0 STIME==27 DEVCHR==4 EXIT==12 CORE==11 SETUWP==36 GETSEG==40 ;REMOTE MACRO DEFINE REMOTE (TX) < HERE1 > DEFINE HERE1 (NEW,OLD,%G) < DEFINE %G < NEW> DEFINE REMOTE (TX) < HERE1 ,>> DEFINE HERE < DEFINE HERE1 (XX,YY) < YY> REMOTE> SALL PAGE SUBTTL TOP LEVEL AND INITIALIZATION REMOTE< LISPGO: SKIPE GCFLG ;$$CHECK FO GARBAGE COLLECTION PUSHJ P,GCING ;$$QUEUE THE REQUEST CAME 0,STNIL ;$$UNBIND STACK IF REGS LOOK OK JRST GETHGH ;GO GET HIGH SEGMENT MOVE B,SC2 PUSHJ P,UBD ;$$UNBIND STACK JRST STRT ;go to re-allocator GETHGH: CALLI RESET MOVSI A,1 CALLI A,CORE ;ELIMINATE ANY OLD HIGH SEGS. HALT MOVEI A,HGHDAT CALLI A,GETSEG ;GET THE PROPER HIGH SEG HALT MOVEI A,DEBUGO ;SET THE REE ADDRESS HRRM A,JOBREN JRST STRT ;GO TO ALLOCATE STORAGE HGHDAT: SYSDEV SYSNAM 0 0 XWD SYSPRG,SYSPN 0> DDT: SETOM ERINT ;$$SET CONTROL H WITHOUT GOING THRU REE JRST @JOBOPC ;$$AND CONTINUE DEBUGO: SKIPE GCFLG# ;CHECK GARBASE COLLECT. PUSHJ P,GCING ;QUEUE INTERRUPT INCHRW 0 ;READ THE CONTROL CHARACTER CAIN 0,CNTLR ; RESTORES SYSTEM OBLIST JRST [HRRI 0,OBTBL(S) HRRM 0,VOBLIST(S) JRST DEBUGO+2] ; AND TRIES FOR ANOTHER CONTROL CHARACTER CAIN 0,CNTLH JRST [MOVE 0,STNIL JRST DDT] CAIN 0,CNTLE JRST [MOVE 0,STNIL MOVEI 1,NIL JRST ERR] CAIN 0,CNTLB JRST [MOVE 0,STNIL SETOM ERINT PUSHJ P,SPDLPT PUSHJ P,SPREDO JRST LSPRET] CAIN 0,CNTLZ JRST [MOVE 0,STNIL JRST LSPRET] CAIN 0,CNTLG JRST [MOVE 0,STNIL JRST RERX] JRST DEBUGO+2 ;NOT A CONTROL CHARACTER ;MUST BE SOMETHING IN THE BUFFER SO TRY AGAIN START: CALLI RESET ;random initializations for lisp interupts MOVE [JSR UUOH] MOVEM JOB41 MOVEI APRINT MOVEM JOBAPR MOVEI APRFLG CALLI APRINI SETZM GCFLG HRRZI 17,1 IFN ALVINE, IFE ALVINE, BLT 17,17 ;clear acs MOVE S,ATMOV ;$$SET UP RELOCATION FOR INTERNAL ATOMS (FOOLIST) LSPRT1: SETZM BIOCHN(S) ;$$CLEAR VARS FOR BREAK PACKAGE SETZM BPMPT(S) ;$$(#%IOCHNAS%#, #%PROMPTS%#, AND #%INDENT) MOVEI A,INUM0 MOVEM A,BINDNT(S) SETZM ERINT# ;$$TURN OFF INTERRUPT FLAG SETOM ERRSW ;print error messages CLEARM ERRTN# ;return to top level on errors SETOM PRVCNT# ;initialize counter for errio MOVE P,C2# ;initial reg pdl ptr MOVE SP,SC2# ;initial spec pdl ptr MOVE A,LSPRMP# ;$$INITIALIZE TO TOP LEVEL PROMPT ;$$CAN BE CHANGED BY INITPROMPT PUSHJ P,PROMPT ;$$ SETZM SMAC ;$$CLEAR SPLICE LIST (JUST IN CASE) MOVE S,ATMOV ;$$SET UP RELOCATION FOR INTERNAL ATOMS (FOOLIST) PUSHJ P,TTYRET ;(outc nil t)(inc nil t)return output for gc message IFN OLDNIL ;INITIALIZE NIL IFE OLDNIL MOVEM 0,STNIL# ;$$SAVE FOR REG CHECK AT START TIME MOVEI A,CNIL2(S) ;## GET PROP LIST OF NIL MOVEM A,NILPRP# ;## AND SAVE IT FOR GET ETC. IFN HASH,< SKIPE HASHFG# JRST REHASH ;rehash if necessary> SKIPN F PUSHJ P,AGC ;garbage collect only if necessary SKIPN BSFLG# ;initial bootstrap for macros JRST BOOTS SKIPE A,INITF CALLF (A) ;evaluate initialization function PUSHJ P,TTYRET ;return all i/o to tty PUSHJ P,TERPRI SKIPE GOBF# ;garbaged oblist flag STRTIP [SIXBIT /GARBAGED OBLIST_!/] SETZM GOBF SKIPE BPSFLG# JRST BINER2 ;binary program space exceeded by loader LISP1: MOVE S,ATMOV# ;$$MAKE SURE REL STAYS ;$$SET UP - BELT AND SUSPENDERS TECHNIQUE PUSHJ P,READ ;this is the top level of lisp PUSHJ P,EVAL PUSHJ P,PRINT PUSHJ P,TERPRI JRST LISP1 INITFL: EXCH A,INITF1# ;## NEW INIT FILE LIST POPJ P, ;## RETURN THE OLD ONE INITFN: EXCH A,INITF# POPJ P, ;return from lisp error LSPRET: PUSHJ P,TERPRI MOVE B,SC2 ;RETURN FROM BELL PUSHJ P,UBD ;unbind specpdl JRST LSPRT1 .RSET: EXCH A,RSTSW# POPJ P, COMMENT % ;## OLD BOOTSTRAP CODE FOR INIT FILE, REPLACED BELOW ;BOOTSTRAPPER FOR USER'S INIT FILE BOOTS: SETOM BSFLG MOVE A,[POINT 7,[ASCII /(ERRSET[INC(INPUT DSK:(INIT.LSP]NIL)[(EVAL(READ]/]] MOVEM A,BOOPT# MOVEI A,BSTYI PUSHJ P,READP1 PUSHJ P,EVAL JUMPE A,BOOTOT MOVEI A,BSTYI PUSHJ P,READP1 PUSH P,A MOVE A,(P) PUSHJ P,ERRSET CAIE A,$EOF$(S) JRST .-3 BOOTOT: PUSHJ P,EXCISE JRST ERR BSTYI: ILDB A,BOOPT POPJ P, % ;## NEW IMPROVED BOOTSTRAPPER FOR USER'S INITFILE(S) ;## ALLOWS MORE THAN ONE FILE. FIRST FILE IS READ IN ;## OR IF NOT FOUND BEHAVES AS BEFORE (I.E. NO ERROR MESSAGE) ;## REMAINING FILES WILL CAUSE AN ERROR MESSAGE IF NOT FOUND. ;## THUS IF THE USER IS USING THIS TO REALLY SET UP HIS OWN ;## SYSTEM, HE WILL KNOW ABOUT A FAILURE, BUT THE FIRST ;## FILES EXISTENCE IS STILL OPTIONAL BOOTS: SETOM BSFLG# ;## INDICATE BOOTSTRAP DONE SKIPN T,INITF1# ;## GET INIT FILE LIST IF IT EXISTS JRST BOOTOT ;## NOPE, EXCISE AND RETURN MOVEI A,TRUTH(S) ;## USE CHANNEL T PUSHJ P,INPUT2 ;## SET UP PUSHJ P,ININIT ;## LOOK UP JUMPN A,BOOTOK ;## IT'S THERE, GO TO IT JUMPE T,BOOTOT ;## NOT THERE AND NO OTHERS REQUESTED PUSHJ P,SETINA ;## SET UP FOR THE REST PUSHJ P,ININIT ;## LOOK UP (SECOND FILE IN LIST) JUMPE A,AIN.7 ;## NOT THERE, ERROR MESSAGE BOOTOK: MOVEI A,TRUTH(S) ;##(INC T NIL) SETZ B, PUSHJ P,INC ;## SELECT MOVEI A,READAT(S) ;## SET UP [(EVAL (READ))] PUSHJ P,NCONS ;## (READ) PUSHJ P,NCONS ;## ((READ)) MOVEI B,EVALAT(S) PUSHJ P,XCONS ;##(EVAL(READ)) PUSHJ P,NCONS ;## [(EVAL(READ))] PUSH P,A MOVE A,(P) PUSHJ P,ERRSET ;## AN EVAL-READ LOOP. PROTECTED AGAINST CAIE A,$EOF$(S) ;## ALL ERRS EXCEPT $EOF$ AND ERRORX JRST .-3 ;## LOOP BOOTOT: PUSHJ P,EXCISE JRST ERR PAGE SUBTTL APR INTERRUPT ROUTINES ;arithmetic processor interupts ;mem. protect. violation, nonex. mem. or pdl overflow APRINT: MOVE R,JOBCNI ;get interupt bits TRNE R,MPV+NXM ;what kind ERR3 @JOBTPC ;an ill mem ref-will become JRST ILLMEM JUMPN NIL,MES21 ;a pdl overflow STRTIP [SIXBIT /_PDL OVERFLOW FROM GC - CAN'T CONTINUE!/] JRST START MES21: SETZM JOBUUO SKIPL P STRTIP [SIXBIT /_REG !/] SKIPL SP STRTIP [SIXBIT /_SPEC !/] SKIPE JOBUUO SPDLOV: ERR2 [SIXBIT /PUSHDOWN CAPACITY EXCEEDED !/] TRNE R,PDOV SKIPE JOBUUO HALT ;lisp should not be here BINER2: SETZM BPSFLG ERR2 [SIXBIT /BINARY PROGRAM SPACE EXCEEDED !/] ILLMEM: LDB R,[POINT 4,@JOBTPC,XFLD] ;get index field of bad word CAIE R,F ;does it contain f ERR3 @JOBTPC ;no! error PUSHJ P,AGC ;yes! garbage collect JRST @JOBTPC ;and continue PAGE SUBTTL UUO HANDLER AND SUBR CALL ROUTINES UUOMIN==1 UUOMAX==4 REMOTE UUOH2: MOVEM T,TSV# MOVEM TT,TTSV# LDB T,[POINT 9,JOBUUO,OPFLD] ;get opcode CAIGE T,34 ;is it a function call JRST ERROR ;or a LISP error HLRE R,@JOBUUO AOJN R,UUOS LDB T,[POINT 4,JOBUUO,ACFLD] CAILE T,15 MOVEI R,-15(T) HRRZ T,@JOBUUO UUOH1: HLRZ TT,(T) HRRZ T,(T) CAIN TT,SUBR(S) JRST @UUST(R) CAIN TT,FSUBR(S) JRST @UUFST(R) CAIN TT,LSUBR(S) JRST @UULT(R) CAIN TT,EXPR(S) JRST @UUET(R) CAIN TT,FEXPR(S) JRST @UUFET(R) HRRZ T,(T) JUMPN T,UUOH1 PUSH P,A PUSH P,B HRRZ A,JOBUUO MOVEI B,VALUE(S) PUSHJ P,GET JUMPN A,[ HRRZ TT,(A) POP P,B POP P,A JRST UUOEX1] HRRZ A,JOBUUO PUSHJ P,EPRINT ERR1 [SIXBIT /UNDEFINED UUO!/] SKIPA T,TT UUOSBR: HLRZ T,(T) MOVE TT,JOBUUO HRLI T,(PUSHJ P,) TLNE TT,1000 ;1000 means no push TLCA T,34600 ;xor PUSH P,UUOH SOS UUOH HRRZ D,UUOH CAIG D,SHRST JRST .+3 SKIPE WRTSTS JRST .+3 REMOTE ;2000 means no clobber XCT UUOCL MOVEM T,@UUOH MOVE TT,TTSV EXCH T,TSV JRST @TSV UUOS: HRRZ TT,JOBUUO CAILE TT,@GCPP1 CAIL TT,@GCP1 JRST UUOSBR-1 JRST .+2 UUOEXP: HLRZ TT,(T) UUOEX1: LDB T,[POINT 5,JOBUUO,ACFLD] TRZN T,20 PUSH P,UUOH PUSH P,TT JUMPE T,IAPPLY CAIN T,17 MOVEI T,1 MOVNS T HRLZ TT,T PUSH P,A(TT) AOBJN TT,.-1 JRST IAPPLY PAGE ARGPDL: LDB T,[POINT 4,JOBUUO,ACFLD] MOVNS T HRLZ R,T ARGP1: JUMPE R,(TT) PUSH P,A(R) AOBJN R,.-1 JRST (TT) QTIFY: PUSHJ P,NCONS MOVEI B,CQUOTE(S) JRST XCONS QTLFY: MOVEI A,0 QTLFY1: JUMPE T,(TT) EXCH A,(P) PUSHJ P,QTIFY POP P,B PUSHJ P,CONS AOJA T,QTLFY1 PDLARG: JRST .+NACS+2(T) POP P,A+5 POP P,A+4 POP P,A+3 POP P,A+2 POP P,A+1 POP P,A JRST (TT) NOUUO: MOVSI B,(TLNN TT,) SKIPE A MOVSI B,(TLNA) HLLM B,UUOCL EXCH A,NOUUOF# POPJ P, PAGE ;r=0 => compiler calling a - ;r=1 => compiler calling a lsubr ;r=2 => compiler calling f type UUST: UUOSBR UUOS1 ;calling l its a subr UUOS2 ;calling f UUFST: UUOS9 ;calling - its a f UUOS10 ;calling l UUOSBR UULT: UUOS7 ;calling - its a l UUOSBR UUOS8 UUET: UUOEXP UUOS5 ;calling l its an expr UUOS6 ;calling f its an expr UUFET: UUOS3 ;calling - its a fexpr UUOS4 ;calling l UUOEXP UUOS1: HLRZ R,(T) MOVE T,TSV JSP TT,PDLARG JRST (R) UUOS3: PUSH P,(T) JSP TT,ARGPDL UUOS4A: JSP TT,QTLFY MOVEI TT,1 DPB TT,[POINT 4,JOBUUO,ACFLD] UUOS6A: POP P,TT HLRZS TT JRST UUOEX1 UUOS4: PUSH P,(T) MOVE T,TSV JRST UUOS4A PAGE UUOS5: HLRZ R,(T) MOVE T,TSV JSP TT,PDLARG MOVNS T DPB T,[POINT 4,JOBUUO,ACFLD] MOVE TT,R JRST UUOEX1 UUOS6: PUSH P,(T) PUSH P,UUOH PUSH P,JOBUUO JSP TT,ILIST JSP TT,PDLARG POP P,JOBUUO POP P,UUOH JRST UUOS6A UUOS8: SKIPA TT,CILIST UUOS7: MOVEI TT,ARGPDL HRRM TT,UUOS7A MOVE TT,JOBUUO TLNN TT,1000 PUSH P,UUOH HLRZ TT,(T) JRST @UUOS7A ;OR ILIST REMOTE UUOS9: PUSH P,T JSP TT,ARGPDL UUS10A: JSP TT,QTLFY MOVSI T,2000 IORM T,JOBUUO POP P,T JRST UUOSBR UUOS10: PUSH P,T MOVE T,TSV JRST UUS10A PAGE SUBTTL ERROR HANDLER AND BACKTRACE ;subroutine to print sixbit error message ERRSUB: MOVSI A,(POINT 6,0) HRR A,JOBUUO MOVEM A,ERRPTR# ERRORB: ILDB A,ERRPTR CAIN A,01 ;conversion from sixbit POPJ P, CAIN A,77 JRST [ PUSHJ P,TERPRI JRST ERRORB] ADDI A,40 PUSHJ P,TYO JRST ERRORB ;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 POPJ P, PUSH P,PRVSEL# ;previously selected output POP P,TYOD POPJ P, ;subroutine to force error messages out on tty ERRIO: MOVE B,ERRSW CAIE B,INUM0 ;inum0 specifies to print message on selected device AOSLE PRVCNT ;only if prvcnt already <0 does deselection occur POPJ P, TALK ;undo control o MOVE B,[JRST TTYO] EXCH B,TYOD MOVEM B,PRVSEL POPJ P, ;ERRTN: 0 ;0 => top level * ;- => pdl to reset to - stored by errorset ;+ => string tyo pout rtn flag REMOTE ;0 means no prnt on error * PAGE ;subroutine to search oblist for closest function to address in r ERSUB3: MOVEI A,QST(S) IFN OLDNIL< HRROI NIL,CNIL2(S)> IFE OLDNIL< SETZ NIL, > HRLZ B,INT1 MOVNS B SETZB AR2A,GOBF PUSH P,JOBAPR MOVEI C,[ SETOM GOBF JRST ERRO2G] HRRM C,JOBAPR HRRZ C,VOBLIST(S) ;## GET CURRENT OBLIST HRRM C,RHX5 HRRM C,RHX2 ;## AND UPDATE LOCATIONS WHICH REF OBLIST HLRZ C,@RHX5 ERRO2B: JUMPE C,[ AOBJN B,.-1 POP P,JOBAPR ;oblist done, restore JRST PRINC] ;print closest match HLRZ TT,(C) ERRO2C: HRRZ TT,(TT) JUMPE TT,ERRO2G HLRZ AR1,(TT) CAIN AR1,LSUBR(S) JRST ERRO2H CAIE AR1,SUBR(S) CAIN AR1,FSUBR(S) JRST ERRO2H HRRZ TT,(TT) JRST ERRO2C ERRO2H: HRRZ TT,(TT) HLRZ TT,(TT) CAMLE TT,AR2A ;le to prefer car to quote CAMLE TT,R JRST ERRO2G MOVE AR2A,TT HLRZ A,(C) ERRO2G: HRRZ C,(C) JRST ERRO2B PAGE ;dispatcher for error message uuos ERROR: MOVEI A,APRFLG CALLI A,APRINI ;enable interupts LDB A,[POINT 9,JOBUUO,OPFLD] ;get opcode CAIL A,UUOMIN ;what CAILE A,UUOMAX ;is it? JRST ILLUUO ;an illegal opcode JRST @ERRTAB-UUOMIN(A) ;or LISP error ERRTAB: ERROR1 ;1 ;ordinary LISP error ERRORG ;2 ;space overflow error ERROR2 ;3 ;ill. mem. ref. STRTYP ;4 ;print error message and continue ERRORG: MOVE P,ERRTN ;IF IN ERRSET, RESTORE P TO THAT LEVEL SKIPN P MOVE P,C2 ;else to top level SETOM UUO2# ;$$ AND DON'T ENTER ERRORX ERROR1: SKIPN ERRSW JRST ERREND ;dont print message, call (err nil) PUSHJ P,ERRIO ;print message on tty PUSHJ P,TERPRI PUSHJ P,ERRSUB ;print the message JRST ERRBK ;go the backtrace STRTYP: PUSHJ P,ERRIO PUSHJ P,ERRSUB ;print message and continue PUSHJ P,OUTRET JRST @UUOH ;USER ENTRY TO ERROR HANDLER, PRINTS ARG IF NON-NIL .ERROR: JUMPE A,ERREND SKIPN ERRSW JRST ERREND PUSHJ P,ERRIO PUSHJ P,TERPRI PUSHJ P,PRINC JRST ERREND PAGE ERROR2: HRRZ A,JOBUUO MOVEI B,[SIXBIT / ILL MEM REF FROM !/] JRST ERSUB2 ILLUUO: HRRZ A,UUOH MOVEI B,[SIXBIT / ILL UUO FROM !/] ERSUB2: SKIPN ERRSW JRST ERREND ;dont print message PUSH P,A PUSH P,B PUSHJ P,ERRIO PUSHJ P,TERPRI PUSHJ P,PRINL2 ;print number POP P,A STRTIP (A) ;print message POP P,R PUSHJ P,ERSUB3 ;print nearest oblist match ERRBK: IFN ALVINE,< SKIPE BACTRF PUSHJ P,BKTRC ;print backtrace > PUSHJ P,OUTRET ;return to previous device ERREND: SETZ A, ;## %CLRBFI USED TO BE HERE(FOR ERR NIL) SKIPN UUO2 ;$$NO ERRORX IF OVERFLOW ERROR JRST .+3 SETZM UUO2 ;$$RESET TO ZERO JRST RERX ;$$BOUNCE BACK TO ERRORX SKIPN RSTSW ;$$NEW *RSET FEATURE JRST ERR ;$$IF (*RSET NIL) UNBIND AND GO TO TOP LEVEL SKIPN ERRSW ;$$NO ERRORX IF NO MESSAGE JRST ERR ;$$ PUSHJ P,%CLRBFI ;## CLEAR TTY BUFFER. ELIMINATE FLUSHING ;## OF TYPE AHEAD MOVEI A,ERRORX(S) ;$$ELSE SET TO CALL ERROR HANDLER MOVEI B,NIL ;$$CREATE FORM (ERRORX) CEV: PUSHJ P,CONS ;$$ JRST EVAL ;$$AND EVALUATE IT ERR: SETZM INHERR ;CLEAR RERX FLAG JUST IN CASE CAIN A,ERRORX(S) ;$$BOUNCE TO ERRORX IF A=ERRORX JRST RERX ERR2: SKIPN ERRTN JRST LSPRET ;not in an errset, or bad error -- go to top level MOVE P,ERRTN ERR1: POP P,B PUSHJ P,UBD ;unbind to previous errset POP P,ERRSW POP P,ERRTN SKIPN INHERR# JRST ERRP4 ;and proceed RERX: SETZM INHERR ;$$ POP TO A BREAK ERRSET MOVE B,ERRSW CAIE B,ERRORX(S) SETOM INHERR JRST ERR2 ERRSET: PUSH P,PA3 PUSH P,PA4 PUSH P,ERRTN PUSH P,ERRSW PUSH P,SP MOVEM P,ERRTN HRRZ C,(A) HLRZ C,(C) MOVEM C,ERRSW HLRZ A,(A) PUSHJ P,EVAL PUSHJ P,NCONS SETZM INHERR ;CLEAR RERX FLAG JRST ERR1 SYSCLR: SETZM BSFLG ;FUNCTION TO MAKE SYSTEM LOOK NEW SETZM CONSVA ;## RESET CONS COUNT SETZM GCTIM ;## RESET GC TIME JRST EXCISE ;## EXCISE PAGE ;error messages RMERR: MOVE A,T ;$$ BAD READ MACRO, GET THE NAME PUSHJ P,EPRINT ;$$ ERR1 [SIXBIT /UNDEFINED READ MACRO!/] BNDERR: PUSHJ P,EPRINT ;$$ATTEMPT TO REBIND NIL OR T ERR1 [SIXBIT /CANNOT BE RE-BOUND!/] RPAERR: PUSHJ P,EPRINT ;$$PRINT OUT OFFENDING ITEM ERR1 [SIXBIT /IS AN ATOM, CAN'T BE RPLACA'D!/] RPDERR: PUSHJ P,EPRINT ;$$ ERR1 [SIXBIT /CAN'T BE RPLACD'D (NIL OR INUM)!/] DOTERR: SETZM OLDCH ERR1 [ SIXBIT /DOT CONTEXT ERROR!/] UNDFUN: HLRZ A,(AR1) PUSHJ P,EPRINT ERR1 [SIXBIT /UNDEFINED FUNCTION!/] UNBVAR: PUSHJ P,EPRINT ERR1 [SIXBIT /UNBOUND VARIABLE - EVAL!/] NONNUM: ERR1 [SIXBIT /NON-NUMERIC ARGUMENT!/] NOPNAM: ERR1 [SIXBIT /NO PRINT NAME - INTERN!/] NOLIST: ERR1 [SIXBIT /NO LIST-MAKNAM!/] TOMANY: ERR1 [SIXBIT /TOO MANY ARGUMENTS SUPPLIED - APPLY!/] TOOFEW: ERR1 [SIXBIT /TOO FEW ARGUMENTS SUPPLIED - APPLY!/] UNDTAC: HRRZ A,(C) UNDTAG: PUSHJ P,EPRINT ERR1 [SIXBIT /UNDEFINED FUNCTION - APPLY!/] SETERR: PUSHJ P,EPRINT ;$$BAD SET OR SETQ ERR1 [SIXBIT /CAN'T BE SET TO A VALUE - SET OR SETQ!/] EG1: PUSHJ P,EPRINT ERR1 [SIXBIT /UNDEFINED PROG TAG-GO!/] EG2: PUSHJ P,EPRINT ERR1 [SIXBIT /GO WITH NO PROG!/] EG3: ERR1 [SIXBIT /RETURN WITH NO PROG!/] PAGE IFN ALVINE,< ;backtrace subroutine BKTRC: MOVEI D,-1(P) MOVN A,BACTRF ADDI A,INUM0 JUMPL A,[ ADD A,P ;backtrace specific number JRST .+3] SKIPN A,ERRTN ;backtrace to previous errset MOVE A,C2 ;or top level HRRZM A,BAKLEV# STRTIP [SIXBIT /_BACKTRACE_!/] BKTR2: CAMG D,BAKLEV JRST FALSE ;done HRRZ A,(D) ;get pdl element CAIGE A,FS(S) JUMPN A,.+2 ;this is (hopefully) a true program address SOJA D,BKTR2 ;not a program address, continue CAIN A,ILIST3 JRST BKTR1A ;argument evaluation BKTR1B: CAIN A,CPOPJ JRST [ HLRZ A,(D) ;calling a function PUSHJ P,PRINC XCT "-",CTY STRTIP [SIXBIT /ENTER !/] SOJA D,BKTR2] HLRZ B,-1(A) CAILE B,(JCALLF 17,@(17)) CAIN B,(PUSHJ P,) ;tests for various types of calls CAIGE B,(FCALL) SOJA D,BKTR2 ;not a proper function call PUSH P,-1(A) ;save object of function call MOVEI R,-1(A) ;location of function call PUSHJ P,ERSUB3 ;print closest oblist match MOVEI A,"-" PUSHJ P,TYO POP P,R TLNE R,17 HRRZ R,ERSUB3 ;qst -- cant handle indexed calls HRRZS R HLRO B,(R) AOSN B JRST [ HRRZ A,R ;was calling an atomic function PUSHJ P,PRINC ;print its name JRST .+2] PUSHJ P,ERSUB3 ;was calling a code location -- print closest match MOVEI A," " PUSHJ P,TYO BKTR1: SOJA D,BKTR2 ;continue BKTR1A: HRRZ B,-1(D) CAIE B,EXP2 CAIN B,ESB1 JRST .+2 JRST BKTR1B ;hum, not really evaluating arguments HLRE B,-1(D) ADD B,D HLRZ A,-3(B) JUMPE A,BKTR1 PUSHJ P,PRINC XCT "-",CTY STRTIP [SIXBIT /EVALARGS !/] JRST BKTR1 > BAKGAG: EXCH A,BACTRF# POPJ P, PAGE SUBTTL TYI AND TYO ;input ITYI: PUSHJ P,TYI ;## RETURN ASCII VALUE OF INPUT CH FIXI: ADDI A,INUM0 POPJ P, TYI: MOVEI AR1,1 ;## TO TEST FOR LINED TYPESEQUENCE #, ETC PUSHJ P,TYIA JUMPE A,.-1 CAME A,IGSTRT ;start of comment or ignored cr-lf POPJ P, PUSHJ P,COMMENT JRST TYI+1 TYIA: SKIPE A,OLDCH ;## IF CH IN OLDCH JRST TYI1 ;## TAKE CARE OF IT TYID: XCT TYI2 ;## INPUT A CHARACTER REMOTE ;sosg x for other device input ;other device input JRST TYI2X TYI3B: ILDB A,@TYI3# ;pointer XCT TYI3A ;## SEE IF LINED TYPE WORD REMOTE ;pointer POPJ P, ;## NO, OK IFN STPGAP,< MOVE A,@TYI3A CAMN A,[+1] ;page mark for stopgap AOSA PGNUM ;increment page number MOVEM A,LINUM > MOVNI A,5 ADDM A,@TYI2 ;adjust character count for line number AOS @TYI3 ;increment byte pointer over line number and tab JRST TYID REMOTE< TYI2X: INPUT X, TYI2Y: STATZ X,740000 ERR1 AIN.8 ;input error TYI2Z: STATO X,20000 JRST TYI3B ;continue with file TYIEOF: JRST TYI2Q ;END OF FILE> TYI2Q: PUSH P,T PUSH P,C PUSH P,R PUSH P,AR1 MOVE A,INCH HRRZ C,CHTAB(A) ;get location of data for this channel HLRZ T,CHTAB(A) ;inlst -- remaining files to input JUMPE T,TYI2E ;none left -- stop PUSHJ P,SETIN ;start next input PUSHJ P,ININIT ;## INIT THE FILE JUMPE A,AIN.7 ;## CAN'T FIND FILE, ERROR POP P,AR1 POP P,R POP P,C POP P,T JRST TYI TYI2E: PUSHJ P,INCNT ;(inc nil t) TALK MOVEI A,$EOF$(S) ;we are done JRST ERR IFN STPGAP,< PGLINE: MOVE C,[POINT 7,LINUM] PUSHJ P,NUM10 ;convert ascii line number to a integer ADDI A,INUM0 MOVE B,PGNUM ADDI B,INUM0+1 JRST XCONS> REMOTE< OLDCH: 0 IFN STPGAP,< PGNUM: 0 LINUM: 0 0>> ;zero to terminate num10 ;TTYECHO - COMPLEMENTS THE TTY: ECHO BIT AND RETURNS T IF THE ECHO ; IS BEING TURNED ON AND NIL IF IT IS BEING TURNED OFF ; - TAKES NO ARGUMENTS ECHO: SETO A, TTYUUO 6,A ;GET STATUS BITS TLC A,4 ;COMPLEMENT THE ECHO BIT TTYUUO 7,A ;RESTORE THE BITS TLNE A,4 ;TEST TO GET FINAL VALUE JRST FALSE JRST TRUE ;CLRBFI - CLEARS TTY INPUT BUFFER FOR USER ERRORS ; - 0 ARGS AND RETURNS NIL %CLRBFI:CLRBFI ;CLEAR BUFFER SETZM SMAC ;CLEAR SPLICE LIST SETZM OLDCH ;CLEAR LAST CHAR. JRST FALSE PAGE ;teletype input ERRCH: MOVEI A,-INUM0(A) ;## CHANGE BELL CHARACTER EXCH A,ERRCHR ;## RETURN OLD CHARACTER JRST FIX1A ;## CONVERT IT REMOTE < ERRCHR: BELL > TTYI: SKIPE DDTIFG ;## DDT MODE? JRST TTYID INCHSL A ;single char if line has been typed JRST [OUTCHR PROMCH# ;$$OUTPUT PROMPT CHARACTER INCHWL A ;wait for a line JRST .+1] TTYXIT: CAME A,ERRCHR ;## BELL, NEED NOT BE ^G POPJ P, IFN ALVINE,< SKIPE PSAV1# ;bell from alvine? JRST [ MOVE P,PSAV1 ;yes, return to alvine JRST @ED1];$$DOUBLY IMPROVED MAGIC> MOVEI A,NIL ;$$ RETURN NIL AS THE VALUE JRST RERX ;$$ RETURN TO AN ERRORX ERRSET TTYID: 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 MOVEI A,RUBOUT POPJ P, PROMPT: SKIPN A SKIPA A,PROMCH MOVEI A,-INUM0(A) ;$$CHANGE FROM INUM EXCH A,PROMCH# ;$$CHANGE PROMPT CHARACTER AND RETURN OLD ONE MOVEI A,INUM0(A) ;$$CHANGE TO INUM POPJ P, ;$$ INTPRP: SKIPN A SKIPA A,LSPRMP EXCH A,LSPRMP# ;$$ EXCHANGE FOR OLD TOP LEVEL PROMPT POPJ P, ;$$ READP: SKPINC ;$$ T IFF A CHARACTER HAS BEEN TYPED JRST FALSE ;$$ (DOES NOT CHECK OLDCH) JRST TRUE UNTYI: MOVEI B,-INUM0(A) ;$$ UN-READ A CHARACTER (PUT IT IN OLDCH) MOVEM B,OLDCH POPJ P, ;$$ RETURN ARG AS VALUE PAGE ;output ITYO: SUBI A,INUM0 PUSHJ P,TYO JRST FIXI TYO: CAIG A,CR JRST TYO3 SOSGE CHCT JRST TYO1 JRST TYOD REMOTE TYO1: PUSH P,A ;linelength exceeded MOVEI A,IGCRLF ;inored cr-lf PUSHJ P,TYOD PUSHJ P,TERPRI ;force out a cr-lf, with special mark POP P,A SOSA CHCT TYO4: POP P,B JRST TYOD TYO3: CAIGE A,TAB JUMPN A,TYO+2 ;everything between 0(null) and 11(tab) decrement chct PUSH P,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 JRST TYO4 LINELENGTH: JUMPE A,LINEL1 SUBI A,INUM0 HRRM A,LINL HRRM A,CHCT LINEL1: HRRZ A,LINL JRST FIXI CHRCT: MOVE A,CHCT JRST FIXI REMOTE< LINL: TTYLL CHCT: TTYLL> ;teletype output TTYO: OUTCHR A ;output single character in a POPJ P, PAGE REMOTE DDTIN: EXCH A,DDTIFG POPJ P, TTYRET: PUSHJ P,OUTCNT JRST INCNT ;THIS IS THE NEW, FAST, AND SHORT ROUTINE TO TURN OFF CONTROL O TTYCLR: SKPINL ;## SKPINL FIXES RUBOUT PROBLEM IN TYPE AHEAD JFCL POPJ P, REMOTE< TTOCH: 0 IFN STPGAP,< 0 ;tty page number always zero 0 ;tty line number -- always zero > TTOLL: TTYLL TTOHP: TTYLL> PAGE SUBTTL INPUT AND OUTPUT INITIALIZATION AND CONTROL ;convert ascii to sixbit for device initialization routines SIXMAK: SETZM SIXMK2# MOVE AR1,[POINT 6,SIXMK2] HRROI R,SIXMK1 PUSHJ P,PRINTA ;use print to unpack ascii characters MOVE A,SIXMK2 POPJ P, SIXMK1: ADDI A,40 TLNN AR1,770000 POPJ P, ;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 AR1,(POINT 6,0,29) ;deposit : in last char position IDPB A,AR1 POPJ P, ;subroutine to process next item in file name list INXTIO: JUMPE T,NXTIO HRRZ T,(T) NXTIO: HLRZ A,(T) PUSHJ P,ATOM JUMPE A,CPOPJ ;non-atomic HLRZ A,(T) JRST SIXMAK ;make sixbit if atomic ;right normalize sixbit LSH A,-6 SIXRT: TRNN A,77 JRST .-2 POPJ P, PAGE ;## SUBROUTINE TO TEST FOR A DEVICE OR QUEUE. USED BY I/O ROUTINES ;## AND THE QUEUE ROUTINES. LEAVES A=0 IF NOT AN ATOM AND B=0 ;## DEVICE OR QUEUE. DEVCHK: PUSHJ P,NXTIO ;## MAKE SIXBIT IF AN ATOM LDB B,[POINT 6,A,35];## GET LAST CHAR CAIN B,':' ;## DEVICE? TRZA A,77 ;## YES, CLEAR CHAR BUT LEAVE B INTACT SETZ B, ;## NO, CLEAR B POPJ P, ;## DONE, IF A=0 OR B=0, NOT A DEVICE ;## SUBROUTINE TO PARSE THE I/O SPECIFICATION. DEFAULT IS DSK IF ;## NO DEVICE SPECIFIED. IOSUB: MOVEM T,DEVDAT# ;## SAVE ARG FOR ERRORS SKIPE DEV ;## DEVICE ALREADY SPECIFIED? JRST IOSUB1 ;## YES, FORGET DEFAULT SETZM PPN ;## CLEAR PPN MOVSI A,'DSK' ;## STORE DSK AS DEFAULT MOVEM A,DEV IOSUB1: PUSHJ P,DEVCHK ;## SEE IF DEVICE SPECIFIED JUMPE A,IOPPN ;## NON-ATOMIC ARG, MUST BE PPN OR (FILE.EXT) JUMPE B,IOFIL ;## NOT A DEVICE, MUST BE FILE NAME SETZM PPN IODEV2: MOVEM A,DEV IODEV3: PUSHJ P,INXTIO IOPPN: JUMPN A,IOFIL ;not ppn or (fil.ext) PUSHJ P,PPNEXT JUMPN A,IOEXT ;(fil.ext) HLRZ A,(T) PUSHJ P,CNVPPN ;## CONVERT PPN MOVEM A,PPN JRST IODEV3 ;%% DON'T ZAP DEVICE NAME FOR PPN IOFIL: JUMPN A,IOFIL2 ;was it an atom JUMPE T,CPOPJ ;no, was it nil (end) PUSHJ P,PPNEXT JUMPE A,CPOPJ ;see a ppn, no file named IOEXT: HLRZ A,(T) ;(file.ext) HRRZ A,(A) ;get cdr == extension PUSHJ P,SIXMAK HLLM A,EXT HLRZ A,(T) HLRZ A,(A) ;get car = file name PUSHJ P,SIXMAK FIL: PUSH P,A PUSHJ P,INXTIO JRST POPAJ IOFIL2: CAIN B,":"-40 POPJ P, ;saw a :,not file name SETZM EXT ;file name -- clear extension JRST FIL PPNEXT: JUMPE T,CPOPJ ;end of file name list HLRZ A,(T) HRRZ A,(A) ;cdar JRST ATOM ;ppn iff (not(atom(cdar l))) CHNSUB: MOVE T,A HLRZ A,(T) PUSHJ P,ATOM JUMPE A,TRUE ;non-atomic head of list -- no channel named HLRZ A,(T) PUSHJ P,SIXMAK ANDI A,77 CAIN A,":"-40 JRST TRUE ;device name, assume channel name t HLRZ A,(T) ;channel name -- return it HRRZ T,(T) POPJ P, ;## LEFT HALF OF A CHANNEL TABLE ENTRY IS THE REMAINING ;## FILE LIST. RH POINTS TO EXTENDED HEADER. REMOTE< CHTAB=.-FSTCH BLOCK NIOCH> PAGE ;search for channel name in chtab TABSR1: MOVE A,[XWD -NIOCH,FSTCH] MOVE C,CHTAB(A) CAME B,CHNAM(C) AOBJN A,.-2 CAMN B,CHNAM(C) POPJ P, ;found it!!! JRST FALSE ;lost ;search for channel name in chtab, and if not there find a free channel, and ;if no free channel, allocate a new buffer and channel TABSRC: MOVE B,A PUSHJ P,TABSR1 JUMPN A,DEVCLR ;found the channel PUSH P,B MOVE B,0 PUSHJ P,TABSR1 ;find a physical channel no. for a free channel JUMPE A,[ERR1 [SIXBIT $NO I/O CHANNELS LEFT !$]] POP P,B JUMPN C,DEVCLR ;found free channel which had buffer space previously PUSH P,A ;must allocate new buffer MOVEI A,BLKSIZ SETZ D, ;SPECIAL RELOCATION - SEE LOAD PUSHJ P,MORCOR ;expand core for buffer if necessary MOVE C,A POP P,A HRRM C,CHTAB(A) DEVCLR: HRRZ C,CHTAB(A) HRRZM B,CHNAM(C) ;store name HRRZM A,CHANNEL# POPJ P, ;subroutine to reset all i/o channels -- used by excise and realloc IOBRST: HRRZ A,JOBREL HRLM A,JOBSA MOVEM A,CORUSE# MOVEM A,JOBSYM SETZM CHTAB+FSTCH MOVE A,[XWD CHTAB+FSTCH,CHTAB+FSTCH+1] BLT A,CHTAB+NIOCH+FSTCH-1 ;clear channel table JRST (R) PAGE INPUT1: PUSHJ P,CHNSUB ;determine channel name MOVEI AR1,(A) ;## SAVE CH NAME EXCH AR1,(P) ;## EXHANGE WITH RETURN ADDR PUSH P,AR1 ;## AND STUFF THE RETURN ADDR. IN INPUT2: PUSHJ P,TABSRC ;## GET PHYSICAL CHANNEL NUMBER MOVEM A,CHANNEL ;## SAVE IT SETZM DEV ;## CLEAR DEV SO THAT WE CAN ;## DEFAULT IF APPROPRIATE JRST SETIN1 ;## SET UP FOR INITIALIZTION INPUT: PUSHJ P,INPUT1 PUSHJ P,ININIT INFAIL: JUMPE A,AIN.7 ;## CAN'T FIND FILE JRST POPAJ BINPUT: PUSHJ P,INPUT1 ;## IMAGE BINARY INPUT PUSHJ P,BNINIT JRST INFAIL ISFILE: JUMPE A,.+5 ;## ROUTINE TO TELL USER IF A FILE EXISTS PUSH P,A ;## SAVE A IF NON-NIL MOVEI A,(B) ;## GET THE FILE NAME PUSHJ P,NCONS ;## (FILNAM) POP P,B ;## GET THE DEVICE BACK PUSHJ P,XCONS ;## (DEV FILNAM) OR (FILNAM) WHEN HERE PUSH P,A ;## SAVE IT FOR RETURN PUSHJ P,RENSUB ;## SEE IF IT'S THERE PUSH P,A ;## SAVE THE ANSWER PUSHJ P,RENCLR ;## CLEAR THE CHANNEL POP P,A ;## ANSWER IN A JUMPN A,POPAJ ;## IF NON-NIL, THEN IT'S THERE POP P,B ;## POP ANSWER OFF POPJ P, ;## AND RETURN NIL RENSUB: MOVEM A,DEVDAT ;## SAVE IT FOR ERROR MSGS PUSHJ P,GENSYM ;## DON'T CLOBBER CURRENT CHANNELS MOVE T,DEVDAT ;## GET IT BACK PUSHJ P,INPUT2 ;## SET UP AND OPEN JRST ININIT ;## AND INIT RENAME: PUSHJ P,RENSUB ;## RENAME SETUP JUMPE A,RENCLR ;## NIL IF CAN'T FIND FILE PUSHJ P,SETINA ;## PROCESS THE NEW NAME XCT RNAME ;## EXECUTE JRST RENCLR ;## RETURN NIL IF FAILURE PUSHJ P,RENCLR ;## CLEAR CHANNEL JRST TRUE ;## AND RETURN T IF GOOD REMOTE < RNAME: RENAME X,LOOKIN ;## RENAME FILE > DELERR: PUSHJ P,AIOP PUSHJ P,RENCLR ;## KILL THE CHANNEL ERR1 [SIXBIT /CAN'T DELETE FILE !/] DELETE: PUSHJ P,RENSUB ;## FIRST SETUP(ALLOWS DEFAULT TO DSK:) JRST .+2 ;## ALREADY INIT'ED DELET1: PUSHJ P,ININIT ;## INIT AND LOOKUP JUMPE A,DELET2 ;## IF FILE NOT THERE IGNORE SETZM LOOKIN ;## BLAST FILE NAME SETZM EXT ;## AND EXTENSION XCT RNAME ;## AND RENAME OUT OF EXISTENCE JRST DELERR ;## RENAME FAILURE DELET2: JUMPE T,RENCLR ;## DONE MOVEM T,DEVDAT ;## SAVE REST OF LIST FOR MSGS. PUSHJ P,SETINA ;## PROCESS NEXT FILE JRST DELET1 ;## AND DO IT AGAIN RENCLR: PUSH P,CHANNEL ;## CLEAR CHANNEL SETO B, ;## FAKE (INC RENCHANNEL T) PUSHJ P,IOSEL ;## RELEASE THE CHANNEL JRST POPAJ ;## RETURN NIL (IOSEL CHANGED THINGS) ;## TO LOOK UP A UFD FOR DIRECTORY FNS. SUBR UFDINP: PUSH P,A MOVEI T,(B) PUSHJ P,TABSRC MOVEM A,CHANNEL ;## HAVE A CHANNEL MOVE A,[XWD 'DSK','UFD'] HRLZM A,EXT HLLZM A,DEV SETZ B, AOBJP B,.+1 ;## UFD'S SHOULD BE ON [1,1] MOVEM B,PPN SKIPN A,T PUSHJ P,MYPPN ;## IF B=NIL, DEFAULT TO USER'S PPN MOVEM A,DEVDAT PUSHJ P,CNVPPN ;## CONVERT PPN SETZ T, ;## ZAP T (NO MORE FILES) PUSHJ P,SETIN2 ;## SETUP PUSHJ P,BNINIT ;## INIT AS BINARY JUMPE A,ERR ;## ERR NIL IF NOT THERE PUSHJ P,ININBF ;## SET UP BUFFERS JRST POPAJ ;## RETURN CHANNEL MYPPN: GETPPN A, ;## GET PPN CAI ;## WIERD SKIP RETURN ON THIS UUO HLRZ C,A ;## ASSUME PPN'S ARE INUMS HRRZI A,INUM0(A) ;## CONVERT PUSHJ P,NCONS HRRZI B,INUM0(C) JRST XCONS ;## (PROJ PRGRM) CNVPPN: MOVS A,(A) ;## ASSUME PPNS INUMS HRRI A,-INUM0(A) ;## LH=CDR, RH=CAR MOVSS A ;## SWAP HALVES HLR A,(A) ;## RH=CADR NOW HRRI A,-INUM0(A) POPJ P, SETINA: MOVE A,CHANNEL ;## FOR ROUTINES THAT PROCESS MORE HRRZ C,CHTAB(A) ;## AND KEEP THE CHANNEL IN CHANNEL SETIN: MOVEM A,CHANNEL MOVE A,CHDEV(C) MOVEM A,DEV MOVE A,CHPPN(C) MOVEM A,PPN SETIN1: PUSHJ P,IOSUB ;get device and file name SETIN2: MOVEM A,LOOKIN ;file name MOVE A,DEV MOVEM A,BDEV ;## ALLOW IMAGE BINARY MODE CALLI A,DEVCHR TLNN A,INB JRST AIN.2 ;not input device TLNN A,AVLB JRST AIN.4 ;not available MOVE A,CHANNEL DPB A,[POINT 4,ININIT,ACFLD] ;set up channel numbers DPB A,[POINT 4,BNINIT,ACFLD] ;## FOR IMAGE BINARY DPB A,[POINT 4,RNAME,ACFLD] ;## FOR RENAME DPB A,[POINT 4,INLOOK,ACFLD] DPB A,[POINT 4,ININBF,ACFLD] HLLZS EXT ;%% CLEAR RIGHT HALF SETZM LOOKIN+2 ;%% CLEAR THIRD WORD HRRZ B,CHTAB(A) HRLM T,CHTAB(A) ;save remaining file name list MOVEI A,CHDAT(B) MOVEM A,DEV1 ;pointer to bufdat MOVEM A,BDEV1 ;## IMAGE BINARY MODE POPJ P, ;## SET UP FOR INITIALIZTION REMOTE< BNINIT: INIT X,13 ;## INIT DEVICE IN IMAGE BINARY BDEV: X BDEV1: X JRST AIN.7 ;## CAN'T INIT JRST INITOK ININIT: INIT X, DEV: X DEV1: X JRST AIN.7 ;cant init INITOK: PUSH B,DEV PUSH B,PPN INLOOK: LOOKUP X,LOOKIN JRST FALSE ;## LET SOMEONE ELSE HANDLE THE ERROR JRST IRET1> IRET1: PUSH B,[0] ;oldch IFN STPGAP,< PUSH B,[0] ;line number PUSH B,[0] ;page number > ADDI B,4 HRRM B,JOBFF JRST ININBF REMOTE< ININBF: INBUF X,NIOB JRST TRUE ;## RETURN FROM GOOD LOOKUP WITH T ENTR: LOOKIN: BLOCK 4 EXT=LOOKIN+1 PPN=LOOKIN+3 > PAGE OUTPUT: PUSHJ P,CHNSUB ;get channel name PUSH P,A TRO A,400000 ;set bit for output PUSHJ P,TABSRC ;get physical channel nuber SETZM DEV ;## CLEAR DEV FOR DEFAULT TO DSK: PUSHJ P,IOSUB ;get device and file name MOVEM A,ENTR ;file name HLLZS ENTR+1 ;%% CLEAR RIGHT HALF SETZM ENTR+2 ;zero creation date MOVE A,CHANNEL DPB A,[POINT 4,AOUT2,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,AOUT3+1 MOVE A,DEV MOVEM A,AOUT3 CALLI A,DEVCHR TLNN A,OUTB JRST AOUT.2 ;not output device TLNN A,AVLB JRST AOUT.4 ;not available JRST AOUT2 REMOTE< AOUT2: INIT X, AOUT3: X X JRST AOUT.4 ;cant init PUSH B,DEV OUTENT: ENTER X,ENTR JRST OUTERR ;cant enter JRST ORET1> ORET1: PUSH B,[LPTLL] ;linelength PUSH B,[LPTLL] ;chrct IFE STPGAP,< ADDI B,4> IFN STPGAP,< ADDI B,6> HRRM B,JOBFF XCT OUTOBF REMOTE< OUTOBF: OUTBUF X,NIOB > JRST POPAJ OUTERR: PUSHJ P,AIOP LDB A,[POINT 3,ENTR+1,35] CAIE A,2 ERR1 [SIXBIT /DIRECTORY FULL !/] ERR1 [SIXBIT /FILE IS WRITE PROTECTED !/] PAGE IOSEL: MOVE C,-1(P) JUMPE C,CPOPJ ;tty JUMPE B,IOSELZ ;dont release IOSEL1: DPB C,[POINT 4,RLS,ACFLD] XCT RLS REMOTE< RLS: RELEASE X, ;release channel > HRRZS CHTAB(C) ;release channel table entry MOVEM 0,@CHTAB(C) ;blast channel name SETZM -1(P) IOSELZ: HRRZ C,CHTAB(C) POPJ P, PAGE INCNT: MOVEI A,NIL ;(INC NIL T) MOVEI B,TRUTH(S) INC: PUSH P,INCH# PUSHJ P,IOSEL JUMPN B,INC2 ;released channel SKIPN C MOVEI C,TTOCH-CHOCH ;tty deselect IFN STPGAP,< MOVEI B,CHOCH(C) HRLI B,OLDCH BLT B,CHLINE(C) ;save channel data > IFE STPGAP,< MOVE B,OLDCH MOVEM B,CHOCH(C) > JRST INC2+1 INC2: SETZM INCH ;CLEAR CHANNEL NOW IN CASE OF BREAK JUMPE A,ITTYRE ;select tty MOVE B,A PUSHJ P,TABSR1 ;determine physical channel number JUMPE A,[ERR1 [SIXBIT/NO INPUT - INC!/]] HRRZM A,INCH DPB A,[POINT 4,TYI2X,ACFLD] ;set up channel numbers DPB A,[POINT 4,TYI2Y,ACFLD] DPB A,[POINT 4,TYI2Z,ACFLD] HRRZ A,CHTAB(A) MOVEI T,COUNT(A) HRLI T,(SOSG) MOVEI B,POINTR(A) HRRM B,TYI3 ;set up tyi parameters HRRM B,TYI3A INC3: IFN STPGAP,< MOVSI B,CHOCH(A) HRRI B,OLDCH BLT B,LINUM ;restore channel data > IFE STPGAP,< MOVE B,CHOCH(A) MOVEM B,OLDCH > MOVEM T,TYI2 IOEND: POP P,A JUMPE A,CPOPJ MOVE A,CHTAB(A) ;get channel name HRRZ A,(A) TRZ A,400000 ;clear output bit POPJ P, ITTYRE: SETZM INCH MOVE T,[JRST TTYI] ;reselect tty MOVEI A,TTOCH-CHOCH JRST INC3 PAGE OUTCNT: MOVEI A,0 ;(outc nil t) MOVEI B,1 OUTC: PUSH P,OUTCH# PUSHJ P,IOSEL JUMPN B,OUTC2 ;closed this file SKIPN C MOVEI C,TTOLL-CHLL ;tty deselect MOVE B,CHCT MOVEM B,CHHP(C) ;save channel data MOVE B,LINL MOVEM B,CHLL(C) JRST OUTC2+1 OUTC2: SETZM OUTCH ;CLEAR CHANNEL NOW IN CASE OF BREAK JUMPE A,OTTYRE ;return to tty TRO A,400000 ;set output bit MOVE B,A PUSHJ P,TABSR1 ;determine physical channel number JUMPE A,[ERR1 [SIXBIT /NO OUTPUT - OUTC!/]] DPB A,[POINT 4,TYO2X,ACFLD] ;set up tyo2 channel numbers HRRZM A,OUTCH HRRZ A,CHTAB(A) MOVEI B,POINTR(A) HRRM B,TYO5 ;set up tyo2 parameters MOVEI T,COUNT(A) HRLI T,(SOSG) OUTC3: MOVE B,CHLL(A) MOVEM B,LINL MOVE B,CHHP(A) MOVEM B,CHCT MOVEM T,TYOD JRST IOEND OTTYRE: SETZM OUTCH MOVE T,[JRST TTYO] MOVEI A,TTOLL-CHLL ;tty reselect JRST OUTC3 PAGE AIN.1: PUSHJ P,AIOP ERR1 [SIXBIT $ILLEGAL I/O ARG!$] AOUT.2: AIN.2: PUSHJ P,AIOP ERR1 [SIXBIT /ILLEGAL DEVICE!/] AOUT.4: AIN.4: PUSHJ P,AIOP ERR1 [SIXBIT /DEVICE NOT AVAILABLE !/] AIN.7: PUSHJ P,AIOP ERR1 [SIXBIT /CAN'T FIND FILE - INPUT!/] AIN.8: SIXBIT /INPUT ERROR!/ AIOP: MOVE A,DEVDAT JRST EPRINT PAGE SUBTTL QMANGR INTERFACE ;## CODE TO ALLOW LISP USER'S TO CALL DEC'S QMANGR, ALLOWING ;## PRINTING OF FILES AND CREATION OF JOBS ;## SCANS ARG LIST SETTING UP THE APPROPRIATE PARAMETERS. IT ;## SAVE THE PDLS, SWAPS HI-SEGS FOR SYS:QMANGR AND ;## DOES A PUSHJ TO 400010. IT ALSO CHANGES JOBREN SO ;## THAT THE USER CAN RECOVER IN CASE OF QMANGR ERRORS. ;## ST WILL ALSO STILL WORK. REG 17 (SP) IS USED AS QMANGR'S ;## PDL. CORE IS CONTRACTED AFTER RETURN FROM QMANGR AND QUEUE ;## RESTORES APPROPRIATE REGS AND RETURNS NIL. ALTHOUGH ;## CODE FOR EXTENDED SWITCHES IS INCLUDED, MOST OF ;## IT IS TURNED OFF. USE AT YOUR OWN RISK. NOTE THAT ;## /LIST, /AFTER AND /DEAD REQUIRE SPECIAL CODE ;## THAT IS NOT INCLUDED. SEE APPROPRIATE ;## DEC DOCUMENTATION FOR FURTHER INFO. 6/12/73 IFN QALLOW < IFNDEF QSWEXT ;## IF NOT DEFINED THEN DEFAULT IS NO EXTENDED IFE QSWEXT ;## NUMBER OF ALLOWED SWITCHES IFN QSWEXT ;## LENGTH OF EXTENDED TABLE IFNDEF QLSTOK IFNDEF QTIME ;%% THE FOLLOWING CODE IS AN ILLUSTRATION OF HOW ;%% EASY IT IS TO LOSE TRYING TO INTERFACE TO ;%% DEC SOFTWARE. THE FOLLOWING DEFINITIONS ALLOW ;%% TOO FEW WORDS FOR THE CURRENT FILE PARAMETER ;%% AREA; SEE THE DEFINITIONS AS COPIED FROM ;%% THE QMANGR SOURCE BELOW. COMMENT & INPPAR==32 ;## NUMBER OF WORDS IN INP AREA FOR INPUT REQUEST OUTPAR==24 ;## NUMBER WORDS IN MAIN AREA FOR OUTPUT REQUEST DIFPAR==INPPAR-OUTPAR ;## DIFFERENCE IN LENGTHS FOR MAIN AREA TYPES FILPAR==14 ;## NUMBER WORDS IN FILE PARAMTER AREA ;## LOCATIONS IN PARAMETER AREAS ;## MAIN AREA Q.MEM==0 ;## MEMORY FOR QMANGR Q.OPR==1 ;## REQUESTED OPERATION Q.LEN==2 ;## RH=NUMBER OF FILES IN REQUEST Q.DEV==3 ;## REQUESTED QUEUE Q.PPN==4 ;## PPN REQUESTING Q.JOB==5 ;## JOB NAME Q.SEQ==6 ;## JOB SEQUENCE # Q.PRI==7 ;## EXTERNAL PRIORITY Q.PDEV==10 ;## Q.TIME==11 ;## Q.CREA==12 ;## Q.AFTR==13 ;## AFTER PARAMETER Q.DEAD==14 ;## DEADLINE PARAMETER Q.CNO==15 Q.USER==16 ;## AND 17 ;## INPUT SECTION OF MAIN PARAMETER AREA Q.IDEP==20 ;## RESTART AND DEPENDENCY PARAMTERS Q.ILIM==21 ;## CORE AND CPU, +1 IS LPT LIMIT AND CDP LIMIT ;## +2 IS PTP LIMIT AND PLOT LIMIT Q.IDDI==24 ;## THRU 31 Q.IEND==31 ;## LAST LOC OF INP AREA ;## OUTPUT SEECTION OF MAIN PARAMETER AREA Q.OFRM==20 ;## FORM PARAMTER Q.OSIZ==21 ;## LH=LIMIT Q.ONOT==22 Q.OEND==23 ;## LAST LOC OF OUTPUT AREA ;## FILE PARAMETER AREA (ONE FOR EACH FILE) Q.FSTR==0 ;## FILE STRUCTURE Q.FDIR==1 ;## THRU 6, DIRECTORY Q.FNAM==7 ;## FILE NAME Q.FEXT==10 ;## FILE EXTENSION Q.FRNM==11 ;## RENAME NAME (0) Q.FBIT==12 Q.FMOD==13 ;## SPACING, FILE DISPOSAL, COPIES & ;%% END OF DELETED DEFINITIONS ;%% THE FOLLOWING ARE AS COPIED FROM QMANGR (VERSION 34) ;%% ON 24 OCTOBER 1973 QDEFST==. ;%% WHERE TO RELOC TO AFTERWARDS RELOC 0 ;%% TO SAVE CORE AND AVOID CONFUSION ;%% COMMENTS BELOW ARE AS COPIED ;%% FROM QMANGR PHASE 0 Q.ZER:! ;START OF QUEUE PARAMETER AREA Q.MEM:! BLOCK 1 ;HOLD XWD WINDOW BLOCK,WINDOW WORD INDEX Q.OPR:! BLOCK 1 ;OPERATION CODE QO.CRE==1 ;CREATION OPERATION QO.LST==4 ;LIST OPERATION QO.MOD==5 ;MODIFY OPERATION QO.KIL==6 ;KILL OPERATION QO.DEL==10 ;DELETE OPERATION QO.REQ==11 ;REQUEUE OPERATION QO.FLS==12 ;FAST LIST OPERATION Q.LEN:! BLOCK 1 ;LENGTHS IN AREA Q.DEV:! BLOCK 1 ;DESTINATION DEVICE Q.PPN:! BLOCK 1 ;PPN ORIGINATING REQUEST Q.JOB:! BLOCK 1 ;JOB NAME Q.SEQ:! BLOCK 1 ;JOB SEQUENCE NUMBER Q.PRI:! BLOCK 1 ;EXTERNAL PRIORITY Q.PDEV:! BLOCK 1 ;PROCESSING DEVICE Q.TIME:! BLOCK 1 ;PROCESSING TIME OF DAY Q.CREA:! BLOCK 1 ;CREATION TIME Q.AFTR:! BLOCK 1 ;AFTER PARAMETER Q.DEAD:! BLOCK 1 ;DEADLINE TIMES Q.CNO:! BLOCK 1 ;CHARGE NUMBER Q.USER:! BLOCK 2 ;USER'S NAME Q.I:! ;START OF INPUT QUEUE AREA Q.IDEP:! BLOCK 1 ;DEPENDENCY WORD Q.ILIM:! BLOCK 3 ;JOB LIMITS Q.IL:! ;END OF AREA NEEDED TO READ FOR MASTER QUEUE Q.IDDI:! BLOCK 6 ;JOB'S DIRECTORY Q.II:! ;START OF INPUT FILES AREA PHASE Q.I Q.O:! ;START OF OUTPUT QUEUE AREA Q.OFRM:! BLOCK 1 ;FORMS REQUEST Q.OSIZ:! BLOCK 1 ;LIMIT WORD Q.OL:! ;END OF AREA NEEDED TO READ FOR MASTER QUEUE Q.ONOT:! BLOCK 2 ;ANNOTATION Q.FF:! PHASE 0 Q.F:! ;DUPLICATED AREA FOR EACH REQUESTED FILE Q.FSTR:! BLOCK 1 ;FILE STRUCTURE Q.FDIR:! BLOCK 6 ;ORIGINAL DIRECTORY Q.FNAM:! BLOCK 1 ;ORIGINAL NAME Q.FEXT:! BLOCK 1 ;ORIGINAL EXTENSION Q.FRNM:! BLOCK 1 ;RENAMED FILE NAME (0 IF NOT) Q.FBIT:! BLOCK 1 ;BIT 0=PRESERVED BY QUEUE, REST=STARTING BIT Q.FMOD:! BLOCK 1 ;FILE SWITCHES X.LOG==1B1 ;FILE IS LOG FILE X.NEW==1B2 ;OK IF FILE DOESNT EXIST YET Q.FRPT:!BLOCK 2 ;/REPORT Q.FLEN==.-Q.F DEPHASE PHASE 0 Q.FDRM:! BLOCK 6 ;DIRECTORY MASK FOR MODIFY Q.FNMM:! BLOCK 1 ;FILE NAME MASK FOR MODIFY Q.FEXM:! BLOCK 1 ;EXTENSION MASK FOR MODIFY Q.FMDM:! BLOCK 1 ;MODIFIER MASK FOR MODIFY Q.FMLN==.-Q.F ;LENGTH OF MODIFY BLOCK DEPHASE RELOC QDEFST ;%% MAKE UP FOR INCREASE IN LOCATION ;%% COUNTER INPPAR==Q.II ;%% SIZE OF MINIMUM INPUT AREA OUTPAR==Q.FF ;%% SIZE OF MINIMUM OUTPUT AREA OUTPR1==OUTPAR-1 ;%% MACRO DOESN'T LIKE EXPRESSIONS DIFPAR==INPPAR-OUTPAR ;%% DIFFERENCE IN AREAS FILPAR==Q.FLEN ;%% FILE DATA AREA LOWLEN==^D110 ;## AREA NEED FOR PARAMETER ;## AREA TO QMANGR LHLEN==OUTPR1*1B26+FILPAR ;## LH OF Q.LEN DEFAULTS NQS==6 ;## NUMBER OF QUEUES ;## QUEUE ERRORS QILLSW: HLRZ A,(T) ;## GET SWITCH THAT CAUSED ERROR PUSHJ P,PRINT STRTIP [SIXBIT / =ILL. SWITCH SPEC.!/] PUSHJ P,CONCOR ;## SAVE THAT CORE QERR1: ERR1 [SIXBIT /ERROR IN QUEUE REQUEST!/] QUEUE: SKIPN T,A ;## ERROR IF NO ARGS JRST QERR1 PUSHJ P,DEVCHK ;## SEE IF QUEUE SPECIFIED JUMPE A,NOQUE ;## IF A=0 THEN NOT A QUEUE JUMPE B,NOQUE ;## IF B=0 THEN NOT A QUEUE MOVE AR2A,A HLRZ B,A ;## GET FIRST THREEE LETTERS MOVEI C,NQS ;## GET NUMBER OF PERMISSIBLE QUEUES SOJL C,NOQUE ;## IF EXHAUSTED TABLE, THEN NO QUEUE MOVE A,QSTABL(C) ;## PERMISSIBLE QUEUES JSP R,CHKGO ;## JUMP TO ROUTINE THAT COMPARES RH AND GO ;## TO LH OF A IFF RH(A)=B JRST .-3 ;## LOOP ;## TABLE OF PERMISSIBLE QUEUES AND WHERE TO GO ON EACH QSTABL: XWD INPREQ, 'INP' XWD OUTREQ, 'LPT' XWD OUTREQ, 'PTP' XWD OUTREQ, 'PTP' XWD OUTREQ, 'CDP' XWD OUTREQ, 'PLT' OUTREQ: TDZA A,A ;## HERE TO PROCESS OUTPUT REQUEST(CLEAR A) INPREQ: MOVEI A,DIFPAR ;## HERE TO PROCESS INPUT REQUEST JRST QGOOD ;## FOUND A QUEUE NOQUE: MOVSI AR2A,'LPT' ;## HERE IF NO QUEUE, DEFAULT=LPT TDZA A,A ;## CLEAR A AND SKIP QGOOD: HRRZ T,(T) ;## HERE IF QUEUE SPECIFIED ADDI A,OUTPAR ;## A IS ZERO OR INPPAR QSETUP: PUSH P,B ;## B CONTAINS THREE LETTERS(OR BLANK). SAVE IT HRLZI TT,(A) ;## SAVE LNENGTH OF AREA PUSHJ P,TEMCOR ;## EXPAND CORE HRRI TT,(A) ;## START ADDR OF MAIN AREA MOVE A,TT PUSHJ P,CLRBLK ;## CLEAR AREA MOVEM AR2A,Q.DEV(TT) MOVEI C,LHLEN ;## GET LENGTHS FOR HEADER AND FILE AREAS MOVE A,[XWD 500,500] HRLZM A,Q.OSIZ(TT) ;## ASSUME OUTPUT HERE POP P,B ;## RESTORE LEFT THREE LETTERS CAIE B,'INP' ;## WAS IT AN INPUT REQUEST? JRST QUEUE1 ;## NO SHOULD BE OK ADDI C,DIFPAR_9 ;## UPDATE HEADER LENGTH MOVEM A,Q.ILIM+1(TT) ;## MAX PAGES AND CARD PUNCH MOVEM A,Q.ILIM+2(TT) ;## MAX PAPER TAPE AND PLOTTER HRLI A,^D256 MOVEM A,Q.ILIM(TT) ;## MAX CORE AND CPU(CORMAX MAY HAVE TO BE ;## CHECKED HERE) MOVSI A,400000 ;## SET BIT 0 FOR NOT RESTARTABLE HLLZM A,Q.IDEP(TT) ;## NOT RESTARTABLE(NO DEPEND OR UNIQUENESS) QUEUE1: MOVSM C,Q.LEN(TT) ;## SET HEADER AND FILE AREA LENGTHS GETPPN A, ;## SET REQUESTING PPN CAI ;## WEIRD SKIP RETURN ON THIS UUO MOVEM A,Q.PPN(TT) SETZ REL, ;## CLEAR REG FOR FILE AREA MOVEI A,20 ;## PRIORITY DEFAULT MOVEM A,Q.PRI(TT) AOSA Q.OPR(TT) ;## SET DEFAULT FOR REQUEST TYPE=/CREATE ;## BASIC LOOP FOR HANDLING THE SWITCHES QLOOP: HRRZ T,(T) ;## HERE IF ROUTINE DID NOT MOVE ARG QSELF: JUMPE T,QDONE PUSHJ P,DEVCHK ;## SEE IF DEVICE OR ATOMIC FILE NAME? JUMPN B,QFILEA ;## IF B#0 THEN DEVICE JUMPN A,QFILE ;## IF A#0 THEN ATOMIC FILE HLRZ C,(T) ;## WELL, SEE IF SWITCH HRRZ A,(C) ;## CDAR PUSHJ P,ATOM ;## ATOM? JUMPN A,QFILE ;## YES, THEREFORE(FILE.EXT) HLRZ B,(C) ;## CAAR SUBI B,(S) ;## STRIP OFF RELOCATION HRRZI C,NSWS ;## GET NUMBER OF SWITCHES QLOOP1: SOJL C,QFILE ;## IF NO SWITCH, GO QFILE MOVE A,QTABLE(C) ;## GET MEMBER OF TABLE JSP R,CHKGO JRST .-3 ;## LOOP ;## DISPATCH TABLE FOR SWITCHES QTABLE: PHASE 1 XWD QCOPIE,COPIES ;## /COPIES XWD QCPU,CPU ;## /CPU XWD QFORMS,FORMS ;## /FORMS XWD QLIMIT,LIMIT ;## /LIMIT QTABL1: XWD QDISP,DISP ;## /DISP (FILE DISPOSITION) ;## EXTENDED SWITCHES IFN QSWEXT < IFE QLSTOK IFN QLSTOK IFE QTIME < XWD QILLSW,AFTER ;## /AFTER ILLEGAL (SEE ABOVE) XWD QILLSW,DEAD ;## /DEAD (DEADLINE) > IFN QTIME < XWD QAFTR,AFTER XWD QDEAD,DEAD > XWD QCORE,COREAT XWD QMOD,MODIFY ;## /MODIFY XWD QKILL,KILL ;## /KILL XWD QJOB,JOB ;## /JOB XWD QDEPND,DEPEND ;## /DEPEND XWD QRSTR,RSTRT ;## /RESTART XWD QUNIQ,UNIQUE ;## /UNIQUE XWD QCORE,COREAT ;## /COREE XWD QPAGES,PAGES ;## /PAGES XWD QPLOT,PLOT ;## /PLOT XWD QPTAPE,PTAPE ;## /PTAPE XWD QCARDS,CARDS ;## /CARDS XWD QSEQ,SEQ ;## /SEQ XWD QPRIOR,PRIOR ;## /PRIOR (PRIORITY) XWD QSPACE,SPACE ;## /SPACE (SPACING) XWD QLIMIT,LIMIT ;## /LIMIT QTABL2: XWD QHEAD,HEAD ;## /HEAD (HEADERS) > DEPHASE ;## DISPATCHING THE VARIOUS SWITCHES IFN QSWEXT ;## INPUT QUEUE ONLY SWITCHES ;## PUTS BYTE POINTER INTO B AND THEN CHECKS TO SEE IF SWITCH VALID IN ;## THIS CONTEXT (I.E. ARE WE PROCESSING AN INPUT REQUEST?) ;## IF NOT VALID, SKIPS THE SWITCH(MAY BE CHANGED LATER) IFN QSWEXT < QPLOT: JSP R,RINPCH AOJA B, QCARD+1 QPTAPE: JSP R, LINPCH AOJA B, .+4 QCARDS: JSP R, RINPCH AOJA B, .+4 QPAGES: JSP R, LINPCH AOJA B, .+4 > QCPU: JSP R, RINPCH AOJA B,QARG IFN QSWEXT < QCORE: JSP R, LINPCH AOJA B,QARG QDEPND: JSP R, RINPCH JRST QARG > ;## OUTPUT QUEUE ONLY SWITCHES QFORMS: JSP R, OUTCHK PUSH P,QSXARG ;## CONVERT ARG TO SIXBIT MOVEM A, Q.OFRM(TT) ;## MAKE SIXBIT IF FORMS JRST QLOOP QLIMIT: JSP R, OUTCHK MOVE B,LINP AOJA B,QARG OUTCHK: HLRZ A,Q.DEV(TT) ;## GET REQUEST TYPE (THREE LETTERS) CAIE A,'INP' ;## ERROR IF INPUT REQUEST JRST (R) JRST QILLSW QCOPIE: JSP R, FILECH ;## CHECK IF WE HAVE SET UP A FILE AREA MOVE B,[POINT 6,Q.FMOD(REL),35] ;## BYTE POINTER JRST QARG ;## FOR DISPOSITION, 1=PRESERVE, 2=RENAME, 3=DELETE, ;## FIRST THREE LETTERS OF ARG TO SWITCH UNIQUELY IDENTIFY ;## ILLEGAL ARG CAUSES ERROR QDISP: JSP R,FILECH ;## BE SURE FILE AREA SET UP PUSHJ P,QSXARG ;## MAKE ARG SIXBIT HLRZ C,A ;## GET FIRST THREE LETTERS SETZ A, ;## CLEAR A CAIN C,'DEL' ;## DELETE AFTER OUTPUT! AOJA A,.+2 ;## YES! CAIN C,'REN' ;## RENAME FILE OUT OF UFD? AOJA A,.+3 CAIE C,'PRE' ;## PRESERVE IT JRST QILLSW ;## HERE IF BAD ARGUMENT ADDI A,1 MOVE B, [POINT 3, Q.FMOD(REL), 29] JRST QARG+1 ;## ARG ALREADY IN A ;## HERE WHEN SWITCH DETERMINED AND BITE POINTER IN B QGTARG: MOVEI A,(T) PUSHJ P,CADAR SUBI A,INUM0 ;## ARG SHOULD BE AN INUM POPJ P, QARG: PUSHJ P,QGTARG ;## GET ARGUMENT DPB A,B ;## JRST QLOOP ;## ALWAYS RETURN TO QLOOP ;## HERE TO SEE IF INP QUEUE FOR EXTENDED PART OF MAIN AREA LINPCH: MOVE B,LINP ;## GET LH BITE POINTER CAIA RINPCH: MOVE B,RINP ;## GET RH BITE POINTER HLRZ A,Q.DEV(TT) ;## GET QUEUE SPEC CAIN A,'INP' ;## INP? JRST (R) ;## YES JRST QILLSW LINP: POINT 18, Q.IDEP(TT),17 ;## BYTE POINTER FOR LEFT HALF OF EXTENDED MAIN AREA RINP: POINT 18, Q.IDEP(TT),35 ;## BYTE POINT FOR RH OF EXTENDED MAIN AREA ;## HERE TO BE SURE FILE AREA HAS BEEN SET UP FILECH: JUMPN REL,(R) ;## REL NONZERO IF FILE AREA SET UP PUSH P,R JRST FILARE ;## HERE TO FIND FILE SPECIFICATION QFILEA: HRRZ T,(T) ;## GET CDR SETZ B, ;## CLEAR B JRST QFILEB QFILE: MOVSI A,'DSK' ;## DEFAULT IS DSK CAIE REL,0 ;## AREA SET UP? SKIPA A,Q.FSTR(REL) ;## GET CURRENT DEVICE SKIPA B,Q.PPN(TT) ;## GET USER'S PPN IF NOT SET UP MOVE B,Q.FDIR(REL) ;## GET CURRENT PPN QFILEB: MOVEM B,PPN ;## SET PPN MOVEM A,DEV ;## HANG ON TO DEVICE JUMPE T,QSELF ;## IF NIL THEN DONE PUSHJ P,NXTIO ;## FAKE IOSUB SEQUENCE PUSHJ P,IOPPN PUSH P,A ;## IOPPN RETURNS FILE NAME IN A CAIE REL,0 ;## AREA SET UP? SKIPE Q.FNAM(REL) ;## AREA SET UP, BUT NO FILE NAME?(PRECEDING SWITCHES) PUSHJ P,FILARE ;## SET UP AREA MOVE A,DEV ;## GET DEVICEE MOVEM A,Q.FSTR(REL) ;## SET FILE STRUCTURE MOVE A,EXT ;## GET EXTENSION MOVEM A,Q.FEXT(REL) ;## SET IT MOVE A,PPN ;## GET PPN MOVEM A,Q.FDIR(REL) ;## SET IT(DIRECTORY) POP P,Q.FNAM(REL) ;## RESTORE NAME JRST QSELF ;## T HAS BEEN RESET BY IO ROUTINES! ;## HERE TO SET UP FILE AREA FILARE: AOS Q.LEN(TT) ;## ADD ONE TO NUMBER FILES IN REQUEST HRLZI A,FILPAR ADD TT,A ;## ADD TO LENGTH OF PARAMETER AREA HRRZI A,FILPAR PUSHJ P,EXPCOR JUMPE REL,FILDEF ;## SET DEFAULST IF NO PREVIOUS FILE AREA HRL A,REL HRRZI B,(A) ;## SET UP FOR BLT OF PREVIOUS AREA ADDI B,FILPAR-1 ;## FINAL DESTINATION ADDRESS HRRZI REL,(A) ;## NEW FILE AREA BLT A,(B) SETZM Q.FNAM(REL) POPJ P, FILDEF: HRRZI REL,(A) HRLI A,FILPAR PUSHJ P,CLRBLK HRLZI A,'DSK' MOVEM A,Q.FSTR(REL) MOVE A,[EXP 1B5+1B20+1B26+1B29+1] ;## DEFAULTS FOR Q.FMOD MOVEM A,Q.FMOD(REL) POPJ P, ;## HERE WHEN FINISHED QDONE: MOVE AR1,OUTPAR+Q.FNAM(TT) ;## GET FIRST FILE NAME HLRZ A,Q.DEV(TT) ;## GET FIRST THREE LETTERS OF Q AGAIN CAIE A,'INP' ;## INPUT QUEUE? JRST QDONEB ;## NO MOVE AR1,INPPAR+Q.FNAM(TT) ;## GET CORRCT FILE NAME HRRZ A,Q.LEN(TT) ;## GET NUMBER OF FILES SPECIFIED SOJG A,QDONEC ;## GREATER THAN ONE MEANS THAT USER ;## SPECIFIED A LOG FILE PUSHJ P,FILARE ;## WE HAVE TO SET UP LOG FILE HRRZI A,'LOG' ;## CHANGE EXTENSION TO .LOG HRLZM A,Q.FEXT(REL) MOVEM AR1,Q.FNAM(REL) ;## SET TO INP FILE NAME QDONEC: HRRI A,3 DPB A,[POINT 2,INPPAR+FILPAR+Q.FMOD(TT),2];## SET BITS ;## INDICATING LOG FILE AND DOESN'T EXIST ;## (AVOIDS ERROR MSGS FROM QMANGR) ;## IN SECOND FILE IN CASE USER STUPIDLY SET ;## UP MORE THAN TWO QDONEB: SKIPE Q.JOB(TT) ;## SPECIFIED NAME JRST QDONE1 ;## YES, DONE MOVEM AR1,Q.JOB(TT) QDONE1: MOVE C,[EXP 'QMANGR'];## SEGMENT NAME MOVEI B,400010 MOVE A,TT PUSHJ P,NEWHI PUSHJ P,CONCOR ;## CONTRACT CORE JRST FALSE ;## RETURN NIL ;## ROUTINE TO SWAP HI-SEGMENTS. REGISTER A CONTAINS ARG TO NEXT HI-SEG, B CONTAINS ;## LOCATION TO JUMP TO IN NEW HI-SEG. REGS ARE ARG BLOCK TO GETSEG UUO ;## TO THE GET SEG NEWHI: PUSH P,SP ;## HAVE TO SAVE SP, SINCE MOST ;## SYSTEM PROGS USE 17 FOR THEIR PDL MOVEM A,HIARGS# ;## SAVE ARG TO HI-SEG HRRZM B,HIADDR# ;## SAVE ADDR TO HI-SEG PUSH P,JOBFF ;%% SAVE OLD VALUE ;%% (DON'T ASK WHY) HLRZ B,A ;%% CALCULATE NEW VALUE ADDI B,1(A) ;%% MOVEM B,JOBFF ;%% RESET SO QMANGR WON'T WRITE ;%% OVER ARGUMENT BLOCK. ;%% JUST BECAUSE LISP IGNORES JOBFF ;%% DOESN'T MEAN ANYONE ELSE DOES MOVEM P,PSAVE# ;## SAVE P (CAN'T USE SP) MOVE SP,P ;## USE RPDL HRRZI A,OLDHI ;## REE WILL RESTORE AND CONTINUE MOVEM A,JOBREN MOVEM A,JOBREN ;## SET FAKE REE ADDRESS HRLZI B,'SYS' ;## SYS: IS LOCATION OF NEW HI-SEG MOVEI A,B ;## B IS STARTING LOCATION OF BLOCK TO GETSEG SETZB AR1,AR2A ;## CLEAR REST OF BLOCK SETZB T,TT ;## DITTO MOVEM SP,SAVSP# ;## SAVE SP AROUND GETSEG (WHICH CLOBBERS ACS) JRST NEWHI1 ;## GO DO IT ;## HERE TO GET THAT HI-SEG REMOTE < NEWHI1: CALLI A,GETSEG JRST @JOBREN ;## FAILED JOBREN HAS LOC OF RESTORE LISP HI-SEG MOVE SP,SAVSP MOVE A,HIARGS PUSHJ SP,@HIADDR ;## JUMP TO HI-SEG OLDHI: MOVEI A,HGHDAT CALLI A,GETSEG HALT ;## YOU'RE DEAD IF YOU ARE HERE ENDHI: JRST RESTOR ;## JUMP TO RESTORE THINGS > RESTOR: MOVE P,PSAVE POP P,JOBFF ;%% RESTORE OLD VALUE POP P,SP MOVE 0,STNIL MOVE S,ATMOV HRRZI A,DEBUGO MOVEM A,JOBREN POPJ P, TEMCOR: HRRZ B,CORUSE ;## GET CURRENT CORUSE. THIS ROUTINE EXPANDS CORE ;## BUT SAVE INFO SO THAT IT CAN BE CONTRACTED LATER HRL B,JOBREL ;## GET CURRENT CORE EXTENT MOVEM B,OLDCU ;## SAVE IT (SEE LOADER INTERFACE) EXPCOR: SETZ D, ;## D IS A RELOC REG JRST MORCOR ;## EXPAND CORE CONCOR: MOVS B,OLDCU ;## CONTRACTS CORE, OPPOSITE TEMCOR HLRZM B,CORUSE HRRZI B,(B) ;## CLEAR LH PUSHJ P,MOVDWN ;## MOVE SYMBOL TABLE CALLI B,CORE ;## CONTRACT (B SHOULD BE UNCHANGED CAI POPJ P, ;## DONE QSXARG: MOVEI A,(T) PUSHJ P,CADAR ;## GET ARGUMENT TO SWITCH JRST SIXMAK ;## CONVERT IT TO SIXBIT CLRBLK: SETZM (A) ;## CLEAR FIRST WORD HLRZ B,A ;## LH OF A CONTAINS LENGTH ADD B,A HRL A,A AOJ A, ;## RH NOW CONTAINS SOURCE+1 BLT A,-1(B) ;## BLT CLEARS BLOCK POPJ P, ;## PICKUP CHKGO: CAIN B,(A) ;## SEE IF RH(A)=(B) HLRZ R,A ;## WHERE TO GO JRST (R) ;## NO, RETURN > PAGE SUBTTL PRINT EPRINT: SKIPN ERRSW POPJ P, PUSHJ P,ERRIO PUSHJ P,PRINT JRST OUTRET PRINT: MOVEI R,TYO PUSHJ P,TERPRI PUSHJ P,PRIN1 XCT " ",CTY POPJ P, PRINC: SKIPA R,.+1 PRIN1: HRRZI R,TYO PUSH P,A PUSHJ P,PRINTA JRST POPAJ PRINTA: PUSH P,A MOVEI B,PRIN3 SKIPGE R MOVEI B,PRIN4 HRRM B,PRIN5 PUSHJ P,PATOM JUMPN A,PRINT1 XCT "(",CTY PRINT3: HLRZ A,@(P) PUSHJ P,PRINTA HRRZ A,@(P) JUMPE A,PRINT2 MOVEM A,(P) XCT " ",CTY PUSHJ P,PATOM JUMPE A,PRINT3 XCT ".",CTY XCT " ",CTY PUSHJ P,PRIN1A PRINT2: XCT ")",CTY JRST POPAJ PRINT1: PUSHJ P,PRIN1A JRST POPAJ PAGE PRIN1A: MOVE A,-1(P) CAILE A,INUMIN JRST PRINIC JUMPE A,PRIN1B CAIGE A,@GCP1 CAIGE A,@GCPP1 JRST PRINL PRIN1B: HRRZ A,(A) JUMPE A,PRINL HLRZ B,(A) HRRZ A,(A) CAIN B,PNAME(S) JRST PRINN CAIN B,FIXNUM(S) JRST PRINI1 CAIN B,FLONUM(S) JRSTF @[XWD 0,PRINO] ; TURN OFF DIVIDE CHECK AND UNDERFLOW BPR: JRST PRIN1B ;bignums change here to JRST BPRINT JRST PRIN1B PRINL2: MOVEI R,TYO JRST PRINL1 PRINL: XCT "#",CTY HRRZ A,-1(P) PRINL1: MOVEI C,8 JRST PRINI3 PRINI1: SKIPA A,(A) PRINIC: SUBI A,INUM0 HRRZ C,VBASE(S) SUBI C,INUM0 JUMPGE A,PRINI2 XCT "-",CTY MOVNS A PRINI2: MOVEI B,"."-"0" HRLM B,(P) CAIN C,TEN SKIPE %NOPOINT(S) JRST .+2 PUSH P,PRINI4 PRINI3: JUMPL A,[ MOVEI B,0 ;case of -2^35 MOVEI A,1 DIVI A,(C) JRST .+2] IDIVI A,0(C) HRLM B,(P) SKIPE A PUSHJ P,.-3 PRINI4: JRST FP7A1 PRINN: HLRZ A,(A) MOVEI C,2(SP) PUSHJ P,PNAMU3 PUSH C,[0] HRLI C,(POINT 7,0,35) HRRI C,2(SP) ILDB A,C JUMPE A,CPOPJ ;special case of null character CAIN A,DBLQT JRST PSTR ;string PRIN2X: LDB B,[POINT 1,CHRTAB(A),1] JUMPL R,PRIN4 ;never slash JRST PRIN2(B) ;1 for no slash PRIN3: SKIPL CHRTAB(A) ;<0 for no slash PRIN2: XCT "/",CTY PRIN4: PUSHJ P,(R) ILDB A,C JUMPN A,@PRIN5# POPJ P, PSTR: MOVS B,(C) CAIN B,() JRST PRIN2X ;special case of /" PSTR3: SKIPL R ;dont print " if no slashify PSTR2: PUSHJ P,(R) ILDB A,C CAIE A,DBLQT JUMPN A,PSTR2 JUMPN A,PSTR3 POPJ P, TERPRI: PUSH P,A MOVEI A,CR PUSHJ P,TYO MOVEI A,LF PUSHJ P,TYO JRST POPAJ CTY: JSA A,TYOI REMOTE< TYOI: X JRST TYOI2> TYOI2: PUSH P,A LDB A,[POINT 6,-1(A),ACFLD] PUSHJ P,(R) POP P,A JRA A,(A) PRINO: MOVE A,(A) CLEARB 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 CLEARM FPTEM# PUSHJ P,FP7 XCT ".",CTY MOVNI T,8 ADD T,FPTEM MOVE B,C FP3A: MOVE A,B MULI A,TEN PUSHJ P,FP7B SKIPE B AOJL T,FP3A POPJ P, 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 PUSH P,TT MOVNI B,-2(B) DPB B,[POINT 2,FP4C,34] PUSHJ P,FP3 MOVEI A,"E" PUSHJ P,(R) MOVE A,FP4C# IORI A,51 PUSHJ P,(R) POP P,A FP7: JUMPE A,FP7A1 IDIVI A,TEN AOS FPTEM HRLM B,(P) JUMPE A,FP7A1 PUSHJ P,FP7 FP7A1: HLRE A,(P) FP7B: ADDI A,"0" JRST (R) 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 PAGE SUBTTL SUPER FAST TABLE DRIVEN READ 14-MAY-69 ;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 REMOTE< IGSTRT: IGCRLF IGEND: LF 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 IDCLS==0 ;identifier STRCLS==1 ;string NUMCLS==2 ;number DELCLS==3 ;delimiter PAGE ;macros for scanner table DEFINE RAD50 (X)< IFB , IFLE <"X"-"9">,,> IFIDN <"X"><".">, IFGE <"X"-"A">,> DEFINE TABIN (S1,SN,R,D,S,I,E,RD,R50)< XLIST IRPC R50< RAD50 (R50) BYTE (1)S1,SN(4)R(3)D(2)S(3)I,E,RD(6)R50VAL> LIST> DEFINE LET (X)< TABIN (1,1,5,2,3,4,2,0,X)> 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)> PAGE REMOTE) ;null LET (< >) IGNORE (< >) ;tab,lf,vtab,ff,cr LET (< >) ;16 to 30 TABIN (0,0,0,0,0,0,0,0,< >) ;igmrk TABIN (0,0,0,0,0,0,0,0,< >) ;32 THE OLD IGMRK, WILL ALLOW THE CHAR. TO WORK ON READS BUT NOT TYI IFE ALTMOD-33 < DELIMIT (< >,3) > ;%% NEW ALTMODE (5S06 MONITOR) IFN ALTMOD-33 < LET (< >) > ;%% OLD ALTMODE (5S04 OR EARLIER MONITOR) LET (< >) ;## 34 TO 37 IGNORE (< >) ;space LET (< >) ;! TABIN (0,0,9,2,2,2,2,0,< >) ;" LET (< $% >) ;#$%&' DELIMIT (< >,0) DELIMIT (< >,1) ;() LET (< >) ;* TABIN (1,1,14,2,3,4,2,0,< >) ;+ IGNORE (< >) ;, TABIN (1,1,6,2,3,4,2,0,< >) ;- TABIN (0,0,7,3,3,2,2,4,<.>) TABIN (0,0,4,2,3,3,2,0,< >) ;/ TABIN (1,0,8,5,3,4,3,0,<0123456789>) LET (< >) ;:;<=>? TABIN (1,0,2,2,3,4,2,5,< >) ;@ LET () TABIN (1,1,5,4,3,4,2,0,) LET () DELIMIT (< >,2) ;[ LET (< >) ;\ DELIMIT (< >,3) ;] LET (< >) ;^_` LET () ;lower case LET (< >) ;{| IFE ALTMOD-175 < DELIMIT (< >,3) > ;%% OLD ALTMODE (5S04 MONITOR) IFN ALTMOD-175 < LET (< >) > ;%% } - ORDINARY CHARACTER (5S06 MONITOR) LET (< >) ;~ DELIMIT (< >,6) ;rubout > PAGE READCH: PUSHJ P,TYI MOVSI AR1,AR1 PUSHJ P,EXPL1 JRST CAR READP1: SETZM NOINFG READ0: PUSH P,TYI2 PUSH P,OLDCH SETZM OLDCH# HRLI A,(JRST) MOVEM A,TYI2 PUSHJ P,READ+1 POP P,OLDCH POP P,TYI2 POPJ P, RDNAM: SETOM NOINFG ;## READ ROUTINE THAT DOES NOT INTERN JRST READ+1 ;## RDRUB: MOVEI A,CR PUSHJ P,TTYO MOVEI A,LF PUSHJ P,TTYO SKIPA P,PSAV# READ: SETZM NOINFG# ;0 means intern MOVEM P,PSAV PUSHJ P,READ1 SETZM PSAV POPJ P, READ1: PUSHJ P,RATOM POPJ P, ;atom XCT RDTAB2(B) JRST READ1 ;try again RDTAB2: JRST READ2 ;0 ( JFCL ;1 ) JRST READ4 ;2 [ JFCL ;3 ],$ JFCL ;4 . JRST RDQT ;5 @ READ2: PUSHJ P,RATOM JRST READ2A ;atom XCT RDTAB(B) READ2A: PUSH P,A PUSHJ P,READ2 POP P,B JRST XCONS RDTAB: PUSHJ P,READ2 ;0 ( JRST FALSE ;1 ) PUSHJ P,READ4 ;2 [ JRST READ5 ;3 ],$ JRST RDT ;4 . PUSHJ P,RDQT ;5 @ RDTX: PUSHJ P,RATOM POPJ P, ;atom XCT RDTAB2(B) JRST DOTERR ;dot context error RDT: PUSHJ P,RDTX PUSH P,A PUSHJ P,RATOM JRST DOTERR CAIN B,1 JRST POPAJ CAIE B,3 JRST DOTERR MOVEM A,OLDCH JRST POPAJ READ4: PUSHJ P,READ2 MOVE B,OLDCH CAIE B,ALTMOD TYI1: SETZM OLDCH ;kill the ] POPJ P, READ5: MOVEM A,OLDCH ;save ] or $ JRST FALSE ;and return nil RDQT: PUSHJ P,READ1 JRST QTIFY PAGE ;atom parser COMMENT: PUSHJ P,TYID CAME A,IGEND JRST COMMENT POPJ P, RATOM: SKIPE SMAC# ;$$ CHECK FOR A SPLICE MACRO LIST JRST PSMAC ;$$ GET ITEM FROM SPLICE MACRO LIST SETZB T,R HRLI C,(POINT 7,0,35) HRRI C,(SP) MOVEM C,ORGSTK# ;SAVE FOR BACKING UP ON + AND - MOVEI AR1,1 RATOM2: PUSHJ P,TYIA LDB B,RATFLD JRST RATAB(B) RATAB: PUSHJ P,COMMENT ;0 comment JRST RATOM2 ;1 null JRST RATOM3 ;2 delimit JRST RATOM2 ;3 ignore PUSHJ P,TYI ;4 / JRST RDID ;5 letter JRST RDNMIN ;6 - JRST RDOT ;7 . JRST RDNUM ;8 digit JRST RDSTR ;9 string JRST RMACRO ;10 MACRO JRST SMACRO ;11 SPLICE MACRO JRST RDNPLS ;12 + ;a real dotted pair RDOT2: MOVEM A,OLDCH MOVE A,ORGSGN ;ORGSGN NORMALLY CONTAINS A "." AT THIS POINT RATOM3: LDB B,RDFLD HRRI R,DELCLS ;delimiter AOS (P) ;non-atom (ie a delimiter) POPJ P, ;dot handler RDOT: MOVEM A,ORGSGN ;INCASE SOMETHING ELSE DEFINED AS "." PUSHJ P,TYID LDB B,DOTFLD JRST DOTAB(B) DOTAB: PUSHJ P,COMMENT ;0 comment JRST RDOT+1 ;1 null JRST RDOT2 ;2 delimit JRST RDOT2 ;3 dot JRST RDOT2 ;4 e MOVEI B,0 ;5 digit IDPB B,C TLO T,SAWDOT JRST RDNUM PAGE ;string scanner STRTAB: PUSHJ P,COMMENT ;0 comment JRST RDSTR+1 ;1 null JRST STR2 ;2 delimit RDSTR: IDPB A,C ;3 string element PUSHJ P,TYID LDB B,STRFLD JRST STRTAB(B) STR2: MOVEI A,DBLQT HRRI R,STRCLS ;string IDPB A,C NOINTR: PUSHJ P,IDEND ;no intern PUSHJ P,IDSUB JRST PNAMAK ;identifier scanner IDTAB: PUSHJ P,COMMENT ;0 JRST RDID+1 ;1 null JRST MAKID ;2 delimit PUSHJ P,TYI ;3 / RDID: IDPB A,C ;4 letter or digit PUSHJ P,TYID LDB B,IDFLD JRST IDTAB(B) PAGE ;LINEREAD - RETURNS ALL THE EXPRESSIONS ON ONE LINE AS A LIST ; LINRD: PUSHJ P,READ HRRZ B,A SKIPE SMAC ;CHECK THE SPLICE LIST JRST LRMORE SKIPN A,OLDCH LRTY: PUSHJ P,TYID ;NEED A CHARACTER MOVEM A,OLDCH ;SAVE IT LDB C,RATFLD ;THIS KLUDGE IS TO AVOID MAKING ANOTHER TABLE ENTRY CAIN C,7 ;SPECIAL CHECK FOR "." JRST LRTY1 ;IGNORE IT CAILE C,3 ;ELIMINATE MOST POSSIBILITIES JRST LRMORE ;MORE ON THE LINE JUMPE C,LREND ;END LINE ON COMMENT - THINK ABOUT IT, ITS RIGHT LDB C,RDFLD JRST LR1(C) LR1: JRST LPIG ;0 MORE TO FIGURE OUT JRST LRTY1 ;1 IGNORE JRST LRMORE ;2 MORE ON THE LINE SUBI A,ALTMOD ;3 CHECK ALTMOD JUMPN A,LRTY1 ;4 IGNORE "]" AND "." JUMPN A,LRMORE ;5 MORE ON "@" JRST LREND LPIG: CAIN A,"(" ;THESE SPECIAL CHECK COULD SCREW UP READ MACROS JRST LRMORE CAIE A,TAB CAIL A,40 ;READ MORE IF SPACE, COMMA, OR TAB JRST [ HRLI B,-1 ;SET SPQCE FLAG AND TRY AGAIN JRST LRTY] CAIE A,CR ;ALWAYS IGNORE CR.S TLZE B,-1 ;EOL - IF SPACE FLAG THEN DO A PEEKC JRST LRTY LREND: HRRZ A,B ;FINALLY GOT THERE JRST NCONS LRMORE: HRLI B,0 PUSH P,B ;MORE TO GO, PUSH PUSHJ P,LINRD ;AND CALL YOURSELF POP P,B JRST XCONS LRTY1: HRLI B,0 ;CLEAR SPACE FLAG JRST LRTY PAGE ;## FUNCTIONS TO READ A FILE.EXT ;## READ A FILE.EXT FROM THE UFD FLTYIA: XCT TYI2 ;## GET NEXT WORD, IGNORE OLDCH JRST [SETZ AR1, JRST TYI2X ] ;%% INPUT SOME MORE, CLEARING TEST REG. ILDB A,@TYI3 ;## AND LOAD WORD POPJ P, RDFIL1: PUSHJ P,FLTYIA ;## FILE NAME NOT THERE, SKIP OVER EXT RDFILE: SETZM NOINFG ;## ## INTERN PUSHJ P,FLTYIA ;## GET FILE NAME WORD PUSHJ P,SIXATM ;## MAKE IT AN ATOM JUMPL A,RDFIL1 ;## A=-1 IF EMPTY PUSH P,A PUSHJ P,FLTYIA ;## GET EXTENSION HRRI A,0 ;## CLEAR RH PUSHJ P,SIXATM JUMPL A,POPAJ ;## NO EXTENSION, RETURN POP P,B ;## GET FILE BACK JRST XCONS ;## RETURN FILE.EXT ;## ROUTINE TO TAKE ONE WORD OF SIXBIT AND MAKE IT AN ATOM ;## IGNORES TRAILING BLANKS, BUT INCLUDES INSERTED BLANKS. NO ;## READ MACROS, ETC. SIXATM: SKIPN B,A JRST SXATER ;## INDICATE WORD EMPTY MOVEI T,5 ;## OF CHS PERMISSIBLE IN FULL WORD ;## NAME T=0 IF FIRST WORD DONE MOVE AR1,[POINT 6,B,5] ;## AR1 HAS PTR TO LOAD BYTE ;## FROM B TO C PUSHJ P,SIXAT1 ;## MAKE THE PNAME LIST PUSHJ P,NCONS MOVEI B,PNAME(S) ;## MAKE PNAME PUSHJ P,XCONS PUSHJ P,ACONS ;## VOILA, AN ATOM SKIPE NOINFG ;## NOINFG=0 MEANS INTERN POPJ P, JRST INTERN SXATER: SETO A, ;## RETURN -1 IN A IF B EMPTY POPJ P, SIXAT1: MOVE AR2A,[POINT 7,0,35] ;## POINTER TO MOVE C TO A SETZ A, ;## CLEAR A SIXAT2: SETZ C, JUMPE B,SIXDON ;## DONE IF B EMPTY LDB C,AR1 LSH B,6 ;## LEFT SHIFT B, REMAINING CH'S IN B HRRI C,40(C) ;## ADD 40 TO C IDPB C,AR2A ;## PUT IT IN A SOJG T,SIXAT2 ;## IF T>0, STILL IN FIRST WORD OF PNAME SIXAT3: PUSHJ P,FWCONS PUSH P,A JRST SIXAT1 ;## TRY FOR THAT SIXTH CH. SIXDON: JUMPN A,SIXAT3 ;## IF A NOT EMTPY, DO ANOTHER FWCONS AND ;## END UP HERE WITH A=0. POP P,A PUSHJ P,NCONS JUMPGE T,CPOPJ ;## IF T>=0, THEN ONLY ONE WORD POP P,B JRST XCONS ;## DONE PAGE ;NEW AND SUPER BITCHEN READ MACROS ; RMACRO: IFN ALVINE,< SKIPE PSAV1 ;$$ ARE WE IN ALVINE? JRST RATOM2 ;$$ YES, IGNORE> RMAC2: IDPB A,C ;$$ CONVERT THE CHAR. TO AN ATOM PUSHJ P,IDEND ;$$ PUSHJ P,INTER0 ;$$ MOVEM A,T ;$$ SAVE ATOM IN CASE OF ERROR MOVEI B,READMACRO(S) ;$$ GET THE FUNCTION NAME PUSHJ P,GET ;$$ JUMPE A,RMERR ;$$ UNDEFINED READ MACRO PUSHJ P,NCONS ;$$ CONVERT TO A FORM PUSH P,PSAV ;$$ PUSHJ P,EVAL ;$$ EVALUATE THE FORM POP P,PSAV ;$$ POPJ P, ;$$ RETURN ;SPECIAL PROCESSING OF SPLICE MACROS SMACRO: IFN ALVINE,< SKIPE PSAV1 ;$$ ARE WE IN ALVINE? JRST RATOM2 ;$$ YES, IGNORE> PUSHJ P,RMAC2 ;$$ EVALUATE THE MACRO MOVEM A,SMAC ;$$ SAVE THE SPLICE LIST JRST RATOM ;$$ START OVER ;GET AN ITEM OFF OF THE SPLICE LIST PSMAC: MOVE A,SMAC ;$$ PUSHJ P,ATOM ;$$ IS SPLICE LIST AN ATOM? JUMPN A,[ MOVE A,SMAC ;$$ YES, SIMULATE . PUSHJ P,NCONS ;$$ MOVEM A,SMAC ;$$ MOVEI B,4 ;$$ JRST RATOM3+1] ;$$ MOVE B,@SMAC ;$$ HLRZ A,B ;$$ RETURN NEXT ITEM OF SPLICE LIST HRRZM B,SMAC ;$$ ADVANCE SPLICE LIST POPJ P, ;$$ RETURN PAGE ;number scanner NUMTAB: PUSHJ P,COMMENT ;0 comment JRST RDNUM+1 ;1 null JRST NUMAK ;2 delimit JRST RDNDOT ;3 dot JRST RDE ;4 e RDNUM: IDPB A,C ;5 digit PUSHJ P,TYID LDB B,NUMFLD JRST NUMTAB(B) RDNDOT: TLOE T,SAWDOT JRST NUMAK ;two dots - delimit MOVEI A,0 JRST RDNUM RDNMIN: TLO T,MINSGN RDNPLS: MOVEM A,ORGSGN# ;SAVE SIGN IN CASE OF BACKUP JRST RDNUM+1 ;exponent scanner RDE: CAME C,ORGSTK ;FOR +E AND -E TYPE OF ATOMS JRST .+3 MOVEM A,OLDCH JRST KLDG1 TLO T,EXP MOVEI A,0 IDPB A,C PUSHJ P,TYID CAIN A,"-" TLOA T,NEXP CAIN A,"+" JRST RDE2+1 JRST RDE2+2 EXPTAB: PUSHJ P,COMMENT ;0 JRST RDE2+1 ;1 null JRST NUMAK ;2 delimit RDE2: IDPB A,C ;3 digit PUSHJ P,TYID LDB B,EXPFLD JRST EXPTAB(B) PAGE ;semantic routines ;identifier interner and builder IDEND: TDZA A,A IDEND1: IDPB A,C TLNE C,760000 JRST IDEND1 POPJ P, MAKID: MOVEM A,OLDCH PUSHJ P,IDEND SKIPE NOINFG JRST NOINTR ;dont intern it INTER0: PUSHJ P,IDSUB PUSHJ P,INTER1 ;is it in oblist POPJ P, ;found PUSHJ P,PNAMAK ;not there MAKID2: MOVE C,CURBUC# ; HLRZ B,@RHX2 PUSHJ P,CONS ;cons it into the oblist HRLM A,@RHX2 JRST CAR ;pname unmaker PNAMUK: MOVEI B,PNAME(S) PUSHJ P,GET JUMPE A,NOPNAM MOVE C,SP PNAMU3: HLRZ B,(A) PUSH C,(B) HRRZ A,(A) JUMPN A,PNAMU3 POPJ P, ;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) HRLI C,1(SP) MOVSM C,IDPTR# POPJ P, PAGE ;identifier interner INTER1: MOVE B,1(SP) ;get first word of pname LSH B,-1 ;right justify it IDIV B,INT1 ;compute hash code REMOTE< INT1: BCKETS RHX2: XXX1: XWD B+1,OBTBL> PUSH P,C ;## SAVE C HRRZ C,VOBLIST(S) ;## THIS GETS THE CURRENT VALUE OF OBLIST(THE ATOM) HRRM C,RHX2 ;## ASSUMES THAT ALL REFERENCE TO OBLIST GOES HRRM C,RHX5 ;## IE INTERN, REMOB ETC GOES THROUGH THIS SECTION. POP P,C ;##RHX2 AND RHX5 ARE HOPEFULLY THE ONLY TWO WORDS ;##WHICH ARE USED TO REFERENCE TABLE 3/28/73 HLRZ TT,@RHX2 ;get bucket MOVEM B+1,CURBUC ;save bucket number MOVE T,TT JRST MAKID1 MAKID3: MOVE TT,T ;save previous atom HRRZ T,(T) ;get next atom MAKID1: JUMPE T,CPOPJ1 ;not in oblist HLRZ A,(T) ;next id in oblist MAKID4: MOVEI B,PNAME(S) ;## USE GET FOR GETTING PNAME PUSHJ P,GET ;## (GET ATOM @PNAME) JUMPE A,NOPNAM ;## NO PRINT NAME MOVE C,IDPTR ;found pname MAKID5: JUMPE A,MAKID3 ;not the one MOVS A,(A) MOVE B,(A) ANDCAM AR1,(C) ;clear low bit CAME B,(C) JRST MAKID3 ;not the one HLRZ A,A ;ok so far AOBJN C,MAKID5 JUMPN A,MAKID3 ;not the one HLRZ A,(T) ;this is it HLRZ B,(TT) HRLM A,(TT) HRLM B,(T) POPJ P, PAGE ;pname builder PNAMAK: MOVE T,IDPTR PUSHJ P,NCONS MOVE TT,A MOVE C,A PNAMB: MOVE A,(T) TRZ A,1 ;clear low bit!!!!! PUSHJ P,FWCONS PUSHJ P,NCONS HRRM A,(TT) MOVE TT,A AOBJN T,PNAMB MOVE A,C HRLZS (A) JRST PNGNK1+1 PAGE ;number builder NUMAK: MOVEM A,OLDCH HRRI R,NUMCLS ;number CAME C,ORGSTK ;BIG KLUDGE FOR + AND - JRST .+5 KLDG1: MOVE A,ORGSGN ;ENTER HERE TO BACK UP IN THE CASE OF +E OR -E IDPB A,C PUSHJ P,TYIA JRST RDID+2 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 MOVE A,VIBASE(S) ;ibase integrer SUBI A,INUM0 PUSHJ P,NUM NUMAK4: MOVEI B,FIXNUM(S) NUMAK6: TLNE T,MINSGN MOVNS A JRST MAKNUM NUMAK2: PUSHJ P,NUM10 MOVEM A,TT TLNN T,SAWDOT JRST [ PUSHJ P,FLOAT ;flt pt without fraction MOVE TT,A JRST NUMAK3] PUSHJ P,NUM10 ;fraction part EXCH A,TT TLNN T,EXP JUMPE AR2A,NUMAK4 ;no exponent and no fraction PUSHJ P,FLOAT EXCH A,TT PUSHJ P,FLOAT MOVEI AR1,FT01 PUSHJ P,FLOSUB FMPR A,B FADRM A,TT NUMAK3: PUSHJ P,NUM10 ;exponent part MOVE AR2A,A MOVEI AR1,FT-1 TLNE T,NEXP MOVEI AR1,FT01 ;-exponent PUSHJ P,FLOSUB FMPR TT,B ;positive exponent MOVEI B,FLONUM(S) MOVE A,TT JFCL 10,FLOOV JRST NUMAK6 FLOSUB: MOVSI B,(1.0) TRZE AR2A,1 FMPR B,(AR1) JUMPE AR2A,CPOPJ LSH AR2A,-1 SOJA AR1,FLOSUB+1 ;variable radix integer builder NUM10: MOVEI A,TEN NUM: HRRM A,NUM1 JFCL 10,.+1 ;clear carry0 flag SETZB A,AR2A NUM2: ILDB B,C JUMPE B,CPOPJ ;done IMUL A,NUM1# ADDI A,-"0"(B) NUM3: JFCL 10,FIXOV ;bignums change this to jfcl 10,rdbnm AOJA AR2A,NUM2 PAGE INTERN: MOVEM A,AR2A PUSHJ P,PNAMUK PUSHJ P,IDSUB MOVEI AR1,1 PUSHJ P,INTER1 ;is it in oblist POPJ P, ;found it MOVE A,AR2A ;not there JRST MAKID2 ;put it there REMOB: JUMPE A,FALSE MOVEI AR1,1 PUSH P,A HLRZ A,(A) PUSHJ P,INTERN HLRZ B,@(P) CAME A,B JRST REMOB2 HRRZ B,CURBUC REMOTE< RHX5: XXX2: XWD B,OBTBL> HLRZ C,@RHX5 HLRZ T,(C) CAMN T,A JRST [ HRRZ TT,(C) HRLM TT,@RHX5 JRST REMOB2] REMOB3: MOVE TT,C HRRZ C,(C) HLRZ T,(C) CAME T,A JRST REMOB3 HRRZ T,(C) HRRM T,(TT) REMOB2: POP P,A HRRZ A,(A) JRST REMOB PAGE ;ROUTINE TO ALLOW ARBITRARY MODIFICATION AND READING OF THE ;READ CHARACTER-TABLE BY LISP FUNCTIONS ;TAKES TWO ARGUMENTS A,B ; IF B = NIL IT RETURNS THE CONTENTS OF CHARACTER TABLE ; LOCATION SPECIFIED BY A ; OTHERWISE IT CHANGES THE CHARACTER TABLE ENTRY SPECIFIED BY A ; TO THE BIT PATTERN SPECIFIED BY B, AND RETURNS THE ; PREVIOUS VALUE MODCHR: PUSH P,B ;$$SAVE BIT PATTERN FOR TABLE PUSHJ P,NUMVAL ;$$GET POSITION IN TABLE POP P,B ;$$ MOVE T,CHRTAB(A) ;$$GET OLD TABLE VALUE JUMPE B,MCEXIT ;$$IF B=NIL THEN JUST RETURN OLD TABLE VALUE PUSH P,A ;$$SAVE TABLE POSITION MOVEI A,(B) ;$$ PUSHJ P,NUMVAL ;$$GET NEW BIT PATTERN POP P,B ;$$GET TABLE POSITION MOVEM A,CHRTAB(B) ;$$CHANGE TABLE MCEXIT: MOVE A,T ;$$RETURN OLD TABLE VALUE JRST FIX1A ;$$CONVERT TO BINARY AND EXIT ;FUNCTION TO DETERMINE THE ASCII VALUE OF A CHARACTER ; CHRVAL TAKES AN ATOM AS ITS ARGUMENT AND USES THE FIRST ; CHARACTER OF THE PRINT NAME CHRVAL: MOVEI B,PNAME(S) ;$$ GET PRINT NAME PUSHJ P,GET ;$$ HLRZ A,(A) ;$$ MOVE A,(A) ;$$ FIRST WORD OF PRINT NAME LSH A,-35 ;$$ SHIFT TO GET FIRST CHARACTER JRST FIX1A ;$$ CONVERT TO INTEGER ;FUNCTION TO SET BITS FOR A READ MACRO ; A IS THE CHAR. ATOM AND B ARE THE STATUS BITS, ; IF B=NIL NO MODIFICATION IS MADE ; THE OLD STATUS BITS ARE RETURNED SETCHR: MOVE TT,B ;$$ PUSHJ P,CHRVAL ;$$ CONVERT CHAR. TO INUM MOVEI B,-INUM0(A) ;$$ CONVERT INUM TO BINARY LDB A,[POINT 5,CHRTAB(B),5] ;$$ LOAD OLD BITS JUMPE TT,FIX1A ;$$ NO CHANGE IF B = NIL MOVEI TT,-INUM0(TT) ;$$ CONVERT STATUS TO BINARY DPB TT,[POINT 5,CHRTAB(B),5] ;$$ SET NEW BITS JRST FIX1A ;$$ RETURN PAGE SUBTTL LISP INTERPRETER SUBROUTINES CADDDR: SKIPA A,(A) CADDAR: HLRZ A,(A) CADDR: SKIPA A,(A) CADAR: HLRZ A,(A) CADR: SKIPA A,(A) CAAR: HLRZ A,(A) CAR: HLRZ A,(A) POPJ P, CDDDDR: SKIPA A,(A) CDDDAR: HLRZ A,(A) CDDDR: SKIPA A,(A) CDDAR: HLRZ A,(A) CDDR: SKIPA A,(A) CDAR: HLRZ A,(A) CDR: HRRZ A,(A) POPJ P, CAADDR: SKIPA A,(A) CAADAR: HLRZ A,(A) CAADR: SKIPA A,(A) CAAAR: HLRZ A,(A) JRST CAAR CDADDR: SKIPA A,(A) CDADAR: HLRZ A,(A) CDADR: SKIPA A,(A) CDAAR: HLRZ A,(A) JRST CDAR CAAADR: SKIPA A,(A) CAAAAR: HLRZ A,(A) JRST CAAAR CDDADR: SKIPA A,(A) CDDAAR: HLRZ A,(A) JRST CDDAR CDAADR: SKIPA A,(A) CDAAAR: HLRZ A,(A) JRST CDAAR CADADR: SKIPA A,(A) CADAAR: HLRZ A,(A) JRST CADAR PAGE QUOTE: HLRZ A,(A) ;car and quote duplicated for backtrace POPJ P, AASCII: PUSHJ P,NUMVAL LSH A,^D29 PUSHJ P,FWCONS PUSHJ P,NCONS PNGNK1: PUSHJ P,NCONS MOVEI B,PNAME(S) PUSHJ P,XCONS ACONS: TROA B,-1 NCONS: TRZA B,-1 XCONS: EXCH B,A CONS: AOS CONSVAL HRL B,A SKIPN A,F JRST [ HLR A,B PUSHJ P,AGC JRST .-1] MOVE F,(F) MOVEM B,(A) POPJ P, ;new consing routines-not finished yet ;acons: troa b,-1 ;ncons: trz b,-1 ;cons: exch b,a ;xcons: hrl a,b ; exch a,(f) ; exch a,f ; popj p, CONSP: JUMPE A,CPOPJ ;## DONE IF NIL CAILE A,INUMIN JRST FALSE HLLE B,(A) AOJE B,FALSE IFN NONUSE ;## T IF NONUSEFUL DESIRED IFE NONUSE ;## THE CELL OTHERWISE PATOM: CAIL A,@GCP1 JRST TRUE CAIL A,@GCPP1 ATOM: CAILE A,INUMIN JRST TRUE JUMPE A,TRUE ;## FAST CHECK FOR NIL CAIGE A,@GCP1 ;## LO-END OF FWS, CAN'T ADD TO 0 HLLE A,(A) AOJE A,TRUE JRST FALSE PAGE NEQ: CAMN A,B JRST FALSE JRST TRUE EQ: CAMN A,B JRST TRUE JRST FALSE LENGTH: MOVEI B,0 LNGTH1: CAIE A,NIL ;## DONE IF NIL CAIL A,@FWSO ;## FWSO IS FULL SPACE ORIGIN, ;## ELIMINATE ILL MEM REF JRST FIX1 HLLE C,(A) AOJE C,FIX1 HRRZ A,(A) AOJA B,LNGTH1 LAST: HRRZ B,(A) CAIE B,NIL ;## IF NIL DONE CAIL B,@FWSO ;## ANOTHER POTENTIAL ILL MEM GONE POPJ P, HLLE B,(B) AOJE B,CPOPJ HRRZ A,(A) JRST LAST ;(LITATOM X) = (AND (ATOM X) (NOT (NUMBERP X))) LITATOM:MOVE B,A PUSHJ P,ATOM JUMPE A,CPOPJ MOVE A,B PUSHJ P,NUMBERP JRST NOT PAGE ;NEW RPLACD AND RPLACA WHICH CHECK SO AS NOT TO CLOBBER NIL AND ATOMS RPLACA: CAIE A,NIL ;## TEST FOR NIL CAILE A,INUMIN ;$$ JRST RPAERR ;$$ ATTEMPT TO RPLACA A SMALL NUMBER HLL A,(A) ;$$TEST FOR OTHER ATOMS TLC A,-1 ;$$ TLZN A,-1 ;$$ATOM CARS ARE -1 JRST RPAERR ;$$ATTEMPT TO RPLACA AN ATOM HRLM B,(A) ;$$STANDARD CODE FOR RPLACA POPJ P, ;$$ RPLACD: CAIG A,INUMIN ;$$CHECK FOR SMALL BER JUMPN A,.+2 ;$$CHECK FOR NIL JRST RPDERR ;$$ATTEMPT TO RPLACD NIL OR A SMALL NUMBER HRRM B,(A) ;$$OLD RPLACD CODE POPJ P, ;$$ ZEROP: PUSHJ P,NUMVAL NOT: NULL: JUMPN A,FALSE TRUE: MOVEI A,TRUTH(S) POPJ P, FW0CNS: MOVEI A,0 FWCONS: JUMPN FF,FWC1 EXCH A,FWC0# PUSHJ P,AGC EXCH A,FWC0 FWC1: EXCH A,(FF) EXCH A,FF POPJ P, PAGE SASSOC: PUSHJ P,SAS1 JCALLF 0,(C) POPJ P, SAS0: HLRZ B,T SAS1: JUMPE B,CPOPJ MOVS T,(B) MOVS TT,(T) CAIE A,(TT) JRST SAS0 HRRZ A,T CPOPJ1: AOS (P) POPJ P, ASSOC: PUSHJ P,SAS1 FALSE: MOVEI A,NIL CPOPJ: POPJ P, REVERSE: MOVE T,A MOVEI A,0 JUMPE T,CPOPJ HLRZ B,(T) HRRZ T,(T) PUSHJ P,XCONS JUMPN T,.-3 POPJ P, REMPROP: HRRZ T,(A) MOVS TT,(T) CAIN B,(TT) JRA TT,REMP1 HLRZ A,TT HRRZ T,(A) JUMPN T,REMPROP+1 JRST FALSE REMP1: HRRM TT,(A) JRST TRUE PAGE ;## IF WE ARE USING NEW NIL, THEN GET IS FOR SYSTEM ONLY AND ;## USRGET IS THE USERS. IF NEW NIL, THEN GET MUST GET NIL'S ;## PROPERTY LIST IFE OLDNIL< USRGET: JUMPE A,CPOPJ ;## ALWAYS NIL> GET: IFE OLDNIL< CAIE A,NIL SKIPA A,NILPRP> HRRZ A,(A) GET1: MOVS D,(A) CAIN B,(D) JRST CADR HLRZ A,D HRRZ A,(A) JUMPN A,GET1 POPJ P, GETL: JUMPE B,FALSE ;$$ NIL LIST - NIL ANSWER IFE OLDNIL ;## TEST FOR NIL HRRZ A,(A) GETL0: HLRZ T,(A) MOVE C,B GETL1: MOVS TT,(C) CAIN T,(TT) POPJ P, HLRZ C,TT JUMPN C,GETL1 HRRZ A,(A) HRRZ A,(A) JUMPN A,GETL0 POPJ P, NUMBERP: CAILE A,INUMIN JRST TRUE HLLE T,(A) AOJN T,FALSE HRRZ A,(A) HLRZ A,(A) CAIE A,FIXNUM(S) CAIN A,FLONUM(S) JRST TRUE NUMBP2: JRST FALSE ;bignums change this to JRST BIGNP STRINGP: MOVE B,A ;= T IF A IS A STRING PUSHJ P,ATOM JUMPE A,CPOPJ MOVE A,B PUSHJ P,NUMBERP ;MUST NO BE A NUMBER JUMPN A,FALSE MOVE A,B PUSHJ P,CHRVAL ;GET THE FIRST CHARACTER CAIE A,42+INUM0 ;CHECK FOR " JRST FALSE JRST TRUE PAGE PUTPROP: IFN OLDNIL IFE OLDNIL HRRZ A,(A) CSET3: MOVS TT,(A) HLRZ A,TT CAIN C,(TT) JRST CSET2 HRRZ A,(A) JUMPN A,CSET3 HRRZ A,(T) PUSHJ P,XCONS HRRZ B,C PUSHJ P,XCONS HRRM A,(T) JRST CADR CSET2: CAIE C,VALUE(S) JRST CSET1 HRRZ T,(B) HLRZ A,(A) HRRM T,(A) JRST PROG2 CSET1: HRLM B,(A) PROG2: MOVE A,B PROG1: POPJ P, DEFPROP: HRRZ B,(A) HRRZ C,(B) HLRZ A,(A) HLRZ B,(B) HLRZ C,(C) PUSH P,A PUSHJ P,PUTPROP JRST POPAJ PAGE EQUAL: MOVE C,P EQUAL1: CAMN A,B JRST TRUE MOVE T,A MOVE TT,B PUSHJ P,ATOM EXCH A,B PUSHJ P,ATOM CAMN A,B JRST EQUAL3 EQUAL4: MOVE P,C JRST FALSE EQUAL3: JUMPN A,EQ2 PUSH P,T PUSH P,TT HLRZ A,(T) HLRZ B,(TT) PUSHJ P,EQUAL1 JUMPE A,EQUAL4 POP P,B POP P,A HRRZ A,(A) HRRZ B,(B) JRST EQUAL1 EQ2: PUSH P,T MOVE A,T PUSHJ P,NUMBERP JUMPE A,EQUAL4 MOVE A,TT PUSHJ P,NUMBERP JUMPE A,EQUAL4 MOVE A,(P) MOVEM C,(P) MOVE B,TT JSP C,OP JUMPL COMP3 JUMPL COMP3 COMP3: POP P,C CAME A,TT JRST EQUAL4 JRST TRUE PAGE COMMENT ? ;## OLD SUBST AND COPY CODE THAT DID NOT WORK AS IT WAS ;## NOT PROTECTED FROM THE GARBAGE COLLECTOR. NASTY, NASTY. ;## REPLACED BY COMPILED LISP CODE SUBS5: HRRZ A,SUBAS POPJ P, SUBST: MOVEM A,SUBAS# MOVEM B,SUBBS# SUBS0A: MOVE A,SUBAS MOVE B,SUBBS PUSH P,C MOVE A,C PUSHJ P,EQUAL POP P,C JUMPN A,SUBS5 CAIE C,NIL ;## TEST FOR NIL CAILE C,INUMIN JRST EV6A HLLE T,(C) AOJN T,SUBS2 EV6A: MOVE A,C POPJ P, SUBS2: PUSH P,C HLRZ C,(C) PUSHJ P,SUBS0A EXCH A,(P) HRRZ C,(A) PUSHJ P,SUBS0A POP P,B JRST XCONS COPY: MOVEI B,INUM0 ;$$ (SUBST 0 0 A) MOVEI C,INUM0 EXCH A,C JRST SUBST ? ; NTHCHAR = THE BTH CHARACTER OF A. NTHCHAR:MOVE T,B SUBI T,INUM0 JUMPE T,FALSE ;FAIL IF = 0 PUSH P,A MOVEM T,ORGSGN JUMPG T,NTH3 PUSHJ P,%FLATSIZEC MOVEI T,1-INUM0(A) ADDB T,ORGSGN NTH3: MOVE A,(P) PUSHJ P,LITATOM JUMPN A,NTH4 POP P,A HRROI R,NTH5 ;I HOPE THIS IS RIGHT PUSHJ P,PRINTA HLRZ A,ORGSGN JRST NTH6 NTH5: SOSN ORGSGN HRLOM A,ORGSGN POPJ P, NTH4: MOVE T,ORGSGN POP P,A MOVEI B,PNAME(S) PUSHJ P,GET JUMPE A,CPOPJ ;FAIL IF NO PRINT NAME NTH1: CAIG T,5 JRST NTH2 HRRZ A,(A) JUMPE A,FALSE ;FAIL IF NO NTH CHARACTER SUBI T,5 JRST NTH1 NTH2: HLRZ A,(A) IMULI T,-7 LSH T,14 ADDI T,440700 HRL A,T LDB A,A JUMPE A,FALSE NTH6: PUSHJ P,AASCII+1 ;CONVERT TO AN ATOM JRST INTERN ;INTERN IT PAGE NCONC: TDZA R,R APPEND: MOVEI R,.APPEND-.NCONC JUMPE T,FALSE POP P,B APP2: AOJE T,PROG2 POP P,A PUSHJ P,.NCONC(R) MOVE B,A JRST APP2 .NCONC: JUMPE A,PROG2 MOVE TT,A MOVE C,TT HRRZ TT,(C) JUMPN TT,.-2 HRRM B,(C) POPJ P, .APPEND: JUMPE A,PROG2 MOVEI C,AR1 MOVE TT,A APP1: HLRZ A,(TT) PUSH P,B PUSHJ P,CONS ;saves b POP P,B HRRM A,(C) MOVE C,A HRRZ TT,(TT) JUMPN TT,APP1 JRST SUBS4 PAGE IFN NONUSE MEMB0: MOVEM A,SUBAS# MEMB1: JUMPE B,FALSE MOVEM B,SUBBS# MOVE A,SUBAS HLRZ B,(B) PUSHJ P,EQUAL JUMPN A,CPOPJ MOVE B,SUBBS HRRZ B,(B) JRST MEMB1 IFE NONUSE MEMB: EXCH A,B ;## NEW MEMQ THAT RETURN TAIL JUMPE A,FALSE MOVS C,(A) CAIN B,(C) POPJ P, HLRZ A,C CAMGE A,FWSO ;##THIS WILL ELIMINATE MOST (MAYBE ALL) ;## ILLEGAL MEM REFS FROM MEMQ ;##AND ASSOCIATED ROUTINES. FWSO IS FWS ORIGIN JUMPN A,MEMQ+1 POPJ P, ;NEW MEM-FUNCTIONS THAT RETURN THE TAIL OF THE LIST STARTING WHERE ; THE ELEMENT IS FOUND IFE NONUSE MEMBR.: PUSHJ P,MEMB0 SKIPE A MOVE A,SUBBS POPJ P, IFN NONUSE< MEMQ: PUSHJ P,MEMB SKIPE A JRST TRUE POPJ P, ;AND OR FUNCTIONS (AND#, OR#) THAT RETURN THE EXPRESSION ; THAT CAUSED THE FUNCTION TO EVALUATE TO TRUE AND.: PUSHJ P,AND SKIPA OR.: PUSHJ P,OR HRRZ A,2(P) POPJ P, > AND: HRLI A,TRUTH(S) OR: HLRZ C,A PUSH P,C ANDOR: HRRZ C,A JUMPE C,AOEND MOVSI C,(SKIPE (P)) TLNE A,-1 MOVSI C,(SKIPN (P)) XCT C JRST AOEND MOVEM A,(P) HLRZ A,(A) PUSHJ P,EVAL EXCH A,(P) HRR A,(A) JRST ANDOR AOEND: POP P,A IFN NONUSE < SKIPE A MOVEI A,TRUTH(S) > POPJ P, 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 PUSHJ P,FWCONS PUSHJ P,NCONS JRST PNGNK1 REMOTE< GNUM: ASCII /G0000/> CSYM: HLRZ A,(A) PUSH P,A MOVEI B,PNAME(S) PUSHJ P,GET JUMPE A,NOPNAM HLRZ A,(A) MOVE A,(A) MOVEM A,GNUM JRST POPAJ PAGE LIST: MOVEI B,CEVAL(S) PUSH P,B PUSH P,A MOVNI T,2 JRST MAPCAR EELS: HLRZ TT,(T) ;interpret lsubr call HRRZ A,(AR1) ILIST: MOVEI T,0 JUMPE A,ILIST2 ILIST1: PUSH P,A HLRZ A,(A) PUSH P,TT HRLM T,(P) PUSH P,SP ;$$SAVE SP POINTER TO RESTORE AFTER ARGUMENT EVALUATED PUSHJ P,EVAL ;EVALUATE ARGUMENT POP P,SP ;$$RESTORE SP POINTER AFTER EVAL ILIST3: POP P,TT HLRE T,TT EXCH A,(P) HRRZ A,(A) SOS T JUMPN A,ILIST1 ILIST2: JRST (TT) ;FAST MAPC FOR 2 ARGS - CALLED BY LAP CODE ONLY .MAPC: PUSH P,A JUMPE B,PRETB HLRZ A,(B) HRRZ B,(B) PUSH P,B CALLF 1,@-1(P) POP P,B JRST .MAPC+1 ;FAST MAP FOR 2 ARGS - CALLED BY LAP CODE ONLY .MAP: PUSH P,A JUMPE B,PRETB MOVE A,B HRRZ B,(B) PUSH P,B CALLF 1,@-1(P) POP P,B JRST .MAP+1 PRETB: SUB P,[XWD 1,1] JRST PROG2 PAGE ; NEW AND SUPER POWERFUL MAP FUNCTIONS MAPCON: TLZ T,100000 JRST MAPLIST MAPCAN: TLZA T,100000 MAPC: TLZA T,400000 MAPCAR: TLZA T,400000 MAP: TLZ T,200000 ; INITIALIZE MAPLIST:SETCA T,T MOVEI A,(CALLF) DPB T,[POINT 4,A,30] MOVE B,P MOVE AR1,T HRL AR1,T SUB B,AR1 PUSH P,B HRLM A,(B) PUSH P,T PUSH P, HRLZM P,(P) ; SET UP TO GET ARGUMENTS MAPL2: HRRZ T,-1(P) MOVEI TT,-3(P) ; MOVE ARGS TO REGS MPL3: MOVE D,(TT) JUMPE D,MPDN MOVEM D,(T) MOVE D,(D) SKIPGE -1(P) HLRZM D,(T) HRRZM D,(TT) SUBI TT,1 SOJG T,MPL3 XCT (TT) ; CALL THE FUNCTION LDB C,[POINT 2,-1(P),2] TRNE C,2 JRST MAPL2 ; ATTACH TO OUTPUT LIST SKIPN C PUSHJ P,NCONS JUMPE A,MAPL2 HLR B,(P) HRRM A,(B) SKIPE C PUSHJ P,LAST HRLM A,(P) JRST MAPL2 ; POP STACK AND RETURN MPDN: POP P,AR1 MOVE P,-1(P) POP P,B SUBS4: HRRZ A,AR1 POPJ P, ;PA3: 0 ;THE REG. PDL POINTER ;PA4: 0 ;Lh=pntr to prog less bound var list ;RH=NEXT PROG STATEMENT PROG: PUSH P,PA3# PUSH P,PA4# HLRZ TT,(A) ;## TT HAS VARIABLE LIST HRRZ A,(A) ;## A HAS PROG BODY HRRM A,PA4 HRLM A,PA4 MOVE T,SP ;$$ADJUST SPDLSAV POINTER TO INCLUDE EVAL BLIP SUB T,[XWD 2,2] ;$$SO PA3,PA4 CAN BE RESTORED MOVEM T,SPSV# ;$$BY UNBIND JRST PG7B ;$$GO CHECK IF ANY VARIABLES TO BIND PG7A: HLRZ A,(TT) MOVEI AR1,0 PUSHJ P,BIND HRRZ TT,(TT) PG7B: JUMPN TT,PG7A PUSH SP,SPSV MOVEM P,PA3 PG1: HRRZ T,PA4 JUMPE T,PG4 ;## IF END OF PROG, QUITE HLRZ A,(T) ;## A HAS FIRST STATEMENT HRRZ T,(T) ;## T KEEPS THE REST CAIE A,NIL ;## TEST FOR NIL CAILE A,INUMIN ;## ALLOW INUMS FOR PROG LABELS 3/28/73 JRST PG1+1 ;## NOW WE CAN SKIP OVER THIS TYPE OF ATOM HLLE B,(A) ;## IS IT A ATOM? AOJE B,PG1+1 ;## JA, SO JUMP HRRM T,PA4 ;## SAVE REST OF BODY PUSH P,SP ;$$SAVE SPDL TO RESTORE AFTER EVAL PUSHJ P,EVAL ;## EVAL THE STATEMENT POP P,SP ;$$RESTORE SPDL AFTER EVAL JRST PG1 PGO: SKIPN PA3 ;## ERROR IF NO PROG JRST EG2 MOVE P,PA3 ;## BACK UP ON RPDL MOVE B,1(P) ;## GET FORM PUSHJ P,UBD HRLZI C,(POPJ P,) ;## NEW CODE TO ALLOW BREAKING ;## AND TRACING OF GO PUSHJ P,DOSET ;## HLRZ T,PA4 PG5: JUMPE T,EG1 ;## ERROR IF NO TAG FOUND HLRZ TT,(T) ;## GET THE CAR HRRZ T,(T) ;## SAVE UP THE REST OF THE BODY CAIN TT,(A) JRST PG1+1 ;FOUND TAG JRST PG5 ;## TRY AGAIN RETURN: SKIPN PA3 JRST EG3 MOVE P,PA3 MOVE B,1(P) PUSHJ P,UBD HRLZI C,(POPJ P,) ;## NEW CODE TO ALLOW BREAKING ;## AND TRACING OF RETURN PUSHJ P,DOSET ;## JRST PG4+1 PG4: SETZ A, PUSHJ P,UNBIND ERRP4: POP P,PA4 POP P,PA3 POPJ P, GO: HLRZ A,(A) CAIE A,NIL ;## TEST FOR NIL CAILE A,INUMIN ;## IS IT AN INUM?(NOW VALID) JRST PGO ;## SEE IF IT IS THE ONE HLLE B,(A) ;## IS IT AN ATOM AOJE B,PGO PUSHJ P,EVAL JRST GO+1 SETQ: HLRZ B,(A) PUSH P,B PUSHJ P,CADR PUSHJ P,EVAL MOVE B,A POP P,A SET: SKIPE A ;$$ MUST BE NON-NIL CAILE A,INUMIN ;$$ AND NOT AN INUM JRST SETERR ;$$ HLRE AR1,(A) ;$$ AND AN ATOM AOJN AR1,SETERR ;$$ MOVE AR1,B PUSHJ P,BIND SUB SP,[XWD 1,1] MOVE A,AR1 POPJ P, CON2: HRRZ A,(T) COND: JUMPE A,CPOPJ ;entry PUSH P,A HLRZ A,(A) HLRZ A,(A) PUSHJ P,EVAL POP P,T JUMPE A,CON2 HLRZ T,(T) COND2: HRRZ T,(T) JUMPE T,CPOPJ ;ENTRY FOR ALL TYPES OF PROGN'S HLRZ A,(T) HRRZ T,(T) ;$$ JUMPE T,EVAL ;$$ SAVE STACK SPACE IF NO IMPLIED PROG PUSH P,T ;$$ PUSHJ P,EVAL POP P,T JRST COND2+2 ;$$ BECAUSE OF THE LAST CHANGE ;LEXORDER - TRUE IF A IS ALPHAMERICALLY LESS THAT OR EQUAL TO B LEXORD: MOVE TT,A PUSHJ P,NUMBERP JUMPN A,LEX2 ;1ST ARG IS A NUMBER MOVE A,B PUSHJ P,NUMBERP EXCH A,TT JUMPN TT,FALSE ;1ST=NOT-NUM, 2ND=NUM, DEFINE AS NIL MOVE T,B MOVEI B,PNAME(S) PUSHJ P,GET EXCH A,T PUSHJ P,GET LEX1: JUMPE T,TRUE JUMPE A,CPOPJ HLRZ AR1,(A) MOVE AR1,(AR1) HLRZ AR2A,(T) MOVE AR2A,(AR2A) LSH AR1,-1 LSH AR2A,-1 CAMLE AR1,AR2A JRST TRUE CAME AR1,AR2A JRST FALSE HRRZ A,(A) HRRZ T,(T) JRST LEX1 LEX2: MOVE A,B PUSHJ P,NUMBERP EXCH A,TT JUMPE TT,TRUE ;1ST=NUM, 2ND=NOT-NUM, DEFINE AS TRUE PUSHJ P,.GREAT ;BOTH NUMBERS, DO (NOT (*GREAT A B)) JRST NOT PROGN: MOVE T,A ;$$ PROGN MOVEI A,NIL JRST COND2+1 ;$$ IMPLIED PROG DOES THE REST PAGE SUBTTL ARITHMETIC SUBROUTINES ;macro expander -- (foo a b c) => (*foo (*foo a b) c) EXPAND: MOVE C,B HRRZ A,(A) PUSHJ P,REVERSE JRST EXPA1 EXPN1: MOVE C,B EXPA1: HRRZ T,(A) HLRZ A,(A) JUMPE T,CPOPJ PUSH P,A MOVE A,T PUSHJ P,EXPA1 EXCH A,(P) PUSHJ P,NCONS POP P,B PUSHJ P,XCONS MOVE B,C JRST XCONS PAGE ADD1: CAILE A,INUMIN CAIL A,-2 SKIPA B,[INUM0+1] AOJA A,CPOPJ .PLUS: JSP C,OP ADD A,TT FADR A,TT SUB1: CAILE A,INUMIN+1 SOJA A,CPOPJ MOVEI B,INUM0+1 .DIF: JSP C,OP SUB A,TT FSBR A,TT .TIMES: JSP C,OP IMUL A,TT FMPR A,TT .QUO: CAIN B,INUM0 JRST ZERODIV JSP C,OP IDIV A,TT FDVR A,TT .GREAT: EXCH A,B JUMPE B,FALSE .LESS: JUMPE A,CPOPJ JSP C,OP JRST COMP2 ;bignums know about me JRST COMP2 COMP2: CAML A,TT JRST FALSE JRST TRUE .MAX: MOVEI D,.GREAT SKIPA .MIN: MOVEI D,.LESS MOVE AR1,A MOVE AR2A,B PUSHJ P,(D) SKIPN A MOVE AR1,AR2A MOVE A,AR1 POPJ P, PAGE MAKNUM: CAIE B,FLONUM(S) ;## DEFAULT TO FIXNUM, NOT FLONUM JRST FIX1A FLO1A: MOVEI B,FLONUM(S) PUSHJ P,FWCONS JRST ACONS-1 FIX1B: SUBI A,INUM0 MOVEI B,FIXNUM(S) PUSHJ P,FWCONS JRST ACONS-1 NUMVLX: JFCL 17,.+1 NUMVAL: CAIG A,INUMIN JRST NUMAG1 SUBI A,INUM0 MOVEI B,FIXNUM(S) POPJ P, NUMAG1: MOVEM A,AR1 HRRZ A,(A) HLRZ B,(A) HRRZ A,(A) CAIE B,FIXNUM(S) CAIN B,FLONUM(S) SKIPA A,(A) NUMV4: SKIPA A,AR1 POPJ P, NUMV2: PUSHJ P,EPRINT ;bignums know about me JRST NONNUM NUMV3: JRST NONNUM ;bignums change me to JRST BIGDIS PAGE FLOAT: IDIVI A,400000 SKIPE A TLC A,254000 TLC B,233000 FADR A,B POPJ P, FIX: PUSH P,A PUSHJ P,NUMVAL CAIE B,FLONUM(S) JRST POPAJ MULI A,400 TSC A,A JFCL 17,.+1 ASH B,-243(A) FIX2: JFCL 10,FIXOV ;bignums change me to jfcl 10,bfix POP P,A FIX1: MOVE A,B JRST FIX1A MINUSP: PUSHJ P,NUMVAL JUMPGE A,FALSE JRST TRUE MINUS: PUSHJ P,NUMVLX MOVNS A JFCL 10,@OPOV JRST MAKNUM ABS: PUSHJ P,NUMVLX MOVMS A JRST MINUS+2 NUMTYP: PUSHJ P,NUMVAL ;## NUMVAL LEAVES TYPE IN B MOVEI A,(B) ;## GET THE TYPE POPJ P, INUMP: CAIG A,INUMIN ;## INUM IF > INUMIN JRST FALSE ;## NO, RETURN NIL POPJ P, ;## RETURN USEFUL VALUE PAGE DIVIDE: CAIN B,INUM0 JRST ZERODIV JSP C,OP JUMPN RDIV ;bignums know about me JRST ILLNUM RDIV: IDIV A,TT PUSH P,B PUSHJ P,FIX1A EXCH A,(P) PUSHJ P,FIX1A POP P,B JRST XCONS REMAINDER: PUSHJ P,DIVIDE JRST CDR FIXOV: ERR1 [SIXBIT /INTEGER OVERFLOW!/] ZERODIV:ERR1 [SIXBIT /ZERO DIVISOR!/] FLOOV: ERR1 [SIXBIT /FLOATING OVERFLOW!/] ILLNUM: ERR1 [SIXBIT /NON-INTEGRAL OPERAND!/] GCD: JSP C,OP JUMPA GCD2 ;bignums know about me JRST ILLNUM GCD2: MOVMS A MOVMS TT ;euclid's algorithm GCD3: CAMG A,TT EXCH A,TT JUMPE TT,FIX1A IDIV A,TT MOVE A,B JRST GCD3 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 CAIL A,-1 JRST FIX1B POPJ P, OPA1: HRRZ A,(A) HLRZ T,(A) HRRZ A,(A) CAIE T,FIXNUM(S) JRST OPA6 SKIPA A,(A) OPA2: MOVEI T,FIXNUM(S) CAILE B,INUMIN JRST OPB2 HRRZ B,(B) HRRZ TT,(B) HLRZ B,(B) CAIE B,FIXNUM(S) JRST OPA5 SKIPA TT,(TT) OPB2: HRREI TT,-INUM0(B) JFCL 17,.+1 XCT (C) ;fixed pt op OPOV: JFCL 10,FIXOV ;bignums change this to jfcl 10,fixovl JRST FIX1A OPA6: CAILE B,INUMIN JRST OPB7 HRRZ B,(B) HRRZ TT,(B) HLRZ B,(B) CAIE B,FLONUM(S) JRST OPB3 CAIE T,FLONUM(S) JRST NUMV3 MOVE A,(A) MOVE TT,(TT) OPR: JFCL 17,.+1 XCT 1(C) ;flt pt op JFCL 10,FLOOV JRST FLO1A OPA5: CAIE B,FLONUM(S) JRST NUMV3 PUSHJ P,FLOAT JRST OPR-1 OPB3: CAIE B,FIXNUM(S) JRST NUMV3 SKIPA TT,(TT) OPB7: HRREI TT,-INUM0(B) MOVEI B,FIXNUM(S) CAIE T,FLONUM(S) JRST NUMV3 MOVE A,(A) EXCH A,TT PUSHJ P,FLOAT EXCH A,TT JRST OPR PAGE SUBTTL EXPLODE, READLIST AND FRIENDS %FLATSIZEC: SKIPA R,.+1 ;$$ FLATSIZEC - (LENGTH (EXPLODEC)) FLATSIZE: HRRZI R,FLAT2 SETZM FLAT1 PUSHJ P,PRINTA MOVE A,FLAT1# JRST FIX1A FLAT2: AOS FLAT1 POPJ P, %EXPLODE: SKIPA R,.+1 EXPLODE: HRRZI R,EXPL1 MOVSI AR1,AR1 PUSHJ P,PRINTA JRST SUBS4 EXPL1: PUSH P,B PUSH P,C ANDI A,177 CAIL A,"0" CAILE A,"9" JRST EXPL2 ADDI A,INUM0-"0" JRST EXPL4 EXPL2: PUSH P,AR1 PUSH P,TT PUSH P,T LSH A,35 MOVE C,SP PUSH C,A MOVEI AR1,1 PUSHJ P,INTER0 POP P,T POP P,TT POP P,AR1 EXPL4: PUSHJ P,NCONS HLR B,AR1 HRRM A,(B) HRLM A,AR1 POP P,C JRST POPBJ PAGE READLIST: TDZA T,T MAKNAM: MOVNI T,1 MOVEM T,NOINFG PUSH P,OLDCH SETZM OLDCH JUMPE A,NOLIST HRRM A,MKNAM3 MOVEI A,MKNAM2 PUSHJ P,READ0 HRRZ T,MKNAM3 CAIE T,-1 JUMPN T,[ERR1 [SIXBIT /MORE THAN ONE S-EXPRESSION-MKNAM!/]] POP P,OLDCH POPJ P, MKNAM2: PUSH P,B PUSH P,T PUSH P,TT HRRZ TT,MKNAM3# JUMPE TT,MKNAM6 CAIN TT,-1 ERR1 [SIXBIT /READ UNHAPPY-MAKNAM!/] HRRZ B,(TT) HRRM B,MKNAM3 HLRZ A,(TT) CAIGE A,INUMIN JRST MKNAM5 SUBI A,INUM0-"0" MKNAM4: POP P,TT POP P,T JRST POPBJ MKNAM5: HLRZ A,(TT) MOVEI B,PNAME(S) PUSHJ P,GET HLRZ A,(A) LDB A,[POINT 7,(A),6] JRST MKNAM4 MKNAM6: MOVEI A," " HLLOS MKNAM3 JRST MKNAM4 ; A COUPLE OF FUNCTIONS SO THAT THE PROGRAMMER MAY RETURN CELLS TO THE FREE LIST FREE: MOVEM F,(A) ;$$ RETURN A SINGLE CELL TO FREE LIST HRRZ F,A JRST FALSE FREELI: JUMPE A,CPOPJ ;$$ RETURN A LIST TO THE FREE LIST HRRZ B,(A) MOVEM F,(A) HRRZ F,A MOVE A,B JRST FREELI PAGE SUBTTL EVAL APPLY -- THE INTERPRETER APPLY.: CAILE A,INUMIN ;$$ AN APPLY TO HANDLE ANY FUNCTION TYPE JRST UNDTAG HLRZ T,(A) CAIE T,-1 JRST GAPP HRRZ T,(A) AAGN: JUMPE T,GAPP HLRZ TT,(T) HRRZ T,(T) CAIN TT,FSUBR(S) JRST [MOVE A,B HLRZ T,(T) JRST (T)] CAIN TT,FEXPR(S) JRST [ HLRZ T,(T) HRL T,A PUSH P,T MOVE A,B JRST APPL.2] CAIN TT,MACRO(S) JRST [ PUSHJ P,CONS JRST EVAL] CAIN TT,EXPR(S) JRST GAPP CAIN TT,SUBR(S) JRST GAPP CAIE TT,LSUBR(S) JRST AAGN GAPP: HRREI T,-2 PUSH P,A PUSH P,B JRST APPLY PAGE EV3: HLRZ A,(AR1) MOVEI B,VALUE(S) PUSHJ P,GET JUMPE A,UNDFUN ;function object has no definition HRRZ A,(A) REMOTE< XXX4: UBDPTR: UNBOUND> HLRZ B,(AR1) ;$$GET ORIGINAL FN NAME CAME A,B ;$$IF VALUE IS THE SAME THE WE HAVE A LOOP CAMN A,UBDPTR JRST UNDFUN HRRZ B,(AR1) ;eval (cons (cdr a)(cdr ar1)) PUSHJ P,CONS JRST XXEVAL PAGE OEVAL: AOJN T,AEVAL POP P,A EVAL: PUSH P,SP ;$$SAVE SPDL PUSHJ P,XXEVAL ;$$GO DO EVALUATION AS USUAL POP P,SP ;$$RESTORE SPDL POPJ P, ;$$AND RETURN TO CALLER XXEVAL: HRRZM A,AR1 CAILE A,INUMIN JRST CPOPJ ;$$CODE TO PUT EVAL BLIP ON SPECIAL PDL PUSH P,B ;$$SAVE WHAT WAS IN B HRRZI B,-1(P) ;$$GET RPDL POINTER AND OFFSET HRLI B,UNBOUND(S) ;$$ SET UP RPDL POINTER PUSH SP,B ;$$ SAVE RPDL POINTER ON SPDL PUSH SP,A ;$$SAVE EVAL FORM ON SPDL POP P,B ;$$AND GO OON HLRZ T,(A) ;;;;;;;;;;;;; SKIPN ERINT# ;$$CHECK IF DDT (CONTROL H) INTERRUPT OCCURRED JRST .+4 ;$$SKIP OVER INTERRUPT FEATURE SETZM ERINT# ;$$TURN OFF INTERRUPT FLAG PUSHJ P,EPRINT ;$$PRINT OUT WHAT WAS INTERRUPTED ERR1 [SIXBIT /WAS JUST INTERRUPTED - NOW IN ERRORX!/] CAIN T,-1 JRST EE1 ;x is atomic CAILE T,INUMIN JRST UNDFUN HLRO TT,(T) AOJE TT,EE2 ;car (x) is atomic JRST EXP3 EE1: EV5: HRRZ AR1,(AR1) JUMPE AR1,UNBVAR HLRZ TT,(AR1) CAIE TT,FLONUM(S) CAIN TT,FIXNUM(S) POPJ P, EVBIG: HRRZ AR1,(AR1) ;bignums know about me CAIE TT,VALUE(S) JRST EV5 HLRZ AR1,(AR1) HRRZ AR1,(AR1) CAIN AR1,UNBOUND(S) JRST UNBVAR MOVEM AR1,A POPJ P, PAGE ; HANDLER OF ALISTS AND SPDL CONTEXT POINTERS ALIST: SKIPE A,-1(P) PUSHJ P,NUMBERP MOVEM SP,SPSV 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 POP C,T ;pointer for next block JUMPGE T,AEVAL6 ;$$SKIP ANY EVAL BLIP CRAP AEVAL4: CAMN C,T JRST AEVAL6 ;thru with block POP C,AR1 TLNE AR1,-1 ;$$ TEST FOR EVAL BLIP JRST .+3 SUB C,[XWD 1,1] ;$$ FOUND ONE, SKIP RPDL WORD JRST AEVAL4 MOVSS AR1 PUSH SP,(AR1) ;save value cell HLRM AR1,(AR1) ;store previous value in value cell HRLM AR1,(SP) ;save pointer to spec pdl loc JRST AEVAL4 AEVAL: PUSHJ P,ALIST POP P,A MOVEI A,UNBIND EXCH A,(P) JRST EVAL PAGE AEVAL1: SKIPGE AEVAL2 SKIPN B,-1(P) JRST ABIND3 ;done with binding ;alist binding MOVE A,B PUSHJ P,REVERSE SKIPA ABIND2: MOVE A,B HRRZ B,(A) HLRZ A,(A) HRRZ AR1,(A) HLRZ A,(A) PUSHJ P,BIND JUMPN B,ABIND2 ABIND3: PUSH SP,SPSV POPJ P, ;spec pdl binding AEVAL7: MOVE A,-1(P) PUSHJ P,NUMVAL JUMPL A,.+5 ;MAKE SURE IT IS A VALID STACK POINTER MOVS T,SC2 ;IT'S NOT, MAKE IT VALID ADD T,A ADD A,SC2 HRL A,T CLEARM AEVAL2# MOVEM A,AEVAL5 ;point to unbind to JRST AEVAL8 ;AEVAL2: 0 ;0 for number, -1 for a-list PAGE EE2: HRRZ T,(T) JUMPE T,EV3 HLRZ TT,(T) HRRZ T,(T) CAIN TT,SUBR(S) JRST ESB CAIN TT,LSUBR(S) JRST EELS CAIN TT,EXPR(S) JRST AEXP CAIN TT,FSUBR(S) JRST EFS CAIN TT,MACRO(S) JRST EFM CAIE TT,FEXPR(S) JRST EE2 HLRZ T,(T) HLL T,(AR1) PUSH P,T HRRZ A,(A) APPL.2: TLO A,400000 PUSH P,A MOVNI T,1 JRST IAPPLY AEXP: HLRZ T,(T) HLL T,(AR1) EXP3: PUSH P,T HRRZ A,(AR1) CILIST: JSP TT,ILIST EXP2: JRST IAPPLY EFS: HLRZ T,(T) HRRZ A,(AR1) JRST (T) PAGE ESB: HRRZ A,(AR1) UUOS2: HLRZ T,(T) HLL T,(AR1) PUSH P,T JSP TT,ILIST ESB1: JRST .+NACS+1(T) POP P,A+4 POP P,A+3 POP P,A+2 POP P,A+1 POPAJ: POP P,A POPJ P, EFM: HLRZ T,(T) CALLF 1,(T) JRST EVAL PAGE APPLY: MOVEI TT,AP2 CAME T,[-3] JRST PDLARG MOVEM T,APFNG1# PUSHJ P,ALIST MOVE T,APFNG1 JSP TT,PDLARG PUSH P,[UNBIND] AP2: PUSH P,A MOVEI T,0 AP3: JUMPE B,IAPPLY ;all args pushed; b has arg list HLRZ C,(B) PUSH P,C ;push arg HRRZ B,(B) SOJA T,AP3 IAP4: JUMPGE D,TOOFEW ;special case for fexprs AOJN R,TOOFEW PUSH P,B MOVE A,SP PUSHJ P,FIX1A EXCH A,(P) MOVE B,A MOVNI R,2 SOJA T,IAP5 FUNCT: PUSH P,A MOVE A,SP PUSHJ P,FIX1A POP P,B HLRZ B,(B) PUSHJ P,XCONS MOVEI B,FUNARG(S) JRST XCONS PAGE APFNG: SOS T MOVEM T,APFNG1 JSP TT,PDLARG ;get args and funarg list HRRZ A,(A) HRRZ D,(A) ;a-list pointer HLRZ A,(A) ;function HRLZ R,APFNG1 ;no. of args PUSH P,[UNBIND] JSP TT,ARGP1 ;replace args and fn name PUSH P,D ;a-list pointer PUSHJ P,ALIST ;set up spec pdl POP P,D AOS T,APFNG1 ;falls through PAGE ;falls in IAPPLY: MOVE C,T ;state of world at entrance ADDI C,(P) ;t has - number of args on pdl ILP1A: HRRZ B,(C) ;next pdl slot has function- poss fun name in lh CAILE B,INUMIN JRST UNDTAC HLRZ A,(B) CAIN A,-1 JRST IAP1 ;fn is atomic CAIN A,LAMBDA(S) JRST IAPLMB CAIN A,FUNARG(S) JRST APFNG CAIN A,LABEL(S) JRST APLBL PUSH P,T MOVE A,B PUSHJ P,EVAL POP P,T MOVE C,T ADDI C,(P) ILP1B: MOVEM A,(C) JRST ILP1A IAPXPR: HLRZ A,(B) JRST ILP1B IAP1: HRRZ B,(B) JUMPE B,IAP2 HLRZ TT,(B) HRRZ B,(B) CAIN TT,EXPR(S) JRST IAPXPR CAIN TT,LSUBR(S) JRST IAP6 CAIE TT,SUBR(S) JRST IAP1 HLRZ B,(B) MOVEM B,(C) JRST ESB1 PAGE IAPLMB: HRRZ B,(B) HLRZ TT,(B) MOVEM SP,SPSV HRRZ B,(B) HLRZ D,(TT) CAIN D,-1 JUMPN TT, IAP3 MOVE R,T IPLMB1: JUMPE T,IPLMB2 ;no more args JUMPE TT,TOMANY ;too many args supplied IAP5: HLRZ A,(TT) MOVEI AR1,1(T) ADD AR1,P HLLZ D,(AR1) HRLM A,(AR1) HRRZ TT,(TT) AOJA T,IPLMB1 PAGE IPLMB2: JUMPN TT,IAP4 ;too few args supplied JUMPE R,IAP69 IPLMB4: POP P,AR1 HLRZ A,AR1 AOJG R,IPLMB3 PUSHJ P,BIND JRST IPLMB4 IPLMB3: SKIPE BACTRF JRST APBK1 APBK2: MOVEI A,NIL ;$$SETUP FOR IMPLIED PROG PUSH SP,SPSV MOVE T,B ;$$SETUP FOR IMPLIED PROG PUSHJ P,COND2+1 ;$$INSTEAD OF EVAL JRST UNBIND IAP69: POP P,(P) MOVEI A,NIL ;$$SETUP FOR IMPLIED PROG MOVE T,B ;$$ JRST COND2+1 ;$$INSTEAD OF EVAL APBK1: HRRI AR1,CPOPJ TLNE AR1,-1 PUSH P,AR1 JRST APBK2 IAP6: MOVEI TT,CPOPJ MOVEM TT,(C) HLRZ B,(B) JRST (B) APLBL: MOVEM SP,SPSV HRRZ B,(B) HLRZ A,(B) HRRZ B,(B) HLRZ AR1,(B) MOVEM AR1,(C) PUSHJ P,BIND MOVEI A,APLBL1 EXCH A,-1(C) EXCH A,LBLAD# HRLI A,LBLAD PUSH SP,A PUSH SP,SPSV JRST IAPPLY APLBL1: PUSH P,LBLAD JRST SPECSTR IAP2: HRRZ A,(C) MOVEI B,VALUE(S) PUSHJ P,GET JUMPE A,UNDTAC HRRZ A,(A) HRRZ B,(C) ;$$GET ORIGINAL FN NAME CAME A,B ;$$IF THE VALUE IS THE SAME THEN WE HAVE A LOOP CAIN A,UNBOUND(S) JRST UNDTAC JRST ILP1B IAP3: MOVNI AR1,-INUM0(T) ;lexpr call MOVE A,TT PUSHJ P,BIND PUSH P,%ARG SUBI C,INUM0 HRRM C,%ARG PUSH SP,SPSV MOVEI A,NIL ;$$ MORE FOR IMPLIED PROG MOVE T,B ;$$ PUSHJ P,COND2+1 ;$$ INSTEAD OF EVAL HRRZ T,%ARG POP P,%ARG SUBI T,1-INUM0(P) HRLI T,-1(T) ADD P,T JRST UNBIND ARG: HRRZ A,@%ARG POPJ P, REMOTE<%ARG: XWD A,0> SETARG: HRRZM B,@%ARG JRST PROG2 PAGE BIND: JUMPE A,BNDERR ;$$CAN'T REBIND NIL CAIN A,TRUTH(S) ;$$SHOULDN'T REBIND T JRST BNDERR ;$$ PUSH P,B HRRZM A,BIND3# BIND2: MOVEI B,VALUE(S) ;bind atom in a to value in ar1,save PUSHJ P,GET ;old binding on s pdl JUMPE A,BIND1 ;add value cell PUSH SP,(A) HRLM A,(SP) HRRM AR1,(A) ;$$THIS WAS HHRZM AR1,(A) WHICH CLOBBERED ATOM POINTER IN MY SYSTEM POPBJ: POP P,B POPJ P, BIND1: MOVEI B,UNBOUND(S) MOVE A,BIND3 ;$$SET UP ATOM POINTER FROM SPECIAL CELL ;$$THIS WAS MOVEI A,0 PUSHJ P,CONS HRRZ B,@BIND3 PUSHJ P,CONS MOVEI B,VALUE(S) PUSHJ P,XCONS HRRM A,@BIND3 MOVE A,BIND3 JRST BIND2 UBD: CAMG SP,B POPJ P, HLRZ TT,(SP) ;$$SKIP OVER EVAL BLIPS ETC. JUMPE TT,.+2 ;$$IF EQUAL TO 0 IT WAS AN EVAL BLIP JRST PJUBND SUB SP,[XWD 2,2] ;$$DECREMENT SPDL JRST UBD ;$$GO BACK AND CHECK PJUBND: PUSHJ P,UNBIND JRST UBD UNBIND: SPECSTR: MOVE TT,(SP) CAMN SP,SC2 ;$$CHECK TO AVOID OVERSHOOT POPJ P, ;$$ SUB SP,[XWD 1,1] JUMPGE TT,UNBIND ;syncronize stack UNBND1: CAMN SP,TT POPJ P, POP SP,T CAIN T,(T) ;$$CHECK TO SKIP OVER NEW ITEMS PUT ON SPDL ;$$ALL SUCH ITEMS HAVE 0 LEFT HAND SIDES JRST PROGUB ;$$THIS IS AN EVAL BLIP - CHECK IF A PROG MOVSS T HLRM T,(T) ;$$CHANGED FROM HLRZM T,(T) TO PROTECT NEW ATOM POINTER JRST UNBND1 PROGUB: HLRZ T,(T) ;$$CHECK FOR A PROG CAIE T,PROGAT+1(S) ;$$CHECK IF IT IS A PROG JRST PROGU1 ;$$NOT A PROG, SKIP IT AND GO ON MOVE T,(SP) ;$$GET THE RPDL POINTER FOR PROG INTO T ADDI T,2 ;$$INCREMENT TO GET TO WHERE PA3,PA4 SAVED POP T,PA4 ;$$RESTORE PA4 POP T,PA3 ;$$AND PA3 FROM WHERE THEY WERE SAVED PROGU1: POP SP,T ;$$ POP RPDL POINTER JRST UNBND1 ;$$AND GO ON WITH THE UNBINDING SPECBIND: MOVE TT,SP SPEC1: LDB R,[POINT 13,(T),ACFLD] CAILE R,17 JRST SPECX SKIPE R MOVE R,(R) HLL R,@(T) ;$$AGAIN SAVE THE POOR LITTLE ATOM POINTER EXCH R,@(T) HRLI R,@(T) PUSH SP,R AOJA T,SPEC1 SPECX: PUSH SP,TT JRST (T) ;random special case compiler run time routines %AMAKE: PUSH P,A ;make alist for fsubr that requires it MOVE A,SP PUSHJ P,FIX1A MOVE B,A JRST POPAJ %UDT: PUSHJ P,PRINT ;error print for undefined computed go tag STRTIP [SIXBIT /UNDEFINED COMPUTED GO TAG IN !/] HRRZ R,(P) PUSHJ P,ERSUB3 JRST ERREND %LCALL: MOVN A,T ;set up routine for compile lsubr ADDI A,INUM0 ADDI T,(P) PUSH P,T PUSHJ P,(3) POP P,T SUBI T,(P) HRLI T,-1(T) ADD P,T POPJ P, PAGE SUBTTL ARRAY SUBROUTINES ARRERR=-1 ARRAY: PUSHJ P,ARRAYS HRRI AR2A,1(R) MOVE A,AR2A PUSH R,[0] AOBJN A,.-1 ARREND: MOVE A,BPPNR# MOVEM AR2A,-1(A) MOVEI A,INUM0+1(R) MOVEM A,VBPORG(S) POPJ P, ARRAYS: PUSH P,A MOVE A,VBPORG(S) SUBI A,INUM0 MOVEM A,BPPNR MOVE A,VBPEND(S) MOVNI A,-INUM0-2(A) ADD A,BPPNR ;bporg-bpend+2 HRLM A,BPPNR POP P,A HRRZ AR1,(A) ;(cdr l) HLRZ A,(A) ;(car l)name HRRZ B,BPPNR ADDI B,2 MOVEI C,SUBR(S) PUSHJ P,PUTPROP HLRZ A,(AR1) ;(cadr l)mode PUSH P,AR1 PUSHJ P,EVAL ;eval mode POP P,AR1 MOVEM A,AMODE# MOVEI C,44 JUMPE A,ARRY1 MOVEI C,-INUM0(A) CAILE A,INUMIN JRST ARRY1 MOVEI C,22 HRRZ A,BPPNR MOVE B,GCMKL PUSHJ P,CONS MOVEM A,GCMKL ARRY1: MOVEM C,BSIZE# MOVEI A,44 IDIV A,C MOVEM A,NBYTES# HRRZ A,(AR1) ;(cddr l)bound pair list JSP TT,ILIST AOS R,BPPNR MOVEI AR1,1 ;ar1 is array size MOVEI AR2A,0 ;ar2a is cumulative residue AOJGE T,ARRYS ;single dimension MOVEI D,A-1 SUB D,T ;d is next ac for array code generation ARRY2: PUSHJ P,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: POP P,TT EXCH TT,(P) CAILE TT,INUMIN JRST ARRB1 HLRZ A,(TT) HRRZ TT,(TT) SUBI TT,(A) ADDI TT,1 JRST ARRB2 ARRB1: MOVEI A,INUM0 SUB TT,A ARRB2: IMUL A,AR1 IMULB AR1,TT ;%% ADDM A,AR2A ADD AR2A,A ;%% SOME PEOPLE HAVE PROBLEMS POPJ P, ARRY3: PUSH R,[ADD A,B] ARRYS: PUSHJ P,ARRB0 HRRZ TT,BPPNR MOVEM AR2A,(TT) HRLI TT,(SUB A,) PUSH R,TT PUSH R,[JUMPL A,ARRERR] MOVE TT,AR1 HRLI TT,(CAIL A,) PUSH R,TT PUSH R,[JRST ARRERR] IDIV AR1,NBYTES ;calc #words in array SKIPE AR2A ;correct for remainder non-zero ADDI AR1,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 AR2A,AMODE CAIL AR2A,INUMIN ADDI TT,40 ;mode not = t TLC TT,(HRLZI C,) PUSH R,TT MOVEI TT,4(R) HRLI TT,(ADDI C,(A)) PUSH R,TT PUSH R,[LDB A,C] HRLZI AR2A,(POPJ P,) SKIPN TT,AMODE MOVE AR2A,[JRST FLO1A] CAIL TT,INUMIN MOVE AR2A,[JRST FIX1A] PUSH R,AR2A MOVS AR2A,AR1 MOVNS AR2A POPJ P, PAGE GTBLK: MOVNI C,-INUM0(A) ;##COMPUTE NEGATIVE LENGTH MOVE A,VBPORG(S) ;## GET BPORG HRRI A,-INUM0(A) ;## CONVERT HRLM C,(A) ;## MOVE TO BPORG INFO FOR (GC) HRRM A,(A) ;## AOS R,(A) ;## ADD ONE TO INFO AND MOVE TO R SUBI R,1 ;## SET PUSH DOWN POINTER(ASSUME POINTER BLOCK) CAIN B,0 ;## IS IT A POINTER BLOCK? SUBI R,1 ;## NO MOVE AR1,VBPEND(S) ;## GET BPEND MOVNI AR1,-INUM0(AR1) ;## CONVERT TO NEGATIVE ADD AR1,R ;## BPORG-BPEND +(0 OR 1) HRLI R,(AR1) ;## MOVE TO R FOR TESTING FOR BPS EXCEEDED PUSH R,[0] ;## CLEAR THE SPACE, NOTE THAT IF IT IS NOT AOJN C,.-1 ;## WE WILL ALSO CLEAR THE INFO LOCATION HRRZI R,INUM0+1(R) ;## COMPUTE NEW BPORG HRRM R,VBPORG(S) CAIN B,0 ;## IF IT WAS NOT A POINTER BLOCK, DONE POPJ P, MOVE B,GCMKL ;## GET GC'S LIST PUSHJ P,CONS ;## CONS MOVEM A,GCMKL ;## SAVE IT HLRZ A,(A) ;GET THE OLD BPORG BACK AOJA A,.-5 ;## ADD ONE AND RETURN BLKLST: PUSH P,A ;## SAVE LIST CAIE B,0 ;## BLK LENGTH GIVEN SKIPA A,B ;## YES PUSHJ P,LENGTH ;## NO, USE LENGTH OF LIST MOVEI B,(A) ;## GET A POINTER BLOCK FROM GTBLK PUSHJ P,GTBLK POP P,B ;## GET LIST BACK PUSH P,A HRRZI R,-1(A) ;## SET UP PDL HLRE C,(R) ;## NEG LENGTH FROM GC INFO. BLKLS1: HRRI A,1(A) ;## BUMP A FOR CDR IFN OLDNIL< ;## IF(CDR NIL)#NIL TRNE B,-1 ;## END OF LIST? SKIPA B,(B) ;## NO SETZ B, ;## YES, REST OF BLOCK IS NIL > IFE OLDNIL< MOVE B,(B) ;## IF (CDR NIL )=NIL > HLL A,B ;## GET (CAR LIST) PUSH R,A ;## AND STORE AOJL C,BLKLS1 ;## SEE IF DONE HLLZM A,(R) ;## SET (CDR (LAST BLOCK)) TO NIL JRST POPAJ ;## AND RETURN POINTER TO THE BLOCK EXARRAY: PUSH P,A HLRZ A,(A) PUSHJ P,GETSYM JUMPE A,POPAJ PUSHJ P,NUMVAL EXCH A,(P) PUSHJ P,ARRAYS POP P,A HRRM A,-2(R) HRR AR2A,A JRST ARREND STORE: PUSH P,A PUSHJ P,CADR PUSHJ P,EVAL ;value to store EXCH A,(P) HLRZ A,(A) PUSHJ P,EVAL ;byte pointer returned in c POP P,A NSTR: PUSH P,A TLNE C,40 PUSHJ P,NUMVAL ;numerical array DPB A,C POP P,A POPJ P, PAGE SUBTTL EXAMINE, DEPOSIT , ETC BOOLE: MOVE TT,T ADDI TT,2(P) MOVE A,-1(TT) SUBI A,INUM0 DPB A,[POINT 4,BOOLI,OPFLD-2] PUSHJ P,BOOLG MOVE C,A BOOLL: PUSHJ P,BOOLG XCT BOOLI REMOTE< BOOLI: CLEARB C,A> JRST BOOLL BOOLG: CAIL TT,(P) JRST BOOL1 MOVE A,(TT) PUSHJ P,NUMVAL AOJA TT,CPOPJ BOOL1: HRLI T,-1(T) ADD P,T POP P,B JRST FIX1A EXAMINE:PUSHJ P,NUMVAL MOVE A,(A) JRST FIX1A DEPOSIT:MOVE C,B PUSHJ P,NUMVAL EXCH A,C PUSHJ P,NUMVAL MOVEM A,(C) JRST MAKNUM LSH: MOVEI C,-INUM0(B) PUSHJ P,NUMVAL LSH A,(C) JRST FIX1A PAGE SUBTTL GARBAGE COLLECTER ;garbage collector GC: PUSHJ P,AGC JRST FALSE AGC: SETOM GCFLG ;SET GCFLAG INCASE OF USER CONTROL-C MOVEM R,RGC# GCPK1: PUSH P,PA3 PUSH P,PA4 IFE OLDNIL PUSH P,UBDPTR ;special atom UNBOUND; not on OBLIST PUSH P,MKNAM3 PUSH P,GCMKL ;i/o channel input lists and arrays PUSH P,BIND3 PUSH P,INITF PUSH P,INITF1 ;## INIT FILE LIST GCPK2: PUSH P,[XWD 0,GCP6] ;this is a return address JRST GCP4 REMOTE< GCP4: MOVEI S,X ;pdlac, .=bottom of reg pdl + 1 GCP41: BLT S,X ;save ACs 0 through 10 at bottom of regpdl ;pdlac+n GCP2: CLEARB 0,X ;gc indicator, init. for bit table zero MOVE A,C3GC GCP5: BLT A,X ;zero bit tables, .=top of bit tables JRST GCRET1> GCRET1: SKIPN GCGAGV JRST GCP5A SKIPN F STRTIP [SIXBIT /_FREE STG EXHAUSTED_!/] SKIPN FF STRTIP [SIXBIT /_FULL WORD SPACE EXHAUSTED_!/] GCP5A: MOVEI TT,1 MOVEI A,0 CALLI A,STIME ;time MOVNS A ADDM A,GCTIM# MOVE C,GCP3# ;.=bottom of reg pdl GCP6B: MOVE S,P HLL C,P MOVEI B,0 GC1: CAMN C,S POPJ P, HRRZ A,(C) GCPI: CAMGE A,GCP# ;.=bottom of bit tables REMOTE< GCPP1: XXX5:FS> CAMGE A,GCPP1 JRST GCEND CAML A,GCP1# ;.=bottom of full word space (fws) JRST GCMFW MOVE F,(A) LSHC A,-5 ROT B,5 MOVE AR1,GCBT(B) TDOE AR1,@GCBTP2 ;bit tab- (fs_-5), .=magic number for sync JRST GCEND MOVEM AR1,@GCBTP1 ;bit tab- (fs_-5) PUSH P,F HLRZ A,F JRST GCPI REMOTE< GCBTP1: XWD A,0 GCBTP2: XWD A,0 GCMFWS: XWD A,0> GCMFW: MOVEI AR1,@GCMFWS ;.=- bottom of fws IDIVI AR1,44 MOVNS AR2A LSH AR2A,36 ADD AR2A,C2GC DPB TT,AR2A GCEND: CAMN P,S AOJA C,GC1 POP P,A HRRZS A JRST GCPI REMOTE< GCMKL: XWD 0,[XWD [XWD -NIOCH,CHTAB+FSTCH],0] C2GC: XWD 430100+AR1,X ;.=bottom of fws bit table C3GC: 0> ;(bottom bit table)bottom bit table+1 GCBT: XWD 400000,0 ZZ==1B1 XLIST REPEAT ^D31, LIST GCP6: HRRZ R,SC2 GCP6C: CAIL R,(SP) ;mark sp JRST GCP6A PUSH P,(R) HRRZ C,P PUSHJ P,GCP6B SUB P,[XWD 1,1] AOJA R,GCP6C GCP6A: HRRZ R,GCMKL ;mark arrays GCP6D: JUMPE R,GCSWP HLRZ A,(R) MOVE D,(A) GCP6E: PUSH P,(D) HRRZ C,P PUSH P,(D) MOVSS (P) PUSHJ P,GCP6B SUB P,[XWD 2,2] AOBJN D,GCP6E HRRZ 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 ;garbage collector sweep GCSWP: MOVSI R,GFSWPP BLT R,LPROG MOVEI F,NIL ;will become movei f,-1 MOVE D,C3GCS JRST XXX3 REMOTE< XXX3: MOVEI R,FS ;$$ANOTHER FOOLIST REMNANT GCBTL1: HRLI R,X ;-(32- MOVE S,(D) GCBTL2: ROT S,X ;fs&37 AOBJN D,GFSP1 JRST GFSPR> GFSPR: MOVE A,C1GCS MOVE B,C2GCS PUSHJ P,GCS0 SKIPN GCGAGV JRST GCSPI1 MOVE B,F PUSHJ P,GCPNT STRTIP [SIXBIT / FREE STG,!/] MOVE B,FF PUSHJ P,GCPNT STRTIP [SIXBIT / FULL WORDS AVAILABLE_!/] GCSPI1: HRLZ S,GCSP1# ;bottom of reg pdl+1 BLT S,NACS+3 ;reload ac's SUB P,[XWD GCPK2-GCPK1,GCPK2-GCPK1] ;restore p AOSN GCFLG ;CHECK FLAG FOR PENDING INTERRUPT JRST GCEXIT ;NO- SO NORMAL EXIT POP P,JOBOPC ;INTERRUPT WILL CONTINUE FROM THE GC RETURN PUSH P,GCFLG ;GC WILL RETURN TO THE INTERRUPT POINT SETZM GCFLG ;CLEAR GCFLG GCEXIT: JUMPE F,[ERR2 [SIXBIT /NO FREE STG LEFT!/]] JUMPE FF,[ERR2 [SIXBIT /NO FW STG LEFT!/]] MOVE R,RGC MOVEI A,0 CALLI A,STIME ;time ADDM A,GCTIM MOVE S,ATMOV ;$$RESTORE ATOM OFFSET RELOCATOR (FOOLIST) ;$$HOPEFULLY S IS USED ONLY BY GC AND ATOM RELOCATION POPJ P, GCS0: MOVEI FF,0 GCS1: ILDB C,B JUMPN C,GCS2 HRRZM FF,(A) HRRZ FF,A GCS2: AOBJN A,GCS1 POPJ P, REMOTE< C1GCS: 0 ;(- length of fws) bottom of fws C2GCS: XWD 100,0 ;.=bottom of fws bit table C3GCS: 0 ;-n wds in bt,,bt > GCGAG: EXCH A,GCGAGV# POPJ P, GCTIME: MOVE A,GCTIM JRST FIX1A TIME: MOVEI A,0 CALLI A,STIME JRST FIX1A SPEAK: MOVE A,CONSVAL# JRST FIX1A GCPNT: MOVEI R,TTYO MOVEI A,0 JUMPE B,PRINL1 HRRZ B,(B) AOJA A,.-2 IFN REALLC < ;%% NEW ROUTINES TO COUNT AVAILABLE ;%% FREE SPACE AND FULL WORD SPACE FSCNT: TDZA C,C ;%% INITIALIZE FWCNT: MOVEI C,1 ;%% MOVE B,F(C) ;%% FREE LIST START SETZ A, ;%% COUNTER JUMPE B,FIX1A ;%% WHEN DONE, NO MORE POINTER HRRZ B,(B) ;%% AOJA A,.-2 ;%% > GCING: OUTSTR [ASCIZ / GARBAGE COLLECTING /] POP P,GCFLG ;CAN'T INTERRUPT GC, QUEUE UP THE REQUEST JRST @JOBOPC PAGE SUBTTL SYMBOL TABLE ACCESSING ROUTINES R50MAK: PUSHJ P,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 POPJ P, IMULI B,50 ADD B,A JRST MK3 ;## NEW ROUTINES FOR CONVERTING SYMBOLS TO CONS CELL SYMERR: MOVE A,B SYMER1: PUSHJ P,EPRINT ;## PRINT OFFENDER ERR1 [SIXBIT /NOT A CONS CELL !/] ;## **CAUSES ERROR IF NOT IN FREE STORAGE** RGTSYM: PUSHJ P,GETSYM PUSHJ P,NUMVAL ;## CONVERT TO REAL ADDRESS ADDI A,(S) ;## ADD RELOCATION CAIL A,FS(S) ;## LESS THAN FS(S) IS NOT CONS CELL CAML A,FWSO ;## FS(S)<= A < FWSO IS A CONS CELL JRST SYMER1 POPJ P, GETSYM: PUSHJ P,R50MAK TLO B,040000 ;04 for globals MOVE C,JOBSYM MK7: CAMN B,(C) JRST MK10 ;found AOBJP C,.+2 AOBJN C,MK7 TLC B,140000 ;10 for locals TLNE B,100000 JRST MK7-1 JRST FALSE MK10: MOVE A,1(C) ;value JRST FIX1A ;## ROUTINE TO STORE A CONS CELL SO THAT IT CAN BE ;## REFERENCED VIA ,CELL(S) I.E. THRU INDEX REG. S ;## ERROR IF NOT LEGITIMATE CONS CELL RPTSYM: CAIL B,FS(S) ;## FS(S) =< B EXCISE: IFN ALVINE< MOVEI A,ED+2 HRRM A,EDA> MOVE A,JRELO SETZM LDFLG# ;initial loader symbol table flag CALLI A,CORE JRST .+1 JSP R,IOBRST JRST TRUE PAGE ; lisp loader interface ; REG. D IS USED SINCE VARIABLES ARE MOVE WHEN LISP IS REENTRANT LOAD: AOS B,CORUSE MOVEM B,OLDCU# MOVEM A,LDPAR# JUMPE A,LOAD2 MOVE B,VBPORG(S) SUBI B,INUM0 LOAD2: MOVEM B,RVAL# ;final destination of loaded code MOVSI A,(SIXBIT /LOD/) SETZ D, PUSHJ P,SYSINI SUBI A,150 ;extra room for locations 0 to 137 and slop PUSH P,A MOVNS A ;length(loader) HRRZM A,LODSIZ# PUSHJ P,MORCOR ;expand core for loader MOVEM A,LOWLSP# ;location of blt'ed low lisp MOVN B,(P) ;length(loader) ADD B,A MOVEM B,HVAL# ;temporary destination of loaded code HRLI A,0 MOVE D,A ;THIS IS THE RELOCATION, THE LOADER WILL SAVE IT BLT A,(B) ;blt up low lisp HLL A,NAME+3(D) ;-length(loader) HRRI A,137-1 PUSHJ P,SYSINP SKIPE LDFLG(D) JRST LOAD3 SETOM LDFLG(D) MOVSI A,(SIXBIT /SYM/) PUSHJ P,SYSINI MOVNS A ;length symbols PUSHJ P,MORCOR ;expand core for symbols SKIPGE B,JOBSYM SOS B ;if no symbol table, use original jobsym HLRZ A,NAME+3(D) ;-length(symbols) ADDB A,B HLL A,NAME+3(D) ;symbol table iowd PUSHJ P,SYSINP HRRM B,JOBSYM HLLZ A,NAME+3(D) ADDM A,JOBSYM SKIPA LOAD3: SOS JOBSYM ;want jobsym to point one below 1st symbol MOVE 3,HVAL(D) ;h MOVE 5,RVAL(D) ;r MOVE 2,3 SUB 2,5 ;x=h-r HRLI 5,12 ;(w) HRLI 2,11 ;(v) SETZB 1,4 JSP 0,140 ;call the loader MOVEM 5,RLAST#(D) ;last location loaded(in final area) MOVE T,OLDCU(D) MOVE A,JOBSYM MOVEM A,JOBSYM(T) MOVE A,JOBREL MOVEM A,JOBREL(T) ;update jobrel HRLZ 0,LOWLSP(D) SOS LODSIZ(D) AOBJN 0,.+1 BLT 0,@LODSIZ(D) ;blt down low lisp MOVE 0,@LOWLSP ;EVERY THING IS FIXED, DON'T NEED REG. D ANYMORE MOVE B,RLAST MOVE A,RVAL HRL A,HVAL SKIPE LDPAR JRST BINLD 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,JOBSYM SUB C,JOBSYM ;length of free core ORCMI C,776000 AOJGE C,START ;no contraction ADD C,JOBREL ;new top of core MOVE B,C PUSHJ P,MOVDWN CALLI C,CORE ;contract core JRST .+1 JRST START BINLD: MOVEI C,INUM0(B) CAML C,VBPEND(S) JRST [ SETOM BPSFLG ;bps exceeded JRST START] MOVEM C,VBPORG(S) ;updat bporg SOS C,OLDCU ;old top of core JRST LDRET2 PAGE SYSINI: MOVEM A,NAME+1(D) ;%% FOLLOWING IS OLD, NON-PATCHABLE CHANNEL OPEN COMMENT & IFN SYSPRG,< MOVE A,[XWD SYSPRG,SYSPN] MOVEM A,NAME+3(D)> IFE SYSPRG,< SETZM NAME+3(D)> INIT 17 SYSDEV 0 JRST AIN.4+1 & ;%% END OF OLD CODE ;%% NEW PATCHABLE CODE (DEVICE NAME IN LOW SEGMENT) MOVE A,SYSIN1(D) ;%% PICK UP PPN REMOTE< SYSIN1: XWD SYSPRG,SYSPN ;%% KEEP IN LOW SEGMENT > MOVEM A,NAME+3(D) ;%% RESET VALUE HERE MOVEI A,17 ;%% SET DATA MODE MOVEM A,SYSIN0(D) ;%% OPEN 0,SYSIN0(D) ;%% OPEN CHANNEL 0 TO READ FILE JRST AIN.4+1 ;%% ERROR IN OPEN IF HERE REMOTE< SYSIN0: 17 ;%% DUMP MODE I/O SYSDEV ;%% INITIALLY SYSTEM DEVICE ;%% MAY BE PATCHED ;%% NOTE THAT THIS MAY REMAIN "SYS" ;%% WHEN HGHDAT IS CHANGED TO ;%% SOMETHING ELSE 0 ;%% NO BUFFERING > LOOKUP NAME(D) JRST AIN.7+1 MOVE A,[IOWD 1,NAME+3] ;KLUDGE BECAUSE OF REG. D ADD A,D MOVEM A,INLOW(D) INPUT INLOW(D) ;INPUT SIZE OF FILE REMOTE< INLOW: IOWD 1,NAME+3 0> HLRO A,NAME+3(D) POPJ P, REMOTE< NAME: SYSNAM 0 0 0> SYSINP: MOVEM A,LST(D) INPUT LST(D) STATZ 740000 ERR1 AIN.8 RELEASE POPJ P, REMOTE< LST: 0 0> PAGE MOVDWN: HRLM B,JOBSA ;##SAVE NEW JOBSA HLRZ A,JOBSYM JUMPE A,MOVS1 ADDI A,1(B) HRL A,JOBSYM HRRM A,JOBSYM BLT A,(B) ;downward blt POPJ P, MOVSYM: MOVE B,JOBREL HRLM B,JOBSA HLRE A,JOBSYM JUMPE A,MOVS1 ADDI B,1(A) ;new bottom of symbol table MOVNI A,1(A) ADD A,JOBSYM ;last loc of old symbol table HRRM B,JOBSYM PUSH P,C MOVE B,JOBREL ;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 POP P,C POPJ P, MOVS1: HRRZM B,JOBSYM POPJ P, ;enter with size needed in a ;exit with pointer in a to core MORCOR: PUSH P,B HRRZ B,JOBSYM SUB B,CORUSE(D) SUBM A,B ;NEEDED-JOBSYM-CORUSE(IE. NEEDED-FREE) JUMPL B,EXPND2 ADD B,JOBREL ;new core size CALLI B,CORE ;expand core ERR1 [SIXBIT /CANT EXPAND CORE !/] PUSH P,A PUSHJ P,MOVSYM POP P,A EXPND2: MOVE B,CORUSE(D) ADDM A,CORUSE(D) MOVE A,B POP P,B POPJ P, PAGE SUBTTL HIGH SEGMENT FUNCTIONS REMOTE HGHCOR: JUMPE A,NOWRT ;EXPAND CORE AND SET WRITE STATUS PUSHJ P,NUMVAL JUMPLE A,FALSE CLEARB C,WRTSTS CALLI C,SETUWP UWPERR: ERR1 [SIXBIT /CAN'T CHANGE HIGH SEG. WRITE PROTECT!/] MOVE B,VHGHORG ADD B,A HRRZ C,JOBHRL CAMG B,C JRST TRUE HRLZ A,B CALLI A,CORE ERR1 [SIXBIT /CAN'T EXPAND HIGH SEGMENT!/] JRST TRUE NOWRT: MOVEI A,1 MOVEM A,WRTSTS CALLI A,SETUWP JRST UWPERR JRST TRUE HGHORG: SKIPE A ;SET HIGH ORG. TO A AND RETURN OLD ORG. PUSHJ P,NUMVAL PUSH P,A MOVE A,VHGHORG MOVEI B,FIXNUM(S) PUSHJ P,MAKNUM POP P,B SKIPE B MOVEM B,VHGHORG POPJ P, HGHEND: HRRZ A,JOBHRL ;GET VALUE OF END OF HIGH SEG. MOVEI B,FIXNUM(S) JRST MAKNUM ;SETS THE GETSEG INFO. SO USER CAN HAVE OWN HIGH SEG. SETSYS: MOVE T,A ;MOVE ARGUMENT FOR UIOSUB SETZM DEV ;## ALLOW DEFAULT TO DSK: PUSHJ P,IOSUB ;BREAKS DOWN THE SPECIFICATION MOVEM A,HGHDAT+1 ;SAVE THE FILE NAME MOVE A,DEV ;GET THE DEVICE AND SAVE IT MOVEM A,HGHDAT MOVE A,PPN ;GET THE PPN AND SAVE IT MOVEM A,HGHDAT+4 JRST FALSE ;RETURN NIL REMOTE PAGE SUBTTL REALLOC CODE IFN REALLC < ;%% DYNAMIC REALLOCTION ROUTINE ;%% ;%% ARGUMENTS: ;%% A = FULL WORD SPACE INCREMENT ;%% B = BINARY PROGRAM SPACE INCREMENT ;%% C = REGULAR PUSHDOWN LIST INCREMENT ;%% AR1 = SPECIAL PUSHDOWN LIST INCREMENT ;%% AR2A = FREE SPACE INCREMENT ;%% ;%% ACTION: ;%% 1) PERFORMS AN EXCISE ;%% 2) ALLOCATES ADDITIONAL CORE AS REQUIRED ;%% (IF IMPOSSIBLE, SIGNALS "CAN'T EXPAND CORE") ;%% 5) UNBINDS ALL VARIABLES ON THE SPECIAL STACK ;%% AND CLEARS BOTH STACKS ;%% 4) REALLOCATES SPACE ACCORDING TO SPECIFICATIONS ;%% (NOTE THAT TOTAL CORE USED WILL BE ROUNDED ;%% UP TO A MULTIPLE OF 1K WORDS, AND ANY EXCESS ;%% WILL BE APPORTIONED TO FWS, RPDL, SPDL, AND ;%% FS.) ;%% 5) RESTARTS THE SYSTEM AT THE TOP LEVEL ;%% REALL1: JUMPE A,.+2 ;%%NO CONVERSION IF NIL PUSHJ P,NUMVAL ;%%CONVERT TO BINARY ADDI T,(A) ;%%ADD TO TOTAL BEING ACCUMULATED EXCH A,(P) ;%%PUSH ON STACK JRST (A) ;%%AND RETURN REALLOC: SETZ T, ;%% CLEAR ACCUMULATOR FOR ALLOC TOTAL MOVE TT,B ;%% SAVE SECOND ARG DURING FIRST CALL PUSHJ P,REALL1 ;%% PROCESS FIRST ARG MOVE A,TT ;%% PUSHJ P,REALL1 ;%% PROCESS SECOND ARG MOVE A,C ;%% PUSHJ P,REALL1 ;%% PROCESS THIRD ARG MOVE A,AR1 ;%% PUSHJ P,REALL1 ;%% PROCESS FOURTH ARG MOVE A,AR2A ;%% PUSHJ P,REALL1 ;%% PROCESS FIFTH ARG MOVE A,-4(P) ;%% PICK UP FWS INCREMENT ADD A,SFWS ;%% MAKE NEW TOTAL FWS IDIVI A,44 ;%% CALCULATE SPACE FOR BIT TABLE ADDI T,1(A) ;%% ADD TO TOTAL MOVEM T,(P) ;%% SAVE TOTAL (FS AMOUNT NOT NEEDED) PUSHJ P,EXCISE ;%% CLEAR BUFFERS, ETC. POP P,A ;%% GET TOTAL BACK SETZ D, ;%% CLEAR RELOCATION REGISTER ;%% (HERE WE GO AGAIN) PUSHJ P,MORCOR ;%% ALLOCATE THE ADDITIONAL SPACE MOVE B,SC2 ;%% CLEAR STACKS AND UNBIND VARIABLES PUSHJ P,UBD ;%% HRRZ B,JOBREL ;%% GET NEW HIGH LIMIT CAMGE B,JRELO# ;%% DID CORE GET SMALLER? HALT . ;%% YES -- WE QUIT MOVEM B,JRELO# ;%% RESET LIMIT HRLM B,JOBSA ;%% IFN ALVINE < MOVEI A,ED+2 ;%%INDICATE ED WAS OVERWRITTEN HRRM A,EDA ;%%SO THEY WILL BE RELOADED IF NEEDED > SETZM LDFLG ;%% INDICATE SYMBOLS GONE [1] MOVE A,SFWS ;%% SAVE OLD VALUE MOVEM A,OSFWS ;%% MOVE A,FSO ;%% MOVEM A,OFSO ;%% POP P,A ;%% SPDL INCREMENT ADDM A,SSPDL ;%% CHANGE TOTAL MOVN AR2A,A ;%% SAVE JUST IN CASE POP P,A ;%% RPDL INCREMENT ADDM A,SRPDL ;%% CHANGE TOTAL MOVN AR1,A ;%% SAVE AGAIN POP P,A ;%% BPS TOTAL MOVEM A,FSMOVE ;%% HOW MUCH TO MOVE FS ADDM A,FSO ;%% NEW FS ORIGIN ADDM A,SBPS ;%% BPS INCREMENT POP P,A ;%% FWS INCREMENT ADDM A,SFWS ;%% ADD TO TOTAL JRST REALL2 ;%% JUMP INTO REGULAR ALLOCATOR ;%% (ALL DATA OFF STACK) > STRT: INALLC: HRRZ A,JOBREL ;SEE IF CORE WAS EXPANDED CAMN A,JRELO# ;OR NOT JRST OUTALC ;NO EXPANSION - DON'T REALLOCATE CAMG A,JRELO# ;CHECK TO SEE IF IT GOT SMALLER! JRST 4,0 ;YES - BITCH MOVEM A,JRELO# ;SAVE NEW CORE BOUND HRLM A,JOBSA IFN ALVINE,< MOVEI F,ED+2 ;INDICATE THAT ED WAS OVERWRITTEN HRRM F,EDA ;SO ED AND GRINDEF WILL BE READ IN IF NEEDED> SETZM LDFLG ;%% INDICATE SYMBOLS GONE [1] INAGN: SETZM NOALIN# ;SET UP TO ASK FOR ALLOCATION OUTSTR [ASCIZ / ALLOC? (Y OR N) /] ;ASK USER IF HE WISHES TO SET UP INCHRW C ;THE ALLOCATION INCREMENTS CAIGE C,"O" SETOM NOALIN# ;SET FLAG SO NO INPUT IS DONE LATER SETFWS: MOVE A,SFWS# ;SAVE OLD SIZE OF FWS MOVEM A,OSFWS# SKIPN NOALIN ;SKIP QUESTIONS IF AUTOMATIC OUTSTR [ASCIZ / FULL WORD SP. = /] JSP R,ALLNUM JUMPN A,.+3 SKIPE INITFW# ADDI A,440 ;INITIAL ALLOCATION FOR FWS ADDM A,SFWS# ;ADD EITHER USER INCREMENT OR 0 TO SFWS MOVE A,FSO# ;SAVE OLD FS ORIGIN MOVEM A,OFSO# ;FOR RELOCATION SKIPN NOALIN ;SKIP IF USER DONE OUTSTR [ASCIZ / BIN. PROG. SP. = /] JSP R,ALLNUM ADDM A,SBPS# MOVEM A,FSMOVE# ;THE INCREMENT TO SBPS IS THE AMOUNT BY ADDM A,FSO# ;THE FREE SPACE IS MOVED - UPDATE ORIGIN SKIPN NOALIN ;SKIPIF USER DONE OUTSTR [ASCIZ / REG. PDL. = /] JSP R,ALLNUM JUMPN A,.+3 SKIPE INITFW# ;CHECK IF INITIAL ALLOCATION ADDI A,1000 ADDM A,SRPDL# MOVN AR1,A ;SAVE IN CASE OF OVERFLOW SKIPN NOALIN ;SKIP IF USER DONE OUTSTR [ASCIZ / SPEC. PDL. = /] JSP R,ALLNUM JUMPN A,.+3 SKIPE INITFW# ;CHECK FOR INITIAL ALLOCATION ADDI A,1000 ADDM A,SSPDL# MOVN AR2A,A ;SAVE IN CASE OF OVERFLOW IFN HASH,< SKIPN INITFW SETOM NOALIN SKIPN NOALIN OUTSTR [ASCIZ / HASH = /] JSP R,ALLNUM CAIG A,BCKETS JRST OCR HRRM A,INT1 MOVNS A HRRM A,RH4 SETOM HASHFG> OCR: OUTSTR [ASCIZ / /] REALL2: MOVE A,JRELO# ;COMPUTE SIZE OF AVAILABLE CORE SUBI A,FS ;SO THAT EXTRA CORE CAN BE DISTRIBUTED SUB A,SBPS ;TAKE OFF CORE ALLOCATED FOR BPS SUB A,SFS# ;TAKE OFF CORE IN PREVIOUS FS SUB A,SBT# ;AND ASSOCIATED BIT TABLE SUB A,SFWS ;TAKE OFF CORE NOW ALLOCATED TO FWS SUB A,SRPDL ;TAKE OFF CORE NOW ALLOCATED TO RPDL SUB A,SSPDL ;TAKE OFF CORE NOW ALLOCATED TO SPDL MOVE F,SFWS ;ESTIMATE SIZE NEEDED FOR BTF IDIVI F,44 ADDI F,1 SUB A,F ;AND TAKE IT OFF TOTAL MOVEM F,SBTF# ;ALSO SAVE TO RESTORE LATER JUMPGE A,ALOK ;MAKE SURE NO OVERFLOW OUTSTR [ASCIZ /ALLOCATIONS ARE TOO LARGE /] ; IF SO THEN RETRY MOVE A,OSFWS MOVEM A,SFWS ;RESTORE SIZE OF FWS MOVN A,FSMOVE ADDM A,SBPS ;RESET SIZE OF BPS ADDM A,FSO ;AND FS ORGIN ADDM AR1,SRPDL ;RESET STACKS ADDM AR2A,SSPDL JRST INAGN ALOK: MOVE B,A ;NOW CAN ALLOCATE EXCESS CORE ACHLOC: ASH B,-4 ;1/16 TO FWS ADDM B,SFWS SUB A,B ;TAKE IT OFF REMAINING CORE SKIPE INITFW SETZ B, ASH B,-4 ;1/64 TO PDLS ADDM B,SSPDL SUB A,B ADDM B,SRPDL SUB A,B ;AND TAKE IT OFF REMAINING CORE MOVE T,SFWS ;CALCULATE ACTUAL SIZE OF BTF IDIVI T,44 ADDI T,1 ADD A,SBTF ;REMOVE ESTIMATED LOSS FOR BTF MOVEM T,SBTF SUB A,T ;AND TAKE OFF ACTUAL LOSS TO BTF ADD A,SFS ;ADD BACK ON SPACE FROM OLD FS ADD A,SBT ;AND ASSOCIATED BT ;GIVING NEW SPACE AVAILABLE FOR ;FS AND BT MOVE TT,A IDIVI TT,41 ;SBS = SFS/32. = (SBS + SFS)/33. ADDI TT,1 MOVEM TT,SBT SUB A,TT ;TAKE OFF SBT FROM REMAINING CORE MOVEM A,SFS ;GIVING AVAILABLE SFS ;SET UP REGISTERS FOR GC ETC. SETUP MOVE A,SFWS ;A _ SFWS MOVEI B,FS ADD B,SFS ADD B,SBPS ;B _ NFWSO (ORIGIN OF NEW FULL WORD SPACE) MOVE C,SRPDL ;C _ SRPDL MOVE F,OSFWS ;F _ OLD SIZE OF FWS HRRM B,GCP1 ;GCP1 _ NFWSO MOVN SP,B ;-NEW BOTTOM OF FWS HRRM SP,GCMFWS HRLZM A,C1GCS MOVNS C1GCS ;-NEW LENGTH OF FWS HRRM B,C1GCS ;HAVE FWS POINTER AND COUNT FOR SWEEP ADD B,A ;NEW FIRST WORD OF BT (FS BIT TABLE) MOVE SP,FSO ;SP _ NEW ORIGIN OF FS LSH SP,-5 SUBM B,SP ;NUMBER USED TO FIND BIT TABLE WORD HRRM SP,GCBTP1 ;FROM FS WORD ADDRESS HRRM SP,GCBTP2 HRLM B,C3GC ;BOTTOM OF BIT TABLES HRRM B,GCP2 HRRM B,GCP ;(ALSO UPPER BOUND ON FWS AND FS) MOVNI SP,-2(TT) ;-SIZE OF BT (TT = SBT) HRLM SP,C3GCS ;IOWD FOR BIT TABLE SWEEP HRRM B,C3GCS MOVE SP,FSO ANDI SP,37 ;MASK OUT ALL BU LAST FIVE BITS HRRM SP,GCBTL2 ;MAGIC NUMBER TO POSITION SUBI SP,40 HRRM SP,GCBTL1 ADDI B,1 ;B _ B + 1 HRRM B,C3GC ;BOTTOM OF FS BIT TABLE + 1 ADDI B,-2(TT) ;GET BOTTOM OF BTF - 1, POINTER IS INCREMENTED HRRM B,C2GCS ;BEFORE USE ADDI B,1 ;B _ B + 1 HRRM B,C2GC ;BOTTOM OF FWS BIT TABLE + 1 ADDI B,-1(T) ;SINCE T IS NOW SIZE OF BTF, NOT SBTF-1 HRRM B,GCP5 ;TOP OF BIT TABLES ADDI B,1 ;BOTTOM OF REG PDL MOVE S,ATMOV ;## S NOT SET IF LISP STARTED WITH CORE ;## ALREADY EXPANDED, SO RESET IT HRRZI A,OBTBL(S) ;GET OBLIST POINTER ;## RHX2 IS NO LONGER PURE, WE WANT THE SYSTEM OBLIST ;## THIS IS IT (I HOPE)3/28/73 ADD A,FSMOVE ;INCREMENT TO ;ACCOUNT FOR MOVE OF FS MOVEM A,(B) HRRM B,GCP3 ;ROOM FOR ACS DURING GC ADDI B,1 ;B _ B + 1 HRRM B,GCSP1 HRRM B,GCP4 ;ROOM FOR ACS ADDI B,10 ;B _ B + 10 HRRM B,GCP41 ;TOP OF AC AREA ADDI B,1 ;B _ B + 1 HRRM B,C2 ;SET UP RPDL POINTER MOVNI A,-20(C) ;A _ - (C -20) = -(SRPDL - 20) HRLM A,C2 ;THIS IS THE ACTUAL SIZE OF RPDL ;TAKING INTO ACCOUNT THE AC AREA HRRZ A,JRELO# ;TOP OF CORE - FOR SPDL PTR MOVN B,SSPDL ADD A,B HRL A,B MOVEM A,SC2# ;SET UP SPDL POINTER (I HOPE) MOVN A,A ;CREATE OFFSET FOR STACK POINTERS ADDI A,INUM0 HRRZM A,SPNM# SETZM INITFW ;TURN OFF INITIAL ALLOCATION FLAG ;RELOCATE THE FULL WORD SPACE ;GCP1 HOLDS POINTER TO ORIGIN OF NEW FWS ;FWSO# HOLDS POINTER TO ORIGIN OF OLD FWS ;AND F HOLDS SIZE OF OLD FWS (AMOUNT TO BE MOVED) MOVSI B,F HRR B,GCP1 MOVE C,FWSO# HRRZI AR2A,-1(C) ;TAKE THE OPPORTUNITY TO GET ADDRESS ;OF END OF OLD FS (USED LATER) HRLI C,F MOVE A,@C ;GET WORD FROM END OF OLD FWS MOVEM A,@B ;AND MOVE TO END OF NEW FWS SOJGE F,.-2 ;F COUNTS DOWN WORDS IN OLDFWS ;END OF FWS RELOCATION MOVE FF,FSMOVE ;GET FAST ACCESS TO RELOCATE SIZE FOR FS HRRZ F,AR2A ADD F,FF ;AND FIND WHERE TO PUT WORDS FROM ;END OF OLD FS IN NEW FS HRRZ AR1,GCP1 ;COMPUTE FWS RELOCATION CONSTANT SUB AR1,FWSO ;RELOCATE FS - ALSO RELOCATE ALL ;POINTERS TO FS AND TO FWS REL1: HLRZ A,(AR2A) ;GET CAR POINTER OF OLD FS WORD JSP R,REL4 HRLM A,(F) ;MOVE CAR TO NEW POSITION HRRZ A,(AR2A) ;GET CDR PTR JSP R,REL4 ;CHECK FOR FS RELOCATE HRRM A,(F) SUBI F,1 ;F _ F -1 CAMLE AR2A,OFSO ;CHECK TO SEE IF DONE SOJA AR2A,REL1 ;NO - GO LOOP HRRZ A,GCMKL ;RELOCATE ARRAYS JSP R,REL4 HRRZ D,A MOVEM D,GCMKL REL5: HLRZ AR2A,(D) MOVE AR2A,(AR2A) REL6: HLRZ A,(AR2A) JSP R,REL4 HRLM A,(AR2A) HRRZ A,(AR2A) JSP R,REL4 HRRM A,(AR2A) AOBJN AR2A,REL6 HRRZ D,(D) JUMPN D,REL5 SETZM BIND3 ;JUST IN CASE SKIPE INITF ;DON'T FORGET THE INITFN ADDM FF,INITF SKIPE INITF1 ;## DON'T FORGET THE INIT FILES ADDM FF,INITF1 ;## SKIPE NOUUOF ;RELOCATE FLAGS ADDM FF,NOUUOF SKIPE BACTRF ADDM FF,BACTRF SKIPE GCGAGV ADDM FF,GCGAGV SKIPE RSTSW ADDM FF,RSTSW JRST RELFOO REL4: CAMGE A,EFWSO ;SEE IF BEYOND END OF FWS CAMGE A,OFSO ;OK - SEE IF MAYBE IN FS JRST (R) CAMGE A,FWSO ;SEE IF IN FWS JRST .+3 ADD A,AR1 ;RELOCATE FWS POINTER JRST (R) ADD A,FF ;RELOCATE FS POINTER JRST (R) RELFOO: MOVE S,SBPS ;S IS THE RELOCATOR FOR MOST MACRO MOVEM S,ATMOV ;REFERENCES TO ATOMS AND FS MOVE A,FSMOVE ;NOW IS THE TIME FOR ALL GOOD MEN TO ADDM A,VBPEND(S) ;SET BPEND IFE OLDNIL< ADDM A,NILPRP> ;## RESET NIL HRR B,VOBLIST(S) ;## GET CURRENT VALUE OF OBLIST HRRM B,RHX5 ;## RESET WORD THAT POSTINDEXES OFF B HRRM B,RHX2 ;## RESET WORD POSTINDEXING OFF C ADDM A,XXX3 ;## RESET WIERD CODE ADDM A,XXX4 ;## RESET UNBOUND ADDM A,XXX5 ;## RESET FS (SAME WORD AS FS),ALSO GCPP1 MOVE A,GCP1 HRRZM A,FWSO MOVE A,C3GCS HRRZM A,EFWSO# OUTALC: CLEARB F,DDTIFG JSP R,IOBRST JRST START ;SUBROUTINE FOR NUMBER INPUT ;%% RETURNS 0 IF NOALIN # 0 ;%% SETS NOALIN # 0 IF ALTMOD IS INPUT ;%% RETURNS 0 IF A BLANK IS INPUT ;%% IGNORES OTHER NON-NUMERIC CHARACTERS EXCEPT ;%% AS TERMINATORS OF NUMBERS ALLNUM: SETZB A,ALLNM1# ;%% CLEAR A AND FIRST TIME FLAG SKIPE NOALIN# JRST (R) INCHRW C CAIN C,RUBOUT JRST [OUTSTR [ASCIZ /XXX /] JRST ALLNUM] CAIL C,"0" CAILE C,"9" JRST BANGCK SETOM ALLNM1# ;%% NOT FIRST TIME NOW ASH A,3 ADDI A,-"0"(C) JRST ALLNUM+3 BANGCK: CAIE C,15 ;%% TERMINATE ON CR OR CAIN C,40 ;%% TERMINATE ON BLANK JRST (R) ;%% CAIN C,ALTMOD ;%% ALTMODE (TERMINATOR)? JRST [SETOM NOALIN# JRST (R) ] ;%% YES--TURN ON SWITCH AND RETURN SKIPE ALLNM1# ;%% IGNORE LEADING JUNK? JRST (R) ;%% NO--RETURN JRST ALLNUM+3 ;%% YES--LOOP PAGE IFN HASH,< REHASH: MOVEI A,BFWS(S) PUSH P,A HRRM A,RHX2 HRRM A,RHX5 MOVS B,RH4# ADD B,S ;$$PUT IN ATOM MOVE OFFSET IN B, SINCE CAN'T ;$$DOUBLE INDEX - THIS REMOVES THE FOO PROBLEM ;$$IN THE NEXT THREE FOO'S HRRZI A,BFWS+1(B) MOVEM A,BFWS(B) AOBJN B,.-2 SETZM BFWS(B) MOVSI AR2A,-BCKETS HRR AR2A,S ;$$PUT IN ATOM MOVE OFFSET IN AR2A TO AVOID ;$$DOUBLE INDEXING WITH S IN REMOVING FOO ;$$PROBLEM RH1: HLRZ C,OBTBL(AR2A) RH3: JUMPE C,RH2 HLRZ A,(C) PUSH P,C PUSH P,AR2A PUSHJ P,INTERN POP P,AR2A POP P,C HRRZ C,(C) JRST RH3 RH2: AOBJN AR2A,RH1 SETZM HASHFG POP P,A HRRM A,@GCP3 MOVEM A,OBLIST(S) JRST START> PAGE SUBTTL NEW FUNCTIONS TO MAKE USE OF MODIFIED SPECIAL PDL FOR ERRORS ;$$ROUTINE TO GET POINTER TO SPDL AND MAKE IT INTO AN INUM SPDLPT: HRRZ A,SP ;$$CREATE A POINTER TO THE CURRENT TOP OF STACK ADD A,SPNM POPJ P, ;$$ ;$$ROUTINE TO GET LEFT HAND SIDE OF SPDL ITEM INDICATED BY AN INUM FROM SPDLPT SPDLFT: SUB A,SPNM ;$$CONVERT TO ADDRESS HLRE A,(A) ;$$GET LEFT HAND ITEM JUMPL A,TRUE ;$$IF IT IS NEGATIVE IT CAME FROM A STACK ;$$POINTER AND WE RETURN T INSTEAD HRRZI A,(A) ;$$CLEAR OUT LEFT HAND OF AC POPJ P, ;$$RETURN - RETURNS NIL FOR LHS = 0 ;$$ROUTINE TO GIVE RIGHT HAND SIDE OF SPDL ENTRY SPECIFIED BY AN INUM FROM SPDLPT SPDLRT: SUB A,SPNM ;$$CONVERT TO AN ADDRESS HRRZ A,(A) ;$$ALL RHS ITEMS ARE LEGAL, NO NEED FOR CHECK POPJ P, ;$$ ;$$ROUTINE TO GET POINTER TO NEXT EVAL BLIP ON SPDL NEXTEV: SUB A,SPNM ;$$GET POINTER INSTEAD OF INUM HRRZ T,SC2 ;$$GET POINTER TO BOTTOM OF SPDL SPDNLP: CAMG A,T ;$$CHECK IF HIT THE BOTTOM OF SPDL JRST FALSE ;$$RETURN NIL IF NO MORE INTERESTING WORDS HLL A,(A) ;$$TEST FOR WORD WITH 0 LHS TLZE A,-1 ;$$ SOJA A,SPDNLP ;$$NOT AN INTERESTING WORD, LOOK AGAIN ADD A,SPNM ;$$FOUND AN INTERESTING WORD, CHANGE POINTER TO INUM POPJ P, ;$$ ;$$ROUTINE TO EVALUATE A VARIABLE IN AN EARLIER CONTEXT ;$$ MORE EFFICIENT THAN EVAL WITH ALIST EVALV: MOVE C,A ;$$ MOVE AROUND FOR ATOM CHECK PUSHJ P,ATOM ;$$ EXCH A,C ;$$ SUB B,SPNM ;$$ EVALV1: CAIN B,(SP) ;$$CHECK FOR END OF SPDL JRST GETV ;$$VARIABLE NOT REBOUND - GET CURRENT VALUE SKIPGE ,(B) ;$$CHECK TO AVOID SPDL POINTERS ON STACK AOJA B,EVALV1 ;$$ HLRZ T,(B) ;$$T_CAR(B) SKIPE C ;$$ HLRZ T,(T) ;$$GET CAR OF SPECIAL CELL - ATOM POINTER CAIE T,(A) ;$$COMPARE WITH ATOM TO BE EVALUATED AOJA B,EVALV1 ;$$NOT IT, LOOK SOME MORE HRRZ A,(B) ;$$GET VALUE FROM SPDL POPJ P, ;$$ GETV: JUMPE C,GETV1 MOVEI B,VALUE(S) ;$$ATOM NOT REBOUND, VALUE THEN IS PUSHJ P,GET ;$$ JUMPE A,UNBOND ;$$NOT BOUND AT ALL, GIVE UNBVAR MESSAGE GETV1: HRRZ A,(A) ;$$GET CDR OF SPECIAL CELL POPJ P, ;$$ UNBOND: HRRZI A,UNBOUND(S) ;$$RETURN ATOM UNBOUND POPJ P, ;$$ ;$$ROUTINE TO CLEAR SPECIAL PDL TO POSITION SPECIFIED BY INUM CLRSPD: MOVEI B,-2-INUM0(A) ;$$ -2 TO GET OVER EVAL BLIP HLRZ TT,SC2# ;$$GET REAL SPD POINTER WITH A LHS ADD TT,B ;$$FIND OUT HOW MANY WORDS ARE USED ADD B,SC2 ;$$ HRL B,TT ;$$SET UP SPD POINTER JRST UBD ;$$UBD DOES ALL THE WORK ;$$ROUTINE TO RETURN FROM SPECIAL PDL CONTEXT, SPECIFIED BY AN ;$$EVAL BLIP, WITH A GIVEN VALUE OUTVAL: PUSHJ P,NEXTEV ;$$FORCE TO AN EVAL BLIP JUMPE A,FALSE ;$$ NO EVAL BLIP, RETURN NIL HRLZI C,(POPJ P,) ;$$ SET TYPE OF RETURN JRST SPRE1 ;$$ FINISH UP IN SPREDO ;$$ROUTINE TO RE-EVALUATE EXPRESSION FROM AN EVAL BLIP AND GO ON FROM ;$$ THAT CONTEXT (NOT A USER CALLABLE FUNCTION) REVAL1: HRRZ P,1(SP) ;$$ RPDL POINTER IS UP ONE HRRZ T,C2# ;$$ HLRZ TT,C2# ;$$ ADD TT,P ;$$ SUB TT,T ;$$ HRL P,TT ;$$ DOSET: MOVE D,ERRTN ;$$ POP ERRSETS, LOAD CURRENT ERRSET SKIPE D ;$$DONE IF EMPTY CAMG D,P ;$$ COMPARE TO CURRENT RPDL XCT C ;$$ DONE, DO A STRANGE EXIT SUB D,[XWD 1,1] ;$$ GO DOWN A WORD POP D,ERRSW ;$$ POP D,ERRTN ;$$ SUB D,[XWD 2,2] ;$$ SKIP PROG JUNK JRST DOSET ;$$ TRY AGAIN ;$$ROUTINE TO CLEAR SPD TO A GIVEN POINT AND REDO FROM THERE ;$$ A CONTAINS AN SPD INUM POINTER, FORCE IT TO BE EVAL BLIP POINTER SPREDO: PUSHJ P,NEXTEV ;$$FORCE TO EVAL BLIP POINTER JUMPE A,CPOPJ ;$$RETURN NIL IF NO EVAL BLIP MOVE B,A ;$$GET THE EXPRESSION SUB B,SPNM HRRZ B,(B) MOVE C,[JRST EVAL] ;$$SET RETURN SPRE1: PUSH P,B ;$$SAVE SPDL POINTER PUSHJ P,CLRSPD ;$$CLEAR OUT SPD - INCLUDES RESTORING PROGS POP P,A ;$$ JRST REVAL1 ;$$ SPREVAL - SIMILAR TO OUTVAL BUT EVALUATES THE GIVEN VALUE ;$$AS OF THE SPECIFIED CONTEXT, EQUIVALENT TO: ;$$ (PROG2 (RPLACD (NUMVAL (SETQ A (NEXTEV A))) B) (SPREDO B)) ; SPREVAL:PUSHJ P,NEXTEV ;$$FORCE TO AN EVAL-BLIP JUMPE A,CPOPJ ;$$RETURN NIL IF NO EVAL-BLIP JRST SPRE1-1 ;$$LET SPREDO FINISH UP ;$$COMPUTES A LISP POINTER TO A STACK ENTRY STKPTR: SUB A,SPNM POPJ P, PAGE SUBTTL LOW SEGMENT INCLUDING REMOTE CODE RELOC 0 HERE VAR XALL PAGE SUBTTL LISP ATOMS AND OBLIST FS: DEFINE MAKBUC (A,%B) XWD %B,IFN <-A>,<.+1> IF1 <%B=0>> DEFINE ADDOB (A,C,%B) IF1 <%B=0> XWD C,%B> DEFINE PUTOB (A,B) _<-1> ZZ==-ZZ/BCKETS*BCKETS+ZZ ADDOB \ZZ,B> DEFINE PSTRCT (A) ) ZY==/5 Q1(ZY,ZZ) > DEFINE Q1 (N,Z)< IFN N, IFE N,> ;## ARGS ARE A=NAME, B=PROP NAME, C'A=THE PROPERTY, D=LABEL OF ATOM DEFINE MKAT (A,B,C,D) LIST> ;## ARGS ARE: D'A=PROPERTY, B=PROP NAME, C=NAME DEFINE MKAT1 (A,B,C,D) LIST> DEFINE LENGTH (A,B) > ;## ATOM WITH SYM PROPERTY =V'ATOM LOCATION DEFINE ML1 (A)> ;## SIMILAR TO ML1, EXCEPT %C=THE SYM PROP DEFINE MKSY1 (A,B,%C)< XLIST %C: XWD -1,.+1 XWD FIXNUM,[A] PUTOB B,.+1 XWD -1,.+1 XWD SYM,.+1 XWD %C,.+1 XWD PNAME,.+1 XWD [PSTRCT(B)],0 LIST> ;## ATOM WITH NO PROPS WITH LABEL SAME AS ATOM NAME DEFINE ML (A)< XLIST IRP A, LIST> ;## CREATE ATOM WITH NO LABEL OR PROPS. USED FOR COMMON ATMS IN SYSTEM DEFINE MK (A)< XLIST IRP A, LIST> OBTBL: OBLIST: ZZ==0 XLIST REPEAT BCKETS, LIST PAGE ;## GENERATE # FNS ONLY IF NONUSEFUL VALUES DESIRED IFN NONUSE< MKAT1 MEMBR.,SUBR,MEMBER# MKAT1 MEMB,SUBR,MEMQ# MKAT1 AND.,FSUBR,AND# MKAT1 OR.,FSUBR,OR# > MKAT,SUBR MKAT,SUBR MKAT,SUBR MKAT,SUBR MKAT,SUBR MKAT,SUBR MKAT,SUBR MKAT,SUBR MKAT,SUBR MKAT,SUBR MKAT,SUBR MKAT,SUBR MKAT,SUBR IFN STPGAP,,SUBR> MKAT EXPLODEC,SUBR,% MKAT TAB,SUBR,. MKAT TYO,SUBR,I MKAT TYI,SUBR,I CEVAL=.+1 MKAT1 EVAL,SUBR,*EVAL ;$$ REDEF. FOR NEW MAP FUNCTIONS MKAT,LSUBR ;$$ GIVE MAPCAN THE DOUBLE NAME MAPCONC MKAT1 MAPCAN,LSUBR,MAPCONC PROGAT: MKAT,FSUBR ;##LIST STARTS HERE MKAT LIST,FSUBR,,LISTAT: MKAT ,FSUBR IFN ALVINE,,FSUBR MKAT,SUBR> IFE ALVINE,> MKAT,FSUBR MKAT,FSUBR MKAT1 QUOTE,FSUBR,FUNCTION MKAT1 %CLRBFI,SUBR,CLRBFI MKAT1 .ERROR,SUBR,ERROR MKAT1 LINRD,SUBR,LINEREAD MKAT1 UNBOND,SUBR,UNBOUND MKAT1 ECHO,SUBR,TTYECHO MKAT1 FUNCT,FSUBR,*FUNCTION MKAT ,LSUBR ;## LABELS ON READ AND LISP EVAL FOR BOOTS MKAT READ,SUBR,,READAT: MKAT EVAL,LSUBR,O,EVALAT: MKAT ASCII,SUBR,A MKAT QUOTE,FSUBR,,CQUOTE: MKAT INUM0,SYM PUTOB T,.+1 TRUTH: XWD -1,.+1 XWD VALUE,.+1 XWD VTRUTH,.+1 XWD PNAME,.+1 XWD [PSTRCT(T)],0 VTRUTH: TRUTH PUTOB NIL,0 CNIL2: XWD VALUE,.+1 XWD VNIL,.+1 XWD PNAME,.+1 XWD [PSTRCT(NIL)],0 VNIL: NIL MKSY1 %LCALL,*LCALL MKSY1 %AMAKE,*AMAKE MKSY1 %UDT,*UDT MKSY1 .MAPC,*MAPC MKSY1 .MAP,*MAP MKAT1 %NOPOINT,VALUE,*NOPOINT %NOPOINT: NIL UNBOUND: XWD -1,.+1 XWD PNAME,.+1 XWD [PSTRCT(UNBOUND)],0 PAGE MKAT1 EXPN1,SUBR,*EXPAND1 MKAT1 EXPAND,SUBR,*EXPAND MKAT1 PLUS,SUBR,*PLUS,. MKAT1 DIF,SUBR,*DIF,. MKAT1 QUO,SUBR,*QUO,. MKAT1 TIMES,SUBR,*TIMES,. MKAT1 APPEND,SUBR,*APPEND,. MKAT1 RSET,SUBR,*RSET,. MKAT1 GREAT,SUBR,*GREAT,. MKAT1 LESS,SUBR,*LESS,. MKAT1 PUTSYM,SUBR,*PUTSYM MKAT1 GETSYM,SUBR,*GETSYM MKAT1 RPTSYM,SUBR,*RPUTSYM MKAT1 RGTSYM,SUBR,*RGETSYM ML1 PUTOB NUMVAL,.+1 XWD -1,.+1 XWD SUBR,.+1 XWD NUMVAL,.+1 XWD SYM,.+3 XWD FIXNUM,[NUMVAL] XWD -1,.-1 XWD .-1,.+1 XWD PNAME,.+1 XWD [PSTRCT(NUMVAL)],0 MKAT ,VALUE,V ;## QUEUE ATOMS AND OTHER NEW FNS. MKAT,SUBR MKAT,SUBR MKAT,SUBR MKAT,FSUBR IFN QALLOW< ;%% [1] ML;;## MKAT,FSUBR; ;## > ;%% [1] MK MKAT1 ISFILE,SUBR,LOOKUP MK IFN QALLOW< ;%% [1] ;## MOST OF THE EXTENDED SWITCHES (NOT ALL) IFN QSWEXT< ML ML ML > ;##END OF EXTENDED SWITCHES > ;%% END OF QALLOW CONDITIONAL [1] ;$$ATOMS FOR DEFINITIONS OF FUNCTIONS FOR NEW SPDL PACKAGE ML ERRORX MKAT1 INTPRP,SUBR,INITPROMPT MKAT1 LSPRET,FSUBR,**TOP** MKAT,SUBR MKAT,SUBR MKAT,SUBR MKAT,SUBR IFN REALLC < ;%% NEW DYNAMIC REALLOCATION FUNCTION MKAT1 REALLO,SUBR,REALLOC MKAT,SUBR > ;$$ MORE EXTENSIONS INCLUDING READ MACROS ML READMACRO MKAT1 %FLATSIZEC,SUBR,FLATSIZEC MKAT ,SUBR MKAT ,SUBR MKAT1 FALSE,FSUBR,SPECIAL MKAT1 FALSE,FSUBR,NOCALL MKAT1 FALSE,FSUBR,DECLARE MKAT1 FALSE,FSUBR,NILL MKAT1 APPLY.,SUBR,APPLY# MKAT1 .MAX,SUBR,*MAX MKAT1 .MIN,SUBR,*MIN ;$$ THE BREAK VARIABLES WHICH TELL ABOUT DEPTH IN THE BREAK PACKAGE MKAT1 BIOCHN,VALUE,#%IOCHANS%# MKAT1 BPMPT,VALUE,#%PROMPTS%# MKAT1 BINDNT,VALUE,#%INDENT BIOCHN: NIL BPMPT: NIL BINDNT: INUM0 VOBLIST: OBLIST VBASE: 8+INUM0 VIBASE: 8+INUM0 ML PUTOB ?,.+1 QST: XWD -1,.+1 XWD PNAME,.+1 XWD [PSTRCT(?)],0 VBPORG: INUM0 VBPEND: INUM0 ;MKAT ACHLOC,SYM ;DONT KNOW WHATS UP HERE, IF NEEDED CHECK ACHLOC ;%% THIS WAS A PREDECESSOR TO THE FUNCTIONS UNDER SWITCH "REALLC" ;%% NO LONGER USEFUL PAGE ; ; ALL THE ATOMS IN THE WHOLE SYSTEM MK MK MK MK MK MK MK MK MK MK MK MK MK MK MK MK MK MK MK MK MK MK MK MK MK MK MK MK MK ;##REMOVE MARKER MK MK MK MK MK MK MK MK MK<@,<\>,<\#\ >,<\P>,^,^^,_,__, , , ?, . ,< . UNBOUND)>> MK<- LOCATION UNCERTAIN, = ,! ,!0,!NX,!UNDO,!VALUE,##> MK<#1,#2,#3,$%DOTFLG,%%BKPOS,%%CMDL,%%V> MK<%DEFINE,%DEREAD,%DEVP,%ERDEPTH,%LOOKDPTH,%PREVFN%> MK<%PRINFN,%READIN,&,& ,<(>,<(DEFPROP >,<)>,*,*ANY*,*RSETERX,--> MK<-IN-,::,:::,/BREAK1,:,=,==,?=,??> MK<... , ...],BINARY PROGRAM SPACE EXCEEDED> MK MK MK MK MK MK MK MK MK ;%% MORE NEW SYSTEM FUNCTIONS MK ;ATOMS OF GENERATED FUNCTIONS MK MK BFWS: EFWS: 0 RELOC XLIST LIT LIST BHORG: 0 RELOC PAGE SUBTTL LISP STORAGE ALLOCATOR (ONCE ONLY) ALLOC: CLEARM 0,SBPS ;SET UP INITIAL ALLOCATIONS FOR SPACE HRRZI A,BFWS-FS ;THIS IS THE SIZE OF THE ORIGINAL FS HRRZM A,SFS HRRZI A,EFWS-BFWS ;THIS ALLOWS ONLY THE INITIAL HRRZM A,SFWS ;FWS HRRZI A,0 ;THE INITIAL ALLOCATION FOR SPDL HRRZM A,SSPDL HRRZM A,SRPDL ;AND FOR RPDL IS SET UP IN INALLC HRRZI A,FS HRRZM A,FSO ;THIS SETS UP INITIAL FS POINTER HRRZI A,BFWS ;THIS SETS UP INITIAL FWS ORIGIN POINTER HRRZM A,FWSO# HRRZI A,EFWS HRRZM A,EFWSO# MOVEI A,FS ADDM A,VBPORG ;SET UP VARIABLE FOR BPS ORIGIN SOS A ADDM A,VBPEND MOVE A,JOBREL HRLM A,JOBSA CALLI RESET MOVEI A,DDT CALLI A,2 ;SET UP DDT REENTRY POINT FOR AUTOMATIC CONTROL H MOVEI A,LISPGO HRRM A,JOBSA SETOM INITFW# ;FLAG FOR STANDARD INITIALIZATION OF SETZM JRELO# ;OF SIZES, AND TO INDICATE CORE WAS EXPANDED JRST INALLC DEFINE MKENT (A)< INTERNAL A> ;##DEBUG QUEUE MKENT IFN QALLOW< ;%% [1] MKENT ;%% [1] > ;%% [1] MKENT MKENT MKENT MKENT MKENT MKENT MKENT MKENT MKENT MKENT MKENT MKENT IFN ALVINE,> ;%% RECENT ADDITIONS MKENT IFN QALLOW< ;%% [1] MKENT ;%% [1] > ;%% [1] MKENT IFN REALLC < MKENT > ;$$ FOR ALAN'S DIRECT ACCESS INPUT MKENT ;## FOR BILL'S DIRECT ACCESS INPUT/OUTPUT MKENT MKENT MKENT MKENT MKENT ;$$ FOR ALVINE MKENT ;%% FOR THE MODIFIED ARITHMETIC PACKAGE MKENT PAGE END ALLOC