Google
 

Trailing-Edge - PDP-10 Archives - bb-bt99q-bb - backup.x23
There is 1 other file named backup.x23 in the archive. Click here to see a list.
	TITLE	BACKUP -- MODULE TO SCAN COMMANDS FOR BACKUP -- %6(701)
	SUBTTL	P.F.CONKLIN/PFC/KCM/JEF/MEB/CLRH/VLR/CGN/WMG/DC/BPK/MS/BAH/EDS	18-FEB-88

DECVER==6		;MAJOR VERSION
DECMVR==0		;MINOR VERSION
DECEVR==701		;EDIT NUMBER
CUSTVR==0		;CUSTOMER VERSION


;+
;.AUTOPARAGRAPH.FLAG INDEX.FLAG CAPITAL.LOWER CASE
;.TITLE ^PROGRAM ^LOGIC ^MANUAL FOR ^^BACKUP\\
;.SKIP 10.CENTER;^^BACKUP\\
;.SKIP 1.CENTER;^PROGRAM ^LOGIC ^MANUAL
;.SKIP 1.CENTER;^VERSION 5A
;.SKIP -20.CENTER;<ABSTRACT
;.SKIP 1

;<BACKUP IS A PROGRAM WHICH BACKS UP THE DISK FILE SYSTEM
;ONTO MAG TAPE AND RESTORES FROM THIS TAPE.  <BACKUP IS A
;SEPARATE MODULE (ACTUALLY THE FIRST MODULE) OF THE
;PROGRAM AND HANDLES ALL THE COMMAND SCANNING AND SETUP.
;^THE SECOND MODULE IS THE ACTUAL <I/O MODULE WHICH HAS NO
;COMMAND SCANNER. ^THIS WORKER MODULE (<BACKRS) LIVES IN THE LOW SEGMENT
;AND RELEASES AND RESTORES THE HIGH SEGMENT TO ELIMINATE MOST
;OF THE CORE WHEN RUNNING.


;.PAGE;^^
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1974,1977,1978,1979,1980,1981,1982,1984,1986,1988.
;ALL RIGHTS RESERVED.
;
;
;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.
;\\
;-
;       	TABLE OF CONTENTS FOR BACKUP
;
;
;                          SECTION                            PAGE
;    1. DEFAULT PARAMETERS....................................   5
;    2. REVISION HISTORY......................................   6
;    3. DEFINITIONS...........................................   7
;    4. IMPURE STORAGE........................................  10
;    5. INITIALIZATION........................................  12
;    6. MISCELLANEOUS NON-ACTION VERBS........................  18
;    7. TAPE POSITIONING VERBS................................  21
;    8. MAIN-LINE OPERATIONS..................................  24
;    9. INTERFACE TO BACKRS...................................  27
;   10. SUBROUTINES...........................................  29
;+
;.PAGE.SUBTITLE ^TABLE OF ^CONTENTS
;.CENTER;^TABLE OF ^CONTENTS
;.NOFILL.NOAUTOP.LM10.TAB STOPS 15,18.SKIP 2

;1.	^GENERAL ^INFORMATION
;2.	^DEFAULT ^PARAMETERS
;3.	^REVISION ^HISTORY
;4.	^DEFINITIONS
;		^A^CS
;		^SOFTWARE ^CHANNELS
;		^MACROS
;5.	^IMPURE ^STORAGE
;6.	^COMMAND ^SCANNING
;7.	^NON-^ACTION ^VERBS
;8.	^TAPE ^POSITIONING ^VERBS
;9.	^MAIN-^LINE ^OPERATIONS
;10.	^INTERFACE TO <BACKRS
;11.	^RUN-TIME ^COMMAND ^HANDLER
;12.	^SUBROUTINES
;13.	^RUN-TIME ^COMMAND ^SUBROUTINES
;^INDEX

;.FILL.AUTOP.LM0.TS5,8
;.CHAPTER GENERAL INFORMATION
;-


;+
;^SEARCHES ^^MACTEN, UUOSYM\\ AND <SCNMAC
;-
	SEARCH	MACTEN,UUOSYM,SCNMAC		;[174]
%%MACT==%%MACT	;SHOW VERSION OF MACTEN		[174]
%%SCNM==%%SCNM	;SHOW VERSION OF SCNMAC

	SALL		;CLEAN LISTING
	SUBTTL	DEFAULT PARAMETERS

;HACK FOR ASSEMBLY

IF1,<
MSGDIR==1
SUPOLDER==2
>

;+
;.CHAPTER DEFAULT PARAMETERS
;
;^THE FOLLOWING PARAMETERS CAN PROBABLY BE REDEFINED:^^
;.TS20.LM20.P-20,0.SK.SELECT D
;D+

ND AD.APP,1		;DEFAULT APPEND TO LOG FILE
ND AD.CKP,0		;DEFAULT TO NO CHECKPOINTING
ND AD.DLT,0		;[234] DEFAULT DELETE
ND AD.CYP,0		;[234] DEFAULT ENCRYPTION
ND AD.FCT,4		;DEFAULT BLOCKING FACTOR
ND AD.RPT,0		;[234] DEFAULT REPEAT
ND AD.SDL,0		;[234] DEFAULT SDELETE
ND AD.D75,1		;DEFAULT DATE-75 DEFENSE
ND AD.INT,0		;DEFAULT INTERCHANGE MODE
ND AD.MUL,1		;DEFAULT MULTIREEL SAVE
ND AD.PRO,000		;[247] DEFAULT PROTECTION FOR INTERCHANGE RESTORE
ND AD.SRD,0		;DEFAULT SORT DIRECTORIES
ND AD.SRF,0		;DEFAULT SORT FILES WITHIN DIRECTORY
ND AD.UNQ,0		;DEFAULT TO NO UNIQUE EXTENSION
ND AD.USG,0		;DEFAULT TO NO USAGE ACCOUNTING
ND AD.UST,1		;DEFAULT USETI MODE
ND AD.WRT,1		;DEFAULT WRITE OUTPUT
ND AD.XMP,1		;DEFAULT TO EXEMPT DEFAULT PPNS
ND LS$DEV,'LPT   '	;DEFAULT LISTING DEVICE
ND LS$EXT,'LOG'		;DEFAULT LISTING EXTENSION
ND LS$NAM,'BACKUP'	;DEFAULT LISTING FILE NAME
ND NM$TBF,6		;[507] NUMBER OF TAPE BUFFERS
ND TY$MSG,MSGDIR	;DEFAULT TYPING MESSAGE LEVEL

;D.SELECT _;

;+
; AD.SUP,SUPOLDER	;DEFAULT SUPERSEDE
; PD.SUP,SUPALWAYS	;DEFAULT SUPERSEDE IF /SUPERSEDE
; PD.UPR,750		;DEFAULT UFD PROTECTION IF /UPROTECT
;-

DM SUP,,SUPOLDER,SUPALWAYS	;DEFAULT SUPERSEDE
DM UPR,777,,750			;DEFAULT UPROTECT
DM ERM,377777,^D100,^D100	;[506] DEFAULT TAPE ERROR MAXIMUM
;+.LM0.P0,-1
;\\ ^THE FOLLOWING PARAMETERS CAN NOT BE CHANGED WITHOUT
;RISKING FURTHER DEBUGGING:		^^
;.LM20.P-20,0.SK.SELECT D
;D+

ND FX$MBF,.FXLEN	;LOCATION OF /MBEFORE	**DUPLICATE OF BACKRS
ND FX$MSN,.FXLEN+1	;LOCATION OF /ASINCE	**DUPLICATE OF BACKRS
ND FX$CNT,.FXLEN+2	;LOCATION OF MATCH COUNTER **DUPLICATE OF BACKRS
ND FX$STR,.FXLEN+3	;LOCATION OF STR FLAGS  **DUPLICATE OF BACKRS
ND FX$LEN,.FXLEN+4	;LENGTH OF SCAN BLOCK	**DUPLICATE OF BACKRS

ND FT$RCV,1		;TAPE ERROR RECOVERY CODE
ND FT$STK,0		;[341] MAKE LOCAL, GLOBAL, AND PERMENANT STICKY
			;[341] TIME AND DATE SWITCHES RATHER THAN LET
			;[341] ANY ASSERTION OF THE SWITCHES BECOME PERMANENT.
			;[341] ENABLING THIS SWITCH REQUIRES THAT CERTAIN
			;[341] LOCALS DEFINED IN SCAN BE REDEFINED AS GLOBALS
			;[341] IN SCAN.  ZERO IS THE ONLY SUPPORTED VALUE
			;[341] FOR THIS SWITCH.
ND FT$FRS,0		;[335] INCLUDE FRS SUPPORT ** DUPLICATED IN <BACKRS **
ND FT$USG,1		;INCLUDE USAGE ACCOUNTING ** DUPLICATED IN <BACKRS **

ND LN$FCT,^D96	;MAXIMUM BLOCKING FACTOR (MUST BE MULTIPLE OF 4)
ND LN$CRP,6	;ENCRYPTION KEY BLOCK LENGTH
ND LN$LEN,11	;LISTING FILE ENTER BLOCK LENGTH
ND LN$MEN,6	;MAG TAPE ENTER BLOCK LENGTH
ND LN$SSN,6	;SAVE SET NAME BLOCK LENGTH	**DUPLICATE OF BACKRS
ND LN$PDL,200	;LENGTH OF PUSH-DOWN LIST
IFN FT$FRS,<		;[335]
ND LN$TBF,24+5*200 ;LENGTH OF TAPE BLOCK	**DUPLICATE OF BACKRS
>; END IFN FT$FRS		;[335]
IFE FT$FRS,<		;[335]
ND LN$TBF,40+4*200 ;LENGTH OF TAPE BLOCK	**DUPLICATE OF BACKRS
>; END IFE FT$FRS		;[335]
ND LN$STR,^D36	;LENGTH OF SYSTEM STRUCTURE TABLE **DUPLICATE OF BACKRS

;D.SELECT _;
;&.FILL;\\

;+
;^ASSEMBLY INSTRUCTIONS:^^
;
;	.LOAD BACKUP.MAC,BACKRS.MAC
;\\
;^THE FOLLOWING FILES MUST BE ON ^^REL: SCAN,WILD,HELPER,ENDECR,USGSUB
;-\\

	.REQUEST	REL:SCAN	; REL:SCAN.REL
%%%SCN==:7				
	.REQUEST	REL:WILD	; REL:WILD.REL
%%%WLD==:7
	.REQUEST	REL:HELPER	; REL:HELPER.REL
	.TEXT\DSK:ENDECR/SEG:LOW\	; LOAD DSK:ENDECR.REL INTO LOW SEG

	IFN FT$USG,<
	.REQUIRE DSK:USGSUB		; USAGE ACCOUNTING SUBROUTINES
>

;&^THEN <SSAVE THE PROGRAM AND PLACE IT ON <SYS:.

%%%BKP==:DECVER		;ENSURE CONSISTENT VERSION OF BACKUP

	TWOSEG

	LOC	137
	BYTE	(3)CUSTVR (9)DECVER (6)DECMVR (18)DECEVR
	RELOC
	SUBTTL	REVISION HISTORY

;+
;.CHAPTER REVISION HISTORY

;^NOTE THAT THIS IS THE REVISION HISTORY FOR THE ENTIRE
;PRODUCT, INCLUDING ALL REVISIONS TO <BACKRS. ^NOTE ALSO THAT
;THE PRODUCT'S VERSION NUMBER IS DEFINED IN THIS MODULE, SO
;IT MUST BE UPDATED ON EVERY EDIT.

;.SK2.LM5.P -5,0.TS 5.AUTOTABLE

;1	^CREATED.
;2	^ADD COMMANDS BASED ON <DECUS REVIEW.
;3	^CHANGE NAME TO <BACKUP.
;4	^REQUEST LOAD <SCAN AND <HELPER.
;5	^ADD VERB <DATE75.
;6	^ADD <ALL AS SAVE SET NAME MEANING RESTORE ALL.
;7	^ADD VERB <APPEND.
;10	^IF NOT 1,2 DEFAULT TO <NOUSETI.
;11	^FIX BUG IN /<SUPERSEDE <OLDER.
;12	^CALL <.CLSTK IN <SCAN TO CORRECT DEFAULTING.
;13	^INTERFACE RUN TIME COMMAND PROCESSOR.
;14	^EXPAND /<CHECK MESSAGES.
;15	^FIX BUGS IN <SFD HANDLING.
;16	^START LONG DISK FILES IN SECOND TAPE BLOCK.
;17	^ADD <GF$NCH AND <GF$SOF FLAGS TO <G$FLAG, AND
;	RESERVE A WORD FOR CHECKSUM IN GENERAL HEADER.
;20	^ADD <L$MON, <L$SVER, <L$MTCH AND REORDER LABEL RECORD HEADER.
;21	^ADD <S$MON AND REORDER SAVE SET RECORD HEADER.
;22	^EXPAND CORE <UUO FAILURE MESSAGES.
;23	^ADD <F$PTH AND CHANGE FORMAT OF <U$STR.
;24	^ADD <G$SIZ, <G$LND. ^CHANGE TO RELATIVE DATA WORD AS FILE INDEX.
;25	^COMPUTE CHECKSUM FOR EACH TAPE RECORD.
;26	^MAKE SAVE SET NAME LONG (MAX OF 30 CHARACTERS). ^MOVE
;	SYSTEM HEADER LINE AND SAVE SET NAME TO DATA REGION OF RECORD.
;27	^DOCUMENT OVERHEAD NON-DATA BLOCKS. ^SAVE <ASCIZ FULL PATH FILE
;	NAME IN <O$NAME BLOCK FORMAT. ^SAVE CHECKSUM OF <O$NAME BLOCK
;	IN FILE AND <UFD  RECORD HEADERS.
;30	^WRITE FILE ATTRIBUTE BLOCK INSTEAD OF <RIB.
;31	^ADD VERB <INTERCHANGE.
;32	^REMOVE <.CLSTK CALLS (<SCAN V.7^A DEFAULTS CORRECTLY).
;33	^HANDLE <DSK AND ERSATZ DEVICES.
;34	^IGNORE <OKSUPERSEDE AND <ERSUPERSEDE <SCAN FILE SPEC SWITCHES
;	DUE TO DEFAULTING CONFLICTS.
;35	^CORRECT BUG IN ALIASING TO ALLOW A RESTORE TO A LOWER <SFD.
;36	^DELETE <SCATTER SWITCH SINCE 5.02 AND LATER MONITORS PERFORM
;	THIS FUNCTION AUTOMATICALLY.
;37	^CHANGE FILE SPEC DEFAULTS.
;40	^CALL <.CLSNS IN <SCAN BETWEEN FILE SPECS.
;41	^DELETE INCORRECT ERSATZ CODE.
;42	^SPLIT LISTING HEADER INTO THREE LINES.
;43	^ALLOW USER TO SPECIFY TAPE DEVICE WITHOUT COLON.
;44	^FIX <SKIP BUG BY BACKSPACING OVER SECOND <EOF TAPE MARK.
;45	^EXPAND /<INITIAL TESTING LOGIC.
;46	^FIX CREATION TIME BUG.
;47	^INCLUDE DATE/TIME IN SAVE SET HEADER LISTINGS.
;50	^USE <%CNDVM FOR MONITOR VERSION. ^START FILE WORD COUNT
;	AT ZERO INSTEAD OF ONE.
;51	^FIX BUG IN CALCULATING FILE WORD COUNT FROM TAPE.
;.SK 1

;%1(51)	<MAY,1975

;.SK 1
;52	^MAKE <PRINT VERB REWIND THE TAPE FIRST.
;53	^ADD <[NO]MULTIREEL SWITCH FOR USE IN <ADS ^BATCH JOBS
;	TO MAKE <EOT AN ERROR.
;54	^MAKE ARGUMENT REQUIRED ON <SKIP AND <SORT VERBS.
;55	^FORCE LOAD <ENDECR INTO THE LOW SEGMENT WITH <.TEXT PSUEDO-OP.
;56	^INHIBIT MONITOR BUFFER CLEARING TO ENSURE THAT DATA
;	STAYS AROUND AFTER TAPE WRITE ERRORS.
;57	^COMPLETE FILE ATTRIBUTE BLOCK FOR NON-INTERCHANGE MODE.
;60	^SET <RP.BFA FOR DISK FILE IF <BACKUP READ ERROR ON <RESTORE.
;61	^ADD <O$DIRT DIRECTORY ATTRIBUTE BLOCK AND WRITE <T$UFD RECORDS.
;62	^CLEAN UP <TTY OUTPUT: OUTPUT LISTING BUFFER BEFORE WARNING MESSAGES,
;	FORCE SILENCE IF <TTY IS LISTING DEVICE, OBSERVE </MESSAGE:NOPREFIX.
;63	^MAKE LISTING SAVE SET HEADER LINES UPPER/LOWER CASE.
;64	^LIMIT <%BKPIBL MESSAGE.
;65	^ALLOW <REENTER MONITOR COMMAND.
;66	^FIX BUG IN SETTING DEFAULT FILE SPECS.
;67	^CLEAR LISTING SPEC AFTER EXECUTING <PRINT COMMAND.
;70	^ENABLE <PSI INTERUPTS FOR <TTY INPUT.
;71	^FIX BUG IN /<ESTIMATE.
;72	^CLEAN UP OPERATOR INTERFACE TO ALLOW RUN-TIME COMMANDS AT <EOT.
;73	^FIX <SFD BUGS: CLEAR WILD CARDS FROM MASK IF NO <SFD SPECIFIED,
;	SPEC MUST MATCH <PTHBLK AT ALL LEVELS IN <VER1 FOR FILES.
;74	^ADD SORT STATUS AND INTERCHANGE MODE TO <WHAT TYPE OUT.
;75	^WRITE <T$CON AND <T$UFD RECORDS ON CONTINUATION TAPE
;	SO PLAYBACK DOES NOT REQUIRE PREVIOUS REEL.
;76	^ALLOW FILES TO BE NON-CONTIGUOUS ON PLAYBACK.
;77	^MAKE </UPROTECT SET PROTECTION FOR CREATED ^^UFD\\S AND ^^SFD\\S.
;100	^IMPLEMENT GENERAL DISK DEVICES VIA <WILD.
;101	^ADD TAPE ERROR RECOVERY CODE.
;102	^IGNORE SWITCH RESTIRCTIONS IF <RP.ABU SET FOR FILE.
;103	^IMPLEMENT </OKNONE AND </OKPROTECTION.
;104	^MAKE DEFAULT DEVICE FOR </INITIAL <ALL.
;105	^ADD FILE SPEC INFO TO <%BKPIBL MESSAGE.
;106	^REQUEST <SCN7B INSTEAD OF <SCN7A. ^USE <TAPOP. INSTEAD OF <MT.CHR
;	FOR TAPE CHARACTERISTICS. ^SET SYNCRONIZE IF ERROR BIT, IF AVAILABLE.
;107	^BELIEVE </OKSUPERSEDE AND </ERSUPERSEDE, IF TYPED EXPLICITLY.
;110	(<QAR 3718) ^IGNORE UPPER/LOWER CASE DIFFERENCES WHEN COMPARING
;	SAVE SET NAMES.
;111	^CORRECT SEPARATOR SCANNING ON <SORT VERB VALUES.
;112	(<QAR 3517) ^REPLACE WAIT LOOP IN <TYI WITH AN <INCHWL.
;113	^USE <%CNDVN INSTEAD OF <%CNVER IN <TAPEDO.
;114	^ALLOW NON-DISK OUTPUT DEVICE ON A <RESTORE. ^GIVE 
;	WARNING MESSAGE ONLY.
;115	^ADD SWITCHES <NOFILES AND <NODIRECTORIES.
;116	^ADD <REELID TO SAVE SET HEADER RECORDS.
;117	^CHANGE <AD.PRO TO 057.
;120	^MAKE <RES UNIQUE ABREVIATION FOR <RESTORE.
;121	^HANDLE <EOT WITH RECOVERY CODE.
;122	^APPLY STRUCTURE FLAGS TO </INITIAL SPEC.
;123	^ADD CHECKPOINT CODE.
;124	^FIX BUGS IN APPLYING STRUCTURE FLAGS FOR DEVICE.
;125	^FIX EDIT 111.
;126	^TRY A <MTCHR. IF <TAPOP. FAILS TO GET DENSITY AND TRACK.
;127	^LONG SAVE SET NAMES OVERFLOW LISTING HEADER LINES--DO SOME
;	REARRANGING OF HEADER INFO.
;130	^ON <EOT - FORCE OUT REMAINING BUFFERS, THEN WRITE <EOV RECORD.
;131	^ASK FOR ENCRYPTION KEY TWICE TO VERIFY, IN CASE OF TERMINAL PROBLEMS.
;132	^USE MORE DISK BUFFERS IF [1,2].
;133	^ADD VERB <DELETE FOR DELETEING FILES AFTER SAVING THEM.
;134	^ADD VERB <NOEXEMPT TO ALLOW NO ^^PPN\\S TO BE EXEMPTED FROM
;	SWITCH RESTRICTIONS.
;135	^FIX BUG WHICH IS PREVENTING DIRECTORY QUOTAS FROM GETTING
;	FILLED IN WHEN CREATING <UFDS. ^ALSO ADD DEFAULT QUOTAS OF
;	+ INFINITY IN CASE <UFD RECORD CAN'T BE READ FROM TAPE.
;136	^STOP READING DOWN TAPE WHEN SAVE SET SPECIFIED & SPEC LIST SATISFIED.
;137	^DO NOT INCLUDE PROTECTION IN LISTING FILE IF NOT INCLUDED ON TAPE.
;140	^TYPE OUT <PPN OF FIRST FILE ON CONTINUATION TAPE.
;141	^ADD VERB <REPEAT TO REPEAT A SPLIT FILE ON CONTINUATION TAPE.
;142	^FIX CORE HANDLING PROBLEM.
;143	^GET A NEW COPY OF THE SYSTEM STRUCTURE TABLE BEFORE EXECUTING
;	EACH ACTION VERB.
;144	^ADD LOGICAL NAME 'BACKUP' AS DEFAULT DEVICE FOR TAPE UNIT.
;145	^DELETE <FL$HAV FLAG, SINCE IT IS NO LONGER NECESSARY.
;146	^ADD MESSAGE TO INDICATE OPERATION DONE.
;147	^DON'T CLEAR TAPE SPEC ON USER SPECIFICATION ERROR.
;150	^GIVE UP AFTER A REASONABLE NUMBER OF TAPE ERRORS (<EMAX)
;	AND RETURN TO COMMAND LEVEL.
;151	^IF <NOWRITE IS SET (BY <PRINT VERB OR BY USER) SKIP SET UP
;	OF DISK OUTPUT CHANNELS.
;152	^CLEAR </INITIAL DEVICE SPEC IF NOT TYPED.
;153	^IMPROVE <I/O ERROR MESSAGES AND CLEAR STATUS AFTER TAPE WRITE LOCK.
;154	^TO PREVENT RUNNING OFF END OF TAPE, WRITE ONLY ONE REPEATER OF
;	BAD RECORDS AFTER <IO.EOT IS SEEN.
;155	^FIX BUG IN <CHKABU TO LOOK IN RIGHT PLACE FOR FLAGS.
;156	^SKIP CODE TO PRESERVE THE DISK OUTPUT FILE ON A RESTORE AT
;	<EOT IF A DISK FILE IS NOT OPEN.
;157	^EXIT TO MONITOR IF <EMAX IS REACHED. ^ALLOW FOR <.CONTINUE 
;	TO TRY AGAIN.
;160	^MAKE NULL SAVE SET NAME MATCH THE FIRST SAVE SET ON TAPE ON
;	A RESTORE INSTEAD OF BEING EQUIVALENT TO "ALL".
;161	^STILL EXPANDING CORE UNREASONABLY ON A READ. ^FIX IT.
;162	^ADD <SUPERSEDE SETTING TO <WHAT TYPEOUT.
;163	^SAVE ^^AC\\S BEFORE RELEASING HIGH SEGMENT.
;164	^OUTPUT LISTING BUFFER BEFORE <DONE MESSAGE.
;165	<DONE SHOULD BE PREFIXED BY " FOR <BATCH JOBS.
;166	^DO NOT REQUIRE <INITIAL DEVICE SPEC TO BE A DISK.
;167	^CHANGE FILE SPEC DEFAULTS FOR NON-[1,2] USERS.
;170	^ADD TAPE NUMBER TO SAVE SET HEADER LISTING.
;171	^FIX <RESTORE SO THAT ONLY THE REQUESTED STRUCTURE IS RESTORED.
;172	^MAKE SURE THE <PRINT COMMAND LIST ALL FILES EVEN IF ON A
;	STRUCTURE NOT IN THE SYSTEM SEARCH LIST.
;173	^CHANGE %BKPROP TO BE A FATAL ERROR MESSAGE.
;174	^SEARCH ^^MACTEN\\ AND ^^UUOSYM\\ INSTEAD OF ^C.
;175	^MAKE <RESTORE <DSKC:=<FOO: WORK WHEN THE DEVICE NAME ON TAPE
;	IS <FOO.
;176	^DONT CREATE A NEW LISTING FILE FOR EACH <PPN WHEN /<LIST IS
;	SPECIFIED AND THE DEVICE IS A SPOOLED <LPT.
;177	<UFD NOT FOUND FOR THE <RESTORE PROCESS WHEN A <UFD PRECEDING
;	IT IN THE SAVE SET HAD <SFD'S SPECIFIED.
;200	^AVOID "^^DEVICE MTA0 OPR ACTION REQUESTED"\\ WHEN <KILL IS
;	TYPED IN RESPONSE TO "^^MOUNT NEW TAPE THEN TYPE "GO"\\".
;201	^MAKE SURE <BACKUP RESPONDS TO RUN TIME COMMANDS AFTER A </KILL
;	IS ISSUED TO A REQUEST FOR A REEL CHANGE.
;202	^PRECEDE OPERATOR ERROR MESSAGES WITH A "$" SO THAT THE OPERATOR
;	HAS A CHANCE TO CORRECT ANY ERROR CONDITIONS OTHERWISE <BATCH
;	KILLS THE JOB DUE TO THE "?".
;203	^IF THE FILE'S DSK AND TAPE CREATION DATES ARE EQUAL THEN
;	DON'T RESTORE TO DSK.
;204	^MAKE </RES <[P,P] RESTORE ALL FILES IN THE <UFD EVEN THOSE
;	THAT APPEAR AFTER A <SFD FILE IN THE DIRECTORY.
;205	^MAKE SURE THE '"' OF <'"DONE' IS PRINTED IN COLUMN 1.
;206	^WHEN <RESTORING DONT SUPERSEDE AN OLD FILE WITH A KNOWN BAD
;	 FILE. ^THAT IS ONE WITH MISSING DATA OR WITH D LIST ALL FILE
;207	^STOP ILLEGAL MEMORY REFERENCE WHEN <RESTORING AND <.RBSPL,
;	THE NAME FOR SPOOLING, IS NON ZERO.
;210	^STOP A DATE-75 BUG WHEN <RESTORING. ^THE FIRST FILE IN EVERY
;	<UFD WAS AFFECTED. ^THE HI-ORDER CREATION BITS WERE NOT BEING
;	RESTORED AFTER AN <ENTER FAILURE (NON-EXISTENT UFD).
;211	^APPEND A FORM-FEED TO THE ENDING CONTINUATION LABEL IN THE
;	<LIST FILE.
;212	^TYPE "% <PRINT <ABORTED" WHEN TRUE.
;213	^MAKE <BACKUP RESTORE ALL OCCURRENCES OF A GIVEN FILE
;	NOT JUST THE FIRST ONE ENCOUNTERED. ^CHECK THE <SFD'S OR
;	THE <UFD IF ONE WAS FOUND IN A <SFD.
;214	^MAKE 2**28-1 BE EQUIVALENT TO 2**36-1 (PLUS INFINITY) FOR
;	<.RBQTF AND <.RBQTO. ^THE HI-ORDER BITS ARE LOST IN CONVERSION
;	OF BLOCKS TO WORDS.
;215	^MAKE A ZERO QUOTA DEFAULT TO PLUS INFINITY ONLY IF 
;	<INTERCHANGE WAS SPECIFIED.
;216	^STOP <.RBSPL FROM PROPAGATING TO SUCCEEDING DIRECTORIES
;	VIA THE LACK OF INITIALIZATION OF THE EXTENDED <ENTER BLOCK.
;217	^FIX EDIT 176 TO USE CORRECT CHANNEL FOR ^^/LIST\\ OPTION.
;220	^ASSIGN PROPER CHANNEL IN ^^SETSTS\\ AT ^^NOFIND:\\.
;221	^STOP ^^BACKRS\\ FROM RUNNING OFF END OF TAPE UNDER MONITORS
;	OF VERSION LESS THAN 6.02.
;222	^RESTORE PROPER CREATION DATE/TIME FOR FILES SPLIT ACROSS
;	TAPES.
;223	^RESTORE PROPER ACCESS DATE/TIME FOR THE FIRST FILE RESTORED TO
;	NON-EXISTANT ^^UFD\\.
;224	^MAKE ^STAND ^ALONE SWITCHES OPERATIONAL
;225	^CORRECT ERRONEOUS ^EDIT NUMBERS
;226	^FIX ^EDIT 224 TO DEFAULT TO PROPER TYPING LEVEL
;	,FIX DELETE SWITCH AND SET NOENCRYPT
;227	^IMPLEMENT A PROTECTION RENAME SCHEME TO PREVENT MULTIREEL 
;	TAPE HANDLING PROBLEMS:FILE TRUNCATION,DISK I/O ERRORS,
;	FILE TRUNCATION AT CHECKPOINTS.
;230	^IMPLEMENT ^^/SDELETE\\ SWITCH TO DELETE OWNER
;	FILE IRRESPECTIVE OF OWNER PROTECTION
;231	^CHANGE ^^TYPID1\\ TO NOT CONVERT LEFT
;	ARROWS IN FILENAMES TO COMMAS
;232	^EXTEND THE LOGIC OF ^EDIT 227 TO RENAME .^^RBEST\\ ASSURING
;	PROPER BLOCK ALLOCATION ON RESTORATION.
;233	^FIX <SFD HANDLING TO SEARCH ALL ^^SFD'\\S, NOT JUST THE FIRST,
;	WHEN RESTORING UNDER WILDCARDED <SFD SPEC.
;234	^UPDATE ^EDIT 224 TO SET CORRECT DEFAULTS FOR SWITCHES NOT SET
;	BY THE USER IN HIS/HER <SWITCH.INI FILE
;235	^STOP <BACKRS FROM SUBSTITUTING QUESTION MARKS FOR NON-
;	TRAILING 0'S (NULLS) IN FILENAMES.
;236	^IMPROVE SYSTEM ACCESS TABLE USAGE BY HAVING <BACKUP
;	DO THE <CLOSE AT <XFRDON WITH <CL.DAT SET
;237	^NORMALIZE SAVE SET NAME SEARCH TO TREAT LOWER CASE "ALL"
;	SAME AS UPPER CASE.
;240	^STOP <BACKUP FROM ENDLESSLY SAVING FILES TOO LARGE TO FIT ON ONE
;	REEL OF TAPE AND /<REPEAT IS SET.
;241	^IMPLEMENT </[NO]NFS SWITCH TO ALLOW USER TO IGNORE
;	RP.NFS RIB STATUS CONDITION IF SET FOR THE FILE THE USER
;	WISHES TO <SAVE.
;242	^RESET <.JBFF AT CHECKPOINTS SO THAT DISK BUFFERS DURING
;	RESTORE ARE ALLOCATED AT THE SAME SET OF ADDRESSES.
;243	^USE <TAPOP. TO SET DENSITY OF TAPE
;244	^CORRECT <BKPFEE MESSAGE WHEN FILE IS IN AN <SFD.
;245	^CHANGE EDIT 227 TO ALLOW FOR USERS RESTORING FILES INTO
;	OTHER <UFD\S INTO WHICH THEY HAVE CREATION RIGHTS.
;246	^FIX EDIT 243 FOR DENSITY SETTING.
;247	^ENTER RESTORED INTERCHANGE MODE FILES WITH THE SYSTEM DEFAULT
;	PROTECTION CODE UNLESS /<PROTECTION WAS GIVEN RATHER THAN
;	_<057_>. ^DO SO BY CHANGING <AD_.<PRO TO 000.
;250	^ALLOW SEPARATE RESTORES OF CONSECUTIVE FILES.
;251	^AVOID HAVING THE WHAT COMMAND TYPE OUT AN EXTENSION IF THE
;	FILENAME IS ZERO DURING <UFD PROCESSING.
;252	^PRINT A SPACE IN FRONT OF THE FILENAME FOR /<LIST, /<PRINT
;	AND /<FILES SO THAT FILES WITH FUNNY NAMES DO NOT CAUSE BATCH
;	JOBS TO HALT.
;253	^ALLOW /RESTORE [-] TO RESTORE INTERCHANGE-MODE FILES TO
;	USER'S DEFAULT PATH RATHER THAN HIS <UFD.
;254	^HANDLE DISK ERRORS BY PRINTING WARNING AND CONTINUING, AND DO NOT
;	MESS UP NEXT FILE AFTER ONE WITH DISK ERROR BY NOT CLEARING BUFFERS.
;255	^INCLUDE SETTING OF <DELETE SWITCH IN <WHAT MESSAGE.
;256	^FIX EDIT 245.
;257	^LOOK FOR UNEXPECTED REPEATER RECORDS ON TAPE AND GIVE A
;	WARNING AND IGNORE THEM.
;260	ADD BKPFRE FILE RENAME ERROR IF RENAME TO FIX UP PROTECTION
;	OR ESTIMATE OF RESTORED FILE FAILS AT CONT-3 IN CODE ADDED BY
;	EDIT 232
;261	^SAVE .<RBPPN AROUND <LOOKUP, <ENTER, OR <RENAME SO THAT
;	RESTORE [-] TO RESTORE TO DEFAULT PATH FROM INTERCHANGE MODE
;	IS NOT FOILED BY MONITOR PUTTING <PPN PART OF DEFAULT PATH INTO
;	<.RBPPN.
;262	^FIX RESTORE WITH MORE THAN ONE INPUT DEVICE NAME AFTER AN
;	OUTPUT DEVICE NAME, AS /RESTORE DSKA:=DSKB:,DSKC:FOO.
;263	^IMPLEMENT LOGICAL NAMES IN RESTORE COMMANDS WITH A <DEVNAM <UUO
;	IN THE CODE MOVED FROM <GETINF TO NEW ROUTINE <SETSTR BY EDIT 262.
;264	^STOP SCANNING AT END OF STRUCTURE WHEN RESTORING A STRUCTURE.
;265	^SAVE ^N IN LOW SEGMENT SO THAT <SAVE ^N <MTA: WORKS.
;266	^USE CORRECT REEL NUMBER IN <SAVE AND <PRINT.
;267	^DONT OUTPUT "^SIZE COPY ERROR" IN ^INTERCHANGE MODE.
;270	^IF ANY WILDCARDS IN SFD MAKE /RESTORE GO TO END OF SAVE SET.
;271	^DO OPEN IN ASCII MODE, NOT DUMP, SO <BACKUP DOESN'T BOMB
;	WITH ILLEGAL DATA MODE
;272	^ALWAYS RENAME FOR PROTECTION UNLESS IN INTERCHANGE MODE
;273	^STOP READING TAPE FOR <RESTORE IN <INTERCHANGE MODE
;	WHEN SPECS ARE SATISFIED.
;274	^FIX /<SORT FOR : AND /<LIST FOR FOLLOWING /.
;275	^DON"T LOOK FOR THE START OF SAVESET MORE THAN ONCE.
;276	^CHECK FOR DISK FULL WHEN DOING DISK OUTPUT.
;277	^FOR /<LIST DON"T OUTPUT 0 AS MAJOR VERSION.
;300	^MAKE TAPE INPUT RECORD THE RIGHT SIZE (1040 NOT 1224).
;301	^DON'T DISABLE MONITOR RE-TRY ON ERROR CONDITIONS.
;302	^DON'T SET ERROR FLAG IN RIB FOR UNEXPECTED REPEATER RECORD.
;303	^FIX UP CREATION DATE FOR FILE THAT WAS SPLIT ACROSS TWO TAPES.
;304	^USE CLOSE INSTEAD OF OUT UUO FOR LAST BLOCK OUTPUT TO FILE.
;305	^ADD /<TPNUMBER VERB TO SET TAPE NUMBER.
;306	^CHANGE DEFAULTS FOR /<RESTORE AND /<CHECK TO ALL:.
;307	^ALLOW LISTING UNSPOOLED TO OUTPUT-ONLY DEVICE.
;310	^WRITE BLANK TAPE FIRST THEN CHECK FOR WRITE-LOCK ERROR
;		SO FIRST BUFFER DOESN'T GET LOST.
;311	^FIX EDIT 266.
;312	^REMOVE EDIT 253.
;313	^SKIP <TAPOP TO SET DENSITY IF /<DENSITY SWITCH WASN'T GIVEN.
;.SK 1

