Google
 

Trailing-Edge - PDP-10 Archives - de-10-omona-v-mc9 - backup.mac
There are 14 other files named backup.mac in the archive. Click here to see a list.
	TITLE	BACKUP -- MODULE TO SCAN COMMANDS FOR BACKUP -- %2(216)
	SUBTTL	P.F.CONKLIN/PFC/KCM/JEF			20-FEB-76

CUSTVR==0		;DEC DEVELOPMENT
DECVER==2		;MAJOR VERSION
DECMVR==0		;MINOR VERSION
DECEVR==216		;EDIT NUMBER


;+
;.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 2
;.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 1974, 1975, 1976 DIGITAL EQUIPMENT CORP., MAYNARD,MASS.***
;\\
;-
;       	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
;+
;.LEFT MARGIN 5.RIGHT MARGIN 55
;.SKIP 3
;^THE INFORMATION IN THIS DOCUMENT IS SUBJECT TO CHANGE WITHOUT
;NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT
;BY ^DIGITAL ^EQUIPMENT ^CORPORATION.
;.SKIP 3
;^DIGITAL ^EQUIPMENT ^CORPORATION ASSUMES NO
;RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY
;^DIGITAL ^EQUIPMENT ^CORPORATION.
;.SKIP 3
;^THIS SOFTWARE IS FURNISHED TO PURCHASER UNDER A LICENSE
;FOR USE ON A SINGLE COMPUTER SYSTEM AND CAN BE COPIED (WITH
;INCLUSION OF ^DIGITAL ^EQUIPMENT ^CORPORATION'S
;COPYRIGHT NOTICE) ONLY FOR USE IN SUCH SYSTEM, EXCEPT AS MAY
;OTHERWISE BE PROVIDED FOR IN WRITING BY ^DIGITAL ^EQUIPMENT
;^CORPORATION.
;.LEFT MARGIN 0.RIGHT MARGIN 60

;.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

;+
;^ASSEMBLY INSTRUCTIONS:^^
;
;	.LOAD BACKUP.MAC,BACKRS.MAC
;\\
;^THE FOLLWING FILES MUST BE ON ^^REL: SCN7B,WLD7A,HELPER,ENDECR
;-\\

	.REQUEST	REL:SCN7B	; USE VERSION 7B OF SCAN
%%%SCN==:7				
	.REQUEST	REL:WLD7A	; USE VERSION 7A OF WILD
%%%WLD==:7
	.REQUEST	REL:HELPER	; USE HELPER.REL
	.TEXT\REL:ENDECR/SEG:LOW\	; LOAD ENDECR.REL INTO LOW SEG

;&^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	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.D75,1		;DEFAULT DATE-75 DEFENSE
ND AD.INT,0		;DEFAULT INTERCHANGE MODE
ND AD.MUL,1		;DEFAULT MULTIREEL SAVE
ND AD.PRO,057		;DEFAULT PROTECTION FOR INTERCHANGE RESTORE
ND AD.SRD,0		;DEFAULT SORT DIRECTORIES
ND AD.SRF,0		;DEFAULT SORT FILES WITHIN DIRECTORY
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,4		;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
;+.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 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
ND LN$TBF,24+5*200 ;LENGTH OF TAPE BLOCK	**DUPLICATE OF BACKRS
ND LN$STR,^D36	;LENGTH OF SYSTEM STRUCTURE TABLE **DUPLICATE OF BACKRS

UU.SIE==1B5	;***TEMP*** 6.02 SYNCRONIZE IF ERROR BIT FOR OPEN UUO
;D.SELECT _;
;&.FILL;\\
	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 ANY <IO ERRORS.
;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.
	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

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	;RUN FILE DIRECTORY
	Z		;ALWAYS 0

;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
LOWLWA==.-1
;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.DT75::BLOCK	1	;DATE-75 DEFENSE (0=NO)
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.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.UPRT::BLOCK	1	;UPROTECT (0=NO CHANGE)
S.USET::BLOCK	1	;USETI (0=NO)
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)

