;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
;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,<TWOSEG>
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"
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
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,BLOCK.,WORD1,SEMI>
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
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.
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<WORD,FIND,LOC.,SEMI,QUESTN> ;FIND MAY SKIP
SUBTTL "GO" (TEXT) INTERPRETER
;INTERPRETER LOOP FOR DICTIONARY REFERENCES BY NAME
GO: USE<WORD,FIND,EXECUT,QUERY>
USE<NUMBER,LITERAL,QUERY>
USE<QUESTN>
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<CORE,FLUSH,READ,SEMI>
CODE.(UPDATE) ;******** UPDATE
MOVE TT,PREV
SETOM LWD+1(TT) ;SET UPDATE FLAG -1
NEXT
CODE.(<ERASE-CORE>) ;******** 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