; FORTH PROGRAMMING SYSTEM ;Martin S. Ewing, California Institute of Technology, ;Pasadena, CA 91125 213-795-6811 ;12/17/77 - REG 16 FREED FOR FORTRAN. ;12/17/77 - RP/IC REG ASSIGNMENTS SWITCHED. ;12/16/77 - ADD SIN,COS,... EXTERNALS TO FORTRAN LIBRARY. ; (MUST NOW USE DUMMY FORTRAN RTN OR MACRO RTN TO LOAD!) ;08/28/77 - ADD "INTERPRET" FOR IN-CORE INTERPRETING. ;03/27/77 - ADD "FORSYS" "NOFORSYS" TO ALLOW SYSTEMS WITHOUT FORSYS.DAT. ;02/21/77 - WORDS "WOPEN", "WCLOSE" ENABLE OPENING BLOCK I/O FOR OUTPUT. ;12/31/76 - MAKE FORSYS.DAT READ ONLY UNTIL FLUSH TIME. ;12/12/76 - FIX UP 'CORE' WORD: TAKE # OF KWDS ON STACK. RADIX 8 TITLE FORTH PROGRAMMING SYSTEM SUBTTL ASSEMBLY PARAMETERS .DIRECTIVE FLBLST ;FIRST LINE BINARY LIST ONLY SALL ..FORT==0 ;IF DEFINED, INCLUDES FORTRAN LIBRARY RTNS IFDEF ..FORT < EXTERN SIN.,COS.,SQRT.,ATAN.,ATAN2.,EXP. EXTERN IFX.2,ASIN.,CEXP.,FLT.2,ALG10.,ALOG. > EXTERN .JBDDT,.JBSA,.JBREN,.JBREL ;Word header format: word 0: LINK ADR, 0 ; Word 1: CNT, C0, C1, C2, C3 ;(Last bit of word 1 is the precedence.) ;ASSEMBLY PARAMETERS ;TWSEG== 0 ;SIGNAL TWO SEGMENT ASSEMBLY, IF PRESENT IFDEF TWSEG, PWR== 4 ;LOG BASE 2 OF NUMBER OF DICT. THREADS NWAY== 1_PWR ;NUMBER OF DICT. THREADS MSK== NWAY-1 ;CORRESPONDING BIT MASK KORE=2 ;2K EXTRA CORE RPSIZ=100 ;RETURN STACK SIZE DCH=0 ;DISK'S SOFTWARE CHANNEL CHPWD=4 ;MAXIMUM NUMBER OF CHARACTERS PER FORTH 'WORD' WDLIM=^D72 ;MAX NUMBER OF CHARACTERS CONVERTIBLE BY "WORD" ;REGISTERS = LOW CORE R0= 0 R1= 1 R2= 2 R3= 3 R4= 4 R5= 5 R6= 6 R7= 7 V= 10 DP= 11 T= 12 TT= 13 ;NOTE TT MUST = T+1! SP= 14 IC= 15 ;R16 == FORTRAN PARAMETER BLOCK REG. RP= 17 SUBTTL MACROS ;MACROS TO ASSEMBLE DICTIONARY ENTRIES DEFINE CODE.(X,NAME< >) < LK.NEW==. XWD LK.OLD,0 ;;LINK ADR, 0 LK.T== LK.OLD ;;(TEMPORARY) LK.OLD==LK.NEW N==0 IRPC X, ;;COUNT CHARACTERS IN X M==N IFG M-CHPWD, ;;CLIP AT MAX LIMIT I==0 ZZ==N ;;TOTAL CHARACTER COUNT IRPC X, < ;;CHARACTER LOOP I==I+1 IFLE I-4, < IFLE I-M, IFG I-M, ZZ==ZZ_7+Q. > > REPEAT 4-I, ;;IF LESS THAN 4 CHARS IN NAME ZZ==ZZ_1 ;;FINAL ALIGNMENT ANAME==. ;;REMEMBER PLACE EXP ZZ IFNB , ;;LABEL IF REQUESTED > ;;END CODE. DEFINE IMMED < QQQQ==. RELOC ANAME EXP ZZ!1 ;;SET PRECEDENCE BIT RELOC QQQQ > DEFINE DEF(X,NAME< >) < CODE.(,) PUSHJ RP,COLON > ;;END DEF DEFINE CONST(X,VALUE) < CODE.() HRREI T,VALUE ;;18-BITS ONLY JRST PUSH1 > ;;END CONST DEFINE USE(LIST) > DEFINE NEXT ;NOTE IC UPDATED AFTER ADR CALC! SUBTTL CONSTANTS, INTEGERS, BUFFERS HEAD: BLOCK NWAY ;FILLED AT ENTRY STATE: 0 LAST: 0 OPX: 0 DP00: XWD 0,DP0 SP00: XWD -1,SP0 RP00: XWD 0,RP0-1 MSGPTR: POINT 7,MSG SPLIM: XWD SP0-DP0-40,0 ;-40 FOR SAFETY OUT: POINT 7,MSG BASE0: 12 ;DECIMAL ******** NOTE! DELIM: " " PREV: BUFF1 ALT: BUFF2 EMPTY: 0 D: 0 L: 0 F: 0 IN: 0 SCR: 0 OKFLG: 0 LWD=400 BUFF1: BLOCK LWD+1 ;LAST WD IS BLOCK NUMBER 0 ;UPDATE FLAG BUFF2: BLOCK LWD+1 0 OUTMSG: BLOCK 33 ;132 CHARACTERS OUTPUT MSG: BLOCK 21 ;72 CHARACTERS INPUT MSGTOP: ASCII/ / GUARD: 0 ;FOR "WORD" TO INSERT DELIM DSK: 016 ;.IODPR MODE: DUMP RECORDS, NON-BUFFERED SIXBIT/DSK/ XWD 0,0 DIN: XWD 0,5 ;EXTENDED FORM FOR LOOKUP 0 SIXBIT/FORSYS/ SIXBIT/DAT/ 0 RBSIZ: 0 ;WILL BE LENGTH OF FILE IN WORDS DOUT: SIXBIT/FORSYS/ SIXBIT/DAT/ 0 0 PROGR: IOWD 200,1 ;I/O PROGRAM (DUMMY ADR) IOWD 200,1 ;TWO '10 BLOCKS PER FORTH BLOCK 0 IOENBL: -1 ;PERMIT OPENING OF FORSYS.DAT IFDEF TWSEG,< LOWLIM== . RELOC 400000> ;SWITCH TO HIGH SEGMENT OKMSG: ASCIZ/ok/ CRMSG: ASCIZ/ / FTBL: IFX.2 ;TABLE OF FORTRAN ENTRIES ALG10. ALOG. ASIN. ATAN2. ATAN. CEXP. COS. FLT.2 SIN. SQRT. EXP. SUBTTL ABORT, ETC. LK.OLD== 0 ;ORIGIN OF DICTIONARY CODE.(QUESTN,QUESTN) ;******** QUESTN ABORT: HRRZ T,DP ADD T,[POINT 7,1] MOVE SP,SP00 MOVE RP,RP00 SETOM EMPTY SETZM SCR SETZM STATE MOVEI TT," " MOVEM TT,DELIM MOVEI IC,ABORT2 JRST PUSH1 ABORT2: USE POINT 7,[BYTE (7)2,077,040] ;QUESTION MARK USE CODE.(FORSYS) ;******** FORSYS SETOM IOENBL ;ENABLE OPENING OF FORSYS.DAT RELEASE DCH, ;IN CASE ALREADY OPEN JSP R2,OPNR ;OPEN FORSYS.DAT NEXT ;(DEFAULT) CODE.(NOFORSYS) ;******** NOFORSYS SETZM IOENBL ;DISABLE FORSYS.DAT RELEASE DCH, ;RELEASE CHANNEL NEXT SUBTTL OPENING OPNR: RESET ;FOR START OR RESTART MOVE TT,IOENBL ;CHECK IF FORSYS JUMPE TT,(R2) ;IS ENABLED SETZM DOUT+2 SETZM DOUT+3 MOVE 1,[POINT 7,MSG] MOVEM 1,OUT ;RE-INITIALIZE OUTPUT PTR OPEN DCH,DSK ;OPEN DISK FILE (TTY ALWAYS OPEN) JRST ERR LOOKUP DCH,DIN JRST ERR JRST (R2) ; NOTE USE OF R2 ERR: OUTSTR [ASCIZ /'FORSYS.DAT' cannot be opened for input./] JRST EOF CODE.(REOPEN) ;******** REOPEN JSP R2,OPNR NEXT CODE.(WOPEN) ;******** WOPEN MOVEI R0,0 HRRM R0,DOUT+1 SETZM DOUT+2 SETZM DOUT+3 MOVEI R0,4 ;NUMBER OF RETRIES ALLOWED WOPL: ENTER DCH,DOUT ;TRY TO OPEN FORSYS FOR OUTPUT JRST WOPERR ;NO, TRY TO RECOVER NEXT ;NORMAL OPEN WOPERR: OUTSTR [ASCIZ/'FORSYS.DAT' unavailable for output. /] SOSGE R0 JRST ABORT ;CAN'T RECOVER MOVEI R1,5 ;WAIT 5 SEC. SLEEP R1, OUTSTR [ASCIZ/Will try again. /] JRST WOPL CODE.(WCLOSE) ;******** WCLOSE CLOSE DCH,2 ;CLOSE OUTPUT ON FORSYS NEXT SUBTTL TTY ROUTINES BASE== R0 Q== R1 PTR== R2 OP== R3 CODE.(CONVERT,CONVERT) ;******** CONVERT JUMPGE SP,ABORT ;UNDERFLOW? MOVE BASE,BASE0 MOVE Q,T ;SIGNED VALUE MOVM T,T ;MAGNITUDE HRRZ PTR,DP ADDI PTR,^D19 ;ALLOWS ABOUT 64 CHARACTERS CNV1: IDIV T,BASE ADDI T+1,"0" PUSH PTR,T+1 SKIPE T JRST CNV1 MOVEI T,"-" SKIPGE Q PUSH PTR,T ;PUT MINUS IF NEGATIVE HLRE T,PTR ;?? SUB T,F ;COMPARE AGAINST FIELD LENGTH JUMPGE T,CNV2 MOVEI Q," " PUSH PTR,Q AOJL T,.-1 ;PAD WITH BLANKS CNV2: HRRZ OP,DP ;REMEMBER DP IS XWD COUNT,ADR ADD OP,[POINT 7,4] ;(WILL PACK BYTES IN FORWARD ORDER) MOVEM OP,OPX ;IF NEEDED LATER HLRZ T,PTR ;COUNT IDPB T,OP ;GOES IN FIRST BYTE CAIG PTR,777777 JRST .+4 POP PTR,T ;GET A CHAR IDPB T,OP ;PACK IT JRST .-4 MOVE T,OPX ;RETURN A BYTE POINTER JRST PUT ;PUT STARTING ADDRESS CODE.(COUNT,COUNT) ;******** COUNT (ILDB) ILDB T,0(SP) ;LOAD CHAR COUNT,LEAVE BYTE POINTER ;INCREMENTED FOR TYPE. JRST PUSH1 CODE.(TYPE,TYPE) ;******** TYPE OP== R1 IP== R0 CAILE T,^D132 ; OVER SIZE? MOVEI T,^D132 ; YES, CLIP MOVE OP,[POINT 7,OUTMSG] MOVE IP,1(SP) ;BYTE PTR TO 1ST CHAR OF MSG TYPE2: ILDB TT,IP ;TRANSFER BYTES IDPB TT,OP SOJG T,TYPE2 MOVEI TT,0 IDPB TT,OP ;END OF MSG OUTSTR OUTMSG ;OUTSTR IS FASTER THAN OUTCHR SETZM OKFLG ;INHIBIT OK JRST POP2 ;DEF( CR LF) ------- MANUALLY CODED TO SUIT MACRO-10 LK.NEW== . XWD LK.OLD,0 ;LINK ADR, 0 LK.OLD== LK.NEW BYTE (7)2,015,012,040,040(1)1 ;CR,LF,BLANK,BLANK, PRECEDENCE SKIPE OKFLG ;TYPE OK? OUTSTR OKMSG SETOM OKFLG SETOM EMPTY JRST CRSND CODE.(CR) ;******** CR CRSND: OUTSTR CRMSG ;SEND CR,LF NEXT CODE.(QUERY,QUERY) ;******** QUERY MOVEI IC,GO MOVE TT,SCR SKIPGE TT NEXT ;LOADING FROM CORE (SCR<0) CAILE TT,2 NEXT ;WE ARE LOAD'ING SKIPN EMPTY ;NEED NEW MSG BUFFER? NEXT ;NO JSP R2,RECEIV SETZM EMPTY SETOM OKFLG NEXT IP== R0 Q== R1 RECEIV: MOVE IP,MSGPTR MOVEM IP,IN MOVEI Q,WDLIM ;CHARACTER LIMIT INCH: INCHWL TT CAIN TT,015 ;CAR RETN JRST RCLF IDPB TT,IP SOJG Q,INCH JRST ABORT ;RUN OUT RCLF: MOVEI TT," " ;SPECIAL BLANK INSERTED IDPB TT,IP MOVEI TT,015 ;CR IDPB TT,IP INCHRW TT ;PRESUMABLY LF IDPB TT,IP MOVEI TT," " ;BLANK FOR SAFETY IDPB TT,IP JRST (R2) CODE.(LOAD) ;******** LOAD MOVE TT,[POINT 7,0] JRST INT0 CODE.(INTERPRET) ;******** INTERPRET MOVE TT,T ;WORD ADDRESS FROM STACK IOR TT,[POINT 7,0] ;MADE INTO BYTE PTR MOVEI T,0 INT0: PUSH RP,IN ;SAVE INFO ON CURRENT INPUT STREAM PUSH RP,SCR PUSH RP,IC MOVEM TT,IN ;USUALLY POINT 7,0 MOVEM T,SCR ;SET NEW BLOCK NUMBER ;OR TTY(0) OR INTRPT ADR(<0) MOVEI IC,GO ;SET UP INTERPRETER JRST POP1 CODE.(<;S>) ;******** ;S POP RP,IC ;RESTORE INPUT STREAM, ETC POP RP,SCR POP RP,IN JUMPL RP,ABORT NEXT SUBTTL STACKS & ARITHMETIC CODE.(OCTAL) ;******** OCTAL IMMED MOVEI R0,10 PBASE: MOVEM R0,BASE0 NEXT CODE.(DECIMAL) ;******** DECIMAL IMMED MOVEI R0,12 JRST PBASE CODE.(DROP) ;******** DROP JRST POP1 POP2: AOBJP SP,SUFLO ;POP 2 WORDS POP1: AOBJP SP,SUFLO ;POP A WORD MOVE T,(SP) ;UPDATE T WITH TOP OF STACK NEXT CODE.(SWAP) ;******** SWAP EXCH T,1(SP) PUT: MOVEM T,0(SP) NEXT CODE.(<+>) ;******** + ADDB T,1(SP) ;RESULT IN T AND 1(SP) AOBJP SP,SUFLO NEXT BINARY: AOBJP SP,SUFLO MOVEM T,0(SP) NEXT CODE.(DUP) ;******** DUP PUSH1: POP SP,V ;DECR SP, IGNORE DATA! MOVEM T,0(SP) NEXT ;OK SUFLO: OUTSTR [ASCIZ/Stack underflow! /] JRST ABORT SUBTTL COMPILATION WORDS DEF(WORD,WORD) ;******** WORD USE SCR1: MOVE T,SCR ;CHECK INPUT SOURCE JUMPGE T,SCRX MOVEI T,0 ;INTERPRET FROM CORE AOJA IC,PUSH1 ;I.E. SCR<0 SCRX: JUMPN T,PUSH1 ;YES, HAVE TO DO BLOCK AOJA IC,PUSH1 ;NO, SKIP&PUSH IP== R1 OP== R2 CT== R3 CH== R4 WORD1: MOVE IP,IN ;BYTE PTR TO FAST CORE ADD IP,T ;ZERO IF BLOCK 0, BUFF ADDR OTHERWISE MOVE OP,[POINT 7,0] ;BYTE PTR SKELETON HRR OP,DP ;ADDR FOR OUTPUT=NEXT DICT ENTRY ADDI OP,1 ;PLUS 1 SETZM (OP) ;MAKE SURE LAST BIT IS ZERO ;(WORKS ON 1ST WORD ONLY! MOVEM OP,OPX ;SAVE INITIAL POINTER MOVE TT,DELIM DPB TT,[POINT 7,GUARD,6] ;INSURE EXISTENCE OF A DELIM MOVEI CT,WDLIM ;MAXIMUM NUMBER OF CHARACTERS ALLOWED IDPB CT,OP ;VALUE IS FIRST BYTE ILDB CH,IP ;GET CHAR CAMN CH,DELIM ;THROW OUT EXTRA DELIMITERS JRST .-2 IDPB CH,OP ILDB CH,IP CAME CH,DELIM SOJG CT,.-3 MOVEI TT,7 ;GUARANTEE LAST WD PADDED WITH BLANKS MOVEI CH," " IDPB CH,OP SOJG TT,.-1 MOVN CT,CT ADDI CT,WDLIM+1 ;WHAT IS TRUE COUNT? MOVE OP,OPX ;RESET TO FIRST OUTPUT CHAR IDPB CT,OP ;TRUE COUNT TO FIRST CHARACTER SUB IP,T ;UNDO THE DAMAGE FROM ABOVE MOVEM IP,IN ;SAVE INPUT PTR MOVEI 0," " MOVEM 0,DELIM ;FORCE DELIM=BLANK AFTER WORD JRST POP1 CODE.(FIND,FIND) ;******** FIND HRLZI TT,FF1 ;PHASE IN LOOP BLT TT,6 MOVE TT,1(DP) MOVE R7,TT LSH R7,-^D22 ANDI R7,MSK ;SELECT PROPER HEAD MOVE T,HEAD(R7) ;MUST RESTORE LATER JRST F1 FF1: PHASE 0 ;TO BE RELOCATED IN LOW MEMORY F1: JUMPE T,SKIPX MOVE R7,1(T) ANDCMI R7,1 ;RESET LSB (PRECEDENCE) CAMN TT,R7 JRST F3 HLRZ T,0(T) JRST F1 DEPHASE ;END OF RELOCATED SEGMENT F3: MOVEM T,L ;L(IN CORE) POINTS TO LK,CA FIELD MOVE T,0(SP) NEXT SKIPX: MOVE T,0(SP) SKIP: ADDI IC,2 ;SKIP USED ELSEWHERE NEXT EXECUT: MOVE V,L DO: MOVE TT,1(V) ;NAME & PRECEDENCE ANDI TT,1 ;PREC. ONLY CAML TT,STATE ;STATE=0 OR 1 EX1: JRST 2(V) ;EXECUTE ADDI V,2 ;POINT TO 1ST PARM WD COMPIL: HRRZM V,0(DP) ;COMPILE ADDR OF 1ST PARM WD AOBJN DP,.+1 NEXT CODE.(LITERAL,LITERAL) ;******** LITERAL RETN: MOVE TT,STATE JUMPG TT,LITC ;COMPILING? MOVE T,L ;NO, PUSH THE NUMBER ON STACK JRST PUSH1 LITC: MOVEI V,LIT. ;WE WILL COMPILE IT MOVEM V,0(DP) ;CALL TO LIT MOVE TT,L MOVEM TT,1(DP) ;NUMBER IS PARAMETER ADD DP,[XWD 2,2] NEXT LIT.: MOVE T,0(IC) ;GET PARAM AOJA IC,PUSH1 ;SKIP LITERAL PARM SEMIC: PUSHJ RP,EXCOL ;LEAVE COMPILE MODE JRST COMPIL ;COMPILE SEMI OR SCODE CODE.(<;>) ;******** ; IMMED JSP V,SEMIC SEMI: POP RP,IC ;NOTE RP POINTS TO LAST USED WORD NEXT ENCOL: MOVE TT,LAST ;ENTER COMPILE MODE AOS -1(TT) AOS -1(TT) ;FLIP LAST WD NAME MOVEI TT,1 MOVEM TT,STATE ;SET COMP STATE AOBJN DP,.+1 ;LEAVE ROOM FOR JSP OR PUSHJ POPJ RP, EXCOL: MOVE TT,LAST ;EXIT COMPILE MODE SOS -1(TT) SOS -1(TT) ;UNFLIP LAST WD NAME SETZM STATE ;RESET STATE POPJ RP, CODE.(<;CODE>) ;********** ;CODE IMMED JSP V,SEMIC SCODE: HRRZ TT,IC ;NOTE IC HAS FLAGS IN LEFT HALF ADD TT,[JSP V,0] SCODEC: MOVEM TT,@LAST ;LAST POINTS TO 1ST PARM WD, PUSHJ, JRST SEMI ;OR JSP. CODE.(<;:>) ;********** ;: IMMED MOVEI TT,SCODE MOVEM TT,0(DP) MOVE TT,[PUSHJ RP,COLON] MOVEM TT,1(DP) ADD DP,[XWD 2,2] NEXT ; CODE.(:<) ;******** :< LK.NEW==. XWD LK.OLD,0 LK.OLD==LK.NEW BYTE (7)2,072,074,040,040(1)1 PUSHJ RP,EXCOL ;LEAVE COMPILE MODE MOVEI TT,COLBRK MOVEM TT,0(DP) AOBJN DP,.+1 SETZM 0,STATE NEXT COLBRK: MOVE V,IC POP RP,IC JRST (V) ; CODE.(>:) ;******** >: LK.NEW==. XWD LK.OLD,0 LK.OLD==LK.NEW BYTE (7)2,076,072,040,040(1)0 PUSHJ RP,ENCOL ;ENTER COMPILE MODE MOVE TT,[PUSHJ RP,COLON] MOVEM TT,-1(DP) NEXT DEF(CODE,CODE) ;******** CODE USE ENTER: MOVE TT,1(DP) LSH TT,-^D22 ANDI TT,MSK HRRZ R0,DP EXCH R0,HEAD(TT) HRLM R0,0(DP) ADD DP,[XWD 2,2] HRRZM DP,LAST ;LAST POINTS TO [LINK,0] NEXT DEF(<:>) ;******** : (COLON) USE COLONS: PUSHJ RP,ENCOL ;ENTER COMPILE MODE MOVE TT,[PUSHJ RP,COLON] ;INSTALL PUSHJ FOR COLON ONLY JRST SCODEC COLON: EXCH IC,(RP) NEXT CODE.(<,>) ;******** , COMMA: MOVEM T,0(DP) AOBJN DP,.+1 JRST POP1 CONS: MOVE TT,[JSP V,CON] MOVEM TT,@LAST AOBJN DP,.+1 JRST COMMA CON: MOVE T,0(V) ;CON PUSHES A NUMBER FROM PARM LIST JRST PUSH1 DEF(FORGET) ;******** FORGET USE PARE: MOVE R0,L CAIGE R0,DP0 MOVEI R0,DP0 ;DON'T TRIM OBJECT MOVEI R1,NWAY-1 ;THREAD INDEX THLP: MOVE R2,HEAD(R1) THLP2: CAMGE R2,R0 JRST THTRNC HLRZ R2,0(R2) JRST THLP2 THTRNC: MOVEM R2,HEAD(R1) SOJGE R1,THLP MOVE DP,R0 ;RECLAIM SPACE NEXT LOC.: AOS L AOS L JRST RETN ;WHERE IT IS PUSHED OR COMPILED DEF(<'>) ;******** ' IMMED USE ;FIND MAY SKIP SUBTTL "GO" (TEXT) INTERPRETER ;INTERPRETER LOOP FOR DICTIONARY REFERENCES BY NAME GO: USE USE USE SUBTTL BLOCK I/O CORE: MOVE TT,PREV ;A BUFFER ADDR (THE LAST READ OR WRITTEN) CAMN T,LWD(TT) ;IS IT OUR BLOCK? JRST GOT ;YES MOVE Q,ALT ;ANOTHER ADDR CAME T,LWD(Q) ;WILL IT BE ALT? NEXT ;NO, HAVE TO READ MOVEM TT,ALT ;YES, SWITCH BUFFERS MOVEM Q,PREV MOVE TT,Q GOT: MOVE T,TT ADDI IC,2 ;SKIP OVER 2 JRST PUT ;PUT THE GOOD BUFFER ADDR CODE.(FLUSH,FLUSH) ;******** FLUSH MOVE Q,PREV ;SWITCH MOVE TT,ALT MOVEM Q,ALT MOVEM TT,PREV SKIPN LWD+1(TT) ;THE UPDTE FLAG NEXT PUSH RP,TT MOVE TT,LWD(TT) ;INFORMALLY PASSING THE BLOCK NUMBER PUSHJ RP,WDISK ;WRITE BACK TO DISK POP RP,TT SETZM LWD+1(TT) NEXT READ: MOVE TT,T ;BLOCK NUMBER MOVE T,PREV ;BUFFER ADDRESS MOVEM TT,LWD(T) PUSHJ RP,RDISK JRST PUT DEF(BLOCK,BLOCK.) ;******** BLOCK USE CODE.(UPDATE) ;******** UPDATE MOVE TT,PREV SETOM LWD+1(TT) ;SET UPDATE FLAG -1 NEXT CODE.() ;******** ERASE-CORE SETZM BUFF1+LWD SETZM BUFF2+LWD NEXT RDISK: CAIG TT,0 ;******** (RDISK) (BLOCK IN TT) MOVEI TT,1 IMULI TT,2 ;DOUBLE BLOCKS SUBI TT,1 ;NO. 1 IS FIRST AVAILABLE TO US PUSHJ RP,CHKBLK ;IN BOUNDS? USETI DCH,(TT) ;SET UP FOR INPUT OF CORRECT BLOCK RRD: MOVE TT,PREV SUBI TT,1 HRRM TT,PROGR ;CORE ADDRESS (-1) ADDI TT,200 ;SECOND PDP-10 BLOCK HRRM TT,PROGR+1 IN DCH,PROGR POPJ RP, ;OK OUTSTR [ASCIZ/Block input error. /] JRST ABORT WDISK: CAIG TT,0 ;******** (WDISK) (BLOCK IN TT) MOVE TT,1 IMULI TT,2 SUBI TT,1 PUSHJ RP,CHKBLK ;IN BOUNDS? USETO DCH,(TT) MOVE TT,PREV SUBI TT,1 HRRM TT,PROGR ADDI TT,200 HRRM TT,PROGR+1 OUT DCH,PROGR POPJ RP, OUTSTR [ASCIZ/Block output error. /] JRST ABORT CHKBLK: MOVE R0,RBSIZ ;WORD LENGTH OF FILE IDIVI R0,200 ;IN BLOCKS (PDP-10) CAML R0,TT POPJ RP,0 ;OK RETURN OUTSTR [ASCIZ/Block number too high! /] JRST ABORT SUBTTL CONSTANT WORDS DEF(CONSTANT,CONSTA) ;******** CONSTANT USE CONST(PUSH,PUSH1) CONST(PUT,PUT) CONST(BINARY,BINARY) CONST(POP,POP1) CONST(COMMA,COMMA) CONST(ABORT,ABORT) CONST(BASE,BASE0) CONST(FORTH,1) ;YOU CAN SAY "FORTH LOAD" IFDEF ..FORT < CONST(FORTRAN,FTBL) ;FORTRAN ENTRY TABLE > SUBTTL ASSEMBLER DEF(CPU) ;******** CPU USE MOVE TT,0(V) ;OP CODE DEPOSITED EARLIER LSH TT,4 IOR T,TT ;OR IN AC FROM STACK HEAD ROT T,-^D13 ;MOVE TO HIGH ORDER 13 BITS IOR T,1(SP) ;SECOND STACK IS I,X,Y (ADDRESS) AOBJP SP,SUFLO ;POP 1, SECOND POPPED BY COMMA JRST COMMA SUBTTL MISCELLANY DEF(<(>) ;***** ( ***** ALLOW COMMENTS IMMED USE LPAR1: MOVEI 0,")" MOVEM 0,DELIM NEXT CODE.(DDT) ;******** DDT HRRZ TT,.JBDDT ;FROM JOB DATA AREA (PDP-10) JUMPE TT,ABORT ;DDT NOT LOADED JRST (TT) ;GO TO DDT CODE.(SAVE) ;******** SAVE SETZM BUFF1+LWD ;DO 'ERASE-CORE' SETZM BUFF2+LWD MOVEI 0,REST ;RESTORE ADDRESS HRRM 0,.JBSA ;DEFINED FOR NEXT START MOVEM DP,STATE ;CONVENIENT PLACE TO KEEP DP JRST EOF REST: JSP R2,OPNR ;NOTE USE OF R2 MOVE DP,STATE ;RESTORE DP JRST ABORT CODE.(NUMBER,NUMBER) ;******** NUMBER IP== R1 LL== R2 BASE== R3 PLACES==R4 SIGN== R5 CH== R6 MOVE IP,[POINT 7,0,6] ;BYTE POINTER SKELETON HRR IP,DP ADDI IP,1 ;PT TO CH STRING FROM WORD MOVEI LL,0 MOVE BASE,BASE0 MOVNI PLACES,1000 ;LARGE NEGATIVE NUMBER ILDB CH,IP ;FETCH CHARACTER MOVE SIGN,CH CAIN CH,"-" ;GET ANOTHER IF WE GOT A MINUS ILDB CH,IP CAIN CH,"+" ;ALLOW + SIGN ILDB CH,IP JRST NATURL+2 NATURL: MOVE BASE,BASE0 ;RESET BASE FROM POSSBILE ":" ILDB CH,IP SUBI CH,"0" JUMPL CH,NONDIG CAML CH,BASE ;TOO HIGH? JRST NONDIG ;WE'D BEST REJECT IT DIGIT: JOV .+1 ;BE CAREFUL OF OVFL IMUL LL,BASE JOV .+2 JRST .+2 IOR LL,[XWD 400000,0] ADD LL,CH ADDI PLACES,1 JRST NATURL NONDIG: ADDI CH,"0" CAIE CH,":" ;FOR SEXIGESIMAL JRST .+3 MOVEI BASE,6 JRST NATURL+1 CAIE CH,"." JRST .+3 MOVEI PLACES,0 JRST NATURL MOVEM PLACES,D ;STORE NUMBER OF DIGITS TO RT OFDECIMAL CAIN SIGN,"-" MOVN LL,LL ;NEGATE MOVEM LL,L CAMN CH,DELIM ;DELIM USUALLY " " NEXT ;DONE OK JRST SKIP ;NOT CONVERTIBLE AS NUMBER CODE.() ;******** CORE? HRRZ T,SP00 ;CALCULATE REMAINING HRRZ R0,DP ;DICT+STACK SPACE SUB T,R0 JRST PUSH1 ;RETURN # WORDS LEFT. CODE.(CORE) ;******** CORE IMULI T,2000 ;INPUT IN KILOWORDS,NOW WORDS SUBI T,1 ;SO 6 --> 6K WORDS, ETC. HRRZ R0,DP ;CHECK THAT WE ADDI R0,RPSIZ+100 ;DON'T CUT OFF CURRENT CAMGE T,R0 ;DICT AND STACK MOVE T,R0 ;CLIP MOVE R0,T ;SAVE CAMG T,.JBREL ;CHECK FOR SENSE OF CHANGE JRST CLWR ;WE WANT TO SHRINK CALLI T,11 ;CORE CALL JRST ABORT ;ERROR CLWR: SUBI R0,RPSIZ+1 HRRZ R2,SP00 ;MOVE STACK DATA HRRZ R1,SP SUB R1,R2 ADD R1,R0 ;TO=R0+SP-SP00 HRL R1,SP ;FROM=SP MOVE R3,R0 HRRZ R4,SP00 SUB R3,R4 ;R0-SP00 HRRZ R2,RP ADD R2,R3 ;END=RP+OFFSET BLT R1,@R2 ;DO IT ADD SP,R3 ;SP=SP+OFFSET ADD RP,R3 ;RP=RP+OFFSET MOVE T,R0 ;RESTORE IF NEEDED CAML T,.JBREL ;SHRINKING? JRST CBIGR ;NO CALLI T,11 ;SHRINK JRST ABORT CBIGR: MOVEM R0,RP00 ;RESET STACKS HRROM R0,SP00 HRRZ R0,.JBREL ;GET HIGH ADR HRLM R0,.JBSA ;FOR RUN AFTER SAVE JRST POP1 ;GET RID OF INPUT HEAD0: CODE.(GOODBY) ;******** GOODBY EOF: RELEASE DCH,0 ;RELEASE DISK EXIT LIT IFDEF TWSEG, ;GO BACK TO LOW SEGMENT VAR DP0: Z BYTE (7)8,7,110,105,114 ;BELL HEL BYTE (7)114,117,15,12 ;LO ENTRY: JSP R2,OPNR ;REENTRANT CALL USING R2 OUTSTR [ASCIZ/Forth 12-19-77! /] MOVEI R0,ABORT MOVEM R0,.JBREN ;SET REENTER ADDRESS MOVE DP,DP00 MOVEI R1,HEAD0 ;TRUNCATE DICTIONARY MOVEM R1,HEAD IFG NWAY-1,< MOVE R1,[XWD HEAD,HEAD+1] BLT R1,HEAD+NWAY-1> JRST ABORT LIT BLOCK KORE*2000 ;CAN BE CHANGED BY "CORE" SP0: Z RP0: BLOCK RPSIZ END ENTRY