P$MBF:	BLOCK	1	;STICKY /MBEFORE
P$MSN:	BLOCK	1	;STICKY /MSINCE
F$MBF:	BLOCK	1	;CURRENT /MBEFORE
F$MSN:	BLOCK	1	;CURRENT /MSINCE
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

	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:	TDZA	T1,T1		;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
	SKIPN	.SGDEV		;SEE IF DEVICE SET
	MOVSI	.SGDEV,'SYS'	;NO--USE SYS
	MOVEM	.SGDEV,SAVDEV	;SAVE THE DEVICE
	SKIPN	.SGNAM		;SEE IF FILE NAME SET
	MOVE	.SGNAM,['BACKUP'];NO--USE BACKUP
	MOVEM	.SGNAM,SAVNAM	;SAVE THE FILE NAME
	MOVEM	.SGLOW,SAVLOW	;SAVE THE LOW EXTENSION
	MOVEM	.SGPPN,SAVPPN	;SAVE THE DIRECTORY

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

	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

	DEFINE	SETUP$(LOC$,VAL$),<
IFN <VAL$>,<IFE <VAL$>-1,<MOVEM T1,<LOC$>;>	STORE	(T2,<LOC$>,,<VAL$>)	>
>

	MOVEI	T1,1		;SET COMMON CONSTANT
	SETUP$	(S.APPD,AD.APP)	;APPEND
	SETUP$	(S.CKPT,AD.CKP) ;NO CHECKPOINTING
	SETUP$	(S.DT75,AD.D75)	;DATE-75 DEFENSE
	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.UPRT,AD.UPR)	;UPROTECT
	SETUP$	(S.USET,AD.UST)	;USETI
	MOVE	T2,FFAPPN	;GET FULL-FILE ACCESS
	CAME	T2,.MYPPN##	;SEE IF THAT IS US
	SETZM	S.USET		;NO--DEFAULT TO /NOUSETI
	CAMN	T2,.MYPPN##	;ALSO INDICATE FOR BACKRS
	SETOM	S.FFA		; 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

	MOVE	T1,OSCNPT	;GET OSCAN POINTER
	PUSHJ	P,.OSCAN##	;GET INITIAL DEFAULTS
;+.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 CHECK,,$CHECK,,
SN CPOINT,S.CKPT,
SN DATE75,S.DT75,
SN DELETE,S.DELT,
SS DIRECTORIES,S.TYMS,MSGDIR,
SN ENCRYPTION,S.CRYP,
SP EOT,,$EOT,,
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 LABEL,,$LABEL,,
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,
SS NOFILES,S.TYMS,MSGDIR,
SS NOLIST,S.LIST,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 UNLOAD,,$UNLOA,,
SP UPROTECT,S.UPRT,.SWOCT##,UPR,
SN USETI,S.USET,
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 LABEL (DECLARE LABEL PARAMETERS)
;
;^THE <LABEL VERB DECLARES PARAMETERS TO BE
;USED DURING TAPE LABELLING. ^IT IS CURRENTLY UNDEFINED.
;-

$LABEL:
E$$LND::MOVEI	T1,'LDN'
	MOVEI	T2,[ASCIZ \Label verb not yet implemented\]
	JRST	SCNERR		;GO ISSUE ERROR

;+.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
	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 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,","		;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>)
	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.
;-

$EOT:	MOVE	T1,[MTEOT. F.MTAP,] ;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.
;-

$REWIN:	MOVE	T1,[MTREW. F.MTAP,] ;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.
;-

$UNLOA:	MOVE	T1,[MTUNL. F.MTAP,] ;GET FUNCTION
				;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
	XCT	(P)		;PERFORM THE FUNCTION
	RELEAS	F.MTAP,		;RELEASE THE CHANNEL
	JUMPG	C,TAPFCL	;LOOP IF NOT DONE WITH COMMAND
	POP	P,(P)		;DISCARD FUNCTION
	JRST	.POPJ1##	;RETURN WITHOUT STORE
;+.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

;LOOP OVER THE LIST OF TAPES TO POSITION

SKPLOP:	PUSHJ	P,TAPARG	;GET NEXT TAPE ARGUMENT
	PUSHJ	P,TAPOPN	;OPEN THAT TAPE
	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