;%2A(313) <MAR,1979

;.SK 1
;314	^DON'T THROW AWAY HIGH SEGMENT IF RUN FROM TAPE.
;315	^FIX EDIT 303 TO REMOVE MAGIC NUMBERS AND SYNCRONIZE STACK
;	 WHEN ERROR OCCURS; ALSO REMOVE OBJECTIONABLE COMMENT LINES.
;316	^MAKE BACKUP HANDLE DEFAULTS MORE DISCREETLY, ESPECIALLY
;		VERSION-NUMBERS.
;317	^FIX EDIT 230; IT LOOKS FOR THE <PPN IN THE WRONG
;		PLACE WHEN SETTING UP FOR AN </SDELETE <CHKACC
;320	^KEEP THE CONTENTS OF THE <TTY BUFFER SYMCHRONIZED WITH
;		THE <PSI INTERRUPTS IN ORDER TO AVOID UNPROCESSED
;		COMMANDS WAITING IN THE <TTY BUFFER.
;
;321	^USE OUT-OF-SEQUENCE RECORDS, WARNING USER OF THE OCCURANCE.
;		^DON'T REJECT UNEXPECTED REPEATER RECORDS.
;
;322	^PREVENT <BACKRS FROM RENAMING FILES TO A 000 PROTECTION CODE
;		WHEN THEY ARE SPLIT OR LAST ON A TAPE.
;
;323	^SPEED UP RESTORE BY NOT DOING AN EXTRA LOOKUP TO
;		DETERMINE FILE SIZE.
;
;324	^SAVE <.RBPPN WHERE NECESSARY TO PREVENT LOSING THE
;		PATH TO THE FILE.
;
;325	^CORRECT DEFAULT PATH HANDLING
;
;326	^CORRECT TAPE DENSITY HANDLING: MAKE SURE DENSITY GETS SET FOR
;		<EOT AND OTHER OPERATIONS, MAKE DENSITY SETTING
;		CONSISTENT, AVOID LOSS OF DENSITY DURING ERROR
;		RECOVERY.
;
;327	^MAKE <INITIAL SPECIFICATIONS CONTAINING ^^SFD\\S WORK.
;
;330	^CHANGE CERTAIN <BYTE PSEUDO-OPS SO THAT <BACKRS WILL
;	 COMPILE UNDER <MACRO VERSION 53A.
;
;331	^HANDLE INTERCHANGE-MODE RESTORES AS A SPECIAL CASE, SO THAT THEY
;	DEFAULT TO THE CURRENT PATH INSTEAD OF THE <UFD.
;
;332	^MAKE [-] FUNCTION AS CURRENT PATH, NOT AS CURRENT PATH PLUS ALL
;	INFERIORS.
;
;333	^SUPRESS ^SUPERCEDE DISPLAY DURING <WHAT WHEN SAVING
;	AND CHECKING.
;
;334	^SHOW BLOCK NUMBER IN <WHAT.
;
;335	^PLACE ALL POSSIBLE <FRS SUPPORT CODE UNDER <FT$FRS CONDITIONAL.
;
;336	^MAKE THE CURRENT PATH'S <UFD THE BLANK-DEFAULT <PPN, RATHER
;	THAN USING THE LOGGED-IN <PPN.
;
;337	^PREVENT MANY MONITOR DISK ACCESSES AND THEREBY SPEED UP THE
;	<SAVE OPERATION BY HOLDING ONTO A FILE IN THE CURRENT <UFD
;	SO THAT THE MONITOR <PPB FOR THE <UFD IS PRESERVED OVER THE
;	ENTIRE <SAVE OF THAT <UFD.
;
;340	^PREVENT <BACKRS FROM ADDING SPURIOUS CHARACTERS TO
;	THREE-CHARACTER FILENAMES BEING <RESUMED.
;
;341	^ADD THREE-LEVEL HANDLING OF TIME AND DATE SWITCHES.
;	<LOCAL, <GLOBAL, AND <PERMANENT STICKYNESS.
;	(^THE FEATURE IS UNDER A FEATURE-TEST SWITCH BECAUSE IT
;	 REPRESENTS A MAJOR CHANGE IN HISTORICAL BEHAVIOR
;	 THAT WILL NOT BE DESIRED BY ALL USERS.)
;
;342	^EXTEND EDIT 337 (SPEED <SAVES UP BY ABOUT 25%) TO INCLUDE
;	<RESTORE.  ^ALSO MODIFY EDIT 337 SLIGHTLY TO MAKE THE
;	<RESTORE CHANGES EASY TO INTEGRATE.
;
;343	^DISALLOW WILD <PPNS WHILE <RESTORING IN <INTERCHANGE MODE.
;
;344	^FEATURE - WHEN USING /<MULTIREEL (<DEFAULT), TAPE NUMBER 
;	WILL NOT BE REINITIALIZED TO 1 FOR EACH NEW <SAVE  COMMAND.
;
;345	^USE <MDA TO GET VOLUME SWITCHING DONE, IF THE LABEL TYPE
;	SUGGESTS THAT THIS MAY WORK.  ALSO, IF TAPE NAME IS DEFAULTED
;	TO <BACKUP, USE THE LOGICAL NAME <BACKUP INSTEAD OF THE
;	<DEVNAM TO WHICH IT MAPS.
;
;346	^FIX FOR <EDIT 343 TO ALLOW [*,*], WHICH WILL DEFAULT TO
;	CURRENT PATH.
;
;347	^ADD A FLAG IN THE <COMMUNICATIONS <SECTION TO FLAG WHEN
;	/TPNUM IS USED SO THE NUMBER WON'T GET TRASHED.
;
;350	^CHECK FOR LOWER CASE <ALL IN THE <PRINT COMMAND SCANNING.
;
;351	^CHANGE EDIT 314 SO IT WILL RUN A LITTLE FASTER.  ^UPDATE
;	DISCLAIMERS.
;
;352	^FIX <BACKRS SO THAT WHEN <DSK OR <ALL IS SPECIFIED WITH A
;	<PPN ON A <RESTORE WE WILL NOT HALT WITH A FILE NOT FOUND
;	ERROR IF THE FIRST STRUCTURE WITH THAT <PPN FAILS.
;
;353	^FIX ROUTINE <TSTRPT IN <BACKRS SO THAT WHEN CHECKING THE
;	BUFFER COUNT, WE ONLY TEST THE RIGHT HALF OF THE WORD.
;	^THE LEFT HALF IS RESERVED FOR MONITOR BOOKKEEPING AND
;	MAY CONTAIN DATA.
;
;354	^FIX <BACKRS SO THAT WHEN RESTORING FILES, THE CREATION DATE
;	IS RESTORED PROPERLY.  ^THIS DID NOT HAPPEN WHEN CHECKPOINTING
;	WAS BEING DONE, OR WHEN A FILE WAS WRITTEN ACROSS VOLUMES.
;
;355	^IF /<REPEAT HAS BEEN GIVEN ALONG WITH /<DELETE, DO NOT DELETE A
;	FILE THAT WAS WRITTEN ACROSS VOLUMES UNTIL IT HAS BEEN REWRITTEN.
;
;356	^FIX PROBLEMS WITH FILES SPLIT ACROSS REELS IN <INTERCHANGE
;	MODE AND FILES PROTECTED BY <FILDAE.  ^DO PROTECTION RENAME
;	FOR ALL NON-[1,2] RESTORES AND FOR [1,2] IF PROTECTED <000>
;	OR <FILDAE PROTECTED.  <GETTAB USERS DEFAULT PROTECTION THEN
;	SYSTEM DEFAULT PROTECTION IF <AD.PRO = 0.
;
;357	^USE <FILOP. INSTEAD OF <USETI OR <USETO WHEN POSITIONING A
;	FILE.  18 BITS IS NOT ALWAYS LARGE ENOUGH FOR A BLOCK
;	SPECIFICATION, <FILOP. PROVIDES A WHOLE WORD (36 BITS). ^THIS
;	CHANGE IS NOT NECESSARY FOR <USETI<S THAT MERELY POSITON TO
;	THE BEGINNING OR END OF A FILE.
;
;360	<FIX <BACKUP SO THAT IT CAN BE RUN EXECUTE ONLY.
;
;361	^FIX /<LIST SO THAT IT WILL NOT SPLIT THE LIST FILE IF IT
;	IS WRITTEN TO AN <SFD.
;
;362	^REMOVE <LABEL VERB SINCE <BACKUP WILL NEVER BE ABLE
;	TO MANIPULATE LABEL TYPES.
;
;363	^MAKE <BKPPUD MERELY A WARNING AND NOT A FATAL ERROR
;	MESSAGE.
;
;364	^IMPLEMENT <USAGE VERB FOR <USAGE ^ACCOUNTING.  <BACKUP
;	WILL SEND <IPCF MESSAGES TO [<SYSTEM]<ACTDAE DESCRIBING
;	THE DISK SPACE USAGE FOR EACH DIRECTORY SAVED.  ^THIS
;	IS A <SAVE ONLY OPERATION AND IS SIMILAR BUT MORE ACCURATE
;	THAN THE <FACT OPTION TO <SPACE. ^THIS REQUIRES A NEW
;	SUBROUTINE PACKAGE <USGSUB ON <REL:
;
;365	^FIX CODE FOR DENSITY SETTING IN <TAPOPN TO RESTORE
;	ARGUMENT IN <AC 1 WHICH MAY BE MODIFIED BY NEW PATCH
;	TO <TAPOP.
;
;366	^FIX PROBLEMS WITH <PRINT AND <LIST WHEN A PATH CONTAINS
;	FIVE LEVELS OF <SFD'S.
;
;367	^CHECK FOR ERROR AFTER PERFORMING <SKIP.  ^IF ONE OCCURS
;	PRINT NEW ERROR MESSAGE <BKPSKF.
;
;370	^MAKE ^W A LEGAL ABBREVIATION FOR <WHAT ALL THE TIME.
;
;371	^FIX UP EDIT 344 A BIT.  ^GET RID OF <NTPE WHICH IS NO LONGER
;	USED.
;
;372	^INITIALIZE <S.SRF AND <S.SRD TO -1 SO THAT USER
;	DEFAULTS WILL BE APPLIED CORRECTLY.
;
;373	^MAKE SURE THAT A MISTYPED RUNTIME COMMAND RETURNS AN <IRC ERROR.
;	^MAKE <GO THE ONLY VALID RESPONSE IN THE CASE OF <BACKUP RUNNING
;	FROM A BATCH JOB AND WAITING TO CONTINUE ON NEXT TAPE.
;
;374	^INITIALIZE <F$MBF, <F$MSN AND <S.NFS PROPERLY SO THAT <MBEFORE,
;	<MSINCE AND <NFS CAN BE SET IN <SWITCH.INI.
;
;375	^CHECK FOR A NULL TAPE DEVICE DURING <TAPE COMMAND.  ^IF DEVICE
;	IS NULL, THEN MAKE SURE ONLY MINIMAL WORK IS DONE (FOR <USAGE)
;	WHEN PROCESSING FILES (I.E. DON'T DO ACTUAL FILE TRANSFERS).
;
;376	^CHANGE "<RELEASE <HOLD" TO "<RELEASE <HOLD," AT <RLSSTR+3
;	AND AT <HOLDRL+2.
;
;377	^IF THE LOG FILE FOR THE <LIST OPTION IS FOUND IN <LIB:, THUS
;	GENERATING AN ERROR CODE 5, <CLOSE THE FILE AND RE<ENTER IT
;	IN NON-UPDATE MODE.
;
;400	^MAKE EDIT 375 EVEN FASTER IF USER DOES NOT SPECIFY <LIST,
;	<DELETE, OR <SDELETE.
;
;401	^SPEED UP EDIT 373 A LITTLE BIT IN <OPRCM1.
;
;402	Needs edit 612.
;	^FIX <BACKRS SO THAT IT WILL RECOGNIZE ERRORS DETECTED BY
;	THE TAPE LABEL HANDLER AND PRINT OUT APPROPRIATE ERROR
;	MESSAGES.
;
;403	^MAKE <CHECK <ALL: WORK IN <INTERCHANGE MODE.
;
;404	^ONLY DO <TAPOP. TO CLEAR TAPE LABEL ERRORS IF AN ERROR
;	ACTUALLY HAS OCCURED.  THIS <TAPOP. PERFORMS A REWIND.
;
;405	^GENERATE MORE INFORMATIONAL ERROR MESSAGES WHEN THE
;	<TAPOP. TO FORCE END OF VOLUME PROCESSING FAILS.  ^NEW
;	ERROR MESSAGE <BKPINS.
;
;406	^DEFAULT STRUCTURE NAME TO DSK: IN <RSTFIL.
;
;407	^SOME MORE FIXING UP FOR WHEN WE ENCOUNTER TAPE LABEL
;	ERRORS.
;
;410	^SEVERAL CODES RETURNED BY THE <DEVOP., <.DFRES MONITOR
;	CALL ARE NONFATAL, INFORMATIVE MESSAGES.  TEST FOR THESE
;	CASES AND DON'T CLEAR THE BITS SINCE THIS WILL REWIND
;	THE TAPE.  ^WHEN OPENING A TAPE, ONLY TEST FOR LABEL ERRORS
;	IF A <TAPE COMMAND IS BEING EXECUTED.
;
;411	^MAKE SURE THAT THE TAPE DEVICE IS ACTUALLY CONTROLLED BY
;	<MDA BEFORE DECIDING IF AN <UNLOAD OPERATION WOULD FAIL.
;	^IF <MDA IS NOT CONTROLLING THE DEVICE OR IF <BYPASS LABEL
;	PROCESSING HAS BEEN SPECIFIED THEN THE <UNLOAD WILL WORK.
;
;***** Begin Version 4 *****
;
;412	^BE MORE LENIENT WITH THE BATCH OPERATOR WHEN REQUESTING THAT
;	THE RESPONSE TO <BKPEOT BE <GO.  ^SOME USERS MAY WISH TO
;	TYPE TAPE INFORMATION AFTER THE <GO FOR DOCUMENTATION
;	PURPOSES.  ^AS LONG AS <GO HAS BEEN TYPED, IGNORE THE REST
;	OF THE LINE AND PROCEED.
;
;413	<RENAME THE <UFD AFTER SAVING IT IF THE USER HAS SPECIFIED
;	<USAGE.  ^THIS IS TO UPDATE <.RBLAD IN THE <UFD RIB.
;	^ALSO FIX UP <USAGE VERB TO CHECK IF USER IS ALLOWED TO DO
;	ACCOUNTING.  ^NEW FATAL ERROR MESSAGE <BKPCDU.
;
;414	^CHANGE <BKPAMD FROM A WARNING TO AN INFORMATIONAL MESSAGE.
;
;415	Deleted by edit 435.
;	
;416	Needs edits 421 and 432.
;	^RETURN FILENAME ON <WHAT RUNTIME COMMAND WITH /<PRINT AND /<LIST
;
;417	^MAKE SURE ACCOUNT STRING POINTER IS LEGITIMATE BEFORE TRYING
;	TO SAVE THE ACCOUNT STRING.  ^IF IT IS NOT, THEN ASSUME A NULL
;	STRING.
;
;420	^WHEN CLEARING THE USE BITS IN THE BUFFER RING SO THAT THE
;	BUFFERS CAN BE REWRITTEN, ALSO SET THE VIRGIN BUFFER BIT.
;	^THIS WILL PROMPT THE MONITOR TO RESET ITS BUFFER COUNTERS SO THAT
;	THEY DO NOT GET OUT OF SYNCH WITH THE ACTUAL NUMBER OF BUFFERS
;	AVAILABLE TO BE WRITTEN (ACCORDING TO THE NEW USE BIT SETTINGS).
;
;421	Needs edit 432
;	INITIALIZE  THSRDB EVERY TIME  NEW FILE IS TO BE STARTED.
;
;422	Replaced by edit 436.
;
;423	^SET NEW BIT <RB.NLB WHEN <ENTER<ING FILES ON DISK.  ^THIS NEW
;	BIT WILL CAUSE THE FILE TO BE WRITTEN ON THE EMPTIEST UNIT IN
;	THE STRUCTURE REGARDLESS OF THE STATE OF OTHER OPEN FILES.
;	<MCO 10133 MUST BE INSTALLED.
;
;424	^IMPROVE EDIT 254.
;
;425	^SET <NOSCAN FLAG WHEN <ENTER FAILS DUE TO <SFD NOT FOUND AND
;	<MAKSFD TRIES TO CREATE ONE.
;
;426	Requires edit 433 and edit 437.
;	^INFORM THE USER OF POSSIBLE LABEL TYPE CONFLICTS.  ^ADD WARNING
;	MESSAGE <BKPDLT.  ^THE SECOND MESSAGE, <BKPTGC WILL GIVE THE
;	OPTION TO THE USER TO CONTINUE OR TO QUIT.
;
;427	^SET <RP.BFA IF BAD FILE WAS SAVED WHILE DOING RESTORE.
;
;430	^CONDITIONALIZE A LINE OF ^USAGE CODE THAT GOT MISSED.
;
;431	^USE FIELD IMAGE VERSIONS OF <SCAN AND <WILD.
;
;432	QAR 10-06849	BAH	5-Mar-82
;	Edit 421 was not complete.  It caused ill mem refs when doing SAVEs
;	with /REPEAT switch on the second save of a file.
;
;433	In-house	BAH	1-Apr-82
;	Edit 426  needs some extra checking.  Any combination of label types
;	BYPASS, UNLABELLED, and USER-EOT are also OK.
;
;434	None.	BAH	5-Apr-82
;	BACKUP still believes ACs 0, 7, 11, and 17 contain correct GETSEG
;	information from the RUN UUO.  Use GETTABs instead.  Also do some
;	code and comment cleanup such as delete internal UUOSYM definitions.
;
;435	None.	BAH	13-Apr-82
;	Delete edit 415.  It does not solve the problem stated in SPR
;	10-30827, trashes files, and skips tape error reporting.  More
;	investating needs to be done before the bug is fixed.
;
;436	10-32229	BAH	21-Apr-82
;	The creation date/time is not restored correctly if a file is
;	being superseded.  There are other pieces of information that can be
;	destroyed by the subroutine HOLDIT.  Rewrite HOLDIT to use its own
;	LOOKUP block.  This edit deletes edit 422 and some parts of other edits
;	that tried to preserve file information piecemeal.
;
;437	In-house.	BAH	26-MAY-82
;	Edit 426 stored the label type iff the user typed the TAPE command.
;	Also store the label type if the logical name BACKUP is being used.
;	This edit moves the routine LABTYP from BACKRS to BACKUP which is the
;	only module that has calls to it.
;	Also create the routine LABCLR to clear any tape labelling errors if
;	any exist.
;	If the device specified by the TAPE command was NUL:, skip density
;	checking in routine TAPOPE.
;
;440	In-house.	BAH	18-Jun-82
;	Output error 14 after the OUT UUO @DSKIN/OUT.  WAIT UUOs are
;	done before the GETSTS.  The monitor clears error bits when the WAIT
;	UUO is done causing the GETSTS to return no error bits.  BACKUP then
;	reports only the data mode for the error. Do the GETSTS before the WAIT.
;
;***** End of Version 4 *****
;
;***** Begin Version 4A *****
;
;500	None.	BAH	15-Apr-82
;	Set up for version 4A.
;
;501	10-31514	EDS	23-Apr-82
;	Fix problems with restoring files when the user has the
;	/SCAN switch set.  Scanning should not be used during the
;	check to see if the file should be superseded.
;
;502	10-31437	BAH	28-Apr-82
;	Many commands to BACKUP can cause routines in SCAN's hi-seg to be
;	called.  If BACKUP is execute only, every entry point to SCAN needs
;	a PORTAL because BACKUP throws away its hi-seg.  If execute only,
;	don't throw away the hi-seg.
;
;503	10-32094	EDS	13-May-82
;	Fix problems with restoring files which were saved from
;	ERSATZ devices.  The DEVNAM UUO does not translate ERSATZ
;	device names to physical device names so use the DSKCHR UUO.
;
;504	10-32738	BAH	26-Aug-82
;	Edit 373 took too many features away.  Restore the check for batch
;	jobs before reporting error messages in order to precede them with
;	a $ sign.  Restore allowing the operator to type any runtime command.
;	Solve the original problem (see routine OPRCHS) of allowing numeric
;	characters to cause breaks.  Only comment characters, spaces, tabs and
;	real break characters will stop parsing.  Delete the E$$ICG error, since
;	it was redundant.
;
;505	10-32868	BAH	17-Sep-82
;	Make LSTVER know about minor version numbers greater than 26 ("Z").
;
;506	10-32867	BAH	22-Sep-82
;	Implement the status-setting verb, ERRMAX, which allows the user to set
;	the maximum number of tape errors allowed before giving a fatal error
;	message ?BKPRTE.  Default still remains 100 decimal.  Argument is a
;	decimal number.
;
;507	10-32858	BAH	24-Sep-82
;	 Make NM$TBF definitions in BACKUP.MAC and BACKRS.MAC agree.
;
;510	10-32866	BAH	5-Oct-82
;	Files written in a customer-specific data mode cannot be restored on
;	another system without getting an "Illegal data mode for device"
;	error message.  Give a warning and restore the file in image mode.
;
;511	10-32915	BAH	13-Oct-82
;	P$MBF and P$MSN storage areas need to be defined IMMEDIATELY after
;	their matching F$xxx storage areas.  (SCAN stored switch values of
;	new switches in addr and addr-2 if the storage location was defined
;	as addr at the end of the SCAN block.)
;
;512	10-31851	BAH	4-Nov-82
;	New.  Listing the version number of files during a /LIST or PRINT
;	command is useful to our customers.
;
;513	10-33182	BAH	4-Mar-83
;	Fix the method of computing length of files for the PRINT command.
;	Base the computation on the byte size instead of the mode of the
;	file.  Used DIRECT's formula.
;
;514	10-33253	BAH	13-Apr-83
;	Prevent a SKIP n, where n is greater than the number of tape marks
;	on a tape, from spinning the tape off the reel.  Only done for
;	USER-EOT labelled tapes.
;
;515	10-33914	BAH	20-Jun-84
;	Delete the routine LABSTS.  It makes reads of tapes written by previous
;	versions of BACKUP difficult to do.  PULSAR has already done appropriate
;	checking long before BACKUP reads the tapes.
;
;516	10-33987	BAH	21-Jun-84
;	If the listing file if found on LIB: and the user typed APPEND, fix
;	routine LISTST so that the USETI -1 is not done.  This caused ?Illegal
;	instruction if the site disabled SUPER I/O.
;
;517	Superseded by edit 520.
;	10-33983	BAH	21-Jun-84
;	If a user is PATHed to an SFD and specifies a listing, the listing
;	gets split between the SFD and the UFD.  Have CLSUF2 zero the PPN
;	word before the LOOKUP.
;
;520	None.		BAH	3-Jul-84
;	This edit supersedes edit 517.  Does not fix the case of a user
;	PATHed to his UFD and specifying an SFD for the listing file.
;	Convert to FILOP. checkpoint.
;
;521	10-33906	BAH	25-Jul-84
;	User experienced an ?Illegal address or a ?UUO error after %BKPPBR
;	Prior block repeated warning during a CHECK command under 7.01A.
;	Insert a WAIT. UUO even though problem could not be reproduced and
;	7.02 addressed the ?UUO error problems.
;
;522	10-33552	DRB	04-Mar-85
;	Rewrite the /INITIAL code so that we don't start from the wrong place
;	if the /INITIAL file doesn't really exist.
;
;523	10==33552	DRB	04-Mar-85
;	If the /INITIAL file isn't found, don't say "no files found 
;	ALL:*.*[*,*,*,*,*,*,*]".  Create a new, more meaningful error
;	message.
;
;524	None.	DRB	22-Apr-85
;	If /INITIAL file is given and not found before an SFD is encountered,
;	BACKUP did not continue the search for the /INITIAL file.
;
;525	33748	BAH	17-May-85
;	Restore reports "Prior block repeated" at EOT when a tape is mounted
;	unavailable.  Edit 321 started warning user of repeated blocks on the
;	tape.  BACKUP failed to clear the EOT bit in the buffer when it first
;	got the EOT error return.  The monitor gives an error return for every
;	OUT that did not first do a SETSTS to clear the EOT condition.  After
;	the second error condition, BACKUP recycles through the buffer ring
;	outputing the buffer occurring after the buffer with EOT but clears
;	the EOT bit.  The buffer after the first error condition will always
;	be repeated.  Clear EOT in the buffer when the first error condition
;	occurs.
;
;526	35186	BAH	15-Jul-85
;	Give a fatal message if an I/O error was encountered during the
;	execution of an EOT or REWIND command.
;
;527	None.	BAH	14-Aug-85
;	If edit 526 is applied, the magtape is SET UNAVAILABLE, and the user
;	typed an UNLOAD command to BACKUP, the user will get "MTxnn OPR 
;	ACTION REQUESTED".  Skip the MTWAT. on an UNLOAD command.
;
;530	35343	BAH	29-Oct-85
;	If the USAGE verb is given, and the SAVE verb specifies UFDs containing
;	SFDs, the last accounting date/time does not get updated in the UFD RIB.
;	BACKUP timeshared the LOOKUP/ENTER block for UFDs and SFDs.  If doing
;	USAGE accounting save away the LOOKUP block for the UFD after updating
;	the block with the appropriate values.  Then use this stored block for
;	the RENAME.
;
;***** End of Version 4A *****
;
;***** Begin Version 5 *****
;
;600	None.	BAH	15-Oct-82
;	Prepare for version 5.
;
;601	10-31434	BAH	15-Oct-82
;	New.  BACKUP needs to use the number of blocks/supercluster when
;	calculating the block number to SUSET. to when the /USETI switch
;	is in effect.  Requires MCO 10276.
;
;602	None.	DPM	7-Apr-84
;	Add support for PSI on reel switch.  Useful for doing BACKUPs on
;	labeled tapes.
;
;603	Development	JMF	17-Nov-82
;	New. Add support for big buffers on disk input (Save).
;
;604	Development	BAH	30-May-84
;	New. Add support for big buffers on disk output (Check/Restore).
;
;605	Development	BAH	2-Oct-84
;	Update copyrights.
;
;606	Development	BAH	28-Dec-84
;	Save and restore the files' attributes stored in .RBTYP, .RBBSZ,
;	.RBRSZ, and .RBFFB; see MCO 11334.  This information is saved
;	on interchange formatted tapes.
;
;607	Development	BAH	24-Jan-85
;	We have customers who are running an unsupported BACKUP which writes
;	the first two blocks of a file in the first T$FIL record all the time.
;	Edit 604 (big buffers on CHECK/RESTORE) did not support this.  Change
;	BACKRS to RESTORE/CHECK 200 words at a time.
;
;610	Development	BAH	13-Feb-85
;	Typing WHAT during runtime sometimes causes job to stay in TI state.
;	Edit 602 inadvertently zeroed FL$PSI.
;
;611	Development	BAH	3-Apr-85
;	A bubble sort for alphabetic sorts is too slow.  Change the routine
;	APHSRT to do a shell sort instead.
;
;612	None.	BAH	22-Apr-85
;	Edit 402 deleted all but IO.ERR in P1.  In some cases, subsequent code
;	depended on P1 being intact.  Change all the ANDI/CAIx to TXC/TXCN and
;	preserve the rest of the status bits.
;
;613	None.	BAH	22-Apr-85
;	If a SAVE gets a disk I/O error, BACKUP eventually ?Ill mem refs. DSKSE3
;	gets called and returns without setting up NDBLIB.  STBLK sets an error
;	bit in the tape buffer and then continues to save the file.  NDBLIB is
;	negative at this time and continues to save the rest of BACKUP's core
;	image until an ill mem ref.  Set up NDBLIB even on an error.
;
;614	None.	LEO  	22-Aug-85
;	Do Copyrights.
;
;***** End of Version 5 *****
;
;***** Begin Version 5A *****
;
;615	None.	BAH	20-Mar-86
;	Set up for version 5A.
;
;616	10-35445	DPM	 1-May-86
;	Respect /ERSUPERSEDE
;
;617	None.	BAH	16-Jun-86
;	Make BACKUP not throw away the high segment while a frustrated
;	programmer is debugging it.
;
;620	None.	DPM	3-Jul-86
;	Implement suggestion from SPR 10-35445 which allows BACKUP to
;	unique extensions if the file being restored from tape already
;	exists on disk.  This facility is under the control of the UNIQUE
;	verb which takes the standard [NO!YES], [OFF!ON], or [0!1] keys.
;	For compatibility, the default of off.  Turning on unique extension
;	generation implies /ERSUPERSEDE:YES.  This feature is most useful
;	when restoring files from a TOPS-20 DUMPER interchange format tape
;	which contains long filenames, but can be use successfully when
;	restoring standard TOPS-10 tapes as well.
;
;621	10-35665	BAH	14-Jan-87
;	BACKUP still believes in the old style of magtape drive management
;	where only one drive can be used per mount request.  GALAXY changed
;	all that so the wrong device name can be stored in the records.
;	Always get the physical device name for each reel switch.
;
;622	10-35686	BAH	17-Feb-87
;	After a REWIND, EOT, or UNLOAD, do a STATZ with a mask of IO.ERR.
;
;623	10-35699	DPM	 2-Sep-87
;	After a reel switch, make sure the tape is rewound and error bits
;	are cleared.
;
;624	None.		DPM	 8-Dec-87
;	After MCO 13534, the density stored in the start/end of save-set
;	records may not match the actual density the tape being written.
;	Fix by never reading the density (on a write operation) when the
;	tape is at the load point.  DIRECT used this method for years.
;	It's the only truely correct way to read the density on a write.
;
;625	None.	BAH	18-Feb-88
;	Fix up copyrights.  Also have BACKUP get USGSUB.REL and ENDECR.REL
;	from DSK:.
;
;***** End of Version 5A *****
;
;***** Begin Version 6 *****
;
;700	None.		DPM	31-Aug-88
;	Add modified version of ADP's wizzy code which allows writing tape
;	with large records.  New switch /BLOCKINGFACTOR:n controls this
;	feature.  The default is off and always off if /INTERCHANGE is
;	enabled.  The value "n" is disk blocks per tape block.  A multiple
;	of 4 is required.  Also, code will write small records when it is
;	more efficient.  Fix minor bugs in ADP implementation.
;
;701	None.		DPM	 1-May-89
;	Add support for pathological names.  Do this by breaking down LNMs
;	into their individual components and building up the equivalent
;	number of pairs of SCAN blocks for each input/output spec.  Note
;	that CHECK may exhibit strange behavior in the sense that files
;	will not necessarily be found in the correct order due to the way
;	that BACKUP loads them onto the tape in the first place.  This
;	is not a new problem, but it may be made more visible through
;	the use of LNMs.
;
;END OF REVISION HISTORY
	SUBTTL	DEFINITIONS

;.FLAGS.LM 0.NOAUTOT.UPPER CASE
;.CHAPTER DEFINITIONS
;.HL1 AC DEFINITIONS
;.NOFILL.TS16;.P0,-1
;-


;AC'S

;&.END SELECT

T1=1		;TEMPORARIES
T2=2
T3=3
T4=4

P1=5		;PRESERVED
P2=6

N=7		;WORD SCANNING RESULT
C=10		;CURRENT BREAK CHARACTER SCANNING

P=17		;STACK POINTER

				;&

;+.HL1 SOFTWARE CHANNELS
;-.NOFILL.END SELECT

F.LIST==1	;LISTING FILE CHANNEL	**DUPLICATE OF BACKRS
F.MTAP==2	;TAPE CHANNEL		**DUPLICATE OF BACKRS

				;&
;+
;.AUTOP.LOWER CASE

;.HL1 MACROS
;-

;+
;<SAVE$ _<LIST_> PUSHS THE LIST OF LOCATIONS
;ONTO THE STACK.
;-

	DEFINE	SAVE$	(LIST$),<
	XLIST
IRP (LIST$),<	PUSH	P,LIST$	>
	LIST
>


;+
;<RSTR$ _<LIST_> POPS THE LIST OF LOCATIONS FROM THE STACK.
;-

	DEFINE	RSTR$	(LIST$),<
	XLIST
IRP (LIST$),<	POP	P,LIST$	>
	LIST
>
	SUBTTL	IMPURE STORAGE

;+
;.TS8,16,24
;.CHAPTER IMPURE STORAGE

;\\^LOCATIONS OF THE FORM <S.XXXX ARE DEFINED AS <INTERNAL
;AND ARE THE COMMUNICATION REGION WITH THE ACTION MODULE,
;<BACKRS. ^THEY ARE DOCUMENTED IN DETAIL LATER IN THIS DOCUMENT.

; ^LOCATIONS WHICH ARE SET AT START-UP TIME AND NEVER CLEARED:^^

;-.SK1.NOFILL.NOAUTOPARAGRAPH.NOFLAGS.END SELECT;

OFFSET:	BLOCK	1	;CONTAINS STARTING OFFSET (1 IF CCL)
INICOR:	BLOCK	1	;INITIAL .JBFF,,.JBREL

SAVDSK:	BLOCK	1	;[314] 0 IF RUN FROM DSK, -1 IF NOT
SAVGET:!		;LOCATIONS FOR GET-SEG OF HIGH SEGMENT
SAVDEV:	BLOCK	1	;RUN DEVICE
SAVNAM:	BLOCK	1	;RUN FILE NAME
SAVLOW:	BLOCK	1	;RUN FILE LOW EXTENSION
	Z		;ALWAYS 0
SAVPPN:	BLOCK	1	;[434] RUN FILE DIRECTORY OR POINTER TO PATH BLOCK
	Z		;ALWAYS 0
SAVPTH:	BLOCK	.PTMAX	;[434] PATH BLOCK POINTED TO BY SAVPPN IF SFD

;AREA TO CLEAR ON STARTUP:

LOWFWA:!		;START
SAVEAC:	BLOCK	20	;AC SAVE AREA FOR GETSEG
ESAVAC==.-1		;END
PDLIST:	BLOCK	LN$PDL+1 ;PUSH-DOWN LIST
FFAPPN:	BLOCK	1	;FULL FILE ACCESS PPN
PTHPPN:	BLOCK	1	;[336] PPN OF CURRENT PATH.
NSVSET:	BLOCK	1	;[265] PLACE TO STASH N ON RETURN FROM .DECNW
LOWLWA==.-1
TAPDEN:	BLOCK 1		;[326] USER-SPECIFIED TAPE DENSITY
TAPLBL::BLOCK	1	;[426] USER SPECIFIED TAPE LABEL
;AREA TO CLEAR ON START OF COMMAND SCANNING:

SCNFWA:!		;START
	DEFINE	S$FILE ($LOC,$MNEM),<
;; $LOC IS 0 IF NOT SPECIFIED, IS 1 IF VERB SPECIFIED BUT
;;	NO FILE SPEC GIVEN, IS OTHER NON-ZERO IF FILE SPEC
;;	GIVEN.
$LOC::	BLOCK	.FXLEN	;;FILE SPEC STORAGE
MX.'$MNEM==.FXLEN	;;LENGTH IS THE MAX
PD.'$MNEM==1		;;NO DEFAULT
>
	S$FILE	(S.LIST,LST)	;LISTING FILE SPEC
	S$FILE	(S.TAPE,TAP)	;MAG TAPE FILE SPEC
	S$FILE	(S.TTAP,TTP)	;TEMP TAPE FILE SPEC

S.INIT::BLOCK	FX$LEN	;INITIAL FILE SPEC
S.CRYP::BLOCK	LN$CRP	;TAPE'S ENCRYPTION KEY
	BLOCK	1	;GUARANTEED END OF ASCIZ STRING
ENCRYP:	BLOCK	LN$CRP	;/ENCRYPT AND VERIFY

S.LOPN:	BLOCK	3	;LISTING FILE OPEN BLOCK
S.LBPT::BLOCK	3	;LISTING FILE BUFFER HEADER
S.LENT::BLOCK	LN$LEN	;LISTING FILE ENTER BLOCK

S.MOPN::BLOCK	3	;MAGE TAPE OPEN BLOCK
S.MBPT::BLOCK	3	;MAG TAPE BUFFER HEADER
S.MENT:	BLOCK	LN$MEN	;MAG TAPE ENTER BLOCK
S.APPD:	BLOCK	1	;APPEND (0=NO)
S.CKPT::BLOCK	1	;CHECKPOINT (0=NO)
S.DELT::BLOCK	1	;DELETE (0=NO)
S.SDEL::BLOCK	1	;[230] SUPERDELETE (0=NO)
S.DT75::BLOCK	1	;DATE-75 DEFENSE (0=NO)
S.EMAX::BLOCK	1	;[506] MAXIMUM NUMBER OF TAPE ERRORS
S.EXIT:	BLOCK	1	;-1 IF RESET, +1 IF EXIT AT END OF WORK
S.FFA:: BLOCK	1	;-1 IF USER = [1,2]
S.FRST::BLOCK	1	;ADDRESS OF START OF LIST
S.INTR::BLOCK	1	;INTERCHANGE MODE (0=NO)
S.LAST::BLOCK	1	;ADDRESS BEYOND END OF LIST
S.MULT::BLOCK	1	;MULTIREEL (0=NO)
S.NARL::BLOCK	1	;NARROW LISTING FORMAT
S.NGST::BLOCK	1	;AOBJN WORD TO STRUCTURE TABLE
S.NLDV::BLOCK	1	;[375] -1 IF NUL TAPE DEVICE
S.OPER::BLOCK	1	;OPERATION
	OPRCHK==1	;/CHECK
	OPRRST==2	;/RESTORE
	OPRSAV==3	;/SAVE
S.PRNT::BLOCK	1	;-1 IF PRINT
S.REPT::BLOCK	1	;/REPEAT(0=NO)
S.RSUM::BLOCK	1	;BLOCK TO RESUME AT
S.SRTD::BLOCK	1	;SORT DIRECTORIES MODE
S.SRTF::BLOCK	1	;SORT FILES MODE
			;0=NONE, 1=ALPHA, 2=LOCATION
S.SSNM::BLOCK	LN$SSN	;SAVE SET NAME
S.STOP::BLOCK	1	;0=GO, 1=STOP
S.STRS::BLOCK	LN$STR	;SYSTEM STRUCTURE TABLE
S.SUPR::BLOCK	1	;SUPERSEDE: 1=ALWAYS; 2=OLDER; 3=NEVER
S.TYMS::BLOCK	1	;TYPING MESSAGE LEVEL
	MSGSIL==0	;SILENCE
	MSGDIR==1	;LIST DIRECTORIES (USERS, NOT SFDS)
	MSGFIL==2	;LIST FILES
S.UNIQ::BLOCK	1	;GENERATE A UNIQUE EXTENSION
S.UPRT::BLOCK	1	;UPROTECT (0=NO CHANGE)
S.USET::BLOCK	1	;USETI (0=NO)
IFN FT$USG,<
S.USG:: BLOCK	1	;/USAGE
>
S.VRBO::BLOCK	1	;/MESSAGE AGRUMENT CODES
S.WRIT::BLOCK	1	;WRITE (0=NO)
S.XMPT::BLOCK	1	;EXEMPT DEFAULT PPNS (0=NO PPNS EXEMPTED)

S.NFS::	BLOCK	1	;CANCEL .RPNFS (ALLOW BACKUP OF FILES WITH
			;.RBSTS=200000)
S.NTPE:: BLOCK	1	; RELATIVE TAPE NUMBER.			[344]
S.TPFG:: BLOCK	1	; FLAG FOR SWITCH /TPNUM.		[347]
F$MBF:	BLOCK	1	;[511] CURRENT /MBEFORE	****************
F$MSN:	BLOCK	1	;[511] CURRENT /MSINCE  *Do NOT change *
P$MBF:	BLOCK	1	;[511] STICKY /MBEFORE  *  ordering!!  *
P$MSN:	BLOCK	1	;[511] STICKY /MSINCE   ****************
IFN FT$STK, <		;[341]
G$SNC:	BLOCK 1		;[341] PERMANENT STICKY /SINCE
G$ASN:	BLOCK 1		;[341] PERMANENT STICKY /ASINCE
G$MSN:	BLOCK 1		;[341] PERMANENT STICKY /MSINCE
G$BFR:	BLOCK 1		;[341] PERMANENT STICKY /BEFORE
G$ABF:	BLOCK 1		;[341] PERMANENT STICKY /ABEFORE
G$MBF:	BLOCK 1		;[341] PERMANENT STICKY /MBEFORE
>; END IFN FT$STK	;[341]

OSPEC:	BLOCK	FX$LEN	;TEMP OUTPUT SCAN BLOCK
ISPEC:	BLOCK	FX$LEN	;TEMP INPUT SCAN BLOCK
OLNM:	BLOCK	.PTLLB	;OUTPUT LOGICAL NAME TRANSLATION BLOCK
ILNM:	BLOCK	.PTLLB	;INPUT LOGICAL NAME TRANSLATION BLOCK
LNMFLG:	BLOCK	1	;NON-ZERO IF SOME LNM WAS TRANSLATED

B.BBKP::BLOCK	1	;MAXIMUM SIZE OF A BACKUP BLOCK ON TAPE (VARIABLE)
S.BFSZ::BLOCK	1	;SIZE OF TAPE BUFFERS
S.BFCT::BLOCK	1	;BLOCKING FACTOR

SCNLWA==.-1		;END

				;&
			;END OF LOW SEGMENT DATA
	SUBTTL	INITIALIZATION

;+
;.AUTOPA.FLAGS.TS8,16,24,32,,,,,,,,,.P0,-1.FILL.LOWER CASE
;.CHAPTER COMMAND SCANNING
;-

;+.HL1 INITIALIZATION
;
;^THE START ADDRESS IS ACTUALLY IN THE LOW SEGMENT SO THAT
;A _^^C FOLLOWED BY A <START WHILE RUNNING WILL WORK AS
;THE USER EXPECTED.
;-

BKPSTR:	TDZA	T1,T1		;CLEAR OFFSET
	MOVEI	T1,1		;INDICATE OFFSET
	ADDI	T1,BACKUP	;CALCULATE REAL START
	HRRM	T1,BKPST1	;SET TO DO THAT

	SKIPN	SAVDSK		;[314] DON'T GET IT BACK IF NOT THROWN AWAY
	SKIPE	.JBHRL##	;SEE IF A HIGH SEG
	JRST	BKPST1		;YES--JUST DO START
GSFAIL:	MOVEI	T1,SAVGET	;SET FOR GETSEG
	GETSEG	T1,		;GET HI SEG BACK
	  SKIPA			;DIE IF DOES NOT WORK
BKPST1:	JRST	.-.		;NOW DO START

	OUTSTR	SEGMSG
	MONRT.			;EXIT TO MONITOR
	JRST	GSFAIL		;A CONTINUE WILL TRY AGAIN


SEGMSG:	ASCIZ/
?BKPHSG Cannot get high segment back
/

	RELOC	400000		;RELOCATE TO HIGH SEG
;+
;^THE PROGRAM STARTS EXECUTION AT <BACKUP IF CALLED BY A <RUN
;COMMAND, OR AT <BACKUP+1 IF CALLED BY A <CCL COMMAND. ^THIS
;STATUS IS SAVED AWAY FOR <SCAN SO THAT IT KNOWS WHETHER TO READ
;A <CCL FILE OR NOT.  ^ALSO, THE FIRST TIME HERE, THE <RUN <UUO
;OR COMMAND ARGUMENTS ARE STORED AWAY FOR SUBSEQUENT <GETSEG\S.
;^THIS IS NECESSARY SO THAT THE SUBSEQUENT <GETSEG WILL ALWAYS
;USE THE SAME DIRECTORY, SEARCH LIST, ETC., AS WAS USED
;ORIGINALLY TO GET THE COMMAND SCANNER. ^THIS CAN BE SAVED ONLY
;ONCE SINCE THE USER MIGHT DO A _^^C AND THEN <START COMMAND.
;^ALSO, THE FIRST TIME HERE THE VALUES OF <.JBFF AND <.JBREL ARE
;SAVED AND ON SUBSEQUENT TIMES THROUGH THEY ARE RESTORED TO THEIR
;ORIGINAL VALUES.
;-

BACKUP:	PORTAL	.+2		;[360] NON-CCL ENTRY TO HIGH-SEG
	PORTAL	.+2		;[360] CCL ENTRY TO HIGH-SEG
	TDZA	T1,T1		;[360] NON-CCL ENTRY
	MOVEI	T1,1		;CCL ENTRY
	MOVEM	T1,OFFSET	;STORE FOR SCAN
	RESET			;CLEAR ALL I/O

	SKIPE	SAVDEV		;SEE IF HERE BEFORE
	JRST	BKPSC1		;YES--ALREADY KNOW THE DEVICE
	HRROI	T1,.GTRDV	;[434] GET DEVICE WE RAN FROM
	GETTAB	T1,		;[434]
	  MOVSI	T1,'SYS'	;[434] NO--USE SYS
	MOVEM	T1,SAVDEV	;[434] SAVE THE DEVICE
	DEVCHR	T1,		;[434][314] IS THIS A DISK?
	SKIPN	.JBDDT		;[617] IF WE ARE DEBUGGING,
	TXNN	T1,DV.DSK	;[434][314] IS IT?
	SETOM	SAVDSK		;[314] NO, DON'T LOSE HIGH SEGMENT
	HRROI	T1,.GTRFN	;[434] GET THE FILENAME
	GETTAB	T1,		;[434]
	  MOVE	T1,['BACKUP']	;[434] NO--USE BACKUP
	MOVEM	T1,SAVNAM	;[434] SAVE THE FILE NAME
	HRROI	T1,.GTRDI	;[434] GET THE PPN
	GETTAB	T1,		;[434]
	  SETZ	T1,		;[434] DEFAULT TO ZERO
	MOVEM	T1,SAVPPN	;[434] SAVE THE DIRECTORY
	MOVEM	T1,SAVPTH+.PTPPN;[434] PPN IS PART OF PATH BLOCK
	MOVSI	T2,-5		;[434] AOBJN FOR SFD GETTABS

BKPSC3:	HRROI	T1,.GTRS0(T2)	;[434] GET AN SFD NAME
	GETTAB	T1,		;[434]
	  JRST	BKPSC4		;[434] NO MORE SFDS
	JUMPE	T1,BKPSC4	;[434] END OF SFDS
	MOVEM	T1,SAVPTH+.PTSFD(T2) ;[434] STORE THE NAME IN THE PATH BLOCK
	AOBJN	T2,BKPSC3	;[434] GET ALL SFDS

BKPSC4:	SETZM	SAVPTH+.PTSFD(T2);[434] PUT ZERO AT END OF LIST
	MOVEI	T1,SAVPTH	;[434] GET ADDRESS OF PATH BLOCK
	SKIPE	SAVPTH+.PTSFD	;[434] ANY SFDS?
	MOVEM	T1,SAVPPN	;[434] YES. POINT TO PATH BLOCK FOR GETSEG
	HRROI	T1,.GTSTS	;[502] GET THE JOB'S STATUS
	GETTAB	T1,		;[502]
	  SKIPA			;[502] IF ERROR, DON'T THROW AWAY HI-SEG
	TXNE	T1,JS.XO	;[502] IS BACKUP EXECUTE ONLY?
	SETOM	SAVDSK		;[502] YES.

BKPSC1:	HRRZ	T1,.JBREL##	;GET FIRST-TIME CORE SIZE
	HRL	T1,.JBFF##	;GET FIRST-TIME FREE CORE
	SKIPN	INICOR		;UNLESS ALREADY SET,
	MOVEM	T1,INICOR	; SAVE INITIAL CORE
	MOVEI	T1,REENTR	;SET REENTER POINT
	MOVEM	T1,.JBREN##	; ...

	STORE	17,0,16,0	;CLEAR ALL ACS
	STORE	17,LOWFWA,LOWLWA,0 ;CLEAR LOW CORE

	MOVE	P,[IOWD LN$PDL,PDLIST]  ;SET STACK
	PUSHJ	P,RESCOR	;RESTORE CORE TO ORIGINAL VALUES

	MOVE	T1,[2,,[  IOWD 1,['BACKUP']
			  OFFSET,,'BKP'  ]]
	PUSHJ	P,.ISCAN##	;INITIALIZE COMMAND SCANNER

	MOVE	T1,[3,,T2]	;[336] SET UP TO READ CURRENT PATH.
	SETO	T2,		;[336] DITTO
	PATH.	T1,		;[336] READ CURRENT PATH.
	  MOVE	T2+.PTPPN,.MYPPN;[336] CAN'T PATH; USE LOGGED-IN PPN
	MOVEM	T2+.PTPPN,PTHPPN;[336] SAVE CURRENT PATH'S PPN.
	MOVX	T1,%LDFFA	;GET FULL-FILE ACCESS
	GETTAB	T1,		; FROM MONITOR
	  MOVE	T1,[1,,2]	;(I.E., [1,2])
	MOVEM	T1,FFAPPN	;SAVE FOR LATER
;+.HL1 INITIALIZE SCANNING
;
;^FIRST, CLEAR OUT COMMAND SCANNER RESULTS. ^THEN SET THE BUILT IN
;DEFAULTS TO STANDARD VALUES. ^THEN USE <.OSCAN TO GET THE USER
;SPECIFIED DEFAULTS FROM THE FILE <SWITCH.INI.
;-

	STORE	T1,SCNFWA,SCNLWA,0	;CLEAR LOW CORE


					;[224] PUT -1 INTO SN SWITCHES
					;[224] TO SHOW SWITCH.INI RESET
	SETOM	S.APPD			;[224] APPEND
	SETOM 	S.CKPT			;[224] CHECKPOINT
	SETOM	S.DT75			;[224] DATE75
	SETOM	S.EMAX			;[506] MAXIMUM TAPE ERRORS
	SETOM	S.TYMS			;[226] PROPER TYPING LEVEL
	SETOM	S.SUPR			;[226] SUPERSEDE
	SETOM	S.UNIQ			;GENERATE UNIQUE EXTENSION
	SETOM	S.DELT			;[234] DELETE
	SETOM	S.CRYP			;[234] ENCRYPTION
	SETOM	S.SDEL			;[234] SDELETE
	SETOM	S.XMPT			;[224] EXEMPT
	SETOM	S.INTR			;[224] INTERCHANGE
	SETOM	S.MULT			;[224] MULTIREEL
	SETOM	S.NFS			;[374] NFS
	SETOM	S.REPT			;[224] REPEAT
	SETOM	S.SRTD			;[372] SORT DIRECTORIES
	SETOM	S.SRTF			;[372] SORT FILES
	SETOM	S.USET			;[224] USETI
IFN FT$USG,<SETOM S.USG>		;USAGE
	SETOM	S.WRIT			;[224] WRITE
	SETOM	F$MBF			;[374] MBEFORE
	SETOM	F$MSN			;[374] MSINCE
	SETOM	S.BFCT			;BLOCKING FACTOR

	MOVE	T1,OSCNPT		;[224] GET OSCAN PTR
	PUSHJ	P,.OSCAN##		;[224] GET INITIAL STATUS
	DEFINE	SETUP$(LOC$,VAL$),<	;[224] SET DEFAULT 
					;[224] SPECIFIED BY SWITCH.INI
		IFN <VAL$>+1,<IFE <VAL$>-1,<SKIPGE LOC$	     ;[224]
					    MOVEM T1,LOC$>   ;[224]
			      IFN <VAL$>-1,<SKIPL LOC$	     ;[224]
					    JRST  .+3	     ;[224]
				            MOVEI  T2,VAL$   ;[224]
					    MOVEM T2,LOC$>   ;[224]
				>
		>

	MOVEI	T1,1		;SET COMMON CONSTANT
	SETUP$	(S.DELT,AD.DLT)	;[234]  DELETE
	SETUP$	(S.CRYP,AD.CYP)	;[234]  ENCRYPTION
	SETUP$	(S.REPT,AD.RPT)	;[234] REPEAT
	SETUP$	(S.SDEL,AD.SDL)	;[234] SDELETE
	SETUP$	(S.APPD,AD.APP)	;APPEND
	SETUP$	(S.CKPT,AD.CKP) ;NO CHECKPOINTING
	SETUP$	(S.DT75,AD.D75)	;DATE-75 DEFENSE
	SETUP$	(S.EMAX,AD.ERM)	;[506] MAXIMUM TAPE ERRORS
	SETUP$	(S.INTR,AD.INT) ;NO INTERCHANGE
	SETUP$	(S.MULT,AD.MUL) ;MULTIREEL SAVES
	SETUP$	(S.SRTD,AD.SRD)	;SORT DIRECTORY
	SETUP$	(S.SRTF,AD.SRF)	;SORT FILES
	SETUP$	(S.SUPR,AD.SUP)	;SUPERSEDE
	SETUP$	(S.TYMS,TY$MSG)	;TYPING MESSAGE LEVEL
	SETUP$	(S.UNIQ,AD.UNQ)	;GENERATE UNIQUE EXTENSION
	SETUP$	(S.UPRT,AD.UPR)	;UPROTECT
	SETUP$	(S.USET,AD.UST)	;USETI
IFN FT$USG,<SETUP$ (S.USG,AD.USG)> ;USAGE ACCOUNTING
	MOVE	T2,FFAPPN	;GET FULL-FILE ACCESS
	CAMN	T2,.MYPPN##	;[413] SEE IF THAT IS US
	JRST	BKPSC2		;[413] YES
	SETZM	S.USET		;[413] NO--DEFAULT TO /NOUSETI
IFN FT$USG,<SETZM S.USG>	;[430][413] AND MAKE SURE /NOUSAGE
	SKIPA			;[413] NOT [1,2] SO SKIP NEXT
BKPSC2:	SETOM	S.FFA		;[413] TELL BACKRS TO USE MORE DISK BUFFERS
	SETUP$	(S.WRIT,AD.WRT)	;WRITE
	SETUP$	(S.XMPT,AD.XMP)	;EXEMPT
	SETUP$	(P$MBF,-1)	;/MBEFORE
	SETUP$	(P$MSN,-1)	;/MSINCE
	SETZ	T1,		;[374] IF NOTHING, ZERO THE FOLLOWING
	SETUP$	(F$MBF,1)	;[374] MBEFORE
	SETUP$	(F$MSN,1)	;[374] MSINCE
	SETUP$	(S.NFS,1)	;[374] NFS
	MOVEI	T1,1		;INITIALIZE T1
	SETUP$	(S.BFCT,AD.FCT)	;NORMAL BLOCKING FACTOR
IFN FT$STK,<			;[341]
	MOVEI	T1,MEMST2	;[341] ROUTINE TO AID SCAN'S FILSTK
	MOVEM	T1,MEMSTK##	;[341]
	MOVEI	T1,CLEARP	;[341] ROUTINE TO AID SCAN'S CLERST
	MOVEM	T1,CLRSTK##	;[341]
>; END IFN FT$STK		;[341]
;+.HL1 MAIN COMMAND SCAN LOOP
;
;^NOW, CALL <.VSCAN TO DO THE COMMAND SCANNING. ^IT WILL
;LOOP UNTIL END OF FILE FROM THE COMMAND TERMINAL. ^THE
;ACTUAL OPERATIONS ARE ALL CALLED AS SUBROUTINES FROM
;<.VSCAN AS IT HITS THE VARIOUS ACTION VERBS.
;-

CMDLOP:	MOVE	T1,VSCNPT	;POINT TO ARGUMENTS
	PUSHJ	P,.VSCAN##	;DO ALL THE WORK

;+.HL1 END OF JOB
;
;^AT END OF FILE ON THE COMMAND TERMINAL, CONTROL RETURNS HERE.
;^THIS HAPPENS EITHER BECAUSE THE USER TYPED _^^Z, OR
;BECAUSE THE COMMANDS WERE GIVEN ON THE INITIAL LINE WHICH
;INVOKED THIS PROGRAM AND THEY HAVE ALL BEEN EXECUTED.
;-

	PUSHJ	P,.MONRT##	;RETURN TO MONITOR
	JRST	CMDLOP		;IF USER TYPES .CONTINUE,
				; RESUME COMMAND LOOP
;ARGUMENT BLOCK FOR OSCAN

OSCNPT:	4,,SCNBLK	;4 WORDS

;ARGUMENT BLOCK FOR VSCAN

VSCNPT:	6,,SCNBLK	;6 WORDS

;COMMAND SCAN BLOCK FOR OSCAN AND VSCAN

SCNBLK:	IOWD	VERBL,VERBN
	XWD	VERBD,VERBM
	XWD	    0,VERBP
	EXP	-1		;STANDARD HELP
	XWD	2,F$MBF		;2-WORDS OF LOCAL FILE SWITCHES
	XWD	0,P$MBF		; ..
	;VERB CONTROL TABLE

	DEFINE	SWTCHS,<
SN APPEND,S.APPD,
SP BLOCKINGFACTOR,S.BFCT,$BLOCK,,
SP CHECK,,$CHECK,,
SN CPOINT,S.CKPT,
SN DATE75,S.DT75,
SN DELETE,S.DELT,
SN SDELETE,S.SDEL,	;[230] IMPLEMENT SUPERDELETE SWITCH
SS DIRECTORIES,S.TYMS,MSGDIR,
SN ENCRYPTION,S.CRYP,
SP EOT,,$EOT,,
SP ERRMAX,S.EMAX,.SWDEC##,ERM,FS.VRQ	;;[506]
SN EXEMPT,S.XMPT,
SS FILES,S.TYMS,MSGFIL,
SS GO,S.STOP,0,
SP INITIAL,,$INITI,,FS.VRQ
SN INTERCHANGE,S.INTR,
SP KILL,,.POPJ1##,,	;;FOR COMPLETENESS
SP LIST,,$LIST,,
SP MBEFORE,F$MBF,.SWDTP##,,FS.VRQ
SP MSINCE,F$MSN,.SWDTP##,,FS.VRQ
SN MULTIREEL,S.MULT,
SP NLIST,,$NLIST,,
SS NODIRECTORIES,S.TYMS,MSGSIL,
SN NFS,S.NFS
SS NOFILES,S.TYMS,MSGDIR,
SS NOLIST,S.LIST,0,
IFN FT$USG,<SS NOUSAGE,S.USG,0,>
SP NPRINT,,$NPRIN,,
SP PAUSE,,.POPJ1##,,	;;FOR COMPLETENESS
SP PRINT,,$PRINT,,
SN REPEAT,S.REPT,
SP RES,,$RESTO,,
SP RESET,,BACKUP,,
SP RESTORE,,$RESTO,,
SP RESUME,,$RESUM,,FS.VRQ
SP REWIND,,$REWIN,,
SP SAVE,,$SAVE,,
SS SILENCE,S.TYMS,MSGSIL,
SP SKIP,,$SKIP,,FS.VRQ
SP SORT,,$SORT,,FS.VRQ
SP SSNAME,<POINT <^D65-LN$SSN>,S.SSNM>,.ASCQW##,SSN,
SS STOP,S.STOP,1,
SL SUPERSEDE,S.SUPR,SUP,PD.SUP,
SP TAPE,S.TAPE,$TAPE,TAP,FS.VRQ
SP TPNUMBER,,$TPNUM,,FS.VRQ	;[305]
SN UNIQUE,S.UNIQ,
SP UNLOAD,,$UNLOA,,
SP UPROTECT,S.UPRT,.SWOCT##,UPR,
SN USETI,S.USET,
IFN FT$USG,<SP USAGE,,$USAGE,,>
SP *WHAT,,$WHAT,,
SN WRITE,S.WRIT,
>

;KEY WORD LISTS

KEYS (SUP,<ALWAYS,OLDER,NEVER>)

;MISC. DEFINITIONS

MX.SSN==1	;DUMMY
PD.SSN==0	;DUMMY
;NOW BUILD THE TABLES
	DOSCAN	(VERB)
	SUBTTL	MISCELLANEOUS NON-ACTION VERBS

;+
;.CHAPTER NON-ACTION VERBS
;-

;+.HL1 INITIAL (DECLARE FILE TO START WITH)
;
;^THE <INITIAL VERB DECLARES THE FILE SPECIFICATION TO START
;WITH. ^THE REQUESTED OPERATION WILL IGNORE ALL FILES UNTIL
;ONE IS FOUND WHICH MATCHES THIS SPECIFICATION.
;-


$INITI:	PUSHJ	P,.FILIN##	;GET FILE SPEC
	MOVEI	T1,S.INIT	;POINT TO INITIAL STORAGE
	MOVEI	T2,.FXLEN	;INDICATE LENGTH
	PUSHJ	P,.GTSPC##	;COPY ACROSS FROM SCAN
	SKIPGE	S.INIT+.FXMOD	;DEVICE DEFAULTED?
	JRST	[SETZM	S.INIT+.FXDEV	;YES--ZILCH
		 JRST	.POPJ1##];RETURN TO VSCAN
	MOVEI	T1,S.INIT	;POINT TO INITIAL SPEC
	PUSHJ	P,FIXPPN	;DO PPN FIXUP
	  JRST	.POPJ1##	;NOT A DISK, SO QUIT NOW
	PUSHJ	P,APPSTR	;APPLY STRUCTURE FLAGS
	JRST	.POPJ1##	;RETURN
;+.HL1 RESUME (DECLARE BLOCK NUMBER TO START WITH)
;
;^THE <RESUME COMMAND IS USED IN CONJUNCTION WITH <CPOINT AND <INITIAL.
;^IF A CRASH OCCURS DURING A CHECKPOINT <SAVE OR <RESTORE, TO RESTART AT
;THE LAST CHECKPOINT, USE <INITIAL TO DECLARE THE FILE SPEC,
;AND <RESUME TO DECLARE THE CHECKPOINT BLOCK NUMBER.
;-

$RESUM:	PUSHJ	P,.DECNW##	;CALL SCAN TO READ SIGNED DECIMAL NBR
	JUMPLE	N,E$$NZC	;ERROR IF NEGATIVE OR ZERO
	MOVEM	N,S.RSUM	;SAVE BLOCK NUMBER
	JRST	.POPJ1##	;RETURN TO .VSCAN

E$$NZC::MOVEI	T1,'NZC'	;MESSAGE PREFIX
	MOVEI	T2,[ASCIZ \Negative and zero checkpoints illegal\]
	PJRST	SCNERR		;ISSUE ERROR MESSAGE

;+.HL1 [N]LIST (DECLARE LISTING FILE)
;
;^THE <LIST AND <NLIST VERBS DECLARE THE FILE ONTO WHICH IS PLACED A
;LISTING OF THE OPERATION. ^THIS LISTING IS SIMILAR TO THAT
;WHICH <DIRECT WOULD GIVE.
;<NLIST SPECIFIES THAT ONLY 72-COL WIDE LISTING IS TO BE GIVEN.
;-

$LIST:	TDZA	T1,T1		;INDICATE FULL WIDTH
$NLIST:	MOVEI	T1,1		;INDICATE NARROW WIDTH
	MOVEM	T1,S.NARL	;SET FLAG FOR LISTER
	MOVEI	T1,1		;INDICATE
	MOVEM	T1,S.LIST	; LISTING NEEDED
	JUMPLE	C,.POPJ1##	;RETURN IF NULL
	PUSHJ	P,.FILIN##	; GET THIS FILE SPEC
	CAIE	C,"/"		;[274] / IS OK
	PJUMPG	C,E.INCL##	;NO MORE THAN ONE SPEC
	PUSHJ	P,LISTSW	;HANDLE LIST SWITCH FOR ERRORS
	RELEAS	F.LIST,		;CLEAR CHANNEL UNTIL NEEDED
	JRST	.POPJ1##	;RETURN WITHOUT STORE


;+.HL1 TAPE (DECLARE TAPEING FILE)
;
;^THE <TAPE VERB DECLARES THE MAGNETIC TAPE WHICH IS USED
;IN THIS OPERATION. ^IT IS ALSO USED AS THE DEFAULT DEVICE
;FOR ANY SUBSEQUENT POSITIONING OPERATIONS.
;-

$TAPE:	PUSHJ	P,.FILIN##	;GET THIS FILE SPEC
	PUSHJ	P,TAPESW	;HANDLE TAPE SWITCH FOR ERRORS
	JRST	.POPJ1##	;RETURN WITHOUT STORE



;+.HL1 TPNUMBER (SET TAPE NUMBER)
;
;^THE <TPNUMBER VERB SETS THE TAPE NUMBER.
;^IF NOT SET EXPLICITLY, NTPE IS EQUAL TO ONE (1).
;-

$TPNUM:	PUSHJ	P,.DECNW##	;[305] CALL SCAN TO READ SIGNED DECIMAL NO.
	JUMPLE	N,E$$NZT	;[305] ERROR IF NEGATIVE OR ZERO
	MOVEM	N,S.NTPE	;[305] SET NTPE
	SETOM	S.TPFG		; FLAG SO BACKRS WON'T CLOBBER TAPE #.[347]
	JRST	.POPJ1##	;[305] RETURN

E$$NZT::MOVEI	T1,'NZT'	;[305] MESSAGE PREFIX
	MOVEI	T2,[ASCIZ \Negative and zero tape numbers illegal\]
	PJRST	SCNERR		;[305] ISSUE ERROR MESSAGE



;+.HL1 USAGE (ENABLE <USAGE ^ACCOUNTING)
;
;^THE <USAGE VERB ENABLES <USAGE ^ACCOUNTING.  FIRST A CHECK
;IS MADE TO SEE IF THE USER IS [1,2]. ^IF NOT, AN ERROR
;MESSAGE IS PRINTED.  THE DEFAULT IS <NOUSAGE.  ^THIS OPTION IS
;AVAILABLE ONLY IF <BACKUP AND <BACKRS WERE ASSEMBLED WITH THE
;COMPILATION SWITCH <FT$USG EQUAL TO 1.
;-

	IFN FT$USG,<		;[413] ONLY IF USAGE ACCOUNTING IS ENABLED
$USAGE:	MOVE	T1,FFAPPN	;[413] GET FULL-FILE ACCESS
	CAME	T1,.MYPPN##	;[413] SEE IF THAT IS US
	JRST	NOUSG		;[413] NO, CANNOT DO ACCOUNTING FROM HERE
	SETOM	S.USG		;[413] ENABLE USAGE ACCOUNTING
	JRST	.POPJ1##	;[413] AND RETURN

NOUSG:	MOVE	T1,['BKPCDU']	;[413] NOT FROM HERE YOU DON'T
	HRLI	T2,"?"		;[413] FATAL
	HRRI	T2,[ASCIZ /Cannot do USAGE Accounting from this PPN/] ;[413]
	PUSHJ	P,.ERMSG##	;[413] TELL THE USER ABOUT FAILURE
	PUSHJ	P,.TCRLF##	;[413]
	PUSHJ	P,.TCRLF##	;[413]
	SETZM	S.USG		;[413] MAKE SURE IT'S ZERO
	JRST	.POPJ1##	;[413] AND RETURN
>				;[413] END IFN FT$USG

;+.HL1 SORT (SPECIFY ORDER)
;
;^THE <SORT VERB SETS THE SORT ORDER OF DIRECTORIES AND OF
;FILES INDEPENDENTLY.  ^IT TAKES TWO KEYWORDS IN ORDER. ^THE
;FIRST SPECIFIES WHETHER THE FILES OR DIRECTORY IS BEING
;SPECIFIED ("<FILES" OR "<DIRECTORY", WITH NEITHER DEFAULTING TO
;DIRECTORY). ^THE SECOND IS THE SORT ORDER. ^IT IS ONE OF
;"<ALPHABETIC" TO ALPHABETIZE THE OUTPUT,
;"<LOCATION" TO TAKE THINGS IN LOCATION ORDER (BY <CFP),
;"<NONE" TO FOLLOW THE ORDER THEY APPEAR IN THE
;DIRECTORY. ^IF THE SECOND KEY IS NOT SPECIFIED, THEN IT DEFAULTS
;TO ALPHABETIC. ^AT LEAST ONE KEYWORD MUST BE SPECIFIED.
;-

$SORT:	PUSHJ	P,.SAVE1##	;SAVE P1
	MOVEI	P1,S.SRTD	;DEFAULT TO DIRECTORY SORT
	PUSHJ	P,.SIXSW##	;GET FIRST KEYWORD
	MOVE	T1,[IOWD SRT1.L,SRT1.T]
	PUSHJ	P,.NAME##	;LOOKUP IN TABLE
	  JRST	SORT2		;MUST BE NEITHER
	TLZ	T1,-1		;CLEAR JUNK
	CAIN	T1,SRT1.T+1	;IF FILES,
	MOVEI	P1,S.SRTF	; SET TO SPECIFY FILES

;HERE TO GET SECOND WORD

SORT1:	MOVEI	T1,SRT2ALPHA	;DEFAULT TO ALPHA SORT
	JUMPLE	C,SORT3		;IF NO WORD COMING, DEFAULT
	CAIN	C," "		;SEE IF SPACE
	PUSHJ	P,.TIALT##	;YES, GET COMMAND CHARACTER
	CAIN	C,":"		;[274] COLON?
	PUSHJ	P,.TIALT##	;[274] 
	CAIN	C,","		;COMMA?
	PUSHJ	P,.TIALT##	;SEE IF FOLLOWED BY SPACES
	CAIE	C," "		; ...
	PUSHJ	P,.REEAT##	;NO--RE-EAT COMMAND CHARACTER
	PUSHJ	P,.SIXSW##	;GET SECOND WORD
SORT2:	MOVE	T1,[IOWD SRT2.L,SRT2.T] ;POINT TO POSSIBILITIES
	PUSHJ	P,.NAME##	;LOOKUP IN TABLE
	  JRST	E.UKK##		;ERROR--UNKNOWN
	TLZ	T1,-1		;REMOVE JUNK
	SUBI	T1,SRT2.T-1	;REMOVE OFFSET
	CAIN	T1,SRT2NONE	;IF NONE,
	MOVEI	T1,0		; CHANGE TO UNSET
SORT3:	MOVEM	T1,(P1)		;STORE IN CORRECT PLACE
	JRST	.POPJ1##	;RETURN WITHOUT STORE

KEYS	(SRT1,<DIRECTORY,FILES>)
KEYS	(SRT2,<ALPHABETIC,LOCATION,NONE>)
;+.HL 1 BLOCKING FACTOR SUPPORT
;
;^THE <BLOCKINGFACTOR COMMAND ENABLES <BACKUP TO READ AND/OR WRITE
;WRITE LARGE TAPE BLOCKS.  ^THE OPTIONAL VALUE IS THE NUMBER OF DISK
;BLOCKS TO PACK INTO A SINGLE TAPE BLOCK.  ^ONLY AN EVEN MULTIPLE OF
;4 BLOCKS IS ALLOWED DUE TO THE WIDESPREAD KNOWLEDGE THROUGHOUT
;<BACKRS 512 IS A SACRED NUMBER, NOT TO BE TAMPERED WITH.
;-

$BLOCK:	SKIPGE	C		;EOL?
	SKIPA	N,[AD.FCT]	;YES--USE DEFAULT VALUE
	PUSHJ	P,.DECNW##	;GET THE DECIMAL NUMBER
	CAIL	N,4		;RANGE
	CAILE	N,LN$FCT	; CHECK
	JRST	E$$BFW		;BLOCKING FACTOR WRONG
	TRNE	N,3		;MULTIPLE OF 4 DISK BLOCKS?
	JRST	E$$BNM		;NO--BAD NUMBER
	MOVE	T1,[%CCTYP]	;GETTAB ARGUMENT
	CAILE	N,^D56		;ABOVE KS10 UNIBUS ADAPTER LIMITATION?
	GETTAB	T1,		;YES--GET CPU TYPE FROM MONITOR
	  SETZ	T1,		;???
	CAIE	T1,.CCKSX	;KS10?
	PJRST	.SWDPB##	;NO--RETURN AND STORE ANSWER
	MOVEI	N,^D56		;REDUCE TO WHAT THE KS10 CAN HANDLE
	MOVE	T1,['BKPRBF']	;PREFIX
	HRLI	T2,"%"		;SET FIRST CHARACTER
	HRRI	T2,[ASCIZ /Reducing blocking factor for KS10/]
	PUSHJ	P,.ERMSG##	;LET USER KNOW WHAT WE DID
	PJRST	.SWDPB##	;RETURN AND STORE ANSWER

E$$BFW:	MOVEI	T1,'BFW'
	MOVEI	T2,[ASCIZ /Blocking factor out of range/]
	PJRST	SCNERR

E$$BNM:	MOVEI	T1,'BNM'
	MOVEI	T2,[ASCIZ /Blocking factor not a multiple of 4 disk blocks/]
	PJRST	SCNERR
	SUBTTL	TAPE POSITIONING VERBS

;+
;.CHAPTER TAPE POSITIONING VERBS
;-

;+.HL1 EOT (SKIP TO END OF TAPE)
;
;^THE VERB <EOT TAKES ZERO, ONE, OR A LIST OF
;TAPES AS ITS ARGUMENTS. ^IF ZERO, THEN THE TAPE
;SPECIFIED BY THE LAST <TAPE VERB IS USED. ^EACH
;SPECIFIED TAPE IS POSITIONED TO LOGICAL END OF TAPE.
;^IF A LIST IS GIVEN AND TWO CONSECUTIVE COMMAS
;ARE SPECIFIED, THEN THE LAST <TAPE VERB IS
;POSITIONED ALSO.
;-

EOTFNC:	MTEOT.	F.MTAP,		;[526]
$EOT:	MOVE	T1,EOTFNC	;[526] GET EOT FUNCTION
	JRST	TAPFCN		;GO FUNCTION

;+.HL1 REWIND
;
;^THE VERB <REWIND TAKES ZERO, ONE, OR A LIST OF
;TAPES AS ITS ARGUMENTS. ^IF ZERO, THEN THE TAPE
;SPECIFIED BY THE LAST <TAPE VERB IS USED. ^EACH
;SPECIFIED TAPE IS POSITIONED TO BEGINNING OF TAPE.
;^IF A LIST IS GIVEN AND TWO CONSECUTIVE COMMAS
;ARE SPECIFIED, THEN THE LAST <TAPE VERB IS
;POSITIONED ALSO.
;-

REWFNC:	MTREW.	F.MTAP,		;[526]
$REWIN:	MOVE	T1,REWFNC	;[526] GET REWIND FUNCTION
	JRST	TAPFCN		;GO FUNCTION TAPE

;+.HL1 UNLOAD
;
;^THE VERB <UNLOAD TAKES ZERO, ONE, OR A LIST OF
;TAPES AS ITS ARGUMENTS. ^IF ZERO, THEN THE TAPE
;SPECIFIED BY THE LAST <TAPE VERB IS USED. ^EACH
;SPECIFIED TAPE IS UNLOADED FROM ITS DRIVE.
;^IF A LIST IS GIVEN AND TWO CONSECUTIVE COMMAS
;ARE SPECIFIED, THEN THE LAST <TAPE VERB IS
;REMOVED ALSO.
;-

UNLFNC:MTUNL. F.MTAP,		;[345] GET FUNCTION
$UNLOA:	MOVE	T1,UNLFNC	;[345] FALL INTO TAPFCN
				;FALL INTO TAPFCN
				;FALL HERE FROM ABOVE

;+
;<TAPFCN IS A COMMON ROUTINE FOR THE TAPE POSITIONING
;COMMANDS WHICH TAKE NO ARGUMENT OTHER THAN THE LIST
;OF TAPES TO FUNCTION. ^IT IS CALLED WITH ^T1 CONTAINING
;THE <MTAPE FUNCTION TO PERFORM.
;-

TAPFCN:	PUSH	P,T1		;PUT FUNCTION IN A SAFE PLACE

;LOOP HERE OVER EACH TAPE IN THE LIST

TAPFCL:	PUSHJ	P,TAPARG	;GET NEXT TAPE ARGUMENT
	PUSHJ	P,TAPOPN	;OPEN THE TAPE
	MOVE	T4,(P)		;[527][411] GET THE REQUIRED FUNCTION
	CAME	T4,UNLFNC	;[527][411] TRYING TO UNLOAD?
	JRST	DOFCN		;[411] NO, DO THE OP
	MOVE	T1,[XWD 2,T2]	;[360] YES, AIM AT THE ARG BLOCK
	MOVEI	T2,.TFLBL	;[360] GET LABEL TYPE
	MOVEI	T3,F.MTAP	;[360] ON THIS OPEN CHANNEL
	TAPOP.	T1,		;[360] ASK THE MONITOR
	  JRST	DOFCN	  	;[411] CAN'T GET IT, ASSUME UNLOAD WORKS
	CAXN	T1,.TFLBP	;[345] BYPASSING LABELS ALTOGETHER?
	JRST	DOFCN		;[411] YES, DO THE UNLOAD
	MOVEI	T1,F.MTAP	;[411] NOW SEE IF DEVICE CONTROLLED BY MDA
	DEVTYP	T1,		;[411]
	  JRST	DOFCN		;[411] ASSUME NOT AND DO UNLOAD
	TLNN	T1,(TY.MDA)	;[411] DEVICE CONTROLLED BY MDA?
	JRST	DOFCN		;[411] NO, DO THE UNLOAD
	MOVE	T1,['BKPPUD']	;[411] YES, CAN'T DO UNLOAD
	HRLI	T2,"%"		;[411] ONLY A WARNING
	HRRI	T2,[ASCIZ/Please use .DISMOUNT monitor command instead of UNLOAD
/]				;[411]
	PUSHJ	P,.ERMSG##	;[411] TELL THE USER ABOUT FAILURE
	JRST	DOFCN1		;[527] TRY THE NEXT ARGUMENT
DOFCN:	XCT	(P)		;[411] PERFORM THE FUNCTION
	CAME	T4,UNLFNC	;[527] IF UNLOAD DON'T WAIT
	MTWAT.	F.MTAP,		;[526] WAIT FOR MAGTAPE ACTIVITY TO STOP
	STATZ	F.MTAP,IO.ERR	;[526] ANY ERRORS?
	JRST	E$$TPF		;[526] YES. REPORT AND STOP PROCESSING
DOFCN1:	RELEAS	F.MTAP,		;[527]RELEASE THE CHANNEL
	JUMPG	C,TAPFCL	;LOOP IF NOT DONE WITH COMMAND
	POP	P,(P)		;DISCARD FUNCTION
	JRST	.POPJ1##	;RETURN WITHOUT STORE


;Here if any IO.ERR bits lit during an EOT, UNLOAD, or REWIND operation
E$$TPF::!MOVE	T1,['BKPTPF']	;[526] PREFIX
	HRLI	T2,"?"		;[526] A FATAL ERROR
	HRRI	T2,[ASCIZ /Tape positioning error during /]
	PUSHJ	P,.ERMSG##	;[526]
	POP	P,T1		;[526] ADJUST STACK AND GET FUNCTION
	CAMN	T1,EOTFNC	;[526] AN EOT FUNCTION?
	OUTSTR	[ASCIZ /EOT /]	;[526] YES. TYPE IT
	CAMN	T1,REWFNC	;[526] A REWIND FUNCTION?
	OUTSTR	[ASCIZ /REWIND /];[526] YES. TYPE IT
	CAMN	T1,UNLFNC	;[526] AN UNLOAD FUNCTION?
	OUTSTR	[ASCIZ /UNLOAD /];[526] YES. TYPE IT
	OUTSTR	[ASCIZ /operation.
/]				;[526]
	RELEAS	F.MTAP,		;[526] RELEASE THE DEVICE
	JRST	.POPJ1##	;[526] AND RETURN
;+.HL1 SKIP (SAVE SETS FORWARD OR BACKWARD)
;
;^THIS VERB TAKES A SIGNED DECIMAL NUMBER (THE NUMBER OF
;SAVE SETS TO SKIP) AND IS FOLLOWED BY ZERO, ONE, OR A LIST
;OF TAPES TO POSITION. ^IF ZERO, THE TAPE SPECIFIED BY THE
;LAST <TAPE VERB IS POSITIONED. ^IF A LIST IS GIVEN, AND
;TWO CONSECUTIVE COMMAS ARE INCLUDED, THEN THE TAPE SPECIFIED
;BY THE LAST <TAPE VERB WILL ALSO BE POSITIONED. ^NOTE
;THAT IF SOME TAPE IS SPECIFIED MORE THAN ONCE, IT
;WILL BE POSITIONED MORE THAN ONCE.
;-

$SKIP:	PUSHJ	P,.DECNW##	;GET SIGNED DECIMAL NUMBER
	MOVEM	N,NSVSET	;[265] STASH # IN SAFE PLACE

;LOOP OVER THE LIST OF TAPES TO POSITION

SKPLOP:	PUSHJ	P,TAPARG	;GET NEXT TAPE ARGUMENT
	PUSHJ	P,TAPOPN	;OPEN THAT TAPE
	MOVE	N,NSVSET	;[265] GET BACK # TO SKIP
	MTWAT.	F.MTAP,		;INSURE TAPE IS NOT MOVING FIRST

	MOVM	T1,N		;GET DISTANCE TO MOVE
	SKIPG	N		;IF POSITIVE, OK
	AOS	T1		;IF 0 OR NEG, ONE MORE
	MOVE	T2,[MTBSF. F.MTAP,] ;GET FUNCTION
	SKIPLE	N		;IF 0 OR NEG, OK
	MOVE	T2,[MTSKF. F.MTAP,] ;IF POS, FORWARD
SKPLO3:	MOVE	T3,TAPLBL	;[514] GET THE LABEL TYPE
	CAIN	T3,.TFLNV	;[514] DO WE NEED TO HANDLE OUR OWN EOT?
	SKIPG	N		;[514] YES. IS THE SKIP IN THE FORWARD DIRECTION?
	JRST	SKPLO1		;[514] NO NEED TO DO SPECIAL EOT CHECKING
	MTSKR.	F.MTAP,		;[514] SKIP A RECORD (MONITOR READ OPERATION)
	MTWAT.	F.MTAP,		;[514] WAIT FOR THE OPERATION TO COMPLETE
	STATZ	F.MTAP,IO.EOF	;[514] DID WE READ A TAPE MARK?
	JRST	E$$AMP		;[514] YES. TELL THE USER
	MTBSR.	F.MTAP,		;[514] NO. UNDO THE MTSKR. AND EXECUTE THE SKIP
SKPLO1:	XCT	T2		;DO THE FUNCTION ONCE
	MTWAT.	F.MTAP,		;[514] WAIT IN CASE OF AN ERROR FOR THIS SKIP
	STATZ	F.MTAP,IO.ERR	;[514] ANY ERROR?
	JRST	E$$SKF		;[514] YES. REPORT A SKIP FAILED -- FATAL
	SOJG	T1,SKPLO3	;[514] DO IT THE RIGHT NUMBER
	SKIPG	N		;IF 0 OR NEG,
	JRST	[MTWAT. F.MTAP,	; WAIT TO COMPLETE
		 STATO  F.MTAP,IO.BOT ;SEE IF AT BEGINNING OF TAPE
		 MTSKF. F.MTAP,	;NO--SKIP THE EOF
		 JRST   .+1]	;AND CONTINUE
SKPLO2:	RELEAS	F.MTAP,		;[514] FREE THE CHANNEL
	JUMPG	C,SKPLOP	;LOOP TO END OF COMMAND
	JRST	.POPJ1##	;RETURN WITHOUT STORE
 ;HERE IF ANY IO.ERR BITS HAVE BEEN LIT ON A SINGLE SKIP
 E$$SKF::MOVEI	T1,'SKF'	;[514] PREFIX
	MOVEI	T2,[ASCIZ \SKIP failed, tape position error\]
	RELEAS	F.MTAP,		;[514] RELEASE THE CHANNEL FIRST
	JRST	SCNERR		;[514]

;HERE IF ANOTHER READ OPERATION ON THE TAPE WILL MOVE THE TAPE OFF THE REEL
E$$AMP::MTBSF.	F.MTAP,		;[514] BACKSPACE OVER THE LAST TAPE MARK
	MOVE	T1,['BKPAMP']	;[514] 
	MOVE	T2,["%",,[ASCIZ \Attempt to move past logical EOT
\]]	;[514]
	PUSHJ	P,.ERMSG##	;[514]
	JRST	SKPLO2		;[514] CONTINUE WITH ARG LIST

	SUBTTL	MAIN-LINE OPERATIONS

;+
;.CHAPTER MAIN-LINE OPERATIONS
;-

;+.HL1 [N]PRINT
;
;<PRINT AND <NPRINT ARE THE SAME AS RESTORE WITHOUT
;WRITING AND INCLUDING A LISTING. ^THE ONLY ARGUMENT IS
;THE NAME OF THE LISTING FILE. ^WE ASSUME THAT THE
;USER WANTS ALL FILES ON THE TAPE LISTED. ^IF HE DOESN'T,
;THEN HE SHOULD SPECIFY <LIST, <NOWRITE, <RESTORE.
;<NPRINT IS THE SAME AS <PRINT EXCEPT THAT THE LISTING IS GIVEN
;IN 72-COL. WIDE FORMAT TO FIT ON A TERMINAL.
;-

$PRINT:	TDZA	T1,T1		;INDICATE WIDE LISTING
$NPRIN:	MOVEI	T1,1		;INDICATE NARROW LISTING
	MOVEM	T1,S.NARL	;SET FLAG FOR LISTER
	SETOM	S.PRNT		;PRINT IN PROGRESS		[172]
	JUMPLE	C,PRINT1	;IF NO ARG, DON'T CHANGE LIST FILE
	PUSHJ	P,.FILIN##	;GET LISTING FILE
	PUSHJ	P,LISTSW	;SETUP LISTING FILE
	RELEAS	F.LIST,		;CLEAR LISTING CHANNEL
				;(IT WILL BE SETUP LATER)
PRINT1:	MOVEI	T1,1		;GET DEFAULT
	SKIPN	S.LIST		;SEE IF LISTING SET
	MOVEM	T1,S.LIST	;NO--ASK FOR DEFAULT
	PJUMPG	C,E.INCL##	;SHOULD BE ONE SPEC ONLY
	PUSHJ	P,$REWIN	;FIRST REWIND THE TAPE
	  JFCL			;IGNORE ERROR (IMPOSSIBLE)
	PUSH	P,S.WRIT	;SAVE VALUE OF WRITE FLAG
	SETZM	S.WRIT		;SET NOWRITE
	PUSH	P,S.SSNM	;SAVE NAME OF SAVE SET
	MOVE	T1,[ASCII/ALL/]	;USE ALL SO DIRECTORY OF
	MOVEM	T1,S.SSNM	; ENTIRE TAPE WILL BE LISTED
	PUSHJ	P,$RESTO	;DO A RESTORE
	  JFCL			;IGNORE ERROR (IMPOSSIBLE)
	POP	P,S.SSNM	;RESTORE NAME OF SAVE SET
	POP	P,S.WRIT	;RESTORE WRITE FLAG
	SETZM	S.LIST		;CLEAR LISTING SPEC
	SETZM	S.PRNT		;TURN OFF PRINT FLAG		[172]
	JRST	.POPJ1##	;GIVE SUCCESS RETURN
;+.HL1 CHECK (VERIFY)
;
;<CHECK IS THE SAME AS RESTORE EXCEPT THAT BOTH DISK AND
;TAPE ARE READ AND THE RESULTS COMPARED.  ^IT TAKES A LIST
;OF FILE SPECIFICATIONS TO CHECK ON.
;-

$CHECK:	MOVEI	T1,OPRCHK	;INDICATE CHECK OPERATION
	JRST	OPERAT		;GO DO OPERATION

;+.HL1 RESTORE
;
;<RESTORE PLAYS BACK A TAPE (OR REQUESTED SUBSET) AND RESTORES
;IT TO THE DISK. ^IT TAKES A LIST OF FILE SPECIFICATIONS
;TO BE RESTORED FROM THE TAPE.
;-

$RESTO:	MOVEI	T1,OPRRST	;INDICATE RESTORE OPERATION
	JRST	OPERAT		;GO DO OPERATION

;+.HL1 SAVE
;
;<SAVE SAVES PART OR ALL OF THE DISK ONTO THE TAPE.
;^IT TAKES A LIST OF FILE SPECIFICATIONS TO BE SAVED.
;-

$SAVE:	HRROI	T1,OPRSAV	;INDICATE SAVE (WRITE) OPERATION
	MOVE	T2,S.SSNM	;GET  SAVE SET NAME
	CAME	T2,[ASCII/ALL/]	;SEE IF "ALL"
	JRST	OPERAT		;NO--OK TO DO OPERATION
E$$CSA::MOVEI	T1,'CSA'	;YES--ERROR
	MOVEI	T2,[ASCIZ \Can't save with save set name "ALL"\]
	PJRST	SCNERR		;GO GIVE FATAL ERROR
;+
;<OPERAT IS THE ROUTINE WHICH SCANS THE ARGUMENTS TO
;THE OPERATIONAL VERBS AND THEN CALLS OFF TO THE PROCESSING
;MODULE TO ACTUALLY DO THE WORK.
;^A LIST OF FILE SPECIFICATIONS IS STORED STARTING AT
;THE CURRENT VALUE OF <.JBFF (WHICH IS UPDATED).
;^THE SPECIFICATIONS ARE <.FXLEN LONG AND START AT THE
;ADDRESS IN <S.FRST AND THE LAST ONE ENDS JUST BEFORE THE
;ADDRESS IN <S.LAST.
;^THE SPECIFICATIONS ARE IN PAIRS WITH THE
;SECOND OF A PAIR BEING USED TO MATCH THE INPUT
;SIDE OF THE OPERATION AND THE FIRST OF THE PAIR TO CONTROL
;THE OUTPUT SIDE.  ^EVEN IF THE USER DOESN'T SPECIFY
;THE OUTPUT SIDE, ONE WILL BE CREATED WHICH IS THE SAME AS THE
;INPUT SIDE.
;-

OPERAT:	MOVEM	T1,S.OPER	;SET THE OPERATION
	MOVE	T1,.JBFF##	;GET THE START OF FREE CORE
	MOVEM	T1,S.FRST	;INDICATE THE START
	MOVEM	T1,S.LAST	; AND THE END
	SETZM	S.STOP		;OVER RIDE STOP COMMAND
IFN FT$STK,<			;[341]
	PUSHJ	P,SETDEF	;[341] SET PERM. AND GLOBAL SWITCH DEFAULTS
>				;[341]

;LOOP OVER THE INPUT FILE SPECIFICATIONS

OPERLP:	JUMPLE	C,OPERDO	;END OF LIST, GO DO THE WORK
	PUSHJ	P,.CLSNS##	;CLEAR STICKY DEFAULTS
IFN FT$STK,<			;[341]
	PUSHJ	P,CLEARF	;[341] CLEAR FILE AREA THAT .CLRFL WON'T
>				;[341]
	PUSHJ	P,.FILIN##	;GET FILE
	MOVEI	T1,OSPEC	;POINT TO TEMP OUTPUT SPEC
	MOVEI	T2,FX$LEN	;GET SCAN BLOCK LENGTH
	PUSHJ	P,GETSPC	;COPY THE OUTPUT SPEC
	CAIE	C,"="		;SEE IF WAS INPUT OR OUTPUT
	JRST	OPRLP1		;INPUT--GO COPY SPEC
	PUSHJ	P,.CLSNS##	;OUTPUT--CLEAR STICKY DEFAULTS
IFN FT$STK,<			;[341]
	PUSHJ	P,CLEARF	;[341] CLEAR FILE AREA THAT .CLRFL WON'T
>				;[341]
	PUSHJ	P,.FILIN##	; AND GET INPUT SPEC
OPRLP1:	MOVEI	T1,ISPEC	;POINT TO TEMP INPUT SPEC
	MOVEI	T2,FX$LEN	;GET SCAN BLOCK LENGTH
	PUSHJ	P,GETSPC	;COPY THE INPUT SPEC
	PUSHJ	P,LNMSPC	;PERFORM LOGICAL NAME TRANSLATIONS
	CAIN	C,","		;SEE IF CORRECT SEPARATOR
	JRST	OPERLP		;YES--LOOP FOR MORE
	JUMPG	C,E.INCL##	;IF NOT DONE, USER ERROR
;HERE WHEN THE LIST HAS BEEN STORED AWAY.

OPERDO:
IFN FT$STK, <			;[341]
	PUSHJ	P,CLERST##	;[341] CLEAR GLOBAL SWITCH AREA.
>				;[341]
	PUSHJ	P,APPDEF	;GO APPLY DEFAULTS
	PUSHJ	P,ENCGET	;GET ENCRYTION KEY IF NEEDED
	PUSHJ	P,TAPEDO	;OPEN TAPE
	PUSHJ	P,INTERC	;APPLY INTERCHANGE DEFAULTS IF NEEDED
	PUSHJ	P,.VERBO##	;GET /MESSAGE ARGS FROM SCAN
	MOVEM	T1,S.VRBO	;SAVE FOR BACKRS

;REPORT OPERATION (CMD)
OPERPT:	SKIPE	LNMFLG		;ANY LOGICAL NAME TRANSLATIONS?
	SKIPGE	S.PRNT		;NO--A PRINT COMMAND?
	JRST	OPERP2		;DON'T REPORT THIS STUFF
	PUSH	P,S.FRST	;START WITH FIRST SCAN BLOCK
	PUSHJ	P,.TCRLF##	;START WITH A BLANK LINE
	MOVEI	T1,[ASCIZ / Logical name translations:/]
	PUSHJ	P,.TSTRG##	;PRINT TEXT
	PUSHJ	P,.TCRLF##	;AND A CRLF
	MOVE	T1,S.OPER	;GET CURRENT OPERATION
	SKIPA	T1,[[ASCIZ / CHECK   /]
		    [ASCIZ / RESTORE /]
		    [ASCIZ / SAVE    /]]-1(T1)

OPERP1:	MOVEI	T1,[ASCIZ /         /] ;SPACE OVER
	PUSHJ	P,.TSTRG##	;PRINT SOMETHING
	MOVE	T1,(P)		;GET OUTPUT SPEC
	PUSHJ	P,.TFBLK##	;PRINT IT
	MOVEI	T1,[ASCIZ / = /] ;SEPARATOR
	PUSHJ	P,.TSTRG##	;PRINT IT
	MOVEI	T1,FX$LEN	;LENGTH OF BLOCK
	ADDB	T1,(P)		;ADVANCE TO NEXT
	PUSHJ	P,.TFBLK##	;PRINT INPUT SPEC
	MOVEI	T3,FX$LEN	;LENGTH OF BLOCK
	ADDB	T3,(P)		;ADVANCE TO NEXT
	MOVEI	T1,[ASCIZ /, -/] ;GET SEPARATOR
	CAMGE	T3,S.LAST	;LAST SPEC?
	PUSHJ	P,.TSTRG##	;PRINT IT
	PUSHJ	P,.TCRLF##	;END LINE
	CAMGE	T3,S.LAST	;ALL DONE?
	JRST	OPERP1		;LOOP BACK FOR MORE
	PUSHJ	P,.TCRLF##	;SPIT OUT AN EXTRA CRLF
	POP	P,(P)		;PHASE STACK

OPERP2:	JRST	OPDOLW		;GO TO LOW SEGMENT
	RELOC			;RELOCATE TO LOW SEGMENT

OPDOLW:	MOVEI	T1,SAVEAC	;POINT TO AC SAVE AREA
	BLT	T1,ESAVAC	;SAVE THEM ALL AWAY
	MOVSI	T1,1		;RELEASE THE
	SKIPN	SAVDSK		;[314] (UNLESS ITS NOT FROM DISK)
	CORE	T1,		;HIGH SEGMENT
	  JFCL			;NICE TRY

	PUSHJ	P,OPRCDN	;SHOW RUNNING AND TEST STOP
	  JRST	OPDONE		;KILL!
	PUSHJ	P,BACKRS##	;CALL SAVE/RESTORE
	  JRST	OPDONE		;KILL!
	SKIPE	S.LIST		;SEE IF LISTING NEEDED
	OUTPUT	F.LIST,		; YES, FINISH UP BEFORE DISPLAYING MESSAGE
	OUTSTR	DONMSG		;TELL THE OPERATOR WE'RE FINISHED

;	HERE AT END OR IF OPERATOR SAYS "KILL"

OPDONE:	CLOSE	F.LIST,		;CLOSE LISTING FILE
	RELEAS	F.LIST,		;RELEASE CHANNEL
	SKIPGE	S.OPER		;[250] SKIP IF NOT /SAVE
	 JRST	OPDON1		;[250] IF /SAVE, SKIP THIS CODE
	WAIT	F.MTAP,		;[250] WAIT FOR TAPE TO STOP
	SETZ	T1,		;[250] CLEAR BUFFER COUNTER
	HRRZ	T2,S.MBPT	;[250] GET CURRENT BUFFER ADDRESS
	HRRZ	T3,0(T2)	;[250] GET NEXT BUFFER ADDRESS
OPDON2:	CAMN	T3,T2		;[250] BACK TO CURRENT BUFFER YET?
	 JRST	OPDON3		;[250] YES, GET OUT OF LOOP
	SKIPG	0(T3)		;[250] IS THE USE BIT SET IN THIS ONE?
	 AOS	T1		;[250] YES, ADD TO COUNT
	HRRZ	T3,0(T3)	;[250] GO TO NEXT BUFFER IN RING
	JRST	OPDON2		;[250] LOOP THROUGH THE RING
OPDON3:	SKIPG	T1		;[250] ANY BUFFERS AHEAD NOW?
	 JRST	OPDON1		;[250] NO, SO SKIP THIS
	MOVE	T2,OPDON5	;[250] OTHERWISE, SET UP TAPOP.
	MOVEI	T4,F.MTAP	;[250] CHANNEL NUMBER
	MOVEI	T3,.TFBSB	;[250] CODE TO BACKSPACE ONE BLOCK
OPDON4:	TAPOP.	T2,		;[250] DO BACKSPACE
	 MTBSR.	F.MTAP,		;[250] BAD, TRY AN MTAPE TO DO IT
	SOJGE	T1,OPDON4	;[250] LOOP N+1 TIMES
OPDON1:				;[250]
	RELEAS	F.MTAP,		;RELEASE CHANNEL

	MOVX	T1,PS.VIP	; GET INTERUPT IN PROGRESS FLAG	[201]
	ANDCAM	T1,PSITTY##+.PSVFL ;TURN OFF TTY		[201]
	ANDCAM	T1,PSIMTA##+.PSVFL ;TURN OFF MTA
	MOVX	T1,PS.FOF	;TURN PSI OFF
	PISYS.	T1,		;EXEC
	  JFCL			;IGNORE ERROR
SEGFLL:	SKIPE	SAVDSK		;[351][314] FIND OUT IF WE NEED TO DO GETSEG
	JRST	SEGFL1		;[351][314] NEVER THREW HI SEG AWAY
	MOVEI	T1,SAVGET	;POINT TO SAVE-GET AREA
	GETSEG	T1,		;GET BACK HIGH SEGMENT
	  JRST	SEGFAL		;DIE IF CAN NOT DO
SEGFL1:	MOVSI	17,SAVEAC	;[314] POINT TO AC SAVE AREA
	BLT	17,16		;RESTORE ALL BUT 17
	MOVE	17,SAVEAC+17	;RESTORE AC 17
	JRST	OPDOHG		;GO BACK TO HIGH SEGMENT

SEGFAL:	OUTSTR	SEGMSG		;ISSUE FATAL MESSAGE
	MONRT.			;EXIT TO MONITOR
	JRST	SEGFLL		;A .CONTINUE WILL TRY AGAIN

OPDON5:	2,,T3			;[250] FOR TAPOP.
DONMSG:	ASCIZ /
"Done
/								;[205]
	RELOC			;SWITCH BACK TO HIGH SEGMENT

OPDOHG:	PORTAL	.+1		;[360] REENTRY POINT TO HIGH-SEG
	PUSHJ	P,.TCRLF##	;[360] CLEAR TO A NEW LINE ON TERMINAL
	PUSHJ	P,CHKSOM	;GO CHECK THAT SOME FILES WERE FOUND
	SETZM	S.STOP		;CLEAR STOP FLAG
	PUSHJ	P,RESCOR	;RESET CORE
	SKIPN	T1,S.EXIT	;SEE IF RESET OR EXIT
	JRST	.POPJ1##	;NO--GIVE GOOD RETURN TO VSCAN
	JUMPL	T1,BACKUP	;IF RESET, GO RESTART PROGRAM
	PUSHJ	P,.MONRT##	;IF EXIT, GO TO MONITOR
	SETZM	S.EXIT		;CLEAR EXIT MODE
	JRST	.POPJ1##	;IF CONTINUE, RETURN TO VSCAN
	SUBTTL	INTERFACE TO BACKRS

;+
;.CHAPTER INTERFACE TO BACKRS
;-

;+.HL1 S_.XXXX AREA FORMAT
;
;.NOAUTOP.AUTOTABLE.LM10.TS10.P-8,0
;
;<S.CKPT	1=USE CHECKPOINTS
;<S.CRYP	7-WORD BLOCK CONTAINING ENCRYTPTION KEY IN
;	<ASCIZ. ^NO ENCRYPTION IF FIRST WORD =0.
;<S.DELT	1 = DELETE FILES AFTER SAVING THEM
;<S.DT75	IF NON-ZERO, GUARD AGAINST BAD <DATE-75 DATES.
;<S.FFA		-1 IF USER <PPN = [1,2]
;<S.INIT	STANDARD <SCAN FILE SPECIFICATION OF FILE TO START
;	WITH.
;<S.INTR	NON-ZERO TO USE INTERCHANGE MODE
;<S.LIST	NON-ZERO IF LISTING DESIRED. CHANNEL WILL ALREADY BE
;	<OPEN. ^SEE ALSO <S.LBPT.
;<S.LBPT	BUFFER POINTERS FOR LISTING CHANNEL
;<S.MBPT	BUFFER POINTERS FOR MAG TAPE CHANNEL
;<S.MOPN	PHYSICAL NAME OF MAG TAPE DEVICE
;<S.MULT	NON-ZERO TO MAKE <EOT AN ERROR DURING SAVE
;<S.NARL	NON-ZERO TO USE NARROW LISTING FORMAT (72-COL)
;<S.NGST	<AOBJN WORD TO <S.STRS STRUCTURE TABLE FOR ACTUAL
;. ;	NUMBER OF STRUCTURES
;<S.OPER	WHICH OPERATION:  (LH=-1 IF WRITE TAPE)
;. ;	1=</CHECK (RESTORE EXCEPT COMPARE WITH DISK)
;. ;	2=</RESTORE
;. ;	3=</SAVE
;<S.REPT	1=REPEAT FILE WHICH IS SPILT ACROSS TAPES
;<S.RSUM	INITIAL BLOCK TO RESUME WITH
;<S.SRTD	SORT DIRECTORIES: 0=NO, 1=ALPHA, 2=LOCATION
;<S.SRTF	SORT FILES: 0=NO, 1=ALPHA, 2=LOCATION
;<S.SSNM	6 WORD <ASCII  SAVE SET NAME
;<S.STOP	1=STOP, 0=GO
;<S.STRS	36-WORD BLOCK CONTAINING SYSTEM STRUCTURE NAMES
;<S.SUPR	</SUPERSEDE: 1=ALWAYS, 2=OLDER, 3=NEVER
;<S.TYMS	TYPE (IN ADDITION TO LIST) 0=NONE, 1=DIRECTORIES, 2=FILES
;<S.UPRT	IF NON-ZERO, PROTECTION TO APPLY TO ALL CREATED DIRECTORIES
;<S.USET	NON-ZERO TO USE SUPER-<USETI MODE
;<S.USG		NON-ZERO TO ENABLE DISK SPACE ACCOUNTING
;<S.VRBO	/<MESSAGE ARGS
;. ;	1==^PREFIX (<JWW.PR)
;. ;	2==^FIRST LINE ONLY (<JWW.FL)
;. ;	4==^CONTINUATION LINES (<JWW.CN)
;<S.WRIT	NON-ZERO TO WRITE OUTPUT
;<S.XMPT	0=EXEMPT NO PPNS, 1 = EXEMPT DEFAULT PPNS
;
;.NOAUTOT.AUTOPARAGRAPH.P0,-1.LM0.TS8,,,,,
;
;-
;+.HL1 LIST OF FILE SPECS TO OPERATE ON
;
;^THE ARGUMENTS TO THE OPERATION COMMAND (E.G., <SAVE) ARE
;PRESENTED AS A STRING OF FIXED SIZE BLOCKS LOCATED
;CONTIGUOUSLY IN CORE. ^THE ADDRESS OF THE START OF THE
;STRING IS CONTAINED IN <S.FRST AND THE FIRST ADDRESS BEYOND
;THE STRING IS CONTAINED IN <S.LAST. ^WHEN <BACKRS IS CALLED,
;IT CAN BE ASSURED THAT THERE IS A LEAST ONE SUCH BLOCK DEFINED.
;^THERE IS NO SPECIFIC UPPER LIMIT TO THE LENGTH OF THE STRING;
;ITS SIZE IS CONSTRAINED ONLY BY THE NUMBER OF SPECIFICATIONS
;WHICH CAN BE FIT INTO CORE, ALLOWING FOR CORE EXPANSION.
;
;^EACH BLOCK IN THE STRING CONSISTS OF TWO <SCAN STYLE FILE
;SPECIFICATIONS. ^THE FIRST SPEC IS THE OUTPUT SIDE AND THE
;SECOND IS THE INPUT SIDE. ^IF THE USER JUST GAVE ONE, THEN IT
;IS DUPLICATED TO INDICATE NO CHANGES ARE NEEDED IN THE FILE
;NAMES. ^EACH FILE SPEC IS <FX$LEN LONG, SO EACH ENTRY
;IN THE STRING IS 2*<FX$LEN LONG. ^THE SYMBOL <FX$LEN IS FOUR
;LARGER THAN <.FXLEN TO MAKE ROOM FOR THE WORDS <FX$MBF AND
;<FX$MSN WHICH CONTAIN THE SETTINGS FOR </MBEFORE AND
;</MSINCE RESPECTIVELY. ^THESE ARE CONSTRAINTS ON THE
;MODIFICATION DATE RATHER THAN THE CREATION DATE. ^THE THIRD
;EXTRA WORD IS  <FX$CNT WHICH COUNTS MATCHING FILES. ^THE FOURTH IS
;<FX$STR WHICH IS USED TO FLAG STRUCTURES IN THE SEARCH LIST INDICATED
;BY THE INPUT DEVICE SPEC. ^THE BITS ARE SET TO CORRESPOND TO THE STRUCTURE'S
;POSITION IN THE <S.STRS TABLE: 1^B0 IS THE FIRST ENTRY IN <S.STRS, ETC.
;
;^EACH FILE SPEC CONSISTS OF A NUMBER OF WORDS, WHICH WILL BE
;PRESENTED WITH ALL DEFAULTS APPLIED. ^IN THE NAME AREA,
;EACH ENTRY HAS A MATCHING ENTRY KNOWN AS THE MASK. ^THE MASK
;CONTAINS A 0 IN EACH BIT FOR WHICH THE USER DOESN'T CARE THE
;VALUE.  ^ON OUTPUT, A 0-BIT IN THE MASK INDICATES WHERE A SUBSTITUTION
;IS TO BE MADE FROM THE CORRESPONDING WILD BIT OF THE INPUT. ^IT
;IS WISE TO COMPRESS OUT IMBEDDED NULL CHARACTERS AFTER THIS
;PROCESS. ^THE FULL ALGORITHM, INCLUDING HANDLING OF OUTPUT
;SWITCHES CAN BE LIFTED FROM <WILD, IN THE <.SCWLD
;ENTRY POINT.
;
;-.PAGE
;+.HL1 FILE SPECIFICATION BLOCK FORMAT
;
;^EACH FILE SPECIFICATION BLOCK HAS THE SAME FORMAT. ^THE SYMBOLS FOR
;THIS FORMAT ARE DEFINED IN THE PARAMETER FILE, ^^SCNMAC.MAC\\.
;^THE INTERPRETATION AND POSSIBLE VALUES OF EACH WORD AFTER ALL
;DEFAULTS HAVE BEEN APPLIED IS AS FOLLOWS:
;
;.NOAUTOP.AUTOTABLE.LM10.TS10.P-8,0
;.SK1
;<.FXDEV	DEVICE NAME IN SIXBIT; NO WILD-CARDS; NEVER 0
;<.FXNAM	FILE NAME (TYPICALLY SIXBIT); NEVER 0
;<.FXNMM	MASK FOR FILE NAME; 0=ALL (*); -1 = NOT WILD
;<.FXEXT	EXTENSION; LH=SIXBIT; RH=MASK
;<.FXMOD	COLLECTION OF FLAGS AS DEFINED BELOW
;<.FXMOM	ONES WHERE <.FXMOD FLAGS ARE TO BE BELIEVED (CONSTANT)
;<.FXDIR	START OF 6 BI-WORDS FOR DIRECTORY--FIRST PAIR IS
;	THE <.UFD, EACH FOLLOWING IS NEXT <.SFD DOWN. ^FIRST WORD OF PAIR
;	IS SIMILAR TO THE FILE NAME, SECOND WORD OF PAIR
;	IS THE CORRESPONDING MASK. ^THE FIRST WORD OF THE PAIR IS
;	0 ONLY IF THAT IS THE END OF LIST (EXCEPT FOR <.UFD).
;	^IF AN <.SFD MASK IS 0 (I.E., *), THEN IT MATCHES FILES AT
;	THIS DEPTH, SINCE <SFD=0 MATCHES THE *.
;	^IF THE FIRST WORD IS 0, THEN THE USER'S DEFAULT DIRECTORY
;	IS IMPLIED (I.E., 0 IN <.RBPPN).
;<.FXBFR	</BEFORE IN UNIVERSAL DATE-TIME FORMAT
;<.FXSNC	</SINCE IN UNIVERSAL DATE-TIME FORMAT
;<.FXABF	</ABEFORE IN UNIVERSAL DATE-TIME FORMAT
;<.FXASN	</ASINCE IN UNIVERSAL DATE-TIME FORMAT
;. ;	EACH IS <.LT. 0 IF TO BE IGNORED
;. ;	FORMAT IS LH=DAYS SINCE 17-^NOV-1858, RH=FRACTION OF DAY
;<.FXFLI	MINIMUM FILE SIZE IN WORDS (-1 IF DON'T CARE)
;<.FXFLM	MAXIMUM FILE SIZE IN WORDS (-1 IF DON'T CARE)
;<.FXEST	FILE ESTIMATE SIZE IN WORDS
;<.FXVER	USER SET VERSION NUMBER
;<FX$MBF=.FXLEN+0	</MBEFORE IN UNIVERSAL DATE-TIME FORMAT
;<FX$MSN=.FXLEN+1	</MSINCE IN UNIVERSAL DATE-TIME FORMAT
;. ;	(-1 IF DONT CARE FOR <FX$MBF AND  <FX$MSN)
;<FX$CNT=.FXLEN+2	USED TO COUNT MATCHES AGAINST SPEC
;<FX$STR=.FXLEN+3	USED TO FLAG STRUCTURES INDICATED BY USER'S INPUT DEVICE
;.SK1
;^THE RELEVANT CONTENTS OF THE <.FXMOD WORD ARE:
;.SK1
;<FX.PHY	</PHYSICAL, I.E., IGNORE LOGICAL NAMES
;<FX.NOM	</OKNONE, I.E., NO ERROR IF NO FILES MATCH
;<FX.STR	</STRS, I.E., LOOK FOR FILE ON EACH STRUCTURE
;	NORMALLY, IF NO WILD-CARDS, LOOK JUST ON DEV:, NOT ALL
;	STRUCTURES WHICH ARE PART OF DEV:
;<FX.PRT	</OKPROTECTION, I.E., NO ERROR IF PROTECTION FAILURE
;<FX.SUP	</ERSUPERSEDE, IE. NEVER SUPERSEDE DISK FILE
;<FX.DEN	</DENSITY
;<FX.PAR	</PARITY
;<FX.PRO	(OUTPUT) </PROTECTION OF FILE TO OUTPUT
;
;.NOAUTOT.AUTOPARAGRAPH.P5,-1.TS8,,,,.LM0
;-
	SUBTTL	RUN-TIME COMMAND HANDLER

;+
;.CHAPTER RUN-TIME COMMAND HANDLER
;-

	XLIST		;FLUSH LITERALS
	LIT
	LIST
	RELOC		;PUT IN LOW SEGMENT

;+
;<OPRCOM IS THE MAIN ENTRY POINT TO THE RUN-TIME COMMAND
;HANDLER. ^IT SHOULD BE CALLED TO SEE IF THERE IS A COMMAND
;WAITING. ^IF THERE IS, IT WILL HANDLE THE COMMAND. ^IF
;NOT, IT WILL RETURN IMMEDIATELY. ^IT SHOULD EITHER BE CALLED
;PERIODICALLY, OR ELSE INTERRUPTS SHOULD BE ENABLED AND IT
;CALLED WHEN THE INTERRUPT HAPPENS.
;^IT WILL TAKE THE NON-SKIP RETURN IF THE TASK IS TO BE
;ABORTED AND A RETURN TO THE MAIN-LINE COMMAND PROCESSOR MADE.
;^IT WILL TAKE THE SKIP RETURN IF NO SPECIAL HANDLING IS NEEDED.
;
;^IF THE OPERATOR (USER) TYPES <WHAT, THEN THE ROUTINE <TYEFL2
;WILL BE CALLED TO TELL THE OPERATOR WHAT IS HAPPENING. ^THIS
;ROUTINE SHOULD NOT SKIP RETURN.
;-

OPRCMD::INCHSL	T1		;SEE IF LINE TYPED
	  JRST	CPOPJ1		;NO--GIVE OK RETURN
	PUSHJ	P,OPRCLN	;CLEAN UP RESULT

;HERE TO PROCESS COMMAND WITH FIRST CHAR IN T1

OPRCM1:	PUSHJ	P,OPRGSX	;GET FIRST WORD
	  JRST	[PUSH	P,0	;[504] ERROR RETURNS EXPECT THIS
		JRST	E$$IRC]	;[504] ILLEGAL COMMAND
	PUSHJ	P,OPRSKL	;[504] SKIP TO THE END OF LINE (ALL COMMANDS
				;[504]  HAVE NO ARGS)
	HRROI	T4,.GTLIM	;[401] WANT BATCH STATUS TABLE
	GETTAB	T4,		;[373] SEE IF BATCH JOB
	SETZ	T4,		;[373] ASSUME NOT
	TXNE	T4,JB.LBT	;[504] IF BATCH JOB
	JUMPE	T2,[PUSH P,0	;[504] ERROR ROUTINES EXPECT THIS
		JRST	E$$IRC]	;[504] REPORT NO COMMAND AS AN ERROR

	JUMPE	T2,OPRCDN	;IF NO COMMAND, JUST END
	PUSH	P,[0]		;[412] PRESET NO MATCH
	MOVSI	T4,-LN$OPR	;GET LENGTH OF OPERATOR COMMAND TABLE
OPRCLP:	CAMN	T2,OPRTBL(T4)	;SEE IF EXACT MATCH
	JRST	OPRCLG		;YES--GOT A MATCH
	MOVE	T1,OPRTBL(T4)	;NO--GET NEXT COMMAND
	XOR	T1,T2		;COMPARE TO INPUT
	TDNE	T1,T3		;SEE IF MATCH
	JRST	OPRCL9		;NO--LOOP ONWARD
	MOVMS	(P)		;IF ALREADY PARTIAL, SET ERROR
	SKIPN	(P)		;IF NOTHING YET,
	MOVEM	T4,(P)		; SET THIS VALUE
OPRCL9:	AOBJN	T4,OPRCLP	;NO--LOOP THROUGH TABLE
;HERE WHEN DONE LOOKING AT ALL COMMANDS IN TABLE WITHOUT
;FINDING AN EXACT MATCH.

	SKIPLE	T4,(P)		;GET ANY PARTIAL MATCH
	JRST	E$$ABC		;AMBIGUOUS--ERROR
	JUMPE	T4,E$$IRC	;ERROR IF NOT FOUND
OPRCLG:	POP	P,(P)		;OK--DISCARD TEMP
	MOVE	T4,OPRDSP(T4)	;GET DISPATCH TABLE
	TLNN	T4,-1		;IF LH=0, THEN JUMP
	JRST	[PUSHJ P,(T4)	;GO TO ROUTINE
		   JRST CPOPJ	;IF ABORT, REPORT TO CALLER
		 JRST  OPRCDN]	;IF OK, END COMMAND
	MOVSS	T4		;IF LH.NE.0, STORE
	HLREM	T4,(T4)		; RH EXTENDED IN C(LH)
	JRST	OPRCDN		;THEN END COMMAND
;+
;<E$$ABC REPORTS AN AMBIGUOUS COMMAND.
;<E$$IRC REPORTS AN AN INVALID RUN-TIME COMMAND.
;-

E$$ABC::MOVEI	T1,[ASCIZ \?BKPABC Ambiguous command
\]
	JRST	OPRERR		;GIVE ERROR

E$$IRC::MOVEI	T1,[ASCIZ \?BKPIRC Invalid run time command 
\]					;[373]

;+
;<OPRERR ISSUES ERROR MESSAGE IN OPERATOR RUN-TIME COMMAND.
;-

OPRERR:	CLRBFI			;[504] CLEAR TYPE-AHEAD
	MOVEI	T2,"$"		;[504] IF BATCH JOB, PRECEDE BY $
	HRROI	T3,.GTLIM	;[504] WANT BATCH STATUS TABLE
	GETTAB	T3,		;[504] SEE IF BATCH JOB
	SETZ	T3,		;[504] ASSUME NOT
	TXNE	T3,JB.LBT	;[504] ARE WE A BATCH JOB?
	OUTCHR	T2		;[504] YES TELL OPERATOR
OPRER1:	OUTSTR	(T1)		;[504] OUTPUT MESSAGE
	POP	P,(P)		;[504] CLEAR STACK


;+
;<OPRCDN COMPLETES THE COMMAND PROCESSING. ^IT SHOWS THE
;OPERATOR THE STATUS PROMPT AND RETURNS TO THE CALLER UNLESS
;THE WORK IS "STOPPED". ^IF STOPPED, IT WILL GO INTO <TTY WAIT
;FOR THE NEXT COMMAND AND RECYCLE THROUGH THE COMMAND HANDLER.
;-

OPRCDN:	PUSHJ	P,SHOWGO	;SHOW PROMPT
	SKIPN	S.STOP		;SEE IF STOPPED
	JRST	OPRCMD		;[320] NO--CHECK FOR MORE COMMANDS
	PUSHJ	P,OPRGCH	;YES--WAIT FOR ANOTHER LINE
	JRST	OPRCM1		;AND GO HANDLE IT

;+
;<REENTR HANDLES THE MONITOR <REENTER COMMAND.
;-

REENTR:	SKIPE	.JBHRL##	;IF HIGH SEG THERE,
	OUTSTR	[ASCIZ \/\]	; GIVE SLASH PROMPT
	SKIPN	.JBHRL##	;IF RUNNING,
	PUSHJ	P,SHOWGO	; CALL SHOWGO FOR RIGHT PROMPT
	JRSTF	@.JBOPC##	;CONTINUE AT OLD PC

;+
;<CPOPJ1 GIVES A SKIP RETURN. <CPOPJ GIVES A NON-SKIP
;RETURN.
;-

CPOPJ1:	AOS	(P)		;GIVE SKIP RETURN
CPOPJ:	POPJ	P,		;GIVE NON-SKIP RETURN
;+
;<OPRCMD IS A MACRO WHICH DEFINES EACH VALID OPERATOR
;RUN-TIME COMMAND. ^EACH LINE OF THE MACRO HAS THREE
;ARGUMENTS. ^THE FIRST ARGUMENT IS THE NAME OF THE
;COMMAND. ^THE OTHER ARGUMENTS HAVE TWO
;POSSIBILITIES:
;. ;IF A ROUTINE IS TO BE CALLED, THE SECOND ARG IS THE
;NAME OF THE ROUTINE, AND THE THIRD IS BLANK.
;. ;IF A VALUE IS TO BE STORED, THE SECOND ARG IS THE
;VALUE AND THE THIRD IS THE LOCATION.
;-

	DEFINE	OPRCMD,<
X	DIRECTORIES,MSGDIR,S.TYMS
X	EXIT,1,S.EXIT
X	FILES,MSGFIL,S.TYMS
X	GO,0,S.STOP
X	HELP,OPRHLP,
X	KILL,CPOPJ,
X	NODIRECTORIES,MSGSIL,S.TYMS
X	NOFILES,MSGDIR,S.TYMS
X	PAUSE,0,S.EXIT
X	RESET,-1,S.EXIT
X	SILENCE,MSGSIL,S.TYMS
X	STOP,1,S.STOP
X	WHAT,OPRWHT,
>
;+
;<OPRTBL IS A LIST OF THE SIXBIT NAMES OF THE COMMANDS.
;-

	DEFINE	X(A,B,C),<
	EXP	<SIXBIT	\A\>
>

OPRTBL:	OPRCMD
LN$OPR==.-OPRTBL	;LENGTH
;+
;<OPRDSP IS A PARALLEL TABLE OF THE DISPATCH ADDRESSES.
;-

	DEFINE	X(A,B,C),<
	XWD	C,B
>

OPRDSP:	OPRCMD
;+
;^THE MACRO <IFWHAT ISSUES SECOND ARGUMENT TEXT IF THE FIRST ARGUMENT
;IS NON-ZERO.
;-

	DEFINE	IFWHAT($VAL,$TXT),<
	SKIPE	T1,$VAL		;;SEE IF SET
	OUTSTR	[ASCIZ \$TXT \]
	IORM	T1,(P)		;;INDICATE IF SET
>

;+
;<OPRWHT HANDLES THE RUN-TIME <WHAT COMMAND.
;-

OPRWHT:	PUSHJ	P,TYEFL2##	;[334] ASK BACKRS FOR STATUS

;HERE FOR ALL WHAT COMMANDS

$WHAT:	PUSH	P,[0]		;CLEAR FLAG OF SOMETHING
	IFWHAT	(S.NARL,Narrow)
	IFWHAT	(S.LIST,Listing )
	MOVE	T1,S.TYMS	;GET TYPING LEVEL
	OUTSTR	@[ [ASCIZ \Silence  \]
	 	 [ASCIZ \Type Directories  \]
		   [ASCIZ \Type Files  \] ](T1)
	AOS	T1
	IORM	T1,(P)
	IFWHAT	(S.DELT,Deleting )	;[255] INDICATE DELETE SETTING
	IFWHAT	(S.STOP,Stopped )
	MOVE	T1,S.WRIT
	SOS	T1
	IFWHAT	(T1,no Write )
	MOVE	T1,S.EXIT
	OUTSTR	@[ [ASCIZ \Will RESET\]
		   [ASCIZ \\]
		   [ASCIZ \Will EXIT\] ]+1(T1)
	IORM	T1,(P)
	POP	P,T1		;GET FLAG
	SKIPE	T1		;IF SET, END LINE
	OUTSTR	[ASCIZ \
\]
	PUSH	P,[0]		;CLEAR FLAG
	IFWHAT (S.INTR,Interchange mode )
	IFWHAT (S.SRTD,Sort directories)
	SKIPE	T1,S.SRTD	;GET SORT ORDER
	OUTSTR	@[ [ASCIZ \alphabetic  \]
		   [ASCIZ \location  \] ]-1(T1)
	IFWHAT (S.SRTF,Sort files)
	SKIPE	T1,S.SRTF	;GET FILE SORT ORDER
	OUTSTR	@[ [ASCIZ \alphabetic  \]
		   [ASCIZ \location  \] ]-1(T1)

	POP	P,T1		;GET FLAG BACK
	SKIPE	T1		;IF SET, END LINE
	OUTSTR	[ASCIZ \
\]
	PUSH	P,[0]		;RESET FLAG
	IFWHAT	(ENCRYP,Encrypted)
	IFWHAT	(S.CKPT,Checkpointing)
	MOVE	T1,S.MULT
	SOS	T1
	IFWHAT	(T1,no Multireel)
	MOVE	T1,S.BFCT	;GET BLOCKING FACTOR
	CAIE	T1,4		;DEFAULT?
	JRST	[IFWHAT (S.BFCT,Blocking factor)
		 MOVE	T1,S.BFCT
		 PUSHJ	P,DECOUT##
		 JRST	.+1]
	MOVE	T1,S.OPER	;[333] GET OPERATION
	CAIE	T1,OPRRST	;[333] RESTORE?
	JRST	[POP	P,T1	;[333] NO.
		 JRST	$WHAT1	;[333] DONE.
		]		;[333]
	POP	P,T1		;GET FLAG
	SKIPE	T1		;IF SET, END LINE
	OUTSTR	[ASCIZ \
\]
	OUTSTR	[ASCIZ \Supersede \]
	SKIPE	T1,S.SUPR	;SUPERSEDE SETTING
	OUTSTR	@[[ASCIZ \Always\]
		  [ASCIZ \Older\]
		  [ASCIZ \Never\]]-1(T1)
$WHAT1:	OUTSTR	[ASCIZ \
\]
	JRST	CPOPJ1		;GIVE OK RETURN
;+
;<OPRHLP HANDLES THE RUN-TIME <HELP COMMAND.
;-

OPRHLP:	OUTSTR	OPRHLM		;OUTPUT THE HELP TEXT
	JRST	CPOPJ1		;OK RETURN

OPRHLM:	ASCIZ	\
[NO]DIRECTORIES     start typing every directory processed
EXIT	            exit to monitor when all done
[NO]FILES           start typing every file and directory processed
GO		    continue from a STOP
HELP	            list these commands
KILL		    abort execution of the current action
PAUSE		    do not exit from BACKUP when done (default)
RESET               clear status settings when done
SILENCE	            stop typing directories and files processed
STOP	            stop temporarily
WHAT	            display current file name and status

\


	XLIST		;FLUSH LITERALS
	LIT
	LIST
	RELOC		;BACK TO HIGH SEGMENT
	SUBTTL	SUBROUTINES

;+
;.CHAPTER SUBROUTINES
;-

;+
;<APPDEF IS A ROUTINE DESIGNED TO APPLY DEFAULTS TO THE ACTION
;COMMANDS. ^THE DEFAULT FILE SPEC FOR THE OPERATOR IS ALWAYS
;<ALL:*.*[*,*,*,*,*,*,*] FOR BOTH INPUT AND OUTPUT SPECS.
;^FOR A NON-[1,2] USER THE DEFAULTS APPLIED FOR A <SAVE ARE
;<ALL:*.*[<PPN,*,*,*,*,*]=<DSK:*.*[<PPN,*,*,*,*,*]
;^THE DEFAULTS APPLIED FOR A USER DOING A <RESTORE ARE
;<DSK:*.*[<PPN,*,*,*,*,*] = <ALL:*.*[<PPN,*,*,*,*,*].
;
;<APPDEF ALSO VERIFIES THAT THE "DISK SIDE" DEVICE SUPPLIED FOR 
;A <SAVE IS IN FACT A DISK. ^IF IT IS NOT A DISK, AN ERROR MESSAGE
;IS GENERATED, AND THE ROUTINE DOES NOT RETURN.
;<APPDEF IS INVOKED BEFORE EACH ACTION COMMAND EXCEPT THE TAPE MOTION COMMANDS.
;-

APPDEF:	MOVE	T1,S.FRST	;SEE IF
	CAME	T1,S.LAST	; NO FILE SPECS
	JRST	APPDF1		;SOME--PROCEED BELOW
	SETZM	LNMFLG		;CLEAR LNM TRANSLATION FLAG
	PUSHJ	P,.CLRFL##	;CLEAR DEFAULT AREA IN <SCAN
	PUSHJ	P,ALLSPC	;GET SPACE FOR OUTPUT SPEC
	PUSHJ	P,GETSPC	;GET DEFAULT VALUES
	PUSHJ	P,ALLSPC	;GET SPACE FOR INPUT SPEC
	PUSHJ	P,GETSPC	;GET DEFAULT VALUES

;LOOP OVER FILE SPECS TO APPLY DEFAULTS

APPDF1:	PUSHJ	P,SETSTR	;SET UP STRUCTURE TABLE
	SKIPA	T1,S.FRST	;POINT TO FIRST FILE SPEC
APPDF2:	ADDI	T1,FX$LEN	;ADVANCE TO NEXT SPEC
	CAML	T1,S.LAST	;SEE IF DONE
	JRST	APPDF4		;YES--EXIT LOOP

;HERE TO APPLY DEFAULTS TO THE OUTPUT SPEC

	MOVSI	T2,'ALL'	;SET DEFAULT DEVICE
	SETO	T3,		;SET WILD UFD AS DEFAULT
	MOVE	T4,.MYPPN##	;GET USER'S LOGGED IN PPN
	CAME	T4,FFAPPN	;SEE IF OPERATOR,
	JRST	[MOVE	T3,PTHPPN  ;[336] NO--CHANGE DEFAULT TO PTHPPN
		 SKIPN	S.INTR	;[306] INTERCHANGE MODE?
		 JRST	APPDF5	;[306] NO - LET 'ALL' BE DEFAULT
				;     FOR /CHECK AND /RESTORE TOO
		 SKIPL	S.OPER	;/SAVE?
		 MOVSI	T2,'DSK';NO--CHANGE DEVICE DEFAULT TO DSK
		 JRST	.+1]	;CONTINUE
APPDF5:	PUSHJ	P,APPSPC	;[306] APPLY DEFAULTS TO OUTPUT SPEC
	PUSHJ	P,FIXPPN	;FIX UP PPN IF ERSATZ DEVICE
	  SKIPGE S.OPER		;HERE IF NON-DISK DEVICE, SEE IF /RESTORE
	JRST	APPDF3		;OK--CONTINUE
	TXNE	T3,DV.DSK	;DISK?
	TXNN	T3,DV.TTY	;AND TTY?
	CAIA			;ERROR
	JRST	APPDF3		;ELSE LET NUL THROUGH

E$$ROD:	MOVEI	T1,'ROD'	; PREFIX			[173]
	MOVEI	T2,[ASCIZ \Restore output device is not a disk\]
	SETZM	S.FRST		; CLEAR FILE SPEC POINTERS	[173]
	SETZM	S.LAST		; ...				[173]
	PJRST	SCNERR		; ISSUE AN ERROR MESSAGE	[173]
;HERE TO APPLY DEFAULTS TO THE INPUT SPEC

APPDF3:	ADDI	T1,FX$LEN	;POINT TO INPUT SPEC
	MOVSI	T2,'ALL'	;RESET DEFAULT DEVICE
	SETO	T3,		; AND DEFAULT PPN TO WILD CARD
	MOVE	T4,.MYPPN##	;GET USER'S LOGGED IN PPN
	CAME	T4,FFAPPN	;SEE IF OPERATOR
	JRST	[MOVE	T3,PTHPPN  ;[336] NO--SWITCH DEFAULT PPN TO PTHPPN
		 SKIPGE	S.OPER	;/SAVE?
		 MOVSI	T2,'DSK';YES--USE DSK AS DEFAULT DEVICE
		 JRST	.+1]	;PROCEED
	PUSHJ	P,APPSPC	;APPLY DEFAULTS TO INPUT SPEC
	PUSHJ	P,FIXPPN	;FIX UP PPN IF ERSATZ DEVICE
	  JRST	[SKIPL  S.OPER	;SEE IF /SAVE,			[171]
		 JRST  .+1	;OK IF NOT			[171]
		 JRST E$$DND]	;ERROR IF NON-DISK INPUT DEVICE	[171]
	PUSHJ	P,APPSTR	;APPLY STR FLAGS FOR INPUT DEVICE
	JRST	APPDF2		;LOOP FOR REST OF FILES

;HERE WHEN DONE WITH MAIN SET OF FILE SPEC DEFAULTING

APPDF4:	PUSHJ	P,LISTST	;HANDLE /LIST SWITCH
	SKIPE	S.LIST		;IF /LIST,
	OUTBUF	F.LIST,0	; SET DEFAULT BUFFERS

	MOVEI	T1,SUPNEVER	;GET /SUPERSEDE:NEVER
	SKIPN	S.SUPR		;SEE IF /NOSUPERSEDE
	MOVEM	T1,S.SUPR	;YES--CLEAN UP TO /SUPERSEDE:NEVER

	MOVEI	T1,MSGFIL	;SET TO TYPE FILES
	SKIPE	S.CKPT		;SEE IF CHECKPOINTING
	MOVEM	T1,S.TYMS	;FORCE TYPEOUT LEVEL TO FILES
	POPJ	P,		;THAT'S ALL, RETURN

;HERE WHEN NON-DISK DEVICE IS ILLEGAL

E$$DND::SETZM	S.FRST		;CLEAR FILE SPEC POINTERS
	SETZM	S.LAST		;...
	MOVEI	T1,'DND'	;INDICATE WHICH ERROR
	MOVEI	T2,[ASCIZ \Device not a disk\]
	PJRST	SCNERR		;ISSUE ERROR MESSAGE
;+
;<APPSPC APPLIES DEFAULTS TO A SINGLE FILE SPECIFICATION BLOCK.
;^CALL WITH ^T1 POINTING TO THE FILE SPEC BLOCK, ^T2 = DEFAULT DEVICE
;(<DSK OR <ALL) AND ^T3 = DEFAULT <UFD (-1 OR <PTHPPN) TO APPLY.
;^CLOBBERS ^T4.
;-

APPSPC:	SKIPL	.FXMOD(T1)	;SEE IF ALREADY DEFAULTED DEVICE,
	SKIPN	.FXDEV(T1)	; OR IF DEVICE MISSING
	MOVEM	T2,.FXDEV(T1)	;YES--USE DEFAULT
	MOVSI	T4,'*  '	;SET DEFAULT NAME
	SKIPN	.FXNAM(T1)	;SEE IF NAME GIVEN
	MOVEM	T4,.FXNAM(T1)	;NO--USE DEFAULT (MASK IS 0)
	SKIPN	.FXEXT(T1)	;SEE IF EXTENSION GIVEN
	MOVEM	T4,.FXEXT(T1)	;NO--USE DEFAULT

;HERE TO APPLY DIRECTORY DEFAULTS IF NEEDED

	MOVSI	T4,1-.FXLND	;SET TO LOOP SFDS
	HRRI	T4,.FXDIR+2(T1)	;POINT TO FIRST SFD
	MOVX	T2,FX.DIR	;GET DIRECTORY INDICATOR BIT
	TDNE	T2,.FXMOM(T1)	;IF [], THEN SKIP
	JRST	APPSP1		; DEFAULTING
	SKIPL	S.OPER		;[331] SAVING?
	SKIPN	S.INTR		;[331] OR NOT INTERCHANGE MODE?
	SKIPA			;[331] YES - HANDLE NORMALLY
	JRST	APPS1C		;[331] NO - HANDLE INTERC-RESTORE AS [-]
	MOVEM	T3,.FXDIR(T1)	;STORE DEFAULT UFD
	CAMN	T3,PTHPPN	;[336] SEE IF USER UFD
	SETOM	.FXDIM(T1)	; YES--CLEAR WILD CARDS FROM MASK
APPSF1:	MOVSI	T2,'*  '	;SET TO WILD-CARD
	SETZ	T3,		;[332] SET UP WILD-CARD MASK.
APPSFD:	MOVEM	T2,(T4)		;STORE * AS NAME
	MOVEM	T3,1(T4)	;[332] SET MASK
	AOS	T4		;INCREMENT POSITION
	AOBJN	T4,APPSFD	;LOOP OVER SFDS
	JRST	APPSP3		;APPLY DEFAULTS TO SWITCHS

APPSP1:
	TDNE	T2,.FXMOD(T1)	;[325] [-] SPECIFIED?
	  JRST	APPS1A		;[325] NO
APPS1C:	HRRZI	T2,<<.FXBFR-.FXDIR>/2>-2(T4) ;[325] SET UP PATH
	HRLI	T2,<<.FXBFR-.FXDIR>/2>+2     ;[325] ARG BLOCK
	SETOM	(T2)		;[325] READ DEFAULT PATH
	PATH.	T2,		;[325] DO IT
	  JRST	APPS1A		;[325] CAN'T PATH
	ADDI	T2,2		;[325] POINT TO PPN
	MOVE	T3,(T2)		;[325] GET PPN FROM PATH BLOCK
	MOVEM	T3,.FXDIR(T1)	;[325] SAVE IT
	SETOM	.FXDIM(T1)	;[325] FLAG NOT A WILD PPN
APPS1B:	AOS	T2		;[325] BUMP SFD POINTER
	SKIPN	T3,(T2)		;[325] AT END OF PATH?
	JRST	[ SETO	T3,	;[332] SET UP NON-WILD MASK
		  SETZ	T2,	;[332] SET FOR NO SFD'S BELOW CURRENT LEVEL
		  JRST	APPSFD	;[332] GO APPLY SFD'S
		]		;[332]
	MOVEM	T3,(T4)		;[325] NO - SAVE SFD NAME
	SETOM	1(T4)		;[325] FLAG NOT WILD SFD
	AOS	T4		;[325] INCREMENT POSITION
	AOBJN	T4,APPS1B	;[325] LOOP OVER SFDS
	JRST	APPSP3		;[325] DONE - DO SWITCH DEFAULTS
APPS1A:	MOVE	T2,.FXDIR(T1)	;[312][253] GET UFD
	TLNN	T2,-1		;IF PROJECT BLANK,
	HRROS	.FXDIM(T1)	; REMOVE WILD-CARD
	TRNN	T2,-1		;IF PROGRAMMER BLANK,
	HLLOS	.FXDIM(T1)	; REMOVE WILD-CARD
	TLNN	T2,-1		;IF PROJECT BLANK,
	HLL	T2,.MYPPN##	; GET LOGGED IN PROJECT
	TRNN	T2,-1		;IF PROGRAMMER BLANK,
	HRR	T2,.MYPPN##	; GET LOGGED IN PROGRAMMER
	MOVEM	T2,.FXDIR(T1)	;STORE RESULTANT UFD
APPSP2:	SKIPN	(T4)		;IF SFD BLANK,
	SETOM	1(T4)		; REMOVE WILD CARDS FROM MASK
	AOS	T4		;INCREMENT POSITION
	AOBJN	T4,APPSP2	;LOOP OVER SFDS

;HERE TO APPLY DEFAULTS TO SWITCHES

APPSP3:	MOVSI	T3,.FXBFR-FX$LEN ;LOOP OVER SWITCHES
	HRRI	T3,.FXBFR(T1)	;START OF SWITCHES
APPSP4:	SKIPN	(T3)		;[316] IF EQUAL TO 0,
	SETOM	(T3)		; SET TO -1 (IGNORE)
	AOBJN	T3,APPSP4	;LOOP OVER SWITCHES
	SETZM	FX$CNT(T1)	;CLEAR COUNT OF MATCHES
	POPJ	P,		;RETURN
;
;+
;<SETDEF ROUTINE SETS PERMANENT STICKY DEFAULTS IN ^G$XXX, OR
;APPLIES THEM IF THEY'RE ALREADY SET.
;-

IFN FT$STK, <			;[341]
SETDEF:	SKIPLE	T1,P.SNC##	;[341] HAS PERM. SINCE BEEN SET?
	MOVEM	T1,G$SNC	;[341] YES - MAKE PERMANENT
	MOVE	T1,G$SNC	;[341]  AND APPLY TO GLOBAL STICKY
	MOVEM	T1,P.SNC##	;[341]
	SKIPLE	T1,P.ASN##	;[341] HAS PERM. SINCE BEEN SET?
	MOVEM	T1,G$ASN	;[341] YES - MAKE PERMANENT
	MOVE	T1,G$ASN	;[341]  AND APPLY TO GLOBAL STICKY
	MOVEM	T1,P.ASN##	;[341]
	SKIPLE	T1,P$MSN	;[341] HAS PERM. SINCE BEEN SET?
	MOVEM	T1,G$MSN	;[341] YES - MAKE PERMANENT
	MOVE	T1,G$MSN	;[341]  AND APPLY TO GLOBAL STICKY
	MOVEM	T1,P$MSN	;[341]
	SKIPLE	T1,P.BFR##	;[341] HAS PERM. SINCE BEEN SET?
	MOVEM	T1,G$BFR	;[341] YES - MAKE PERMANENT
	MOVE	T1,G$BFR	;[341]  AND APPLY TO GLOBAL STICKY
	MOVEM	T1,P.BFR##	;[341]
	SKIPLE	T1,P.ABF##	;[341] HAS PERM. SINCE BEEN SET?
	MOVEM	T1,G$ABF	;[341] YES - MAKE PERMANENT
	MOVE	T1,G$ABF	;[341]  AND APPLY TO GLOBAL STICKY
	MOVEM	T1,P.ABF##	;[341]
	SKIPLE	T1,P$MBF	;[341] HAS PERM. SINCE BEEN SET?
	MOVEM	T1,G$MBF	;[341] YES - MAKE PERMANENT
	MOVE	T1,G$MBF	;[341]  AND APPLY TO GLOBAL STICKY
	MOVEM	T1,P$MBF	;[341]
	POPJ	P,		;[341] RETURN

;+
;^^CLEARF\\ CLEARS THE LOCAL SWITCH VALUES THAT .^^FILIN\\ WON'T.
;-

CLEARF:	SETOM	F$MSN		;[341] CLEAR LOCAL /MSINCE
	SETOM	F$MBF		;[341] CLEAR LOCAL /MBEFORE
	POPJ	P,		;[341] RETURN

;+
;^^CLEARP\\ CLEARS THE GLOBAL STICKY SWITCHES THAT ^^CLERST\\ WON'T.
;-
CLEARP:	SETOM	P$MSN		;[341] CLEAR GLOBAL STICKY /MSINCE
	SETOM	P$MBF		;[341] CLEAR GLOBAL STICKY /MBEFORE
	POPJ	P,		;[341] RETURN

;+
;^^MEMST2\\ FINISHES MEMORIZING THE GLOBAL STICKY SWITCHES THAT ^^SCAN\\
;DOESN'T KNOW ABOUT.  ^^MEMST2\\ IS A SUPPLEMENT TO ^^SCAN'S\\ ^^FILSTK\\.
;-

MEMST2:	SKIPLE	T1,F$MSN	;[341] MEMORIZE /MSINCE
	MOVEM	T1,P$MSN	;[341]
	SKIPLE	T1,F$MBF	;[341] MEMORIZE /MBEFORE
	MOVEM	T1,P$MBF	;[341]
	POPJ	P,		;[341] RETURN
>; END IFN FT$STK		;[341]


;+
;<SETSTR IS A SUBROUTINE TO SET UP THE SYSTEM STRUCTURE TABLE IN
;<S.STRS AND AN <AOBJN WORD TO THE TABLE FOR THE ACTUAL
;NUMBER OF STRUCTURES IN <S.NGST. ^CALLED BEFORE EACH ACTION VERB.
;-

SETSTR:	MOVSI	T1,-LN$STR	;MAX NUMBER OF FILE STRUCTURES
	SETZ	T2,		;ZERO STRUCTURE NAME
SETST1:	SYSSTR	T2,		;GET A STRUCTURE NAME
	  JRST	TBLSET		;LOSE--PUNT
	JUMPE	T2,TBLSET	;DONE
	MOVEM	T2,S.STRS(T1)	;STORE IN TABLE
	AOBJN	T1,SETST1	;CONTINUE

TBLSET:	MOVNI	T1,(T1)		;COMPUTE NEGATIVE STRUCTURE COUNT
	HRLZM	T1,S.NGST	;STORE FOR LATER USERS
	MOVSI	T1,'DSK'	;SET DSK AS DEFAULT
	SKIPN	S.STRS		;SEE IF SYSSTR UUO FAILED
	MOVEM	T1,S.STRS	;YES--USE GENERIC DSK
	POPJ	P,		;RETURN

;+
;<FIXPPN IS A ROUTINE TO INITIALIZE FOR <WILD, AND TO FIX UP
;THE <PPN IF THE DEVICE IS AN ERSATZ DEVICE.
;^A NON-SKIP RETURN IS TAKEN IF THE DEVICE IS NOT A DISK.
;-

FIXPPN:	MOVX	T2,FX.PHY	;/PHYSICAL
	TDNN	T2,.FXMOD(T1)	;SEE IF SET FOR FILE
	TDZA	T2,T2		;NO
	MOVEI	T2,UU.PHY	;YES, SET PHYSICAL
	MOVE	T3,.FXDEV(T1)	;GET DEVICE
	DEVCHR	T3,(T2)		;SEE WHAT WE'VE GOT
	TXNE	T3,DV.DSK	;DISK?
	TXNN	T3,DV.TTY	;AND TTY?
	CAIA			;NO
	POPJ	P,		;THEN IT'S REALLY NUL:

	MOVX	T2,FX.PHY	;/PHYSICAL
	TDNN	T2,.FXMOD(T1)	;SEE IF SET FOR FILE
	TDZA	T2,T2		;NO
	MOVSI	T2,(1B0)	;YES, SET PHYSICAL
	PUSH	P,T1		;SAVE SPEC POINTER
	MOVE	T1,.FXDEV(T1)	;GET DEVICE
	PUSHJ	P,.INIST##	;CALL WILD TO INITIALIZE
	  JRST	[POP P,T1	;HERE ON NON-DISK DEVICE, RESTORE T1
		 POPJ	P,]	;GIVE BAD RETURN
	POP	P,T1		;RESTORE SPEC POINTER
	SKIPN	T2,.FRCPP##	;WAS PPN FORCED BY WILD?
	JRST	HPOPJ1		;[360] NO--LEAVE ALONE AND SKIP RETURN
	MOVEM	T2,.FXDIR(T1)	;MUST BE ERSATZ--CHANGE
	SETOM	.FXDIM(T1)	;CLEAR WILD CARDS 
	MOVSI	T2,1-.FXLND	;SET TO LOOP SFDS
	HRRI	T2,.FXDIR+2(T1) ;POINT TO FIRST SFD
FIXPP1:	SETZM	(T2)		;CLEAR ANY SFD SPEC
	AOS	T2		;POINT TO SFD MASK
	SETOM	(T2)		;NO WILD CARDS
	AOBJN	T2,FIXPP1	;LOOP OVER ALL SFDS
	MOVSI	T3,'DSK'	;COULD BE SYSB:, SYSC: ETC.
	HRRZ	T2,.FXDEV(T1)	;GET RH OF DEVICE SPEC
	SKIPE	T2		;SEE IF NON-ZERO
	HLLM	T3,.FXDEV(T1)	;YES, FIX UP DEVICE SPEC
	JRST	HPOPJ1		;[360] GIVE GOOD RETURN
;+
;<APPSTR IS A ROUTINE TO DETERMINE THE FILE STRUCTURES INDICATED BY
;THE FILE SPEC DEVICE, AND SET THE CORRESPONDINNG BITS IN THE
;<FX$STR WORD FOR THIS SPEC. ^ASSUMES <.INIST HAS BEEN CALLED TO
;INITIALIZE FOR <WILD.  ^CALL WITH ^T1 POINTING TO THE FILE SPEC BLOCK.
;-

APPSTR:	SAVE$	T1		;SAVE SPEC POINTER
	SETZM	FX$STR(T1)	;CLEAR STR FLAG WORD
	MOVE	T1,.FXDEV(T1)	;LOAD DEVICE NAME
	DEVNAM	T1,		;GET PHYSICAL DEVICE NAME
	  JFCL			;USE LOGICAL
APSTR1:	MOVE	T2,S.NGST	;LOAD AOBJN WORD TO S.STRS
	CAME	T1,S.STRS(T2)	;FIND MATCH IN TABLE
	AOBJN	T2,.-1		; ...
	JUMPGE	T2,APSTR2	;NO MATCH!
	MOVSI	T1,(1B0)	;SET BIT ZERO
	MOVNI	T2,(T2)		;SET TO SHIFT RIGHT
	LSH	T1,(T2)		;SHIFT TO CORRECT STR BIT
	MOVE	T2,(P)		;COPY SPEC POINTER
	IORM	T1,FX$STR(T2)	;STORE STR BIT
APSTR2:	PUSHJ	P,.NXSTR##	;CALL WILD TO GET FILE STRUCTURE NAME
	JUMPN	T1,APSTR1	;LOOP FOR NEXT STR IN THE SEARCH LIST
	RSTR$	T1		;RESTORE FILE SPEC POINTER
	POPJ	P,		;RETURN

;+
;<INTERC IS A ROUTINE TO APPLY INTERCHANGE MODE DEFAULTS TO THE OUTPUT
;SPEC IF NEEDED. ^DEFAULTS APPLIED:  ON <SAVE -- ZERO FULL PATH OF FILE,
;ON <RESTORE -- DEFAULT PROTECTION TO <AD.PRO.
;-

INTERC:	SKIPN	S.INTR		;SEE IF /INTERCHANGE,
	POPJ	P,		;NO--RETURN

	SKIPA	T1,S.FRST	;ADDRESS OF FIRST SPEC
INTER1:	ADDI	T1,FX$LEN*2	;POINT TO NEXT OUTPUT SPEC
	CAML	T1,S.LAST	;SEE IF DONE
	POPJ	P,		;YES--RETURN
	SKIPG	S.OPER		;SEE IF /SAVE
	JRST	INTER2		;YES
	MOVE	T2,.FXDIR(T1)	; GET THE PPN.			[346]
	CAMN	T2,[377777,,377777] ; ALL WILD?			[346]
	 JRST	INTR1A		; YES, GO ALONG MERRILY.	[346]
	HLRZ	T2,.FXDIR(T1)	; GET LH PPN OF OUTPUT SPEC.	[343]
	CAIN	T2,377777	; PROJECT WILD?			[343]
	 JRST	PPNWLD		; GO WARN THE USER.		[343]
	HRRZ	T2,.FXDIR(T1)	; GET RH PPN OF OUTPUT SPEC.	[343]
	CAIN	T2,377777	; PROJECT WILD?			[343]
	 JRST	PPNWLD		; GO WARN THE USER.		[343]
	JRST	INTR1A		; ALL OK CONTINUE.		[343]
PPNWLD:	MOVEI	T1,'WPI'	; SET UP PREFIX.		[343]
	MOVEI	T2,[ASCIZ/Wild PPN Illegal in INTERCHANGE mode/] ;[343]
	SETZM	S.FRST		; CLEAR FILE SPEC POINTERS.	[343]
	SETZM	S.LAST		; . . .				[343]
	 PJRST	SCNERR		; ISSUE ERROR MESSAGE.		[343]

INTR1A:	LDB	T2,[POINTR (.FXMOM(T1),FX.PRO)];GET /PROTTECTION
	JUMPN	T2,INTER1	;OKAY IF SET
	MOVEI	T2,AD.PRO	;GET DEFAULT
	JUMPN	T2,INTPRO	;[356] JUMP IF NON-ZERO
	HRROI	T2,.GTDFL	;[356] USERS DEFAULT PROTECTION
	GETTAB	T2,		;[356] GET IT
	  SETZ	T2,		;[356] SOMETHING WRONG
	TXNE	T2,JD.SDP	;[356] DID USER SET A PROTECTION?
	JRST	INTER4		;[356] YES, WERE DONE
	MOVE	T2,[%LDSTP]	;[356] TRY SYSTEM DEFAULT
	GETTAB	T2,		;[356] GET IT
	  MOVSI	T2,057000	;[356] ASSUME <057>
INTER4:	ROT	T2,^D9		;[356] POSITION
INTPRO:	DPB	T2,[POINTR (.FXMOD(T1),FX.PRO)]  ;[356] SET PROTECTION
	MOVEI	T2,777B35	;PROTECTION MASK
	DPB	T2,[POINTR (.FXMOM(T1),FX.PRO)];SET MASK
	JRST	INTER1		;LOOP OVER ALL SPECS

INTER2:	SETZM	.FXDEV(T1)	;ZILCH DEVICE
	MOVSI	T2,-.FXLND	;NUMBER OF DIRECTORY LEVELS
	HRR	T2,T1		;START ADDRESS OF SPEC
INTER3:	SETZM	.FXDIR(T2)	;CLEAR DIRECTORY
	SETOM	.FXDIM(T2)	;CLEAR WILD CARDS FROM MASK
	ADDI	T2,1		;STEP POINTER
	AOBJN	T2,INTER3	;LOOP
	JRST	INTER1		;DO NEXT SPEC
;+
;<LISTSW IS A ROUTINE TO GET THE <LIST SWITCH ARGUMENT.
;^IT VERIFIES THE AVAILABILITY OF THE FILE AND LEAVES
;THE LISTING CHANNEL <OPEN AND ^^ENTER\\RED.
;-

LISTSW:	MOVEI	T1,S.LIST	;POINT TO LISTING SPEC
	MOVEI	T2,.FXLEN	;INDICATE LENGTH
	PUSHJ	P,.GTSPC##	;GET FROM SCAN
				;FALL INTO LISTST

;+
;<LISTST IS A ROUTINE TO SETUP THE LISTING FILE. ^IT LEAVES
;THE LISTING CHANNEL <OPEN AND ^^ENTER\\RED, BUT HAS NOT ALLOCATED
;ITS BUFFERS.
;-

LISTST:	SKIPN	S.LIST		;LIST FILE SPECIFIED?
	POPJ	P,		;NO
	MOVX	T1,LS$DEV	;DEFAULT TO LPT:
	MOVE	T2,S.LIST+.FXDEV ;GET DEVICE
	CAIN	T2,1		;IF DEFAULT,
	MOVEM	T1,S.LIST+.FXDEV ; USE DEFAULT
	SKIPN	S.LIST+.FXNAM	;IF NO FILE NAME,
	SETOM	S.LIST+.FXNMM	; REMOVE WILD-CARDS
	MOVX	T1,LS$NAM	;DEFAULT TO BACKUP
	SKIPN	S.LIST+.FXNAM	; IF USER GAVE NO
	MOVEM	T1,S.LIST+.FXNAM ; FILE NAME
	HRLOI	T1,LS$EXT	;DEFAULT TO .LOG
	SKIPN	S.LIST+.FXEXT	;SEE IF EXTENSION
	MOVEM	T1,S.LIST+.FXEXT ;NO--USE DEFAULT

	MOVE	T1,[.FXLEN,,S.LIST] ;POINT TO SPEC
	MOVEI	T2,S.LOPN	;POINT TO OPEN BLOCK
	MOVE	T3,[LN$LEN,,S.LENT] ;POINT TO ENTER BLOCK
	PUSHJ	P,.STOPN##	;CONVERT SCAN BLOCK
	  JRST	E$$LSI		;LIST SPEC ILLEGAL IF WILD
	MOVSI	T1,S.LBPT	;POINT TO BUFFER
	MOVEM	T1,S.LOPN+.OPBUF ; FOR MONITOR
	MOVEI	T1,LN$LEN-1	;SET LENGTH OF
	IORM	T1,S.LENT+.RBCNT ; ENTER BLOCK
	OPEN	F.LIST,S.LOPN	;OPEN FILE
	  JRST	LISTS5		;ERROR IF CAN'T OPEN
	MOVEI	T1,F.LIST	;LISTING CHANNEL
	DEVCHR	T1,		;GET CHARACTERISTICS
	TXNE	T1,DV.TTY	;SEE IF DEVICE IS A TTY
	SETZM	S.TYMS		;YES, FORCE SILENCE FOR CLEAN LISTING
	SKIPN	S.LENT+.RBNAM	;SEE IF NAME
	POPJ	P,		;NO--SKIP ENTER
	SKIPLE	T1,S.APPD	;IF APPEND,
	JRST	[
		PUSH	P,S.LENT+.RBPPN	; (SAVE DIRECTORY)
		LOOKUP	F.LIST,S.LENT	;LOOK AT FILE
		  SETZM	T1		;FILE NOT THERE
		POP	P,S.LENT+.RBPPN	; (RESTORE DIRECTORY)
		JRST	.+1]		;CONTINUE
	HRRZ	T2,S.LENT+3	;[377] SAVE DATES JUST IN CASE
	ENTER	F.LIST,S.LENT	;YES--ENTER FILE
	JRST	[			;[377] ERROR IF CAN'T ENTER
		HRRZ	T3,S.LENT+3	;[377] GET ERROR CODE
		CAIE	T3,ERISU%	;[377] FUNNY ERROR?
		JRST	E$$LFE		;[377] NOPE, REGULAR ERROR RETURN
		HRRM	T2,S.LENT+3	;[377] PROBABLY FOUND FILE IN LIB:
		CLOSE	F.LIST,		;[377] RESTORE DATES AND CLOSE FILE
		ENTER	F.LIST,S.LENT	;[377] ENTER IN NON-UPDATE MODE
		  JRST	E$$LFE		;[377] LOSE FOR SURE THIS TIME
		SETZM	T1		;[516] DON'T APPEND THE FILE
		JRST	.+1]		;[377] ALL SET
	SKIPLE	T1		;IF APPEND,
	USETI	F.LIST,-1	; POSITION TO END
	POPJ	P,		;RETURN

LISTS5:!
E$$COL::MOVEI	T1,'COL'	;JUST GIVE OPEN ERROR
	MOVEI	T2,[ASCIZ \Can't OPEN listing device\]
	PJRST	LSTERR		;ISSUE FATAL ERROR

E$$LFE::MOVEI	T1,'LFE'	;JUST GIVE ENTER ERROR
	MOVEI	T2,[ASCIZ \Listing file ENTER error\]
	PJRST	LSTERR		;ISSUE FATAL ERROR

E$$LSI::MOVEI	T1,'LSI'	;INDICATE WHICH ERROR
	MOVEI	T2,[ASCIZ \Listing specification incorrectly formatted\]
LSTERR:	SETZM	S.LIST		;CLEAR LISTING FILE
	PJRST	SCNERR		;ISSUE FATAL ERROR

;+
;<TAPESW IS A ROUTINE TO GET THE <TAPE SWITCH ARGUMENT.
;^IT VERIFIES THE AVAILABILITY OF THE DRIVE AND THEN ^^RELEAS\\ES
;THE CHANNEL.
;-

TAPESW:	MOVEI	T1,S.TAPE	;POINT TO TAPE STORAGE
	MOVEI	T2,.FXLEN	;INDICATE LENGTH
	PUSHJ	P,.GTSPC##	;GET THE SPECIFICATION
	PUSHJ	P,TAPARS	;APPLY DEFAULTS AND SETUP
	PUSHJ	P,TAPOPN	;OPEN TAPE CHANNEL
	SKIPE	S.NLDV		;[437] IS THIS THE NULL DEVICE?
	JRST	TAPES1		;[437] YES SKIP TAPE INQUIRY STUFF
	MOVEI	T3,F.MTAP	;[437] USE THE CHANNEL WHICH IS OPEN
	PUSHJ	P,LABCLR	;[437] CHECK FOR TAPE DEVICE ERRORS
	MOVEI	T3,F.MTAP	;[437] Use the channel which is open
	PUSHJ	P,LABTYP	;[437][426] GET LABEL TYPE
TAPES1:	RELEAS	F.MTAP,		;[437]FREE THE CHANNEL
	POPJ	P,		;RETURN
;LABTYP - Routine to get the label type from the monitor.  Stores the label type
;	in TAPLBL.
;
;Call:	MOVE	T3,Device/Channel/UDX
;	PUSHJ	P,LABTYP
LABTYP:	MOVE	T1,[XWD 2,T2]	;[437][345] AIM AT THE ARG BLOCK
	MOVEI	T2,.TFLBL	;[437][345] FUNCTION - GET LABEL TYPE
	TAPOP.	T1,		;[437][345] ASK THE MONITOR
	  MOVEI	T1,.TFLBP	;[437][345] CAN'T GET IT, ASSUME (OLD) BYPASS
	MOVEM	T1,TAPLBL	;[437] Store the label type.
	POPJ	P,		;[437][345] RETURN
;LABCLR - Routine to clear tape label errors in case a different volume set is
;	being used.
;
;Call:	MOVE	T3,Device/Channel/UDX
;	PUSHJ	P,LABCLR
LABCLR:	MOVE	T1,[XWD 2,T2]	;[437] AIM AT ARG BLOCK. T3 CONTAINS DEVICE ARG
	MOVEI	T2,.DFRES	;[437]RETURN EXTENDED I/O ERROR STATUS IN AC
	DEVOP.	T1,		;[437]
	  POPJ	P,		;[437] IGNORE DEVICE ERROR STATUS IF FAILURE
	JUMPE	T1,HPOPJ	;[437] RETURN IF NOTHING
	CAIE	T1,IONOP%	;[437] 
	CAIN	T1,IOEOF%	;[437] EOF ISN'T CONSIDERED AN ERROR
	POPJ	P,		;[437] RETURN IF NO ERROR
	CAIN	T1,IOBOT%	;[437] BEGINNING OF TAPE NOT AN ERROR EITHER
	POPJ	P,		;[437]
	MOVE	T1,[XWD 3,T2]	;[437] SET UP TO CLEAR ERRORS. T3 STILL CONTAINS
	MOVEI	T2,.TFURQ	;[437]  THE DEVICE ARGUMENT
	MOVEI	T4,.TFCLE	;[437] CLEAR 
	TAPOP.	T1,		;[437]
	  JFCL			;[437] IGNORE THESE ERRORS TOO
	POPJ	P,		;[437] RETURN
;+
;<TAPEDO IS A ROUTINE TO OPEN THE MAG TAPE FOR REGULAR
;OPERATION AND ALLOCATE THE BUFFERS.
;-

TAPEDO:	PUSHJ	P,TAPARS	;APPLY DEFAULTS AND SETUP
	TXO	T1,UU.IBC	;INHIBIT BUFFER CLEAR

IFN FT$RCV,<
	MOVX	T3,%CNDVN	;MONITOR VERSON
	GETTAB	T3,		;ACCESS
	  SETZ	T3,		;LOSE
	TXZ	T3,VR.WHO!VR.MIN;LEAVE MAJOR VERSION
	LSH	T3,-^D24	;POSITION RELEASE LEVEL
	CAIL	T3,602		;6.02 OR LATER?
	TXO	T1,UU.SOE	;[434] YES--SET SYNCRONIZE IF ERROR BIT
	TXNE	T1,UU.SOE	;[434] SEE IF SYNCRONIZATION AVAILABLE,
	SKIPL	S.OPER		; AND IF THIS IS A WRITE OPERATION,
	SKIPA			;NO
	TXZ	T1,UU.DER	;[301] YES--LET MONITOR DO ERROR RE-TRY ANYWAY
>;END IFN FT$RCV

	MOVE	T4,S.FRST	;FILE SPEC AREA
	MOVX	T3,FX.PAR	;/PARITY
	TDNE	T3,.FXMOD(T4)	;CHECK USER SET PARITY
	TXO	T1,IO.PAR	;SET PARITY
	IORI	T1,.IOBIN	;SET FOR BINARY MODE
	MOVEI	T3,S.MBPT	;POINT TO MAG TAPE HEADERS
	SKIPGE	S.OPER		;IF WRITE,
	MOVSI	T3,S.MBPT	; POINT AS OUTPUT
	PUSHJ	P,TAPOPE	;OPEN TAPE

	PUSHJ	P,INIBBS	;INITIALIZE BIG BLOCK VARIABLES
	MOVE	T1,S.BFSZ	;GET MAXIMUM SIZE OF A BACKUP TAPE BLOCK
	ADDI	T1,3		;ACCOUNT FOR OVERHEAD WORDS
	MOVE	T4,.JBFF##	;GET START OF AREA
	ADDB	T1,.JBFF##	;ADVANCE TO END+1
	CAMG	T1,.JBREL##	;SEE IF IN CORE
	JRST	TAPED1		;YES--PROCEED
	CORE	T1,		;NO--GET ENOUGH
	  JRST	E$$TMI		;ERROR IF NO ROOM
TAPED1:	MOVEI	T1,NM$TBF	;NUMBER OF BUFFERS
	MOVEI	T2,.BFHDR(T4)	;ADDRESS OF FIRST+1
	MOVE	N,S.BFSZ	;SIZE OF A TAPE BUFFER

TAPED2:	SETZM	(T2)		;CLEAR USE BITS, ETC.
	MOVSI	T3,1(N)		;DATA WORDS
	SOJLE	T1,TAPED3	;SEE IF THIS IS LAST BUFFER
	HRRI	T3,3(N)		;NO, GET LOC OF NEXT BUF+1
	ADDI	T3,(T2)		;...
	MOVEM	T3,(T2)		;STORE
	ADDI	T3,3(N)		;ADVANCE TO NEXT BUFFER
	JRST	TAPED2		;LOOP

TAPED3:	HRRI	T3,.BFHDR(T4)	;LOC OF FIRST BUF+1
	MOVEM	T3,(T2)		;STORE

	HRLI	T3,(BF.VBR)	;VIRGIN RING
	TXO	T3,BF.IBC	;INHIBIT BUFFER CLEAR
	MOVEM	T3,S.MBPT	;SET IN BUFFER POINTER
	MOVSI	T3,(POINT 36,,35) ;INDICATE 36-BIT BYTES
	MOVEM	T3,S.MBPT+.BFPTR ;SET IN POINTER
	SETZM	S.MBPT+.BFCTR	;CLEAR INITIAL COUNT
	POPJ	P,		;RETURN
;+
;<TAPARG IS A ROUTINE TO GET AN ARGUMENT WHICH IS A
;TAPE SPECIFICATION.  ^IF THE USER DOESN'T
;SUPPLY THE ARG, THEN THE LAST TAPE VERB IS USED
;AS THE DEFAULT. ^IF THERE WAS NO TAPE VERB, THEN
;AN ERROR RESULTS. ^THIS ROUTINE IS CALLED BY THE
;VARIOUS POSITIONING VERBS. ^IT RETURNS THE DEVICE
;IN ^T2 WITH VARIOUS SWITCHES IN ^T1. ^THE MODE
;WILL BE LEFT 0.
;-

TAPARG:	JUMPLE	C,TAPARS	;IF END OF LINE, DON'T GET ANY
	PUSHJ	P,.FILIN##	;GET FILE SPEC FROM USER
	MOVEI	T1,S.TTAP	;POINT TO TEMP TAPE SPEC
	MOVEI	T2,.FXLEN	;INDICATE LENGTH
	PUSHJ	P,.GTSPC##	;GET SPEC FROM SCAN
	MOVEI	T1,S.TTAP	;INDICATE USING TEMP SPEC
	JRST	TAPAR2		;GO DO THE SETUP

;HERE IF DEFAULT BEING USED

TAPARS:	HRRZI	T2,F.NAM##-1	;[326] GET ADDR OF SCAN'S AREA
	LDB	T1,[POINTR(.FXMOD(T2),FX.DEN)] ;[326] GET DENSITY
	SKIPE	T1		;[326] A REAL SETTING THERE?
	HRRZM	T1,TAPDEN	;[326] YES - SAVE IT FOR EVERYBODY ELSE
	PUSHJ	P,TAPDEF	;GO APPLY DEFAULTS TO /TAPE
	MOVEI	T1,S.TAPE	;POINT TO TAPE SPEC

;HERE WITH T1=LOC OF TAPE SPEC TO USE

TAPAR2:	SKIPGE	.FXMOD(T1)	;SEE IF NULL DEVICE
	SKIPN	T2,.FXNAM(T1)	;AND FILE NAME GIVEN
	SKIPA			;NO
	MOVEM	T2,.FXDEV(T1)	;YES--MEANS USER FORGOT COLON
	HRLI	T1,.FXLEN	;INDICATE LENGTH OF SPEC
	MOVEI	T2,S.MOPN	;POINT TO OPEN BLOCK
	MOVEI	T3,S.MENT	;POINT TO LOOKUP BLOCK
	HRLI	T3,LN$MEN	;INDICATE ITS LENGTH
	PUSHJ	P,.STOPN##	;CONVERT SCAN BLOCK
	  JRST	E$$TSI		;TAPE SPEC ILLEGAL IF WILD
	SKIPN	S.MENT+.RBPPN	;IF FILE DIRECTORY,
	SKIPE	S.MENT+.RBEXT	; OR EXTENSION,
	JRST	E$$TSI		; TAPE SPEC IS ILLEGAL
	SKIPL	.FXMOD(T1)	;IF BOTH DEVICE
	SKIPN	.FXNAM(T1)	; AND FILE NAME GIVEN -- ERROR
	SKIPA			;OK
	JRST	E$$TSI		;TAPE SPEC ILLEGAL
	MOVE	T1,S.MOPN+.OPMOD ;GET MODE WORD
	MOVE	T2,S.MOPN+.OPDEV ;GET DEVICE WORD
	POPJ	P,		;RETURN

E$$TSI::MOVEI	T1,'TSI'	;INDICATE WHICH ERROR
	MOVEI	T2,[ASCIZ \Tape specification incorrectly formatted\]
	PJRST	SCNERR		;INDICATE SCANNING ERROR
;+
;<TAPOPN <OPEN\S THE TAPE CHANNEL.  ^IF THE <OPEN
;FAILS, AN ERROR MESSAGE IS GENERATED AND THE ROUTINE DOES
;NOT RETURN. ^IF THE SPECIFICATION IS NOT OF A MAG TAPE, A FATAL
;MESSAGE IS GENERATED INSTEAD. ^CALL WITH ^T1=MODE, ^T2=NAME.
;
;<TAPOPE IS THE SAME, BUT DOES NOT FORCE DUMP MODE.
;-

TAPOPN:	MOVEI	T3,0		;INDICATE NO BUFFERS
	IORI	T1,.IOASC	;[271] INDICATE ASCII MODE

TAPOPE:	ANDCM	T1,[IO.DEN]	;[326] CLEAR THE DENSITY BITS
	OPEN	F.MTAP,T1	;TRY TO OPEN DEVICE
	  JRST	TAPOP1		;ERROR--FIND OUT WHY
	MOVEI	T1,F.MTAP	;INDICATE THIS CHANNEL
	DEVCHR	T1,		;GET ITS CHARACTERISTICS
	TXNN	T1,DV.MTA	;[402] SEE IF MAG TAPE
	JRST	TAPOP2		;[437]
	SETZM	S.NLDV		;[375] ZERO NUL DEVICE FLAG
	TXNE	T1,DV.LPT	;[375] NUL DEVICE IF MULTIPLY DEFINED
	JRST	[SETOM	S.NLDV	;[437][375] YUP, FLAG IT
		POPJ	P,]	;[437] IF NULL DEVICE SKIP TAPE OPERATIONS

	SKIPN	T1,TAPDEN	;GET THE SPECIFIED DENSITY
	POPJ	P,		;USE CURRENT DENSITY
	MOVE	T2,[2,,T3]	;SET UP UUO AC
	MOVEI	T3,.TFPDN	;FUNCTION CODE
	MOVEI	T4,F.MTAP	;CHANNEL
	TAPOP.	T2,		;READ MASK OF POSSIBLE DENSITIES
	  SETZ	T2,		;MAKE SURE TEST FAILS
	MOVEI	T3,1		;GET A BIT
	LSH	T3,-1(T1)	;POSITION IT
	TDNN	T3,T2		;VALID DENSITY SPECIFIED?
	SETZ	T1,		;MAKE IT THE DRIVE DEFAULT
	MOVE	T4,T1		;COPY TO A SAFER PLACE
	MOVE	T1,[3,,T2]	;SET UP UUO AC
	MOVEI	T2,.TFDEN+.TFSET ;FUNCTION CODE + SET
	MOVEI	T3,F.MTAP	;CHANNEL
	TAPOP.	T1,		;SET DENSITY
	  SETZ	T4,		;FAILED
	JUMPN	T4,CPOPJ	;RETURN IF SETTING A REAL DENSITY
	JRST	TAPOP3		;GIVE A WARNING AND RETURN


;HERE WHEN CAN NOT OPEN MAG TAPE

TAPOP1:!
E$$COM::MOVEI	T1,'COM'	;JUST GIVE OPEN ERROR
	MOVEI	T2,[ASCIZ \Can't OPEN mag tape\]
	PJRST	SCNERR		;ISSUE SCANNING ERROR

;Here when device is not a magtape
TAPOP2:!				;[437]
E$$DNM::RELEAS	F.MTAP,		;[437]NO--FREE CHANNEL
	MOVEI	T1,'DNM'	;[437]ERROR
	MOVEI	T2,[ASCIZ \Device not a mag tape\]	;[437]
	JRST	SCNERR		;[437]ISSUE SCANNING ERROR


;HERE, WARN ON AN ILLEGAL DENSITY
TAPOP3:!
E$$SDI:	MOVE	T1,['BKPSDI']	;SET UP PREFIX
	HRLI	T2,"%"		;WARNING
	HRRI	T2,[ASCIZ/Specified density incorrect, drive default used/]
	PUSHJ	P,.ERMSG##	;PRINT MESSAGE
;+
;<TAPDEF APPLIES DEFAULTS TO THE /<TAPE SWITCH.
;^IT IS INVOKED BEFORE EXECUTING THE NON-POSITIONING
;ACTION VERBS AND ON THE POSITIONING VERBS IF NO DEVICE IS SPECIFIED.
;-
TAPDEF:	SKIPE	S.TAPE		;/TAPE?
	POPJ	P,		;SOMETHING REAL THERE--RETURN
	MOVE	T1,[SIXBIT/BACKUP/] ;SEE IF LOGICAL NAME BACKUP ASSIGNED
	DEVNAM	T1,		;GET PHYSICAL TAPE DEVICE
	  JRST	E$$NTS		;LOSE
	MOVE	T3,[SIXBIT/BACKUP/] ;[437][345] GOT IT, USE IT SO WE CAN SWAP
				; UNITS.  ALSO SET UP FOR CALL TO LABCLR
	MOVEM	T3,S.TAPE	;[345]STORE IT IN S.TAPE.
	PUSHJ	P,LABCLR	;[437]CLEAR ANY POSSIBLE TAPE LABELLING ERRORS
	MOVE	T3,S.TAPE	;[437]USE DEVICE FOR ARGUMENT TO LABTYP
	PUSHJ	P,LABTYP	;[437]FIND THE LABEL TYPE
	POPJ	P,		;RETURN

E$$NTS::MOVEI	T1,'NTS'	;INDICATE WHICH MESSAGE
	MOVEI	T2,[ASCIZ \No tape specified\]
	PJRST	SCNERR		;ISSUE FATAL ERROR
;+
;<CHKSOM VERIFIES THAT FILES WERE FOUND TO MATCH ALL OF THE
;COMMANDS. ^IF NOT, WARNINGS ARE ISSUED, UNLESS </OKNONE WAS TYPED.
;-

CHKSOM:	PUSHJ	P,.SAVE1##	;SAVE P1
	MOVE	T1,S.INIT+.FXNAM;[523] Did we
	IOR	T1,S.INIT+.FXDEV;[523]  find our
	IOR	T1,S.INIT+.FXDIR;[523]  /INITIAL file?
	JUMPN	T1,E$$INF	;[523] No. Complain about that specifically.
	SKIPA	P1,S.FRST	;ADDRESS OF SPECS

CHKSM1:	ADDI	P1,FX$LEN*2	;POINT TO NEXT SPEC
	SKIPN	S.PRNT		;NO MESSAGE IF "PRINT" COMMAND	[172]
	CAML	P1,S.LAST	;SEE IF DONE
	POPJ	P,		;YES
	MOVX	T1,FX.NOM	;FLAG FOR /OKNONE
	SKIPN	FX$CNT(P1)	;SPEC USED?
	TDNE	T1,.FXMOD(P1)	;OR /OKNONE?
	JRST	CHKSM1		;OK--SKIP THIS CODE
E$$NFF::MOVE	T1,['BKPNFF']	;PREFIX
	MOVE	T2,["%",,[ASCIZ /No files found to match /]]
	PUSHJ	P,.ERMSG##	;ISSUE MESSAGE
	TXNN	T1,JWW.FL	;IF /MESSAGE:NOFIRST
	JRST	CHKSM2		; SKIP REST
	MOVEI	T1,FX$LEN(P1)	;POINT TO INPUT SPEC
	PUSHJ	P,.TFBLK##	;TYPE FILE BLOCK
CHKSM2:	PUSHJ	P,.TCRLF##	;ISSUE END OF LINE
	JRST	CHKSM1		;CONTINUE

E$$INF::MOVE	T1,['BKPINF']	;[523] PREFIX
	MOVE	T2,["%",,[ASCIZ \/INITIAL file not found: \]] ;[523]
	PUSHJ	P,.ERMSG##	;[523] ISSUE THE MESSAGE
	TXNN	T1,JWW.FL	;[523] IF /MESSAGE:NOFIRST
	PJRST	.TCRLF##	;[523]  SKIP THE REST
	MOVEI	T1,S.INIT	;[523] POINT TO THE /INITIAL SPEC
	PUSHJ	P,.TFBLK##	;[523] TYPE THE FILE BLOCK
	PJRST	.TCRLF##	;[523] TYPE THE END OF LINE AND RETURN
;+
;<ENCGET IS A ROUTINE TO GET THE TAPE'S ENCRYPTION KEY FROM
;THE USER.  ^IF ENCRYPTION HAS BEEN REQUESTED, WHEN THE
;ACTION IS INITIATED, <ENCGET PROMPTS FOR THE ENCRYPTION KEY
;WITH TERMINAL ECHO SUPPRESSED, THEN ASKS FOR VERIFICATION (IN CASE
;OF TERMINAL PROBLEMS). ^ONLY THE FIRST 30 CHARACTERS OF THE KEY ARE SAVED.
;-

ENCGET:	SKIPN	S.CRYP		;SEE IF /ENCRYPT
	POPJ	P,		;NO--RETURN TO CALLER

	SETZM	S.CRYP		;CLEAR INDICATOR
	MOVEI	T1,IO.SUP	;SUPPRESS
	MOVSI	T2,'TTY'	; ECHO ON
	MOVEI	T3,0		; TTY:
	OPEN	F.MTAP,T1	; (USE SCRATCH CHANNEL)
	  JFCL			;IGNORE ERROR

ENCKEY:	OUTSTR	[ASCIZ \Tape Encryption Key: \]
	MOVE	T2,[POINT 7,S.CRYP]
	MOVEI	T3,5*LN$CRP	;LIMIT RESULT
	PUSHJ	P,ENCYLP	;GET KEY AND STORE

	OUTSTR	[ASCIZ \
Reenter key to verify: \]
	MOVE	T2,[POINT 7,ENCRYP]
	MOVEI	T3,5*LN$CRP	;LIMIT RESULT
	PUSHJ	P,ENCYLP	;GET AND STORE SECOND COPY OF KEY

	MOVSI	T1,-LN$CRP	;
ENCVER:	MOVE	T2,S.CRYP(T1)	;GET KEY WORD
	CAME	T2,ENCRYP(T1)	;COMPARE WITH VERIFICATION KEY
	JRST	E$$KDM		;KEYS DON'T MATCH
	AOBJN	T1,ENCVER	;LOOP
	RELEASE	F.MTAP,		;RELEASE SCRATCH CHANNEL
	PJRST	.TCRLF##	;RETURN TO CALLER WITH CLEAN LINE
				; (ECHO SUPP LOOSES CRLF)

ENCYLP:	INCHWL	T1		;GET CHARACTER
	PUSHJ	P,OPRCLN	;CLEAN UP CHARACTER SET
	PORTAL	.+1		;[360] RETURNING FROM LOW-SEG
	JUMPE	T1,ENCYLP	;IF NULL, DISCARD
	CAIN	T1,.CHLFD	;SEE IF DONE YET
	JRST	ENCGOT		;YES--FINISH UP
	SOSL	T3		;NO--COUNT DOWN
	IDPB	T1,T2		;UNLESS OVERFLOW, STORE
	JRST	ENCYLP		;LOOP UNTIL DONE

ENCGOT:	MOVEI	T1,0		;DONE--STORE ZEROS
	SOSL	T3		;COUNT DOWN
	IDPB	T1,T2		;CLEAR REST OF KEY
	JUMPGE	T3,.-2		;LOOP UNTIL DONE
	POPJ	P,		;RETURN

E$$KDM::MOVE	T1,['BKPKDM']	;PREFIX
	MOVE	T2,["?",,[ASCIZ \Keys don't match -- please try again
\]]
	PUSHJ	P,.ERMSG##	;ISSUE ERROR MESSAGE
	JRST	ENCKEY		;CIRCLE TO TRY AGAIN
;+
;+
;^ROUTINE TO INITIALIZE VARIABLES USED BY THE BIG BLOCK SIZE CODE.
;<B.N IS SET TO THE MAXIMUM NUMBER OF DISK BLOCKS IN A TAPE BLOCK,
;<B.BBKP IS SET TO THE MAXIMUM SIZE OF A BACKUP TAPE BLOCK, AND
;<S.BFSZ IS SET TO THE LARGER OF <LN$TBF AND <B.BBKP (THIS IS THE
;SIZE OF AN <I/O BUFFER FOR THE TAPE).
;-

INIBBS:	SKIPN	S.INTR		;INTERCHANGE MODE?
	SKIPG	T1,S.BFCT	;NO, BLOCKING FACTOR SPECIFIED?
	MOVEI	T1,4		;USE SMALL SIZE
	MOVEM	T1,S.BFCT	;UPDATE IT
	IMULI	T1,200		;COMPUTE MAX SIZE OF A BACKUP TAPE BLOCK
	ADDI	T1,^D32		;ADD IN HEADER WORDS
	MOVEM	T1,B.BBKP	;STORE IT
IFN FT$FRS,<			;IF FRS SUPPORT
	CAIGE	T1,LN$TBF	;ENOUGH ROOM FOR AN FRS BLOCK?
	MOVEI	T1,LN$TBF	;NO, LEAVE ENOUGH ROOM FOR FRS BLOCKS
> ;END IFN FT$FRS
	MOVEM	T1,S.BFSZ	;STORE BUFFER SIZE
	POPJ	P,		;RETURN
;+
;<ALLSPC IS A ROUTINE TO ALLOCATE SPACE FOR A FILE
;SPECIFICATION. ^IT ALWAYS ALLOCATES AT <.JBFF WHICH
;MUST BE THE SAME AS <S.LAST. ^IT WILL EXPAND CORE IF
;NECESSARY. ^IT RETURNS THE LOCATION IN ^T1 AND THE
;LENGTH (=<FX$LEN) IN ^T2. ^THE ALLOCATED AREA WILL BE ZEROED.
;-

ALLSPC:	MOVE	T1,.JBFF##	;ALLOCATE AT .JBFF
	CAME	T1,S.LAST	;MAKE SURE NO MISTAKES
	JRST	E$$FSL		;WRONG--STOP
	MOVEI	T2,FX$LEN(T1)	;COMPUTE NEW FREE SPACE
	MOVEM	T2,.JBFF##	;UPDATE MONITOR
	MOVEM	T2,S.LAST	;UPDATE POINTER
	SOS	T2		;COMPUTE WHAT NEW .JBREL IS
	CAMG	T2,.JBREL##	;IF ENOUGH ROOM,
	JRST	ALLSP1		; PROCEED BELOW
	CORE	T2,		;ELSE, GET MORE CORE
	  SKIPA			;BAD IF WE CAN'T GET IT
	JRST	ALLSP1		;OK--GOT SOME
E$$TMI::MOVEI	T1,'TMI'	;ERROR--TOO MUCH CORE
	MOVEI	T2,[ASCIZ \Insufficient core for command\]
	JRST	SCNERR		;GO ISSUE ERROR

E$$FSL::MOVEI	T1,'FSL'	;FILE SPEC LOST
	MOVEI	T2,[ASCIZ \File specification data lost\]
	JRST	SCNERR		;GO ISSUE ERROR


;HERE WHEN CORE HAS BEEN ALLOCATED

ALLSP1:	HRLZI	T2,(T1)		;SETUP BLT
	HRRI	T2,1(T1)	; POINTER AND
	SETZM	(T1)		; CLEAR OUT
	BLT	T2,FX$LEN-1(T1)	; NEW CORE
	MOVEI	T2,FX$LEN	;GIVE LENGTH OF ALLOCATION
	POPJ	P,		;RETURN TO CALLER

;+
;<GETSPC IS THE ROUTINE TO GET THE LAST FILE SPECIFICATION
;INTO THE AREA POINTED TO BE ^T1 AND ^T2.
;^IT WILL APPLY ANY NECESSARY STANDARD DEFAULTS.
;-

GETSPC:	SKIPG	T3,F$MBF	;GET MBEFORE
	MOVE	T3,P$MBF	; OR STICKY VALUE
	MOVEM	T3,FX$MBF(T1)	;STORE
	SKIPG	T3,F$MSN	;GET MSINCE
	MOVE	T3,P$MSN	; OR STICKY VALUE
	MOVEM	T3,FX$MSN(T1)	;STORE
	PJRST	.GTSPC##	;GO DO THE SCAN THINGS
;+
;<LNMSPC WILL ATTEMPT TO BREAK DOWN PATHOLOGICAL NAMES INTO THEIR
;INDIVIDUAL COMPONENTS.  A SEPARATE PAIR OF INPUT/OUTPUT SCAN
;BLOCKS IS CREATED FOR EACH COMPONENT.
;-

LNMSPC:	SETZM	LNMFLG		;CLEAR FLAG
	MOVX	T1,.PTFRN	;FUNCTION CODE TO READ LNM
	MOVEM	T1,ILNM+.PTFCN
	MOVX	T1,PT.RCN	;RETURN CURRENT NAME
	MOVEM	T1,ILNM+.PTLNF
	MOVE	T1,ISPEC+.FXDEV	;GET DEVICE IN QUESTION
	MOVEM	T1,ILNM+.PTLNM
	MOVE	T1,[.PTLLB,,ILNM]
	PATH.	T1,		;READ INPUT LNM
	  SETZM	ILNM+.PTLNM	;FLAG NOT A LNM

	MOVE	T1,ISPEC+.FXDEV	;GET INPUT DEVICE
	CAMN	T1,OSPEC+.FXDEV	;SAME AS OUTPUT DEVICE?
	JRST	LNMSP1		;FAKE OUT
	MOVX	T1,.PTFRN	;FUNCTION CODE TO READ LNM
	MOVEM	T1,OLNM+.PTFCN
	MOVX	T1,PT.RCN	;RETURN CURRENT NAME
	MOVEM	T1,OLNM+.PTLNF
	MOVE	T1,OSPEC+.FXDEV	;GET DEVICE IN QUESTION
	MOVEM	T1,OLNM+.PTLNM
	MOVE	T1,[.PTLLB,,OLNM]
	PATH.	T1,		;READ OUTPUT LNM
LNMSP1:	  SETZM	OLNM+.PTLNM	;FLAG NOT A LNM

	SKIPN	ILNM+.PTLNM	;CHECK INPUT
	TDZA	T1,T1		;NO LOGICALS
	MOVEI	T1,1		;...
	SKIPE	OLNM+.PTLNM	;CHECK OUTPUT
	TRO	T1,2		;...
	JRST	@.+1(T1)	;DISPATCH
	EXP	LNMNON		;(0) NO LOGICAL NAME USAGE
	EXP	LNMINP		;(1) INPUT ONLY
	EXP	LNMOUT		;(2) OUTPUT ONLY
	EXP	LNMBTH		;(3) BOTH
;HERE IF NO LOGICAL NAME USAGE
LNMNON:	PUSHJ	P,ALLSPC	;ALLOCATE A SCAN BLOCK
	MOVSI	T2,OSPEC	;POINT TO TEMP OUTPUT SPEC
	HRRI	T2,(T1)		;MAKE A BLT POINTER
	BLT	T2,FX$LEN-1(T1)	;COPY OUTPUT SPEC

	PUSHJ	P,ALLSPC	;ALLOCATE A SCAN BLOCK
	MOVSI	T2,ISPEC	;POINT TO TEMP INPPUT SPEC
	HRRI	T2,(T1)		;MAKE A BLT POINTER
	BLT	T2,FX$LEN-1(T1)	;COPY INPUT
	POPJ	P,		;RETURN


;HERE IF BOTH INPUT AND OUTPUT LNM
LNMBTH:	MOVEI	T1,'LOI'	;PREFIX
	MOVEI	T2,[ASCIZ /Logical names on output and input are illegal/]
	JRST	SCNERR		;REPORT ERROR
;HERE IF INPUT LNM ONLY
LNMINP:	SKIPL	S.OPER		;SAVING?
	JRST	LNMNON		;NO (LNM IS REALLY TAPE FILESPEC)
	PUSHJ	P,.SAVE1##	;SAVE P1
	MOVEI	P1,ILNM+.PTLSB	;POINT TO FIRST COMPONENT SUB-BLOCK

LNMIN1:	MOVE	T1,ISPEC+.FXDEV	;GET INPUT DEVICE
	CAMN	T1,OSPEC+.FXDEV	;SAME AS OUTPUT DEVICE?
	JRST	LNMIN2		;YES
	PUSHJ	P,ALLSPC	;ALLOCATE A SCAN BLOCK
	MOVSI	T2,OSPEC	;SOURCE ADDRESS
	HRRI	T2,(T1)		;MAKE A BLT POINTER
	BLT	T2,FX$LEN-1(T1)	;COPY SCAN BLOCK
	CAIA			;NOW FOR THE INPUT SIDE

LNMIN2:	PUSHJ	P,LNMCPY	;BUILD OUTPUT SCAN BLOCK
	PUSHJ	P,LNMCPY	;GENERATE AN INPUT SCAN BLOCK
	MOVEI	P1,1(T2)	;ADVANCE TO NEXT SUB-BLOCK
	SKIPE	1(P1)		;TERMINATOR?
	JRST	LNMIN1		;NO--LOOP BACK FOR MORE
	AOS	LNMFLG		;REMEMBER WE TRANSLATED SOMETHING
	POPJ	P,		;RETURN
;HERE IF OUTPUT LNM ONLY
LNMOUT:	SKIPGE	S.OPER		;SAVING?
	JRST	LNMNON		;DON'T EXPAND (LNM IS ALIAS)
	PUSHJ	P,.SAVE1##	;SAVE P1
	MOVEI	P1,OLNM+.PTLSB	;POINT TO FIRST COMPONENT SUB-BLOCK

LNMOU1:	PUSHJ	P,LNMCPY	;GENERATE AN OUTPUT SCAN BLOCK
	MOVE	T1,ISPEC+.FXDEV	;GET INPUT DEVICE
	CAMN	T1,OSPEC+.FXDEV	;SAME AS OUTPUT DEVICE?
	JRST	LNMOU2		;YES
	PUSH	P,T2		;SAVE END OF SUB-BLOCK
	PUSHJ	P,ALLSPC	;ALLOCATE A SCAN BLOCK
	MOVSI	T2,ISPEC	;SOURCE ADDRESS
	HRRI	T2,(T1)		;MAKE A BLT POINTER
	BLT	T2,FX$LEN-1(T1)	;COPY SCAN BLOCK
	POP	P,T2		;RESTORE END OF SUB-BLOCK
	CAIA			;NOW FOR THE OUTPUT SIDE

LNMOU2:	PUSHJ	P,LNMCPY	;GENERATE AN INPUT SCAN BLOCK
	MOVEI	P1,1(T2)	;ADVANCE TO NEXT SUB-BLOCK
	SKIPE	1(P1)		;TERMINATOR?
	JRST	LNMOU1		;NO--LOOP BACK FOR MORE
	AOS	LNMFLG		;REMEMBER WE TRANSLATED SOMETHING
	POPJ	P,		;RETURN
;COPY A LOGICAL NAME COMPONENT INTO A SCAN BLOCK
;CALL:	MOVE	P1, COMPONENT ADDRESS
;	PUSHJ	P,LNMCPY

LNMCPY:	PUSHJ	P,ALLSPC	;ALLOCATE A SCAN BLOCK
	MOVE	T3,.PTLSL(P1)	;DEVICE
	MOVEM	T3,.FXDEV(T1)	;STORE IT
	SKIPN	T3,.PTFIL(P1)	;FILE NAME
	JRST	LNMCP1		;NONE GIVEN
	MOVEM	T3,.FXNAM(T1)	;STORE IT
	SETOM	.FXNMM(T1)	;SET MASK

LNMCP1:	HLLO	T3,.PTEXT(P1)	;EXTENSION
	TLNE	T3,-1		;HAVE ONE?
	MOVEM	T3,.FXEXT(T1)	;STORE IT
	SKIPN	T3,.PTLPP(P1)	;HAVE AT LEAST A PPN?
	JRST	LNMCP2		;NO
	MOVX	T2,FX.DIR!FX.DFX ;GET DIRECTORY BITS FOR WILD
	TLC	T3,-1		;DEFAULT
	TLCN	T3,-1		; PROJECT?
	TLZ	T3,-1		;YES
	TRC	T3,-1		;DEFAULT
	TRCN	T3,-1		; PROGRAMMER?
	TRZ	T3,-1		;YES
	TLNE	T3,-1		;DOES DIRECTORY
	TRNN	T3,-1		; NEED FIXUP BY WILD?
	TXZ	T2,FX.DFX	;YES
	MOVEM	T3,.FXDIR(T1)	;STORE PPN
	SETOM	.FXDIM(T1)	;AND MASK
	MOVEM	T2,.FXMOD(T1)	;LITE BITS FOR WILD
	MOVEM	T2,.FXMOM(T1)	;MAKE THEM STICK

LNMCP2:	ADDI	T1,.FXDIM+1	;OFFSET TO START OF PATH IN SCAN BLOCK
	MOVEI	T2,.PTLSF(P1)	;OFFSET TO START OF PATH IN LNM BLOCK
	HRLI	T1,-5		;MAKE AN AOBJN POINTER

LNMCP3:	SKIPN	T3,(T2)		;GET AN SFD
	JRST	LNMCP4		;ALMOST DONE
	MOVEM	T3,0(T1)	;STORE IT
	SETOM	1(T1)		;SET MASK
	AOS	T2		;ADVANCE LNM POINTER
	AOS	T1		;ACCOUNT FOR TWO WORD ENTRIES
	AOBJN	T1,LNMCP3	;LOOP BACK FOR MORE

LNMCP4:	SETOM	1(T1)		;FILL OUT REMAINDER OF PATH
	AOS	T1		;ACCOUNT FOR TWO WORD ENTRIES
	AOBJN	T1,LNMCP4	;LOOP
	POPJ	P,		;RETURN
;+
;<SCNERR ISSUES <BACKUP SCANNING ERROR MESSAGES. ^IT IS
;CALLED WITH <RH(T1) = 3 LETTER CODE AND <RH(T2) = ADDRESS OF
;<ASCIZ TEXT. ^IT DOES NOT RETURN.
;-

SCNERR:	HRLI	T1,'BKP'	;INCLUDE BACKUP PREFIX
	HRLI	T2,"?"		;INDICATE FATAL
	PUSHJ	P,.ERMSG##	;ISSUE ERROR
	PUSHJ	P,RESCOR	;RESET CORE ALLOCATIONS
	PJRST	.FMSGE##	;END OF COMMAND SCANNING ERROR

;+
;<RESCOR IS A ROUTINE TO RELEASE CORE AND SET THE CORE
;ALLOCATION BACK TO ITS INITIAL VALUES.
;-

RESCOR:	MOVE	T1,INICOR	;GET INITIAL CORE
	HLRZM	T1,.JBFF##	;RESTORE .JBFF
	TLZ	T1,-1		;CLEAR JUNK
	CAME	T1,.JBREL##	;SEE IF NO CHANGE
	CORE	T1,		;NO--DROP CORE
	  JFCL			;IGNORE ERROR
	POPJ	P,		;RETURN TO VSCAN

;+
;<HPOPJ AND <HPOPJ1 ARE USED FOR GIVING A NON-SKIP OR
;SKIP RETURN RESPECTIVELY FOR HIGH-SEGMENT ROUTINES.
;-
HPOPJ1:	AOS	(P)		;[360] GIVE SKIP RETURN
HPOPJ:	POPJ	P,		;[360] GIVE NON-SKIP RETURN
	SUBTTL	SUBROUTINES FOR RUN-TIME COMMAND HANDLER

;+
;.CHAPTER RUN-TIME COMMAND SUBROUTINES
;-

	XLIST		;FLUSH LITERALS
	LIT
	LIST
	RELOC		;SHIFT TO LOW SEGMENT


;+
;<SHOWGO IS A ROUTINE WHICH WILL DISPLAY EITHER AN "!" OR
;A "/" TO INDICATE THAT WE ARE RUNNING OR STOPPED, BUT THAT
;WE ARE LISTENING.
;-

SHOWGO:	SKIPN	S.STOP		;IF RUNNING,
	OUTSTR	[ASCIZ \!\]	; GIVE !
	SKIPE	S.STOP		;IF STOPPED,
	OUTSTR	[ASCIZ \/\]	; GIVE /
	POPJ	P,		;RETURN
;+
;<OPRGSX GETS A SIXBIT ALPHA QUANTITY FROM THE OPERATOR COMMAND,
;SKIPPING LEADING BLANKS. ^IT SKIP-RETURNS THE BREAK
;CHARACTER IN ^T1, THE SIXBIT WORD IN ^T2, AND A MASK OF THE
;WORD IN ^T3. ^IT ALSO CLOBBERS ^T4.  NON-SKIP RETURN IF AN ILLEGAL CHARACTER TYPED.
;-

OPRGSX:	PUSHJ	P,OPRSKB	;SKIP OVER LEADING BLANKS
	MOVE	T4,[POINT 6,T2]	;INITIALIZE POINTER
	SETZB	T2,T3		;CLEAR BOTH WORD AND MASK
OPRGS1:	PUSHJ	P,OPRCKS	;[504] CHECK CHARACTER - CONVERT IF NECESSARY
	CAIN	T1,40		;[504] SPACE (OR TAB)?
	JRST	CPOPJ1		;[504] YES DONE PARSING
	CAIN	T1,";"		;[504] COMMENT?
	JRST	CPOPJ1		;[504] YES. DONE PARSING
	CAIN	T1,.CHLFD	;[504] LINE TERMINATOR?
	JRST	CPOPJ1		;[504] YES. DONE PARSING
	CAIL	T1,"0"		;[504] IF BELOW NUMERICS
	CAILE	T1,"Z"		;[504] OR ABOVE ALPHABETICS
	POPJ	P,		;[504] GIVE "ILLEGAL COMMAND" RETURN
	CAILE	T1,"9"		;[504] IF NOT NUMERIC
	CAIL	T1,"A"		;[504] OR NOT ALPHABETIC
	SKIPA			;[504] YES IT IS
	POPJ	P,		;[504] GIVE ERROR RETURN
	SUBI	T1," "-' '	;YES--CONVERT TO SIXBIT
	TLNE	T4,(77B5)	;SEE IF OVERFLOW
	IDPB	T1,T4		;NO--STORE AWAY IN ANSWER
	LSH	T3,-6		;POSITION MASK
	TLO	T3,(77B5)	;INDICATE A CHARACTER
	PUSHJ	P,OPRGCH	;GET ANOTHER CHARACTER
	JRST	OPRGS1		;LOOP UNTIL DONE


;+
;<OPRCKS USED BY <OPRGSX TO DO SOME CHECKS ON THE CHARACTER IN ^T1.  <OPRCLN
;HAS ALREADY BEEN EXECUTED SO LINE TERMINATORS AND NULL-TYPE CHARACTERS DON'T
;NEED TO BE CHECKED.  ^THE FOLLOWING CONVERSIONS ARE DONE TO SIMPLIFY CHECKING
;IN UPPER LEVEL ROUTINES:
;	1.  ^COMMENT CHARACTERS (; AND !) ARE CONVERTED TO SEMI-COLON.
;	2.  ^TABS AND SPACES ARE CONVERTED TO SPACE.
;	3.  ^LOWER CASE IS CONVERTED TO UPPER CASE.
;^CALLED WITH THE CHARACTER IN T1.  ^RETURNS THE APPROPRIATE CHARACTER IN ^T1
;AND DOES NOT USE ANY OTHER <AC.
;-

OPRCKS:	CAIN	T1,"!"		;IF EXCLAMATION POINT
	MOVEI	T1,";"		;CONVERT TO SEMI-COLON
	CAIN	T1,.CHTAB	;IF TAB
	MOVEI	T1,40		;CONVERT TO SPACE
	CAIL	T1,"A"+40	;IF NOT LOWERCASE
	CAILE	T1,"Z"+40	; THEN JUST RETURN WITH
	POPJ	P,		; CHARACTER
	SUBI	T1,40		;ELSE CONVERT TO UPPERCASE AND
	POPJ	P,		; THEN RETURN
;+
;<OPRSKB SKIPS OVER SPACES AND TABS IN THE OPERATOR COMMAND.
;^IT RETURNS WITH THE FIRST NON-BLANK IN ^T1. ^IT MUST BE
;CALLED WITH THE NEXT CHARACTER IN ^T1.
;-

OPRSKB:	JUMPE	T1,OPRSK1	;SKIP NULLS ALSO
	CAIE	T1,.CHTAB	;IF TAB
	CAIN	T1," "		; OR SPACE
	SKIPA			;YES--MUST GET NEXT CHAR
	POPJ	P,		;NO--OK
OPRSK1:	PUSHJ	P,OPRGCH	;GET NEXT CHARACTER
	JRST	OPRSKB		;LOOP

;+
;<OPRSKL SKIPS TO END OF LINE IN THE OPERATOR COMMAND.
;^IT MUST BE CALLED WITH ^T1 CONTAINING THE CURRENT CHARACTER,
;WHICH CAN BE THE END OF LINE ALREADY.
;-

OPRSKL:	CAIN	T1,.CHLFD	;SEE IF END OF COMMAND
	POPJ	P,		;YES--RETURN
	PUSHJ	P,OPRGCH	;NO--GET NEXT CHARACTER
	JRST	OPRSKL		;AND TRY AGAIN
;+
;<OPRGCH GETS A CHARACTER FROM THE OPERATOR'S TERMINAL AND
;CLEANS IT UP BY REMOVING IGNORED CHARACTERS AND CONVERTING
;ALL LEGITIMATE END OF COMMAND CHARACTERS TO LINE-FEED.
;^IT RETURNS THE CHARACTER IN ^T1 AND USES NO OTHER
;ACCUMULATORS.
;-

OPRGCH:	INCHWL	T1		;GET CHARACTER
	PUSHJ	P,OPRCLN	;CLEAN IT UP
	JUMPE	T1,OPRGCH	;LOOP IF NULL
	POPJ	P,		;RETURN IF NOT

;+
;<OPRCLN IS A ROUTINE TO CLEAN UP A CHARACTER WHICH WAS JUST
;RECEIVED FROM THE TERMINAL. ^IT CHANGES THE CHARACTER IN ^T1
;TO NULL TO DISCARD IT AND TO LINE FEED IF IT IS AN END
;OF LINE CHARACTER.
;-

OPRCLN:	CAIE	T1,.CHCRT	;SEE IF CARRIAGE RETURN
	CAIN	T1,.CHDEL	; OR DELETE (RUBOUT)
	MOVEI	T1,0		;YES--CHANGE TO NULL
	CAIE	T1,.CHFFD	;SEE IF FORM FEED
	CAIN	T1,.CHVTB	; OR VERTICAL TAB
	MOVEI	T1,.CHLFD	;YES--CHANGE TO LINE FEED
	CAIE	T1,.CHBEL	;SEE IF BELL (HACK BREAK)
	CAIN	T1,.CHESC	; OR ESCAPE
	MOVEI	T1,.CHLFD	;YES--CHANGE TO LINE FEED
	CAIE	T1,.CHCNC	;SEE IF ^C
	CAIN	T1,.CHCNZ	; OR ^Z
	MOVEI	T1,.CHLFD	;YES--CHANGE TO LINE FEED
	POPJ	P,		;RETURN


;+
;.DO INDEX
;-

	END	BKPSTR		;&.SKIP 2;[^END OF <BACKUP.PLM]