Google
 

Trailing-Edge - PDP-10 Archives - FORTRAN-10_V7wLink_Feb83 - lnkscn.mac
There are 48 other files named lnkscn.mac in the archive. Click here to see a list.
TITLE	LNKSCN - INTERFACE TO SCAN FOR LINK
SUBTTL	D.M.NIXON/DMN/JLd/JNG/PAH/DZN/PY	6-Jan-83



;COPYRIGHT (C) 1973, 1983 BY
;DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
;
;
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY  IN  ACCORDANCE  WITH  THE  TERMS  OF  SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR ANY  OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF THE  SOFTWARE  IS  HEREBY
;TRANSFERRED.
;
;
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT  NOTICE
;AND  SHOULD  NOT  BE  CONSTRUED  AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY  OF  ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.


SEARCH	LNKPAR,LNKLOW,MACTEN,UUOSYM,SCNMAC
SALL

ENTRY	LNKSCN
EXTERN	LNKLOD,LNKCOR,LNKLOG,.TYOCH


CUSTVR==0		;CUSTOMER VERSION
DECVER==5		;DEC VERSION
DECMVR==1		;DEC MINOR VERSION
DECEVR==2026		;DEC EDIT VERSION

VERSION


SEGMENT
SUBTTL	COMMUNICATION WITH SCAN


EXTERN	.ISCAN,.TSCAN,.OSCAN
EXTERN	.POPJ1,.SWDEC,.SWOCT,.SWSIX,F.NAM,.OCTNW
;COMMUNICATION WITH .TYOCH
EXTERN	.TCHAR,.TCRLF,.TDECW,.TOCTW,.TSIXN,.TSTRG,.TIAUC


;ACCUMULATORS

C==P4		;CHARACTER INPUT
SUBTTL	REVISION HISTORY


;START OF VERSION 1A
;37	ADD GARBAGE COLLECTOR AT CLANS
;47	INTEGRATE WITH SCAN %4
;52	ADD ASCIZ TEXT BLOCK
;60	ADD /VERSION SWITCH, MOVE .INSUB TO LNKSCN.MAC
;71	ADD PEF MESSAGE

;START OF VERSION 1B
;121	(12145)	.VERSW DOESN'T PRESERVE P4, /VER:1(20) FAILS

;START OF VERSION 2
;141	TURN ON ASCII TEXT BLOCK
;145	ADD /USERLIB & /NOUSERLIB SWITCHES
;147	TURN ON MIXFOR FEATURE
;150	REMOVE EDIT #71 (PEF MESSAGE)
;151	(12491) CALL .OSCAN CORRECTLY
;165	INTEGRATE WITH SCAN %5(356), REMOVE .VERSW

;START OF VERSION 2B
;253	Fix ASCII blocks:
;	if in CCL mode, tell SCAN to read our input
;	if multi-line, keep byte pointer so don't lose characters
;	if error, SCAN comes back for more, even if none
;264	Allow editing of bad file specs. when indirect
;411	If SCAN retruns again after the end of an ASCII block,
;	hand it "/K<eol>" so it will return from .TSCAN
;426	Suppress the prompt characters while processing ASCII text.
;427	Save all of SCAN's ACs in TXTIN.
;430	Prevent hanging in TI state while reading ASCII text.
;433	Properly support the /RUN switch.
;436	Defeat ^O when prompting.

;START OF VERSION 2C
;534	Fix problems with .OSCAN, ASCII text, and add /CRLF.
;554	Fix problems with switch scanning for cases like /SAVE.
;557	Clean up listing for release.

;START OF VERSION 3A
;560	Release on both TOPS-10 and TOPS-20 as LINK version 3A(560)

;START OF VERSION 4
;600	Remove call to DEFVALUES macro
;731	SEARCH MACTEN,UUOSYM
;740	Remove .SWVER code.
;765	Release on both TOPS-10 and TOPS-20 as LINK version 4(765)

;START OF VERSION 4A
;1122	Remove edit 740.
;1167	Don't allow symbol names to start with digits.
;1174	Label and clean up all error messages.
;1217	Clean up the listings for release.
;1220	Release on both TOPS-10 and TOPS-20 as version 4A(1220).

;START OF VERSION 4B
;1221	Allow .R LINK (commands) and @LINK commands
;1252	Remove edit 1221 on TOPS-20.
;1301	Use the message bits from SCAN.

;Start of Version 5.1
;2026	Update copyright notice.

SUBTTL	INITIALIZE SCANNER

LNKSCN:	JFCL	.+1		;NORMAL ENTRY
	SKIPE	F.EDIT		;ARE WE CORRECTING SPEC?
	JRST	[MOVEI	T1,FORCIN	;FORCE INPUT FROM TTY:
		PUSHJ	P,.TYPRE##	; INCASE INDIRECT/CCL
		JRST	MAINLP]		;GO GET LINE
	SKIPE	F.ASCI		;HOW ABOUT ASCII TEXT?
	JRST	[MOVEI	T1,USRIN	;YES, READ IT INSTEAD
		PUSHJ	P,.TYPRE##	;EVEN IF IND/CCL
		JRST	MAINLP]		;GO GET COMMAND
	MOVEI	T1,0		;NO, SET INPUT TO START
	PUSHJ	P,.TYPRE	;  OR CONTINUE NORMAL SOURCE
	SKIPE	N.ZER##			;CALLED TO PROCESS /RUN?
	JRST	[PUSHJ	P,.RUNCM##	;YES, DO THE RUN
		HRRZ	T1,.JBSA##	;RESTART IF FAILED
		JRST	(T1)]