SKPLO1:	XCT	T2		;DO THE FUNCTION ONCE
	SOJG	T1,SKPLO1	;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
	RELEAS	F.MTAP,		;FREE THE CHANNEL
	JUMPG	C,SKPLOP	;LOOP TO END OF COMMAND
	JRST	.POPJ1##	;RETURN WITHOUT STORE
	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

;LOOP OVER THE INPUT FILE SPECIFICATIONS

OPERLP:	JUMPLE	C,OPERDO	;END OF LIST, GO DO THE WORK
	PUSHJ	P,.CLSNS##	;CLEAR STICKY DEFAULTS
	PUSHJ	P,.FILIN##	;GET FILE
	PUSHJ	P,ALLSPC	;GO ALLOCATE ROOM FOR A SPEC
	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
	PUSHJ	P,.FILIN##	; AND GET INPUT SPEC
OPRLP1:	PUSHJ	P,ALLSPC	;GO ALLOCATE ROOM FOR A SPEC
	PUSHJ	P,GETSPC	;COPY THE INPUT SPEC
	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:	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

;HERE TO CALL THE WORK MODULE

	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
	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
	RELEAS	F.MTAP,		;RELEASE CHANNEL

	MOVX	T1,PS.VIP	; GET INTERUPT IN PROGRESS FLAG	[201]
	ANDCAM	T1,PSIVCT##+.PSVFL; TURN IT OFF			[201]
	MOVX	T1,PS.FOF	;TURN PSI OFF
	PISYS.	T1,		;EXEC
	  JFCL			;IGNORE ERROR
SEGFLL:	MOVEI	T1,SAVGET	;POINT TO SAVE-GET AREA
	GETSEG	T1,		;GET BACK HIGH SEGMENT
	  JRST	SEGFAL		;DIE IF CAN NOT DO
	MOVSI	17,SAVEAC	;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

DONMSG:	ASCIZ /
"Done
/								;[205]
	RELOC			;SWITCH BACK TO HIGH SEGMENT

OPDOHG:	PUSHJ	P,.TCRLF##	;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.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 <DOWHAT
;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
	PUSHJ	P,OPRSKL	;SKIP TO END OF LINE (ALL COMMANDS
				;  HAVE NO ARGUMENTS)
	JUMPE	T2,OPRCDN	;IF NO COMMAND, JUST END

	PUSH	P,[0]		;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 -- Type KILL to abort run first
\]

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

OPRERR:	CLRBFI			;CLEAR TYPE-AHEAD
	MOVEI	T2,"$"		; IF BATCH JOB, PRECEDE BY $	[202]
	PJOB	T3,		; GET OUR JOB NUMBER		[202]
	HRLI	T3,.GTLIM	; SET FOR BATCH GRTTAB		[202]
	MOVS	T3,T3		; AND CHANGE TO A REAL GETTAB	[202]
	GETTAB	T3,		; SEE IF WE ARE A BATCH JOB	[202]
	 JRST	OPRER1		; ASSUME NOT			[202]
	TXNE	T3,JB.LBT	; ARE WE A BATCH JOB?		[202]
	OUTCHR	T2		; YES - TELL OPR HE GOOFED	[202]
OPRER1:	OUTSTR	(T1)		;OUTPUT MESSAGE			[202]
	POP	P,(P)		;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	CPOPJ1		;NO--GIVE OK RETURN
	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,DOWHAT##	;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.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)
	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)
	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
	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,T4	;NO--CHANGE DEFAULT TO .MYPPN
		 SKIPL	S.OPER	;/SAVE?
		 MOVSI	T2,'DSK';NO--CHANGE DEVICE DEFAULT TO DSK
		 JRST	.+1]	;CONTINUE
	PUSHJ	P,APPSPC	;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
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,T4	;NO--SWITCH DEFAULT PPN TO .MYPPN
		 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 <.MYPPN) 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
	MOVEM	T3,.FXDIR(T1)	;STORE DEFAULT UFD
	CAMN	T3,.MYPPN##	;SEE IF USER UFD
	SETOM	.FXDIM(T1)	; YES--CLEAR WILD CARDS FROM MASK
	MOVSI	T2,'*  '	;SET TO WILD-CARD