E$$SNL::.ERR.	(MS,,V%L,L%I,S%I,SNL,<Scanning new command line>) ;[1174] 
	SETZ	T1,		;SCAN CAN USE TTCALLS
	PUSHJ	P,.TYOCH##	;SINCE PROBLEM WITH EXECUTE ONLY HACK
	MOVE	T1,.ISBLK	;DATA BLOCK FOR .ISCAN
	SKIPL	OSCANF		;ONLY INITIALIZE ONCE
	PUSHJ	P,.ISCAN	;INITIALIZE COMMAND SCANNER
	SKIPE	T1,TTYSUB	;NOW WE CAN SET LINE BUFFERING ROUTINE
	PUSHJ	P,.TYOCH##	;UNLESS STILL ZERO
SUBTTL	MAIN LOOP FOR COMMAND SCANNING

MAINLP:	MOVE	T1,.JBREL	;SET .JBFF OUTSIDE CORE RANGE
	MOVEM	T1,.JBFF	;INCASE /HELP
	MOVE	T1,.TSBLK	;DATA BLOCK FOR .TSCAN
	PUSHJ	P,.TSCAN	;GET THE COMMAND
	HLRZ	T1,.FLVRB##	;[1301] GET THE /MESSAGE MASK
	ANDCAM	T1,VERLVL	;[1301] RESET SPECIFIED BITS
	HRRZ	T1,.FLVRB##	;[1301] GET THE BITS SET BY /MESSAGE
	IOR	T1,VERLVL	;[1301] GET THE OLD BITS TOO
	SKIPN	T1		;[1301] ANY BITS SET
	MOVX	T1,M%P!M%F	;[1301] NO, USE THE DEFAULT
	TXNE	T1,M%C		;[1301] USER WANT CONTINUATION?
	TXO	T1,M%F		;[1301] YES, MAKE SURE HE GETS FIRST TOO
	MOVEM	T1,VERLVL	;[1301] STORE THE RESULT
IFN FTOPTION,<
	SKIPE	OSCANF		;-1 IF ALREADY DONE FOR THIS LOAD
	JRST	MAINL1		;NOT FIRST TIME
	PUSH	P,F.NXZR	;SAVE PTR TO END OF SCAN CHAIN
	PUSH	P,F.INZR	;AND TO BEGINNING
	SETZM	F.NXZR		;ZAP SO WON'T UPSET CLANS
	SETZM	F.INZR		;..
	SETZM	SWFLAG		;NO SWITCHES YET SEEN
	MOVE	T1,.OSBLK	;DATA BLOCK FOR OPTION FILE
	PUSHJ	P,.OSCAN	;READ USER OPTION PROFILE
	MOVEI	T2,F.INZR	;START OF NEW LIST
	MOVE	T1,T2		;NOT YET END OF LIST
	HRRZ	T2,(T1)		;LIST TERMINATED?
	JUMPN	T2,.-2		;NO
	POP	P,T2		;GET PREVIOUS LIST
	HRRM	T2,(T1)		;LINK INTO NEW LIST
	POP	P,F.NXZR	;MAKE SURE END OF CHAIN IS OK
	SETZM	SWFLAG		;CLEAR SWITCH SEEN FLAG
>;END OF IFN FTOPTION
	SETOM	OSCANF		;ONLY ONCE
MAINL1:	HRRZS	F.NXZR		;MAKE SURE LH ISN'T -1 FROM USRSWT
	SKIPN	F.INZR		;ANYTHING TO LOAD?
	JRST	MAINLP		;NO, TRY AGAIN
	MOVE	T1,F.INZR	;POINT TO CURRENT DATA BLOCK
	ADDI	T1,F.ZER	;POINT TO START OF SCAN INFO
	MOVEM	T1,F.WLZR	;FOR WILD
	MOVE	T1,LOGSUB	;RESET LOG DEVICE
	PUSHJ	P,.TYOCH	;SINCE SCAN WIPES IT OUT
	SKIPL	GOTO		;SEEN /G YET?
	JRST	MAINRT		;NO, LOAD WHAT WE HAVE
	SETZM	GOTO		;DON'T CONFUSE LNKLOD
	PUSHJ	P,.KLIND##	;IF CCL MODE DELETE TEMP FILE
MAINRT:	IFN FTOVERLAY,<
	SKIPE	OVERLW		;LOADING IN OVERLAY MODE
	JRST	LNKOV1##	;YES
>
	JRST	LNKLOD##	;AND LOAD THIS
.ISBLK:	5,,.+1
IFE TOPS20,<			;[1252]
	IOWD	1,[SIXBIT /LINK/] ;[1221] ALLOW MONITOR COMMANDS
>
IFN TOPS20,<			;[1252]
	0			;[1252] RESCAN DOES NOT WORK WITH TOPS-20
>				;[1252]
	OFFSET,,'LNK'
	USRIN,,0
	0
	UPRMPT,,0

.TSBLK: 9,,.+1
	IOWD LNKSWL,LNKSWN
	LNKSWD,,LNKSWM
	0,,LNKSWP
	-1
	CLANS,,0
	AIN,,AOUT
	0
	0,,FS.MOT!FS.MIO
	0,,USRSWT

IFN FTOPTION,<
.OSBLK: 4,,.TSBLK+1
>;END OF IFN FTOPTION

;SUBROUTINE TO CLEAR ANSWER AREA

CLRRET:	PUSHJ	P,DY.RET##	;RESTORE SPACE

CLANS:				;CLEAR START OF PARAMS
	SKIPN	T1,F.INZR	;NEED TO GARBAGE COLLECT?
	JRST	CLANZ		;NO
	SKIPE	T3,1(T1)	;YES, ANY SWITCHES FOR THIS SPEC?
	JRST	CLANSW		;YES, RETURN THEM FIRST
	HRRZ	T2,0(T1)	;GET NEXT POINTER
	MOVEM	T2,F.INZR	;STORE BACK FOR NEXT TIME ROUND
	MOVEI	T2,F.LEN	;LENGTH WE ALLOCATED
	JRST	CLRRET		;RETURN SPACE

CLANSW:	EXCH	T1,T3		;PUT ADDRESS OF SWITCH IN T1
	TLNN	T1,-1		;LEFT HALF SWITCH?
	JRST	CLANRS		;NO, TRY RIGHT
	HLRZ	T1,T1		;FOR INDEXING
	MOVE	T2,0(T1)	;LENGTH,,NEXT POINTER
	HRLM	T2,1(T3)	;STORE BACK IN (F.INZR)+1
	HLRZ	T2,T2		;LENGTH
	JRST	CLRRET		;RETURN SPACE

CLANRS:	MOVE	T2,0(T1)	;LENGTH,,NEXT POINTER
	HRRZM	T2,1(T3)	;STORE BACK IN (F.INZR)+1
	HLRZ	T2,T2		;LENGTH
	JRST	CLRRET		;RETURN SPACE

CLANZ:	SETZM	F.NXZR		;FOR SCAN
	SETZM	SWFLAG		;CLEAR SWITCH SEEN INDICATOR
CPOPJ:	POPJ	P,		;RETURN



;HERE FROM SCAN TO PRINT PROMPT CHARACTERS.
;NEED TO SUPPRESS THEM IF PROCESSING ASCII TEXT.
UPRMPT:	SKIPE	F.ASCI		;PROCESSING ASCII TEXT?
	  POPJ	P,		;YES, JUST RETURN
	SKPINL			;DEFEAT ^O SO PROMPT WILL APPEAR
	  JFCL			;IGNORE POSSIBLE SKIP
	SKIPGE	T1		;CONTINUATION LINE?
	MOVEI	T1,"#"		;YES, CHANGE PROMPT CHARACTER
	OUTCHR	T1		;DELIVER IT
	POPJ	P,		;RETURN TO SCAN
;SUBROUTINES TO ALLOCATE FILE AREAS
;EXITS WITH T1 = ADDRESS
;T2 = LENGTH

;SUBROUTINE TO ALLOCATE OUTPUT FILE AREA

AOUT:				;FALL INTO AIN TO GET SPACE

;SUBROUTINE TO ALLOCATE INPUT FILE AREA

AIN:	MOVEI	T2,F.LEN	;SET LENGTH
	SKIPGE	F.NXZR		;SET NEGATIVE IF SWITCHES SEEN
	JRST	AIN4		;BLOCK IS ALREADY SETUP
	SETZM	SWFLAG		;CLEAR GARBAGE IN SWFLAG
	SKIPE	T1,LOGSUB	;IF WE HAVE A REAL LOG FILE
	PUSHJ	P,.TYOCH##	;RESET LOG OUTPUT ROUTINE
	PUSHJ	P,DY.GET##	;GET SOME FREE SPACE
	SKIPN	LOGSUB		;DID WE RESET TTY OUTPUT
	JRST	AIN0		;NO
	MOVE	T2,T1		;SAVE T1
	MOVE	T1,TTYSUB	;GET TTY ROUTINE BACK
	PUSHJ	P,.TYOCH##	;RESET TTY
	MOVE	T1,T2		;RESTORE CORE POINTER
AIN0:	SKIPE	F.INZR		;FIRST ONE?
	JRST	AIN1		;NO
	MOVEM	T1,F.INZR	;SET FIRST ADDRESS POINTER
	JRST	AIN2		;FIXUP SIZE AND ADDRESS FOR SCAN

AIN1:	HRRM	T1,@F.NXZR	;STORE POINTER TO THIS
AIN2:	MOVEM	T1,F.NXZR	;ADVANCE TO IT
	SETZM	(T1)		;CLEAR FORWARD POINTER
	SETZM	1(T1)		;AND SWITCH POINTER
AIN3:	ADDI	T1,F.ZER	;PASS OVER HEADER WORDS
	SUBI	T2,F.ZER	;SINCE SCAN DOESN'T KNOW ABOUT THEM
	POPJ	P,		;RETURN

AIN4:	HRRZS	T1,F.NXZR	;GET CURRENT BLOCK
	HRRZS	(T1)		;CLEAR DUMMY FILE BLOCK FLAG
	SETZM	SWFLAG		;CLEAR SWITCH SEEN FLAG
	JRST	AIN3		;AND RETURN