APPSFD:	MOVEM	T2,(T4)		;STORE * AS NAME
	SETZM	1(T4)		;SET WILD AS MASK
	AOS	T4		;INCREMENT POSITION
	AOBJN	T4,APPSFD	;LOOP OVER SFDS
	JRST	APPSP3		;APPLY DEFAULTS TO SWITCHS

APPSP1:	MOVE	T2,.FXDIR(T1)	;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:	SKIPG	(T3)		;IF .LE. 0,
	SETOM	(T3)		; SET TO -1 (IGNORE)
	AOBJN	T3,APPSP4	;LOOP OVER SWITCHES
	SETZM	FX$CNT(T1)	;CLEAR COUNT OF MATCHES
	POPJ	P,		;RETURN
;+
;<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
	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	CPOPJ1		;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	CPOPJ1		;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
	LDB	T2,[POINTR (.FXMOM(T1),FX.PRO)];GET /PROTTECTION
	JUMPN	T2,INTER1	;OKAY IF SET
	MOVEI	T2,AD.PRO	;GET DEFAULT
	DPB	T2,[POINTR (.FXMOD(T1),FX.PRO)];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
	ENTER	F.LIST,S.LENT	;YES--ENTER FILE
	  JRST	E$$LFE		;ERROR IF CAN'T ENTER
	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
	RELEAS	F.MTAP,		;FREE THE CHANNEL
	POPJ	P,		;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.SIE	;YES--SET SYNCRONIZE IF ERROR BIT
	TXNE	T1,UU.SIE	;SEE IF SYNCRONIZATION AVAILABLE,
	SKIPL	S.OPER		; AND IF THIS IS A WRITE OPERATION,
	SKIPA			;NO
	TXO	T1,UU.DER	;YES--DISABLE MONITOR ERROR RE-TRY
>;END IFN FT$RCV

	MOVE	T4,S.FRST	;FILE SPEC AREA
	LDB	T3,[POINTR (.FXMOD(T4), FX.DEN)];GET USER SET DENSITY
	DPB	T3,[POINTR (T1, IO.DEN)];SET DENSITY
	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

	MOVEI	T1,NM$TBF*<3+LN$TBF> ;SPACE FOR TAPE BUFFERS
	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

TAPED2:	SETZM	(T2)		;CLEAR USE BITS, ETC.
	MOVSI	T3,LN$TBF+1	;DATA WORDS
	SOJLE	T1,TAPED3	;SEE IF THIS IS LAST BUFFER
	HRRI	T3,LN$TBF+3(T2)	;NO--GET LOC OF NEXT BUF+1
	MOVEM	T3,(T2)		;STORE
	ADDI	T2,LN$TBF+3	;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:	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,.IODMP	;INDICATE DUMP MODE

TAPOPE:	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
	TXNE	T1,DV.MTA	;SEE IF MAG TAPE
	POPJ	P,		;YES--OK
	RELEAS	F.MTAP,		;FREE CHANNEL
E$$DNM::MOVEI	T1,'DNM'	;NO--ERROR
	MOVEI	T2,[ASCIZ \Device not a mag tape\]
	JRST	SCNERR		;ISSUE SCANNING ERROR

;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

;+
;<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
	MOVEM	T1,S.TAPE	;STORE
	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
	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
;+
;<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
	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
;+
;<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
;+
;<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
	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 RETURNS THE BREAK
;CHARACTER IN ^T1, THE SIXBIT WORD IN ^T2, AND A MASK OF THE
;WORD IN ^T3. ^IT ALSO CLOBBERS ^T4.
;-

OPRGSX:	PUSHJ	P,OPRSKB	;SKIP OVER LEADING BLANKS
	MOVE	T4,[POINT 6,T2]	;INITIALIZE POINTER
	SETZB	T2,T3		;CLEAR BOTH WORD AND MASK
OPRGS1:	CAIL	T1,"A"+40	;SEE IF
	CAILE	T1,"Z"+40	; LOWER CASE
	SKIPA			;NO--LEAVE ALONE
	SUBI	T1,40		;YES--CONVERT TO UPPER
	CAIL	T1,"A"		;SEE IF
	CAILE	T1,"Z"		; ALPHABETIC
	POPJ	P,		;NO--RETURN BREAK
	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

;+
;<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]