SUBTTL	HERE TO HANDLE SWITCHES


;HERE FOR GLOBAL SWITCHES (LHS)
;ENTER FROM SCAN WITH VALUE IN P3 AND TOKEN IN T2
;AND DELIMITER CHARACTER IN C=P4
;SPECIAL ACTION IS REQUIRED IF DELIMITER IS ":"
;SINCE SCAN HAS NOT YET RETURNED THE FILE SPEC BLOCK THE FIRST SWITCH
;MUST ALLOCATE A DUMMY BLOCK.
;IT DOES THIS BY CALLING AIN AND MARKS THE BLOCK BY
;-1 IN LEFT OF F.NXZR AND -1 IN LEFT OF @F.NXZR
;THE SWITCHES ARE IN CHAINED BLOCK
;ALL GLOBAL SWITCHES, THOSE BEFORE THE FILE NAME ARE CHAINED TO THE
;LEFT HALF OF (@F.NXZR)+1, AND ALL LOCAL SWITCHES TO THE RIGHT HALF.
;THE SWITCHES ARE IN BLOCKS WHOSE STRUCTURE IS
;WORD COUNT ,, LINK TO NEXT SWITCH
;TOKEN VALUE
;VALUE
;REST DEPENDS UPON TOKEN #

;WHEN THE FILE SPEC IS RETURNED THE LEFT HALVES OF F.NXZR AND @F.NXZR
;ARE CLEARED.

USRSWT:	LDB	T3,[POINT 6,T2,11]	;GET BYTE SIZE
	SUBI	T3,^D65		;CONVERT TO - ARG LEN IF MULTI
	MOVN	T3,T3		;MAKE POSITIVE ARG LENGTH
	CAIG	T3,LN.SWV	;LOOK TOO LONG?
	JRST	USRSW0		;NO, IS OK AS IS
	MOVEI	T3,1		;YES, IS REALLY 1 WORD OR LESS
	MOVEM	N,.NMUL##	;SINGLE WORDS NOT ALWAYS STORED
USRSW0:	PUSH	P,T3		;SAVE 1ST SWITCH ARG MAX LEN
	HRRZ	T2,T2		;CLEAR BYTE POINTER FROM LEFT
	PUSH	P,T2		;AND TOKEN
	CAIN	T2,%GO%		;IS THIS /G?
	SETOM	GOTO		;YES, MARK SO WE CAN DELETE TMP FILE
IFN FTOVERLAY,<
	CAIN	T2,%OV%		;/OVERLAY?
	HRROS	OVERLW		;YES, MARK SEEN IT
>
	HLRZ	T2,SWTTAB(T2)	;PICKUP SIZE OF SWITCH BLOCK
	SKIPE	T1,LOGSUB	;IF A LOG FILE,
	PUSHJ	P,.TYOCH##	;SET IT TO RECEIVE MESSAGES
	PUSHJ	P,DY.GET##	;GET THE SWITCH BLOCK
	SKIPN	LOGSUB		;DID WE RESET TTY OUTPUT?
	JRST	.+5		;NO
	PUSH	P,T1		;SAVE SWITCH BLOCK ADDR OVER TYOCH
	MOVE	T1,TTYSUB	;GET TTY ROUTINE BACK
	PUSHJ	P,.TYOCH##	;TELL SCAN
	POP	P,T1		;NOW NEED SWITCH BLOCK ADDR

;FALL THROUGH TO NEXT PAGE
;HERE TO STORE THE FIRST ARG IN OUR SWITCH BLOCK & CHECK FOR A 2ND ARG

	HRLZM	T2,0(T1)	;STORE SIZE, CLEAR LINK TO NEXT
	POP	P,1(T1)		;STORE TOKEN # IN BLOCK
	POP	P,T3		;RESTORE # WORDS IN SWITCH ARG
	CAILE	T3,-2(T2)	;WILL IT FIT IN OUR BLOCK?
	PUSHJ	P,E$$IST	;[1174] NO, ERROR IN SWITCH MACRO
	SUBI	T2,2(T3)	;YES, T2 GETS WORDS LEFT OVER
	MOVSI	T4,.NMUL##	;NOW TO BLT ARG TO SWITCH BLOCK
	HRRI	T4,2(T1)	;WILL WORK FINE IF AT LEAST 1 WORD
	ADDI	T3,2(T1)	;LAST DEST+1
	BLT	T4,-1(T3)	;COPY ARG
	SKIPE	T2		;ANY ROOM FOR 2ND ARG TO SWITCH?
	CAIE	C,":"		;YES, IS THERE ONE?
	JRST	USRSW1		;NO, GET ERROR FROM SCAN IF ":"
	MOVE	T4,1(T1)	;YES, GET TOKEN BACK
	HRRZ	T4,SWTTAB(T4)	;GET ADDR OF SCANNER FOR 2ND ARG
	JUMPE	T4,USRSW1	;NONE, GET ERROR FROM SCAN
	SPUSH	<T3,T2,T1>	;SAVE GOOD INFO OVER PROCESSOR
	SETZM	.NMUL##		;CLEAR ANSWER AREA
	MOVE	T1,[.NMUL##,,.NMUL##+1]	;TO AVOID CONFUSION
	BLT	T1,.NMUE##	;IF NO VALUE SUPPLIED NEXT TIME
	PUSHJ	P,0(T4)		;CALL SECOND PROCESSOR
	SPOP	<T1,T2,T3>	;RESTORE ALL GOOD VALUES
	CAIN	T2,1		;SINGLE WORD ARG?
	MOVEM	N,.NMUL##	;YES, N NOT ALWAYS STORED
	HRLI	T3,.NMUL##	;RH T3 ALREADY OK FOR BLT
	ADDI	T2,0(T3)	;LAST DEST. IS REMAINDER OF BLOCK
	BLT	T3,-1(T2)	;SO FILL IN REST OF SWITCH BLOCK
USRSW1:	SETZM	.NMUL##		;AVOID CONFUSION ON NEXT CALL
	MOVE	T2,[.NMUL##,,.NMUL##+1]	;BY ZEROING THINGS NOW
	BLT	T2,.NMUE##	; ..
	SKIPGE	F.NXZR		;IF FIRST SWITCH FOR THIS FILE
	JRST	USRSW2		;NO, FILE AREAS ALREADY SET UP
	PUSH	P,T1		;SAVE SWITCH BLOCK ADDR
	PUSHJ	P,AIN		;ALLOCATE A BLOCK
	HRROS	-F.ZER(T1)	;MARK BLOCK AS A DUMMY ONLY
	HRROS	F.NXZR		;MARK DUMMY BLOCK SET UP
	POP	P,T1		;RESTORE SWITCH BLOCK ADDR
USRSW2:	SKIPE	F.NAM		;GLOBAL IF FILE NAME NOT YET SEEN
	JRST	USRLSW		;NO, ITS LOCAL

;FALL THROUGH TO NEXT PAGE
;HERE TO CHAIN GLOBAL SWITCH INTO SCAN BLOCK (OFF OF SWFLAG)

	SKIPL	T2,SWFLAG	;SEE IF FIRST SWITCH
	JRST	USRGS2		;YES IT IS
	HRROM	T1,SWFLAG	;STORE NEW POINTER
	HRRM	T1,(T2)		;AND LINK IN
USRRET:	POPJ	P,

USRGS2:	HRROM	T1,SWFLAG	;STORE POINTER AND FLAG GLOBAL
	MOVE	T2,F.NXZR	;GET POINTER TO  BLOCK
	HRLM	T1,1(T2)	;LINK SWITCH CHAIN TO FILE CHAIN
	POPJ	P,


;HERE FOR LOCAL SWITCHES (RHS)

USRLSW:	SKIPG	T2,SWFLAG	;SEE IF FIRST SWITCH
	JRST	USRLS2		;YES IT IS
	HRRZM	T1,SWFLAG	;STORE NEW POINTER
	HRRM	T1,(T2)		;AND LINK IN
	POPJ	P,

USRLS2:	HRRZM	T1,SWFLAG	;STORE POINTER AND FLAG LOCAL
	MOVE	T2,F.NXZR	;GET POINTER TO  BLOCK
	HRRM	T1,1(T2)	;LINK SWITCH CHAIN TO FILE CHAIN
	POPJ	P,


E$$IST::.ERR.	(MS,,V%L,L%F,S%F,IST,<Inconsistency in switch table>) ;[1174]
SUBTTL	GENERATE SWITCH TABLES


;GENERATE SWITCH TABLES
DEFINE SWMAC (A,B,C,D,E,F,G,H,I)<
 IFB <C>,<
  A H'B,TK.,D,E
 >
 IFNB <C>,<
  A H'B,<POINT 65-C,TK.,35>,D,E
 >
 IF1,<
  IFIDN <B><GO>,<
   IFNDEF %GO%,<
    %GO%==TK.
  >>
  IFIDN <B><OVERLAY>,<
   IFNDEF %OV%,<
    %OV%==TK.
  >>
  TK.==TK.+1
 >
 IF2,<
  IFG .-LNKSWP,<TK.==TK.+1>
>>

TK.==0			;INITIAL CONDITION
DOSCAN (LNKSW)
DEFINE KEYMAC (A,B)<
KEYS A'K,<B>>

KEYWORDS
SUBTTL	GENERATE SIZE TABLE FOR SWITCH STORAGE


DEFINE SWMAC (A,B,C,D,E,F,G,H,I)<
 IF1,<
	F,,0
 >
 IF2,<
  IFNB <I>,<IFNDEF I,<EXTERN I>>
	F,,I
>>

SWTTAB:	SWTCHS
SUBTTL	CHARACTER INPUT ROUTINES


IFE .ASBLK,<USRIN==0>		;USE INCHWL ROUTINE IN SCAN

IFN .ASBLK,<
USRIN:	SKIPE	F.ASCI		;READING ASCIZ TEXT FROM CORE?
	JRST	TXTIN		;YES
	INCHWL	C		;NO
	POPJ	P,


TXTIN:	AOSE	F.ASCI		;IS SCAN RETURNING TOO MUCH?
	SOSA	F.ASCI		;NO, CONTINUE
	 JRST	TXTKOM		;YES, GO GIVE IT A KOMMAND
	SOSGE	F.ASCC		;BUFFER STILL CONTAINS DATA?
	JRST	NXTTXT		;NO, GET NEXT BUFFER	
	ILDB	C,F.ASCI	;READ A CHAR
	JUMPN	C,CPOPJ		;RETURN IF NOT NULL
	SKIPA	C,F.ASCC	;NO OF CHAR LEFT
NXTTXT:	TDZA	C,C		;ENTER HERE WHEN BUFFER EMPTY
	IDIVI	C,5		;NO OF WORDS LEFT
	SUBI	C,^D127		;NO. TO BACKUP
	ADDB	C,F.ASCI	;TO START OF BLOCK
	PUSHJ	P,.PSH4T##	;SCAN USES ALL THE T ACS
	HRRZ	T1,C		;GIVE BLOCK BACK
	MOVEI	T2,^D128
	MOVE	C,(C)		;STORE POINTER TO NEXT BLOCK OR 0
	MOVEM	C,F.ASCI	;NEW POINTER
	PUSHJ	P,DY.RET##	;RETURN SPACE
	PUSHJ	P,.POP4T##	;RESTORE ALL T ACS
	JUMPE	C,TXTFIN	;FINISHED IF NOTHING TO LINK TO
	MOVE	C,[POINT 7,1]	;ASCII BYTE POINTER
	ADDM	C,F.ASCI	;FOR READIN
	MOVEI	C,^D127*5	;MAX BYTE COUNT FOR THIS BUFFER
	MOVEM	C,F.ASCC	;FOR SOSGE LOOP
	JRST	TXTIN		;GET NEXT CHAR

TXTFIN:	SETOB	C,F.ASCI	;RETURN EOL CHAR
	POPJ	P,

E$$ITB::.ERR.	(MS,.EC,V%L,L%F,S%F,ITB,<Invalid text in ASCII block from file >) ;[1174]
	.ETC.	(FSP,,,,,DC)

;STILL IN IFN .ASBLK
;HERE IF SCAN IS RETURNING TOO MUCH. HAND IT THE NEXT CHAR
;OF "/K<CRLF>". IF THAT DOESN'T STOP IT, BOMB WITH ?LNKITB.

TXTKOM:	SETOM	F.ASCI		;RESET ASCII TEXT IN PROGRESS
	SKIPN	F.ASCK		;FIRST TIME THROUGH?
	JRST	[MOVE	C,[POINT 7,KOMTXT]	;YES, SET UP BP
		MOVEM	C,F.ASCK		;FOR USE BELOW
		JRST	.+1]			;RETURN TO MAIN FLOW
	ILDB	C,F.ASCK	;NEXT BYTE OF KOMMAND
	JUMPE	C,E$$ITB	;[1174] IF SCAN STILL WANTS MORE, GIVE UP
	POPJ	P,		;ELSE RETURN IT THE CHARACTER

;THE NO-OP KOMMAND ITSELF

KOMTXT:	ASCIZ	./K
.


>;END IFN .ASBLK


;ROUTINE CALLED TO DO CHARACTER INPUT DURING EDITING OF A FILE
;SPECIFICATION SO THAT NORMAL COMMAND INPUT CAN BE SUSPENDED
;AND RESUMED AFTER THE EDIT.  CALLED BY SCAN DURING PUSHJ
;TO .TSCAN TO GET NEXT LINE.  ENABLED BY CALL TO .TYPRE

FORCIN:	INCHWL	C		;GET NEXT CHARACTER
	POPJ	P,		;RETURN IT TO SCAN
SUBTTL	.INSUB - SPECIAL INPUT SUBROUTINES NOT YET IN SCAN


ENTRY	.SYMSW,.SWSYM,.SYOSW,.SWSYO,.SXDSW,.SWSXD
ENTRY	.DPKSW,.SWDPK

N==P3
C==P4
;.SYMSW -- INPUT A SIXBIT SYMBOL FROM COMMAND STRING
;.SYMSC  -- DITTO (CHARACTER ALREADY IN C)
;TERMINATES AT FIRST NON-SYMBOL CHARACTER
;THROWS AWAY ANY CHARACTERS BEYOND THE FIRST SIX
;CALL:	PUSHJ	P,.SYMSC/.SYMSW
;	RETURN WITH WORD IN N
;USES T1    UPDATES C (SEPARATOR)

.SYMSW::PUSHJ	P,.TIAUC##	;PRIME THE PUMP

.SYMSC::MOVEI	N,0		;CLEAR NAME
	MOVE	T1,[POINT 6,N]	;INITIALIZE BYTE POINTER FOR WORD

SYMS1:  PUSHJ	P,.TICAN##	;SEE IF CHARACTER IS ALPHA-NUMERIC
SYMS2:	  JRST	[CAIE	C,"%"	;SEE IF ALLOWED RADIX-50 CHARACTER
		CAIN	C,"$"	;DITTO
		JRST	.+1	;YES
		CAIN	C,"."	;LAST CHANCE
		JRST	.+1	;YES
		POPJ	P,]	;NO--ALL DONE
SYMS3:	JUMPE	N,[CAIL C,"0"	;[1167] IF FIRST CHAR, IS IT A DIGIT?
		CAILE C,"9"	;[1167] MAYBE, IS IT?
		JRST	.+1	;[1167] NO, FIRST CHAR IS OK
		POPJ	P,]	;[1167] DON'T ALLOW FIRST CHAR TO BE A DIGIT
	SUBI	C," "-' '	;CONVERT TO SIXBIT
	TLNE	T1,(77B5)	;DON'T OVERFLOW
	IDPB	C,T1		;STORE CHARACTER
	PUSHJ	P,.TIAUC##	;GO GET ANOTHER CHARACTER
	JRST	SYMS1		;LOOP BACK TO PROCESS IT


;HERE WHEN SWITCH VALUE IS A ONE WORD SIXBIT SYMBOL

.SWSYM::PUSHJ	P,.SYMSW	;GET THE WORD
	JRST	.SWDPB##	;AND STORE IT
;.SYOSW -- INPUT A SIXBIT SYMBOL OR OCTAL WORD FROM COMMAND STRING
;.SYOSC  -- DITTO (CHARACTER ALREADY IN C)
;TERMINATES AT FIRST NON-SYMBOL CHARACTER (AFTER FIRST #)
;THROWS AWAY ANY CHARACTERS BEYOND THE FIRST SIX (IF SYMBOL)
;ASSUMES OCTAL IF FIRST CHAR IS #, OR FIRST 6 CHAR ARE 0-7
;ASSUMES SYMBOLIC IF ANY OF FIRST 6 CHARS ARE ALPHABETIC OR SPECIAL
;CALL:	PUSHJ	P,.SYOSC/.SYOSW
;	RETURN WITH WORD IN N
;USES T1    UPDATES C (SEPARATOR)

.SYOSW::PUSHJ	P,.TIAUC##	;PRIME THE PUMP

.SYOSC::MOVEI	N,0		;CLEAR NAME
	MOVE	T1,[POINT 6,N]	;INITIALIZE BYTE POINTER FOR WORD

	PUSHJ	P,.TICAN##	;[1167] SEE IF CHARACTER IS ALPHA-NUMERIC
	  JRST	[CAIN	C,"#"		;NO, BUT IS IT OCTAL
		JRST	.OCTNW		;YES, ITS ONLY OCTAL
		CAIE	C,"%"		;TEST FOR SPECIAL SYMBOL CHARS
		CAIN	C,"$"		;AND SWITCH TO SYMBOLIC MODE
		JRST	SYMS3		;YES
		CAIN	C,"."		;LAST CHANCE
		JRST	SYMS3		;TO BE SYMBOLIC
		POPJ	P,]		;[1167] TERMINATOR
	CAIL	C,"0"		;[1167] DIGITS?
	CAILE	C,"9"		;[1167] ?
	JRST	SYMS3		;[1167] NO, MUST BE A SYMBOL
	JRST	.OCTNC##	;[1167] OCTAL NUMBER

;HERE WHEN SWITCH VALUE IS A ONE WORD SIXBIT SYMBOL OR OCTAL WORD

.SWSYO::PUSHJ	P,.SYOSW	;GET THE WORD
	JRST	.SWDPB##	;AND STORE IT
;.SXDSW -- INPUT A SIXBIT SYMBOL OR DECIMAL WORD FROM COMMAND STRING
;.SXDSC  -- DITTO (CHARACTER ALREADY IN C)
;TERMINATES AT FIRST NON-SYMBOL CHARACTER (AFTER FIRST #)
;THROWS AWAY ANY CHARACTERS BEYOND THE FIRST SIX (IF SYMBOL)
;ASSUMES OCTAL IF FIRST CHAR IS #, DECIMAL IF FIRST 6 CHAR ARE 0-9
;ASSUMES SYMBOLIC IF ANY OF FIRST 6 CHARS ARE ALPHABETIC OR SPECIAL
;CALL:	PUSHJ	P,.SXDSC/.SXDSW
;	RETURN WITH WORD IN N
;USES T1    UPDATES C (SEPARATOR)

.SXDSW::PUSHJ	P,.TIAUC##	;PRIME THE PUMP

.SXDSC::PUSHJ	P,.CKNEG##	;SEE IF NEGATIVE, ALSO CLEAR N
	MOVE	T1,[POINT 6,N]	;INITIALIZE BYTE POINTER FOR WORD

SXDS1:	PUSHJ	P,.TICAN##	;SEE IF CHARACTER IS ALPHA-NUMERIC
	  JRST	[CAIN	C,"#"		;NO, BUT IS IT OCTAL
		JRST	.OCTNW		;YES, ITS ONLY OCTAL
		JRST	SXDS2]		;END OF DECIMAL NUMBER
	TLNN	T1,(77B5)	;SEEN SIX YET?
	JRST	SXDS2		;YES, AND ALL NUMERIC, SO MUST BE DECIMAL
	CAIL	C,"0"		;IF ALPHABETIC
	CAILE	C,"9"
	JRST	SYMS3		;WE'VE GOT A SYMBOL
	SUBI	C," "		;CONVERT TO SIXBIT
	IDPB	C,T1		;DON'T KNOW WHICH YET
	PUSHJ	P,.TIAUC##	;GO GET ANOTHER CHARACTER
	JRST	SXDS1		;PROCESS IT

;HERE WHEN SIXBIT WORD IS NUMERIC  (THROUGH FIRST SIX CHARS)
;CONVERT SIXBIT SYMBOL INTO RIGHT JUSTIFIED DECIMAL

SXDS2:	PUSH	P,N+1		;GET A SPARE ACC
	MOVE	N+1,N		;PUT SIXBIT IN LOWER ACC
	SETZ	T1,		;START WITH ZERO
SXDS3:	SETZ	N,		;RECIEVING ACC
	LSHC	N,6		;GET NEXT CHAR
	IMULI	T1,^D10		;MAKE ROOM
	ADDI	T1,-'0'(N)	;ADD IN NEW DIGIT
	JUMPN	N+1,SXDS3	;MORE TO DO
	POP	P,N+1		;RESTORE ACC
	MOVE	N,T1		;PUT IN RIGHT ACC
SXDS4:	CAIL	C,"0"		;SEE IF DECIMAL
	CAILE	C,"9"
	PJRST	.SENEG##	;ALL DONE, NOW SEE IF SHOULD BE NEGATED
	IMULI	N,^D10		;YES, MULTIPLY NUMBER
	ADDI	N,-"0"(C)	;INCORPORATE DIGIT
	PUSHJ	P,.TIAUC##	;GET NEXT CHAR
	JRST	SXDS4		;LOOP BACK

;HERE WHEN SWITCH VALUE IS A ONE WORD SIXBIT WORD OR DECIMAL WORD

.SWSXD::PUSHJ	P,.SXDSW	;GET THE WORD
	JRST	.SWDPB##	;AND STORE IT
;.DPKSW -- INPUT A DECIMAL PAGE OR CORE SIZE FROM COMMAND STRING
;.DPKSC  -- DITTO (CHARACTER ALREADY IN C)
;FORM IS /CORE:NK OR /CORE:LK+HK
;IF IT STARTS WITH #, THEN OCTAL TYPEIN
;TERMINATES AT FIRST NON-DECIMAL CHARACTER
;IF SUFFIX IS P USES PAGE SIZE, IF K USE CORE SIZE
;THROWS AWAY ANY CHARACTERS BEFORE THE LAST 10 OR SO
;CALL:	PUSHJ	P,.DPKSC/.DPKSW
;	RETURNS WITH DOUBLE WORD IN .NMUL, .NMUL+1
;USES T1	UPDATES C (SEPARATOR)

.DPKSW::PUSHJ	P,.TIAUC##	;PRIME THE PUMP

.DPKSC::SETZB	N,.NMUL##	;CLEAR STORAGE AREA
	SETZM	.NMUL##+1
DPKIN0:	CAIN	C,"#"		;SEE IF OCTAL FLAGGED
	PJRST	.OCTNW##	;YES--GO READ OCTAL FIELD
	CAIN	C,"-"		;IN CASE NEGATIVE
	JRST	.DPKSW		;JUST IGNORE SIGN, BUT TEST FOR OCTAL AGAIN
DPKIN1:	CAIL	C,"0"		;SEE IF DECIMAL
	CAILE	C,"9"		; ..
	PJRST	DPKMUL		;NO--AT END, SO HANDLE SUFFIX
	IMULI	N,^D10		;YES--MULTIPLY NUMBER
	ADDI	N,-"0"(C)	;INCORPORATE DIGIT
	PUSHJ	P,.TIAUC##	;GET NEXT CHARACTER
	JRST	DPKIN1		;LOOP BACK FOR MORE

;DPKMUL -- HANDLE P OR K SUFFIX MULTIPLIER
;	P FOR #1000, K FOR #2000
;CALL:	MOVE	N,NUMBER
;	PUSHJ	P,DPKMUL
;	RETURN	WITH NUMBER MULTIPLIED BY SUFFIX
;USES T1  (MULTIPLIER--RETURNED)	UPDATES C (SEPARATOR)

DPKMUL:	MOVEI	T1,0		;INITIALIZE SUFFIX MULTIPLIER
	CAIN	C,"K"		;K = 2 000
	MOVEI	T1,^D10
	CAIN	C,"P"		;P = 1 000
	MOVEI	T1,^D9
	LSH	N,(T1)		;APPLY TO NUMBER
	JUMPN	T1,.TIAUC##	;IF SUFFIX--GET ONE MORE CHARACTER
	POPJ	P,

;HERE WHEN SWITCH VALUE IS A CORE OR PAGE SIZE 

.SWDPK::PUSHJ	P,.DPKSW	;GET THE NUMBER
	MOVEM	N,.NMUL##	;STORE LOW
	CAIE	C,"+"		;SEE IF ANY MORE
	JRST	.SWDPB##	;NO, STORE WHAT WE HAVE
	PUSHJ	P,.TIAUC##	;GET NEXT CHARACTER
	PUSHJ	P,DPKIN0	;AND SEE WHAT IT IS
	MOVEM	N,.NMUL##+1	;STORE HIGH
	JRST	.SWDPB##	;AND RETURN
	ENTRY	.SWVER		;[1122]

;HERE WHEN SWITCH VALUE IS A VERSION NUMBER

.SWVER::PUSHJ	P,.VERSW##	;[1122] GET THE WORD
	JRST	.SWDPB##	;[1122]   AND STORE IT
SUBTTL	THE END


SCNLIT:	END	LNKSCN