Google
 

Trailing-Edge - PDP-10 Archives - bb-d868b-bm_tops20_v3a_2020_dist - 3a-sources/dumper.mac
There are 42 other files named dumper.mac in the archive. Click here to see a list.
;<3A.UTILITIES>DUMPER.MAC.8, 17-Aug-78 15:40:43, EDIT BY DBELL
;CHANGE "?" TO "%" IN "NO FILES DUMPED" MESSAGE
;<3A.UTILITIES>DUMPER.MAC.7,  8-Aug-78 17:03:54, Edit by PORCHER
;FIX EXTRANEOUS MESSAGE FOR CONTINUED FILES
;<3A.UTILITIES>DUMPER.MAC.6,  2-Jun-78 09:31:32, Edit by FORTMILLER
;<3A.UTILITIES>DUMPER.MAC.5,  1-Jun-78 13:28:52, Edit by FORTMILLER
; TCO 1891 ADD 6250 BPI
;<3A.UTILITIES>DUMPER.MAC.4, 30-May-78 09:30:24, Edit by PORCHER
;<3A.UTILITIES>DUMPER.MAC.3, 19-May-78 17:16:46, Edit by PORCHER
;ADD CONDITIONALS TO REMOVE NEW FEATURES (BLOCKING FACTOR + INCREMENTAL STUFF
; + UNLOAD) FOR RELEASE 3A
;<4.UTILITIES>DUMPER.MAC.189, 16-May-78 16:22:51, Edit by PORCHER
;TCO # 1910 -- HANDLE ZERO BYTE SIZE CORRECTLY IN INTERCHANGE MODE
;<4.UTILITIES>DUMPER.MAC.188, 10-May-78 16:33:53, Edit by PORCHER
;<4.UTILITIES>DUMPER.MAC.187, 10-May-78 14:39:14, Edit by PORCHER
;TCO # 1909 -- USE SYSTEM DEFAULT ACCOUNT IF TAPE ACCOUNT INVALID ON RESTORE
;MAKE BACKSPACE TO BEGINNING OF TAPE ONLY WARNING ERROR
;<4.UTILITIES>DUMPER.MAC.186, 27-Apr-78 16:58:35, Edit by PORCHER
;FIX BUGS IN /INCREMENTAL: ...
;<4.UTILITIES>DUMPER.MAC.185, 18-Apr-78 11:28:28, Edit by PORCHER
;TCO # 1903 - Add /FULL-INCREMENTAL, /INCREMENTAL:n, no restore of backup words
;<4.UTILITIES>DUMPER.MAC.184, 13-Apr-78 16:06:07, Edit by PORCHER
;MAKE CHECKSUM ERRORS INTERRUPTABLE
;ALLOW FOR "DUMPX3" - BUFFER SIZE TOO BIG
;<4.UTILITIES>DUMPER.MAC.183, 12-Apr-78 13:16:14, Edit by PORCHER
;FIX EXPRESSION FOR MTBUF2 DUE TO MACRO BUG
;<4.UTILITIES>DUMPER.MAC.182,  6-Apr-78 17:33:33, Edit by PORCHER
;MAKE ALL ERRORS TYPE <CR> ONLY IF NOT AT LEFT MARGIN ALREADY
;<4.UTILITIES>DUMPER.MAC.181,  6-Apr-78 17:08:11, Edit by PORCHER
;PUT MTBUF1 AND MTBUF2 ON PAGE BOUNDARY FOR BLOCKING-FACTOR OF 15
;<4.UTILITIES>DUMPER.MAC.180,  6-Apr-78 16:31:25, Edit by PORCHER
;<4.UTILITIES>DUMPER.MAC.179,  3-Apr-78 12:22:13, Edit by PORCHER
;<4.UTILITIES>DUMPER.MAC.178,  3-Apr-78 08:55:45, Edit by PORCHER
;<4.UTILITIES>DUMPER.MAC.177, 31-Mar-78 13:31:15, Edit by PORCHER
;MAKE BEGUSR COPY ENTIRE DIRECTORY NAME STRING
;USE DIRECTORY STRING (WITH WILD CARDS) FROM USER FOR RCDIR ON SAVE
;ALLOW TTY OUTPUT AFTER INTERRUPTED "PRINT TTY:"
;<4.UTILITIES>DUMPER.MAC.176, 31-Mar-78 10:49:14, Edit by PORCHER
;<4.UTILITIES>DUMPER.MAC.175, 31-Mar-78 10:42:24, Edit by PORCHER
;<4.UTILITIES>DUMPER.MAC.174, 31-Mar-78 10:21:55, Edit by PORCHER
;TCO # 1986 - PRINT FILENAME PROPERLY ON RESTORE ERRORS
;<4.UTILITIES>DUMPER.MAC.173, 30-Mar-78 16:27:11, Edit by PORCHER
;<4.UTILITIES>DUMPER.MAC.172, 30-Mar-78 16:19:35, Edit by PORCHER
;UPDATE TO VERSION 4(166)
;MISCELLANEOUS BUG FIXES AND ...
;TCO # 1895 - COPY PROTECTION/ACCOUNT FROM OUTPUT SPEC IN SAVE/RESTORE
;TCO # 1894 - ALLOW JUST DATE IN BEFORE/SINCE COMMANDS
;TCO # 1893 - DON'T ABORT COMMAND IF "FILE NOT FOUND" IN SAVE COMMAND
;TCO # 1892 - AUTO-UNLOAD FOR MULTI-REEL SAVESETS, UNLOAD COMMAND
;<4.UTILITIES>DUMPER.MAC.170, 21-Mar-78 13:26:50, Edit by DBELL
;ALLOW /INCREMENTAL SWITCH IF NOT WHEEL, BUT THEN COMPLAIN
;<4.UTILITIES>DUMPER.MAC.169, 17-Mar-78 16:02:47, Edit by DBELL
;DON'T SET PROTECTION FROM TAPE IF RESTORING IN INTERCHANGE MODE
;<PORCHER>DUMPER.MAC.170, 16-Mar-78 16:25:07, Edit by PORCHER
;TCO # 1891 - CHANGES FOR MULTIPLE RECORD BLOCKING
;<4.UTILITIES>DUMPER.MAC.168, 17-Feb-78 18:05:26, Edit by DBELL
;HANDLE FULL WILDCARDS IN RESTORE COMMAND BY CALLING CHKWLD ROUTINE
;<3-UTILITIES>DUMPER.MAC.167,  8-Nov-77 10:47:04, EDIT BY KIRSCHEN
;MORE COPYRIGHT UPDATING...
;<3-UTILITIES>DUMPER.MAC.166, 26-Oct-77 11:01:28, EDIT BY KIRSCHEN
;UPDATE COPYRIGHT FOR RELEASE 3
;<3-UTILITIES>DUMPER.MAC.165,  5-Aug-77 14:08:39, Edit by HESS
;<3-UTILITIES>DUMPER.MAC.164,  5-Aug-77 11:56:43, Edit by HESS
;CORRECT RCDIR WITH INITIAL FILESPEC, FIX CRDIR RESTORE LOGIC AT
;LODUSR, FIX HEADER CHECK FOR CONTINUED FILES
;<3-UTILITIES>DUMPER.MAC.163, 22-Jul-77 12:06:01, Edit by HESS
;<3-UTILITIES>DUMPER.MAC.162, 22-Jul-77 10:40:31, Edit by HESS
;<3-UTILITIES>DUMPER.MAC.161, 21-Jul-77 17:06:46, Edit by HESS
;CHANGES FOR NEW CRDIR FORMAT, RCDIR FOR DIRECTORY DUMPING
;<3-UTILITIES>DUMPER.MAC.160, 19-Jul-77 18:32:32, EDIT BY HURLEY
;MAKE DUMPER NOT CHANGE EXISTING DIR PARAMETERS ON CRDIR'S
;<3-UTILITIES>DUMPER.MAC.159, 17-Jun-77 11:26:47, EDIT BY HURLEY
;MAKE CLOSING OF FILES UPDATE THE DIRECTORY
;<3-UTILITIES>DUMPER.MAC.158, 14-Jun-77 11:59:21, EDIT BY BOSACK
;TCO 1817 - FIX ILL MEM READ DUMPING SPARSE FILES
;<3-UTILITIES>DUMPER.MAC.157, 20-May-77 11:50:58, Edit by HESS
;TCO 1801 - ALLOW SPECIFYING NON-EX STR NAME ON RESTORE
;<3-UTILITIES>DUMPER.MAC.156, 12-Apr-77 15:05:11, Edit by LCAMPBELL
;TCO 1778 - Fix PDL overflow in INTERCHANGE mode
;<3-UTILITIES>DUMPER.MAC.155, 12-Apr-77 13:51:54, Edit by HESS
;FIRST RELEASE 3 VERSION (FIX TO BATCH PROBLEM)
;<2-UTILITIES>DUMPER.MAC.154, 21-Feb-77 10:14:52, Edit by HESS
;MORE ON TCO 1682 (FOR -1 GENERATION IN OUTPUT SPEC)
;<2-UTILITIES>DUMPER.MAC.153, 10-Feb-77 13:34:37, Edit by HESS
;TCO 1732 - FIX TO ^E ABORT (DLTOLD)
;<2-UTILITIES>DUMPER.MAC.152, 27-Dec-76 17:05:39, EDIT BY HURLEY
;<2-UTILITIES>DUMPER.MAC.151, 13-Dec-76 10:34:20, Edit by HESS
;TCO 1682 - MAKE FILE SPLIT ACROSS TAPE REELS WORK IN ALL CASES.
;<2-UTILITIES>DUMPER.MAC.150,  8-Dec-76 09:49:29, Edit by HESS
;TCO 1680 - WRITE ERROR RECOVERY ALLOWED
;MINOR BUG FIXES
;<2-UTILITIES>DUMPER.MAC.149,  2-Dec-76 08:56:49, Edit by HESS
;DONT PRINT DIRST/SFUST FAILURES IF DIRECTORY DOESN'T EXIST
;<2-UTILITIES>DUMPER.MAC.148,  1-Dec-76 13:05:38, Edit by HESS
;<2-UTILITIES>DUMPER.MAC.147, 30-Nov-76 16:08:25, Edit by HESS
;<2-UTILITIES>DUMPER.MAC.146, 29-Nov-76 11:19:21, Edit by HESS
;<2-UTILITIES>DUMPER.MAC.145, 29-Nov-76 10:58:12, Edit by HESS
;TCO 1670 - JFN STACK AND COMMAND BUFFER EXPANDED
;   FIX DIRECTORY RESTORE TO WORK ON MULTIPLE STRS
;<2-UTILITIES>DUMPER.MAC.144, 29-Oct-76 08:45:54, Edit by HESS
;INTERCHANGE MODE NEEDS TO LOOK AT PRE-FAULT BUFFERS
;<2-UTILITIES>DUMPER.MAC.143, 26-Oct-76 11:50:54, Edit by HESS
;<2-UTILITIES>DUMPER.MAC.142, 26-Oct-76 10:59:01, Edit by HESS
;Fix SETTRP calls to handle errors better
;<2-UTILITIES>DUMPER.MAC.141, 21-Oct-76 09:14:22, Edit by HESS
;EXCHANGE AUTHOR/LAST-WRITER STRINGS IN BUFFER
;<2-UTILITIES>DUMPER.MAC.140, 20-Oct-76 09:38:12, Edit by HESS
;<2-UTILITIES>DUMPER.MAC.139, 19-Oct-76 18:33:13, Edit by HESS
;<2-UTILITIES>DUMPER.MAC.138, 19-Oct-76 18:09:55, Edit by HESS
;TCO 1608 - DUMPER SPEEDUP CHANGES
;<2-UTILITIES>DUMPER.MAC.137, 18-Oct-76 14:30:33, Edit by HESS
;MORE CORRECTIONS TO HANDLE DEV:<DIR> STRINGS , GFUST BUG
;<KOHN>DUMPER.MAC.135,  6-Oct-76 09:49:27, Edit by KOHN
;TCO #1569-DON'T PRINT PARTIAL FILE SKIPPED MESSAGE IF FILE
;NOT OF INTEREST
;<2-UTILITIES>DUMPER.MAC.131,  5-Oct-76 15:22:30, Edit by HESS
;<2-UTILITIES>DUMPER.MAC.130,  5-Oct-76 14:02:26, Edit by HESS
;CHANGE TO HANDEL 36-BIT DIRECTORY NUMBERS
;<KOHN>DUMPER.MAC.128, 27-Sep-76 19:04:13, Edit by KOHN
;TCO #1501-ADD GFUST AND SFUST JSYS'S
;TCO #1500-FIX ZERO LENGTH INTERCHANGE FORMAT FILE PROBLEM
;TCO #1499-FIX CHECK TO STOP AT EOF FOR INTERCHANGE FORMAT
;<1B-UTILITIES>DUMPER.MAC.100, 21-Jun-76 15:50:51, Edit by KOHN
;TCO 1448-MAKE DUMPER APPEND TO THE LIST FILE
;<1B-UTILITIES>DUMPER.MAC.96,  7-JUN-76 16:06:45, Edit by KOHN
; TCO #1360 CHANGE SET TAPE NUMBER COMMAND WORDING 
;<1B-UTILITIES>DUMPER.MAC.93,  7-JUN-76 13:44:56, Edit by KOHN
;<1B-UTILITIES>DUMPER.MAC.92,  7-JUN-76 13:42:27, Edit by KOHN
;TCO #1351-PUT IN REENTER ADDRESS
;TCO #1350-DON'T REPORT FILE TRAILER MISSING FOR INTERCHANGE FORMAT
;<1B-UTILITIES>DUMPER.MAC.89,  3-JUN-76 21:57:12, Edit by KOHN
;TCO #1349-BACKSPACE OVER TAPE TRAILER AFTER PRINT COMMAND
;TCO #1348-FIX PRINT SO IT PRINTS FILE NAMES AGAIN
;TCO # 1338-TYPE FILE NAMES WITH PARTIAL FILE MESSAGES
;TCO #1336-DIRECTORY NAMES NOT GETTING PRINTED FOR A RESTORE
;TCO #1329-PICKING UP ONLY RIGHT HALF OF .FBSIZ WORD IN FDB
;TCO #1328-CHECKSUMS FOR FILES THAT CROSS TAPE BOUNDARIES DON'T WORK
;TCO #1327-JFN'S PILING UP IF USER TYPES INVALID ANSWER TO TAPE NEEDED
;TCO #1326-NOT RESETTING TAPE NO. IF GET OUT OF SEQUENCE TAPE
;<1B-UTILITIES>DUMPER.MAC.71, 25-MAY-76 16:28:48, Edit by KOHN
;TCO #1319-FIX BUG INTRODUCED BY TCO #1301
;TCO #1318-ADD "SET TAPE NUMBER" COMMAND
;TCO #1317-FIX BUG IN RENAME UNDER SAVE 
;<1B-UTILITIES>DUMPER.MAC.67, 21-MAY-76 12:07:07, Edit by KOHN
;TCO #1296-TAKE OUT THE REWIND AFTER THE PRINT COMMAND
;<1B-UTILITIES>DUMPER.MAC.66, 19-MAY-76 14:08:17, Edit by KOHN
;MERGE 1A SOURCE AND 1B SOURCE
;<1B-UTILITIES>DUMPER.MAC.65, 19-MAY-76 14:07:10, Edit by KOHN
;TCO #1301-MESSAGES FOR LOG FILE WHEN FILE BROKEN ACROSS REELS
;TCO #1300-FIX JFNLST BUG INTRODUCED UNDER ^E FIXUP
;<1B-UTILITIES>DUMPER.MAC.57, 17-MAY-76 15:21:04, Edit by KOHN
;TCO #1299-PUT IN RECOGNITION FOR RENAME ON RESTORE
;TCO #1298-ADD RENAME ON SAVE
;TCO #1297-FIX BUGS HAVING TO DO WITH LTTYF BEING LEFT ON
;<1B-UTILITIES>DUMPER.MAC.48,  6-MAY-76 18:58:51, Edit by KOHN
;TCO #1295-MORE INFORMATION IN SAVE SET TRAILER FOR INTERCHANGE FORMAT
;<1B-UTILITIES>DUMPER.MAC.45,  4-MAY-76 23:30:15, Edit by KOHN
;TCO #1279-INTERCHANGE RESTORE FDB INFORMATION GETTING CLOBBERED
;<1B-UTILITIES>DUMPER.MAC.43,  4-MAY-76 16:59:37, Edit by KOHN
;TCO #1278-IF LOG FILE IS TO DISK, CLOSE AFTER EACH DIRECTORY DUMPED
;TCO #1277-CHANGE INITIAL COMMAND TO CONTINUE SAVE SET
;<1B-UTILITIES>DUMPER.MAC.39, 27-APR-76 17:24:17, Edit by KOHN
;TCO #1264-FIX SAVING FILES ACROSS REELS.
;TCO #1263-DIFFERENTIATE BETWEEN END OF TAPE AND END OF SAVESET
;TCO #1261 MAKE 'NO LIST' THE DEFAULT
;<1B-UTILITIES>DUMPER.MAC.34, 26-APR-76 16:46:22, Edit by KOHN
;<KOHN>D.MAC.3, 26-APR-76 16:30:53, Edit by KOHN
;TCO #1260- MAKE DUMPER DO CFIBF WHEN COMMAND BOMBS
;<1B-UTILITIES>DUMPER.MAC.31, 26-APR-76 15:35:19, Edit by KOHN
;TCO #1259-MORE JFN CLEAN UP
;<1B-UTILITIES>DUMPER.MAC.27, 26-APR-76 13:36:57, Edit by KOHN
;TCO #1258-PUT IN CHECKSUM COMMAND
;<1A-UTILITIES>DUMPER.MAC.24,  6-MAY-76 10:41:52, EDIT BY HURLEY
;<1B-UTILITIES>DUMPER.MAC.21, 13-APR-76 17:49:23, Edit by KOHN
;TCO #1251 -MAKE CHECK PRINT FILE NAMES UNDER 'FILES'
;<1A-UTILITIES>DUMPER.MAC.18, 23-APR-76 15:56:49, Edit by KOHN
;TCO #1257-FIX PAGE COUNT FOR PRINT COMMAND IN INTERCHANGE FORMAT
;<1A-UTILITIES>DUMPER.MAC.15,  2-APR-76 17:13:57, Edit by KOHN
;TCO # 1236 -CHANGE MESSAGE UNDER ^E.
;<1A-UTILITIES>DUMPER.MAC.12, 31-MAR-76 14:52:34, EDIT BY HURLEY
;<1A-UTILITIES>DUMPER.MAC.11, 31-MAR-76 14:50:13, EDIT BY HURLEY
;TCO # 1228 - MAKE DUMPER ASSEMBLE WITH MACRO 50
;<1A-UTILITIES>DUMPER.MAC.10, 31-MAR-76 10:17:53, EDIT BY HURLEY
;TCO # 1227 - ADD TOPS-20 ENTRY VECTOR AND VERSION NUMBER
;<V-SOURCES>DUMPER.MAC.9, 25-MAR-76 15:47:32, Edit by KOHN
;TCO #1221- FIX JFN AND PAGE 600 PROBLEMS
;<KOHN>DUMPER.MAC.14, 16-MAR-76 16:02:53, Edit by KOHN
;FIX REPARSE PROBLEM CONCERNING JFN RELEASE TCO 1187
;<V-SOURCES>DUMPER.MAC.4,  5-MAR-76 17:24:59, EDIT BY MURPHY
;<MURPHY>DUMPER.MAC.7, 10-FEB-76 12:14:30, EDIT BY MURPHY
;<MURPHY>DUMPER.MAC.3,  6-FEB-76 23:05:07, EDIT BY MURPHY
;FIX RESTORE OVER DELETED FILE
;NUMEROUS BUG FIXES
;<MURPHY>DUMPER.MAC.1,  2-FEB-76 18:39:43, EDIT BY MURPHY
;INSTALL 36-BIT MODE
;<V-SOURCES>DUMPER.MAC.5,  9-JAN-76 11:26:47, EDIT BY MURPHY
	TITLE DUMPER



;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1976, 1977, 1978 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.

	SEARCH MONSYM,MACSYM
	SALL
	.REQUIRE SYS:MACREL
	IFNDEF .PSECT,<
		.DIRECT .XTABM>
	IFDEF .PSECT,<
	.DIRECT FLBLST>

; VERSION NUMBER DEFINITIONS

VMAJOR==3		;MAJOR VERSION OF DUMPER
VMINOR==1		;MINOR VERSION NUMBER
VEDIT==172		;EDIT NUMBER
VWHO==0			;GROUP WHO LAST EDITED PROGRAM (0=DEC DEVELOPMENT)

VDUMPR== <VWHO>B2+<VMAJOR>B11+<VMINOR>B17+VEDIT

	SUBTTL STORAGE AND DEFINITIONS

FMTV1==1
FMTV2==2
FMTV3==3		;RELEASE 2 (FDB CHANGES, STRUCTURES, ETC.)
FMTV4==4		;RELEASE 3 (NEW GTDIR BLOCKS)
CURFMT==FMTV4			;DATA FORMAT TO WRITE

USRLH==500000			;THIS IS TO IDENTIFY A USER
				;NUMBER. IF THE MONITOR 
				;CHANGES THE DEFINITION, IT 
				;MUST CHANGE HERE

F=0
A=1
B=2
C=3
D=4
Q1=5
Q2=6
Q3=7
P1=10
P2=11
P3=12
P4=13
P5=14
P6=15
CX=16
P=17
PGSIZ==1000			;PAGE SIZE

OPDEF CALL [PUSHJ P,0]
OPDEF RET [POPJ P,0]
OPDEF CALLRET [JRST]

DEFINE RETSKP <
	JRST RSKP>

DEFINE SAVPQ <
	JSP CX,.SAV8##>

DEFINE SAVEQ <
	JSP CX,.SAV3##>


;FLAGS IN F

NOFLG==1B0			;'NO' PRECEDED COMMAND
USRDAT==1B1			;DUMP/LOAD USER DATA
T36MOD==1B2			;36-BIT TAPE MODE
DIRCHG==1B3			;OUTPUT DIRECTORY NOT SAME AS
				;INPUT DIRECTORY
TNSF==1B4			;TAPE NUMBER SET FLAG
LRERR==1B5			;LAST RECORD HAD AN UNRECOVERABLE ERROR
SAVUSF==1B6			;WE SHOULD SAVE USER DATA IF SET
DMPFLF==1B7			;(SAVE) WE HAVE FOUND A VALID JFN TO DUMP

TF1==1B9			;TEMP FLAGS FOR LOCAL USE
TF2==1B10			;FILE CONTINUED ON NEXT REEL			

LFDSK==1B11			;LOG FILE NOT DISK
ICMT1==1B12			;INTERCHANGE MODE - REPEAT LAST RECORD
ICMODF==1B13			;USE INTERCHANGE MODE TAPE FORMAT
LDIRF==1B14			;LIST DIRECTORIES WHILE RUNNING
LFILF==1B15			;LIST FILES WHILE RUNNING
LTTYF==1B16			;LOG FILE IS TTY
LREOF==1B17			;LAST RECORD READ WAS EOF

SSA==1B18			;SUPERSEDE ALWAYS
SSN==1B19			;SUPERSEDE NEVER
RESPRO==1B20			;RESTORE PROTECTION FROM TAPE
RESACC==1B21			;RESTORE ACCOUNT FROM TAPE
CHKSM==1B23			;CHECKSUMMING
CS%SEQ==1B24			;SEQUENTIAL CHECKSUMMING

;INTERRUPT CHANNELS

CECHN==1			;^E
;FORMAT OF HEADER PORTION OF RECORD

XCKSUM==0			;CHECKSUM
XACC==1				;ACCESS
XTAPNO==2			;TAPE NUMBER
XPAGNO==3			;PAGE NUMBER
XTYP==4				;RECORD TYPE
XSEQ==5				;RECORD SEQUENCE
NHEAD==6			;HEADER SIZE

NIHEAD==^D32			;HEADER SIZE, INTERCHANGE FORMAT

MXHEAD==NHEAD			;SET MAX (NHEAD, NIHEAD)
 IFG NIHEAD-MXHEAD,<MXHEAD==NIHEAD>

MAXBKF==^D15			;MAXIMUM BLOCKING FACTOR
DEFBKF==^D1			;DEFAULT BLOCKING FACTOR

MTBFSZ==<<NHEAD+PGSIZ>*MAXBKF>+1 ;SIZE OF PHYSICAL RECORD BUFFERS
 IFG <MXHEAD+PGSIZ+1>-MTBFSZ,<MTBFSZ==MXHEAD+PGSIZ+1>
				;(THE EXTRA 1 IS TO FORCE RECORD LENGTH ERROR
				; ON READING TO DETERMINE BLOCKING FACTOR)


;LOCATIONS IN UPPER ADR SPACE

N.JFN==2*PGSIZ			;DOUBLE LENGTH BUFFER (JFNSTK)
CBFSIZ==2*PGSIZ			;2 PAGES (CBFR)
NJFNL==PGSIZ			;(JFNLST & JF2LST)

JFNLST=500000			;LIST OF JFNS FOR CURRENT COMMAND
JF2LST=501000			;LIST OF DEST JFNS, PARALLEL TO JFNLST
JFNSTK=502000			;JFN STACK FOR REPARSE (2 PAGES)
CBFR=504000			;2 PAGE LINE BUFFER FOR COMMAND

MTBUF1=506000			;ALTERNATING BUFFERS FOR MAGTAPE I/O
MTBUF2=<MTBUF1+MTBFSZ+777>&<^-777> ; . .

BUFF=600000
BUFPAG==<BUFF>B44
 IFL BUFF-<<MTBUF2+MTBFSZ+777>&<^-777>>,<PRINTX ? MTBUF2 OVERLAPS BUFF>

BUFF2=601000
BF2PAG==<BUFF2>B44

BUF0==602000		;FILE WINDOW
BUF0PG==<BUF0>B44	;PAGE NUMBER OF SAME

XBUFF=BUFF-NHEAD		;BUFFER ORIGIN
CHKSUM=XBUFF+XCKSUM
ACCESS=XBUFF+XACC
TAPNO=XBUFF+XTAPNO
PAGNO=XBUFF+XPAGNO
TYP=XBUFF+XTYP
SEQ=XBUFF+XSEQ
;RECORD TYPE CODES

DATAX==0			;DATA RECORD
TPHDX==1			;TAPE HEADER
FLHDX==2			;FILE HEADER
FLTRX==3			;FILE TRAILER
TPTRX==4			;TAPE TRAILER
USRX==5				;USER BLOCK
CTPHX==6			;CONTINUED SAVE
FILLX==7			;FILLER RECORD

;NUMBER OF ERROR RETRIES FOR MTA

NRETRY==^D40

;LISTING FORMAT PARAMETERS

FLCOL==^D5			;COLUMN FOR FILE NAME
WTCOL==^D60			;COLUMN FOR WRITE DATE
SIZCOL==^D80			;COLUMN FOR SIZE
CSCOL==^D100			;COLUMN FOR CHECKSUM
PAGLEN==^D58			;LINES PER LISTING PAGE

;FORMAT OF RECORDS ON TAPE
;TAPE HEADER

BFMSGP==1			;PTR TO SAVE SET NAME
BFTAD==2			;TAD OF SAVE
BFMSG==3			;SAVE SET NAME

;FILE HEADER

FHNAM==0			;FILE NAME
FHFDB==200			;FDB

;DIRECTORY INFORMATION BLOCK

UHNAM==40			;NAME STRING
UHPSW==60			;PASSWORD STRING
UHACT==100			;ACCOUNT STRING
UGLEN==200			;USER/DIRECTORY GROUP LENGTH
CDUG==200			;USER GROUPS
CDDG==400			;DIRECTORY GROUPS
CDSG==600			;SUBDIRECTORY GROUPS

;FILE NAME PUNCTUATION

DEVPCT==":"			;DEVICE
DIRBP=="<"			;DIRECTORY BEGIN
DIREP==">"			;DIRECTORY END
EXTPCT=="."			;EXTENSION
GENPCT=="."			;GENERATION
ATTPCT==";"			;ATTRIBUTE
	SUBTTL INTERCHANGE FORMAT DEFINITIONS

BKFMT==1			;FORMAT VERSION NUMBER (CONSTANT)

;RECORD TYPES

T$LBL==1			;LABEL IDENTIFICATION RECORD
T$BEG==2			;SAVE START
T$END==3			;SAVE END
T$FIL==4			;DISK FILE DATA
T$UFD==5			;UFD RIB
T$EOV==6			;END OF VOLUME
T$COM==7			;COMMENT
T$CON==10			;CONTINUE (SAME DATA AS T$BEG-T$END)
T$MAX==T$CON			;MAXIMUM RECORD TYPE

;STANDARD RECORD

G$TYPE==0			;RECORD TYPE
G$SEQ==1			;SEQUENCE NUMBER
G$RTNM==2			;RELATIVE TAPE NUMBER
G$FLAG==3			;RECORD DEPENDENT BITS
 GF$EOF==1B0			;LAST RECORD OF FILE
 GF$RPT==1B1			;REPEAT OF LAST RECORD WRITE ERROR
 GF$NCH==1B2			;IGNORE CHECKSUM
 GF$SOF==1B3			;START OF FILE
G$CHK==4			;CHECKSUM
G$SIZ==5			;NUMBER OF DATA WORDS
G$LND==6			;TOTAL LENGTH OF NON-DATA SECTION
G$CUSW==13			;RESERVED FOR CUSTOMER USE

;O$FILE/A$FLGS

B$PERM==1B0			;PERMANENT
B$TEMP==1B1			;TEMPORARY
B$DELE==1B2			;ALREADY DELETED
B$DLRA==1B3			;DON'T DELETE FOR LACK OF RECENT ACCESS
B$NQCF==1B4			;NOT QUOTA CHECKED
B$NOCS==1B5			;DOES NOT HAVE VALID CHECKSUMS
B$CSER==1B6			;HAS CHECKSUM ERROR
B$WRER==1B7			;HAS DISK WRITE ERROR
B$MRER==1B8			;HAD <BACKUP READ ERROR ON RESTORE
B$DAER==1B9			;DECLARED BAD BY DAMAGE ASSESMENT

;O$FILE BLOCK

A$FHLN==0			;HEADER LENGTH WORD
A$FLGS==1			;FLAGS
A$WRIT==2			;CREATION DATE/TIME
A$ALLS==3			;ALLOCATED SIZE
A$MODE==4			;MODE
A$LENG==5			;LENGTH
A$BSIZ==6			;BYTE SIZE
A$VERS==7			;VERSION
A$PROT==10			;PROTECTION
A$ACCT==11			;BYTE POINTER ACCOUNT STRING
A$NOTE==12			;BYTE POINTER TO ANONOTATION STRING
A$CRET==13			;CREATION DATE/TIME OF THIS GENERATION
A$REDT==14			;LAST READ DATE/TIME OF THIS GENERATION
A$MODT==15			;MONITOR SET LAST WRITE DATE/TIME
A$ESTS==16			;ESTIMATED SIZE IN WORDS
A$RADR==17			;REQUESTED DISK ADDRESS
A$FSIZ==20			;MAXIMUM FILE SIZE IN WORDS
A$MUSR==21			;BYTE POINTER TO ID OF LAST MODIFIER
A$CUSR==22			;BYTE POINTER TO ID OF CREATOR
A$BKID==23			;BYTE POINTER TO SAVE SET OF PREVIOUS <BACKUP
A$BKDT==24			;DATE/TIME OF LAST BACKUP
A$NGRT==25			;NUMBER OF GENERATIONS TO RETAIN
A$NRDS==26			;NBR OPENS FOR READ THIS GENERATION
A$NWRT==27			;NBR OPENS FOR WRITE THIS GENERATION
A$USRW==30			;USER WORD
A$PCAW==31			;PRIVILEGED CUSTOMER WORD
LN$AFH==32			;LENGTH OF FIXED HEADER

;PROTECTION FIELDS

AC$OWN==377B19			;OWNER ACCESS FIELD
AC$GRP==377B27			;AFFINITY GROUP ACCESS FIELD
AC$WLD==377B35			;WORLD ACCESS FIELD
PR$ATR==7B31			;ATTRIBUTE PROTECTION SUBFIELD
PR$WRT==3B33			;WRITE PROTECTION SUBFIELD
PR$RED==3B35			;READ PROTECTION SUBFIELD

;O$DIRT/D$FLGS

DF$FOD==1B0			;FILES ONLY DIRECTORY
DF$AAL==1B1			;ALPHA ACCOUNTS ARE LEGAL
DF$RLM==1B2			;REPEAT LOGIN MESSAGES

;O$DIRT BLOCK

D$FHLN==0			;FIXED HEADER LENGTH WORD
D$FLGS==1			;DIRECTORY FLAGS
D$ACCT==2			;ACCOUNT NUMBER
D$PROT==3			;DIRECTORY PROTECTION
D$FPRT==4			;DEFAULT FILE PROTECTION
D$LOGT==5			;LOGIN DATE/TIME
D$GENR==6			;NUMBER GENERATIONS TO KEEP
D$QTF==7			;LOGGED-IN QUOTA
D$QTO==10			;LOGGED-OUT QUOTA
D$ACSL==11			;ACCESS LIST
D$USRL==12			;USER LIST
D$PRVL==13			;PRIVILEGE LIST
D$PSWD==14			;PASSWORD
LN$DFH==15			;LENGTH OF DIRECTORY FIXED HEADER

;NON-DATA BLOCK TYPES

O$NAME==1			;FULL PATH NAME BLOCK
O$FILE==2			;FILE ATTRIBUTE BLOCK
O$DIRT==3			;DIRECTORY ATTRIBUTE BLOCK
O$SYSN==4			;SYSTEM HEADER BLOCK
O$SSNM==5			;SAVE SET NAME BLOCK

;T$LBL RECORD

L$DATE==14			;DATE/TIME OF LABELING
L$FMT==15			;BACKUP FORMAT
L$BVER==16			;BACKUP VERSION
L$MON==17			;MONITOR TYPE
L$SVER==20			;SYSTEM VERSION
L$APR==21			;APR SERIAL NUMBER WRITING LABEL
L$DEV==22			;DEVICE ID WRITING LABEL
L$MTCH==23			;TAPE WRITE PAREMETERS
L$RLNM==24			;SIXBIT TAPE REEL NAME
L$DSTR==25			;DATE/TIME FOR DESTRUCTION
L$CUSW==37			;RESERVED CUSTOMER WORD

;T$BEG, T$END, T$CON RECORDS

S$DATE==14			;DATE/TIME OF START/END OF SAVE
S$FMT==15			;RETRIEVAL VERSION
S$BVER==16			;BACKUP VERSION
S$MON==17			;MONITOR TYPE
S$SVER==20			;SYSTEM VERSION
S$APR==21			;APR SERIAL NUMBER
S$DEV==22			;DEVICE ID WRITING SAVE SET
S$MTCH==23			;TAPE WRITE PARAMETERS
S$RLNM==24			;REELID
S$CUSW==37			;CUSTOMER WORD

;T$UFD RECORD

D$PCHK==14			;PATH CHECKSUM
D$LVL==15			;UFD LEVEL (UFD=0, SFD1=1, ETC.)
D$STR==16			;STRUCTURE OF UFD ( MAX OF 12(10) WORDS )
D$CUSW==37			;CUSTOMER WORD

;T$FIL RECORD

F$PCHK==14			;PATH CHECKSUM
F$RDW==15			;RELATIVE DATA WORD OF FILE
F$PTH==16			;START OF PATH BLOCK
LN$PTH==14			;LENGTH OF F$PTH BLOCK
F$CUSW==37			;RESERVED CUSTOMER WORD

F$NND==400			;LENGTH OF NON-DATA PORTION OF FIRST RECORD

;T$FIL/O$NAME SUB-BLOCK TYPES

.FCDEV==1			;DEVICE
.FCNAM==2			;FILE NAME
.FCEXT==3			;EXTENSION
.FCVER==4			;VERSION
.FCGEN==5			;GENERATION
.FCDIR==40			;DIRECTORY
.FCSF1==41			;FIRST SFD
.FCSF2==42			;SECOND SFD
	SUBTTL STORAGE

;BUFFERS NOT CLEARED AT STARTUP

ICOBUF:	BLOCK PGSIZ+NHEAD	;CONVERSION OUTPUT BUFFER

;STORAGE CLEARED AT STARTUP

STGBGN:				;BEGINNING OF STORAGE CLEARED AT STARTUP

CURBUF:	BLOCK 1			;CURRENT OUTPUT BUFFER
FORMAT:	BLOCK 1			;DATA FORMAT
MTBUFF:	BLOCK 1			;BUFFER SWITCH
MTBPTR:	BLOCK 1			;ADDRESS OF CURRENT LOGICAL RECORD WITHIN
				; MTBUF1 OR MTBUF2
MTRACT:	BLOCK 1			;READ-AHEAD REQUEST ISSUED
SETBKF:	BLOCK 1			;LAST BLOCKING-FACTOR SET
TAPBKF:	BLOCK 1			;BLOCKING-FACTOR OF CURRENT TAPE
BLKCNT:	BLOCK 1			;DOWN-COUNTER FOR LOGICAL RECORDS BLOCKED
				; WITHIN EACH PHYSICAL RECORD
NAMBUF:	BLOCK 100		;FULL FILESPEC FOR FILE BEING DUMPED
ONMBUF: BLOCK 100		;FULL SPEC FOR FILE NAME GOING ON TAPE
IPDLP:	BLOCK 1			;PDL POINTER AT INTERUPT TIME
TPDLP:	BLOCK 1			;TEMP PDL POINTER
PDLP:	BLOCK 1			;STACK PTR AT TOP OF COMMAND
NPDL==100
PDL:	BLOCK NPDL		;MAIN FORK STACK
INIPTR:	BLOCK 1			;INITIAL JFN STACK POINTER
CMDPTR:	BLOCK 1			;TOP OF COMMAND POINTER
RPSPTR:	BLOCK 1			;REPARSE JFN STACK POINTER
CURPTR:	BLOCK 1			;CURRENT JFN STACK POINTER
NLINB==40
LINBUF:	BLOCK NLINB		;RDTTY LINE BUFFER

;COMND STORAGE

ACBSIZ==^D200/5			;SIZE OF ATOM BUFFER
ACBFR:	BLOCK ACBSIZ
CBLK:	BLOCK .CMGJB+1		;COMMAND STATE BLOCK
GJBLK:	BLOCK .GJBFP+1		;GTJFN ARG BLOCK

;COMMAND TYPE INFORMATION.  

CMDTYP:	BLOCK 1			;CURRENT COMMAND TYPE HERE
TY%NOC==1B0		;NO-CONTINUE COMMAND
TY%RPO==1B1		;STACK JFNS FOR REPARSE ONLY
TY%MAP==1B2		;COMMAND MAPS BUFPAG
TY%DBL==1B3		;COMMAND USES JFNLST


;STORAGE FOR GTJFN DEFAULT STRINGS

DEFDEV:	BLOCK 20		;DEFAULT DEVICE
DEFDIR:	BLOCK 20		;DEFAULT DIRECTORY
DEFNAM:	BLOCK 20		;DEFAULT NAME
DEFEXT:	BLOCK 20		;DEFAULT EXTENSION
DEFVER:	BLOCK 20		;DEFAULT VERSION
DEFPRO:	BLOCK 20		;DEFAULT PROTECTION
DEFACC:	BLOCK 20		;DEFAULT ACCOUNT
NIJFN:	BLOCK 1			;SAVED JFNLST PTR IN CASE OF INTERRUPT
NJFN:	BLOCK 1			;NUMBER OF JFNS IN JFNLST IN USE
NJFN1:	BLOCK 1			;NUMBER ACTIVE JFNS STILL IN LIST
NSSNBF==^D140/5			;SIZE OF SAVE SET NAME BUFFER
SSNBUF:	BLOCK NSSNBF		;SAVE SET NAME BUFFER
MTDSG:	BLOCK 1			;DESIGNATOR FOR SPECIFIED MAGTAPE
NAMPTR:	BLOCK 1			;POINTER TO NAME FIELD OF NAMBUF
ONMPTR: BLOCK 1			;POINTER TO NAME FIELD OF ONMBUF
OGNPTR:	BLOCK 1			;POINTER TO GENERATION NUMBER IN ONMBUF
OACPTR:	BLOCK 1			;POINTER TO ACCOUNT FIELD IN ONMBUF
NOFILS:	BLOCK 1			;NUMBER FILES DUMPED THIS DIRECTORY
TOTFIL:	BLOCK 1			;NUMBER FILES DUMPED ALL DIRECTORIES
WHEEL:	BLOCK 1			;NON-0 IF BEING RUN WITH WHEEL STATUS
DIRNUM:	BLOCK 1			;DIRECTORY NUMBER CURRENT DUMP DIRECTORY
RCDNUM:	BLOCK 1			;DIRECTORY NUMBER FOR RCDIR STEPPING
RCDSTR:	BLOCK 12		;STR:<*> STRING FOR RCDIR
SCNJFN:	BLOCK 1			;CURRENT JFN FOR DUMP SCAN
MTDEV:	BLOCK 2			;NAME STRING FOR SPECIFIED MTA
DENSIT:	BLOCK 1			;SPECIFIED MTA DENSITY
PARITY:	BLOCK 1			;SPECIFIED MTA PARITY
LASTID:	BLOCK 1			;ID OF CURRENT DUMP PAGE FOR ERROR PSI
LSTERO:	BLOCK 1			;LAST ID REPORTED BY PSI

INT1AC:	BLOCK 20		;INT LEVEL 1 ACS
INT2AC:	BLOCK 20		;INT LEVEL 2 ACS
INT3AC:	BLOCK 20		;INT LEVEL 3 ACS
NINTPD==30			;SIZE OF INT STACKS
INT1PD:	BLOCK NINTPD		;INT LEVEL 1 STACK
INT2PD:	BLOCK NINTPD		;INT LEVEL 2 STACK
INT3PD:	BLOCK NINTPD		;INT LEVEL 3 STACK
LPC1:	BLOCK 1			;PSI PC'S
LPC2:	BLOCK 1
LPC3:	BLOCK 1
EINT1:	BLOCK 2			;JSR ENTRY
INTRQ:	BLOCK 1			;INTERRUPT REQUEST FLAG
INTPC:	BLOCK 1			;INTERRUPT PC
ICMDTY: BLOCK 1			;INTERRUPTED COMMAND TYPE
CEXFLG:	BLOCK 1			;COMMAND IN EXECUTION FLAG
TRAPJ:	BLOCK 1			;TRAP RECOVERY JUMP ADDRESS
TRAPSP:	BLOCK 1			;TRAP RECOVERY STACK FENCE
ITRAPJ: BLOCK 1			;INTERRUPTED TRAP RECOVERY
ITRAPS: BLOCK 1			;...
RTAPNO:	BLOCK 1			;EXPECTED TAPE NUMBER OF READ
RSEQ:	BLOCK 1			;EXPECTED SEQ NUMBER ON READ
TAPLFT:	BLOCK 1			;SET TO 0 WHEN EOT MARK ENCOUNTERED
CNTR:	BLOCK 1			;PAGES THIS FILE REMAINING TO BE DUMPED
USRCNT:	BLOCK 1			;COUNT OF PAGES THIS DIR
TOTCNT:	BLOCK 1			;COUNT OF PAGES ALL DIRS
CDIRN:	BLOCK 1			;CONNECTED DIRECTORY NUMBER
CHECK:	BLOCK 1			;NON-0 IF CHECKING, 0 IF LOADING
LPTJFN:	BLOCK 1			;JFN FOR LISTING FILE
LSTFIL:	BLOCK 40		;FILESPEC FOR LOG FILE
INCRSW:	BLOCK 1			;-1 FOR FULL-INCREMENTAL, ELSE INCREMENTAL COUNT OR 0
TFNAME:	BLOCK 100		;SAVE FILE NAME HERE
DIRNAM:	BLOCK 20		;NAME STRING OF CURRENT DIRECTORY
ODRNAM:	BLOCK 20		;NAME STRING OF OUTPUT DIRECTORY
LSTDIR:	BLOCK 20		;NAME STRING OF LAST DIRECTORY
CONDIR:	BLOCK 20		;NAME STRING OF CONNECTED DIRECTORY
JFN:	BLOCK 1			;JFN FOR CURRENT DUMP OR LOAD FILE
MTJFN:	BLOCK 1			;JFN OF MAG TAPE
RWFRK:	BLOCK 1			;FORK WAITING FOR REWIND TAPE
FRKJFN:	BLOCK 1			;JFN FOR REWIND FORK
MTCOMS:	BLOCK 2			;MTA DUMPI/DUMPO COMMAND LIST
LPTPOS:	BLOCK 1			;LPT LINE POSITION
BGNTAD:	BLOCK 1			;TAD AT START OF SAVE
INIJFN:	BLOCK 1			;INITIAL JFN FOR SAVE
INIPGN:	BLOCK 1			;INITIAL PAGE NUMBER FOR SAVE
INICNT:	BLOCK 1			;SAVED COUNTER IF IN MIDDLE OF FILE
ININUM:	BLOCK 1			;FLAG FOR INITIAL DDB
FDB:	BLOCK .FBLN0		;FDB FOR CURRENT FILE
FDBAUT:	BLOCK 10		;STORE AUTHER OF FILE
FDBLWR:	BLOCK 10		;STORE LAST WRITER NAME
ICFDB:	BLOCK .FBLN0		;SAVED FDB FOR INTERCHANGE FORMAT
WBTAD:	BLOCK 1			;WRITTEN-BEFORE TAD
WSTAD:	BLOCK 1			;WRITTEN-SINCE TAD
ABTAD:	BLOCK 1			;ACCESSED-BEFORE TAD
ASTAD:	BLOCK 1			;ACCESSED-SINCE TAD
MBTAD:	BLOCK 1			;MOVED-BEFORE TAD
MSTAD:	BLOCK 1			;MOVED-SINCE TAD
DEVNAM:	BLOCK 14		;DEVICE NAME FOR INCREMENTAL SAVE
FBUF1:	BLOCK 11		;BUFFERS FOR FILESPEC STRING COMPARE
FBUF2:	BLOCK 11
LPTBUF:	BLOCK 40		;BUFFER FOR LPT TEXT
LSTHDR:	BLOCK ^D200/5		;HEADING FOR EACH LISTING PAGE
LPTLIN:	BLOCK 1			;LISTING LINE NUMBER
LPTPAG:	BLOCK 1			;LISTING PAGE
TMODE:	BLOCK 1			;MODE OF LAST MTA OPENF
NWTBIT:	BLOCK 1			;OVERLAP BIT
ICOLEN:	BLOCK 1			;LENGTH OF FILE FOR INTERCHANGE SAVE
;CHECKSUM INFORMATION
CHKCN0:	BLOCK 1			;CHECKSUM FOR FILE
LSTPGE: BLOCK 1			;LAST PAGE CHECKSUMMED
FPGCNT: BLOCK 1			;# OF COMPLETE PAGES BEFORE EOF
RMRPGE: BLOCK 1			;PARTIAL PAGE BEFORE EOF
STGEND:				;END OF STORAGE CLEARED AT STARTUP
;FLAG USED IN DUMPI/DUMPO TO REQUEST OVERLAPPED OPERATION

NWTBT0:	DM%NWT			;SET TO 0 FOR NON-OVERLAPPED

NBUF:	10			;SIZE OF FILE WINDOW AT BUF0

INIPDL:	IOWD NPDL,PDL		;INITIAL PUSH DOWN LIST

;STANDARD RETURNS

RSKP:	AOS 0(P)
R:	RET

DEFINE JSERR<
	JSP CX,JSERR0>

DEFINE ERROR (TAG,MSG)<
	JRST [	TMSGC <MSG
>
		JRST TAG]>

DEFINE ERRORJ (TAG,MSG)<
	JRST [	TMSGC <MSG, >
		CALL JSERRM
		JRST TAG]>

DEFINE TMSG(S)<
	HRROI B,[ASCIZ \S\]
	CALL TMSGQ>

DEFINE LPMSG(S)<
	HRROI B,[ASCIZ \S\]
	CALL LPMSGQ>

DEFINE BTMSG(S)<
	HRROI B,[ASCIZ \S\]
	CALL BTMSGQ>

DEFINE TMSGC(S)<
	HRROI B,[ASCIZ \S\]
	CALL TMSGQC>

DEFINE BTMSGC(S)<
	HRROI B,[ASCIZ \S\]
	CALL BTMSQC>

DEFINE TXTPTR (MSG)<POINT 7,[ASCIZ \MSG\]>

DEFINE TB (DAT,TXT)<
	XWD [ASCIZ \TXT\],DAT>
;THE W,X,Y,Z ARE CALCULATED BY THE MACRO LIKE THIS:

;W - THE NUMBERICAL VALUE OF VMAJOR
;
;X - THE LETTER CORRESPONDING TO THE VALUE OF VMINOR.  @=0, A=1...
;
;Y - THE NUMERICAL VALUE OF VEDIT
;
;Z - THE NUMERICAL VALUE OF VWHO

	DEFINE	.CLNAM<
	  DEFINE  .CLNM(LETTER,WHO)<
	    IRPC LETTER,<
	      IFE "A"-"'LETTER'"+VMINOR-1,<
		STOPI
		IFIDN <LETTER><@>,<
		  IFE VWHO,< .NAME(\VMAJOR,,\VEDIT,)>
		  IFN VWHO,< .NAME(\VMAJOR,,\VEDIT,-WHO)>>
		IFDIF <LETTER><@>,<
		  IFE VWHO,< .NAME(\VMAJOR,LETTER,\VEDIT,)>
		  IFN VWHO,< .NAME(\VMAJOR,LETTER,\VEDIT,-WHO)>>>>>
	IFGE VMINOR-^D26,< VMINOR==0
	  PRINTX %MINOR VERSION TOO LARGE - IGNORED>
	IFGE VWHO-7,< VMINOR== 
	  PRINTX %VWHO IS TOO LARGE - IGNORED>
	.CLNM(@ABCDEFGHIJKLMNOPQRSTUVWXYZ,\VWHO)
>

;DEFINE A .NAME MACRO TO GEN THE TEXT STRING

	DEFINE	.NAME(V,M,E,W)<
ASCIZ /V'M'('E')'W/>

VTXT:	.CLNAM			;GENERATE VERSION STRING
	SUBTTL MAIN LOOP
;PROGRAM ENTRY VECTOR

ENTVEC:	JRST START		;STARTING LOCATION
	JRST CLRST		;REENTER LOCATION
	VDUMPR			;VERSION NUMBER

START:	RESET
	MOVE A,[STGBGN,,STGBGN+1]
	SETZM -1(1)
	BLT A,STGEND-1		;CLEAR ALL VARIABLES
	MOVE P,INIPDL
	MOVEM P,PDLP		;SET COMMAND STACK FENCE
	MOVE A,[IOWD N.JFN,JFNSTK]
	MOVEM A,INIPTR		;INITIALIZE JFN STACK POINTER
	MOVEM A,RPSPTR		;REPARSE POINTER
	MOVEM A,CURPTR		;AND CURRENT POINTER
	MOVEM A,CMDPTR		;AND COMMAND POINTER
	MOVE A,[JRST EINT1A]
	MOVEM A,EINT1+1		;SETUP JSR DISPATCH
	MOVX F,LDIRF+RESPRO+RESACC ;DEFAULTS
	SETZM LSTFIL		;NO LIST IS DEFAULT
	SETO A,
	MOVE B,[-2,,Q1]
	MOVEI C,.JIDEN
	GETJI			;GET JOB DEFAULT DENSITY AND PARITY
	 JSERR
	MOVEM Q1,DENSIT		;SAVE THEM
	MOVEM Q2,PARITY
	MOVEI A,CURFMT		;DEFAULT IS CURRENT FORMAT
	MOVEM A,FORMAT
	MOVX A,DEFBKF		;GET DEFAULT BLOCKING-FACTOR
	MOVEM A,SETBKF		; AS LAST BLOCKING-FACTOR SET
	CALL MTBOT		;SET UP AS IF AT BEGINNING OF TAPE

	MOVEI A,.FHSLF
	MOVE B,[LEVTAB,,CHNTAB]
	SIR			;DECLARE INTERRUPT TABLES
	EIR			;ENABLE INTERRUPTS
	MOVE B,CHNMSK
	AIC			;ACTIVATE CHANNELS
	MOVE A,[.TICCE,,CECHN]
	ATI			;ACTIVATE ^E INTERRUPT
	CALL UNMAPB		;RESET BUFFERS
	TMSG <
DUMPER >
	HRROI A,VTXT
	PSOUT			;DUMP VERSION INFO
	TMSG <

>
	MOVEI A,.FHSLF
	RPCAP
	TXNE C,SC%WHL+SC%OPR	;WHEEL OR OPERATOR?
	SETOM WHEEL		;YES
	HRLOI A,377777		;INIT 'BEFORE' DATE TO PLUS INFINITY
	MOVEM A,ABTAD
	MOVEM A,WBTAD
	MOVEM A,MBTAD
	MOVX A,1B0		;INIT 'SINCE' DATE TO MINUS INFINITY
	MOVEM A,ASTAD
	MOVEM A,WSTAD
	MOVEM A,MSTAD
	MOVE A,[ICBLK,,CBLK]	;INIT COMMAND STATE BLOCK
	BLT A,CBLK+.CMGJB

;RESET AND START COMMAND

CLRST:	MOVE P,PDLP		;RESTORE PDL NOW
	SKIPE A,MTJFN		;GET MAG TAPE JFN
	CALL RLSJFN		;RELEASE JFN
	SETZM MTJFN
	SETZM TRAPJ		;CLEAR TRAP FENCE
	SETZM INTPC		;NO ^E
	CALL INIRST		;RESET JFN STACK TO INIPTR
	MOVE P,INIPDL		;RESET PUSH DOWN LIST
;	JRST RESTRT		;AND START OVER
	; ..
;TOP OF COMMAND

RESTRT:	MOVEM P,PDLP		;SAVE PDL POINTER
	SETZM CMDTYP		;ZERO COMMAND TYPE FLAG
	SETZM TRAPSP
	SETZM TRAPJ		;ZERO TRAP STUFF
	SETZM CEXFLG
	SETZM INTRQ
	MOVE A,CURPTR
	CAME A,CMDPTR		;ERROR IF NOT SAME
	ERROR BMBCM1,<?CMDPTR SHOULD EQUAL CURPTR>
	TXZ F,NOFLG
	MOVE A,CMDPTR		;GET COMMAND POINTER
	MOVEM A,RPSPTR		;RESET REPARSE POINTER
	MOVEM A,CURPTR		;AND CURRENT POINTER
	HRROI A,[ASCIZ /DUMPER>/]
	MOVEM A,CBLK+.CMRTY	;RESTORE CBLK
	MOVEI A,REPAR0
	MOVEM A,CBLK
	MOVEI A,CBLK		;SETUP COMMAND STATE BLOCK
	MOVEI B,[FLDDB. (.CMINI)]
	COMND			;INIT LINE
REPAR1:	TXZ F,NOFLG		;FORGET STUFF FROM PARTIAL COMMAND
	MOVEI A,CBLK
	MOVEI B,[FLDDB. (.CMKEY,,CTBL,<COMMAND NAME>)]
	COMND			;GET COMMAND NAME
NO1:	TXNE A,CM%NOP
	ERROR RESTRT,<?NOT A DEFINED COMMAND>
	HRRZ B,0(B)		;GET POINTER TO  COMMAND WORD
	MOVE B,(B)		;FLAGS,,DISPATCH ADDRESS
	MOVEM B,CMDTYP		;STORE AS CURRENT TYPE
	JRST 0(B)		;DISPATCH TO IT

;HERE WHEN REPARSE NEEDED

REPAR0:	MOVE P,PDLP		;RESTORE PDL PNTR
	CALL REPRST		;RESET JFN STACK
	JRST REPAR1		;CONTINUE PARSE

REPRST:	MOVE D,RPSPTR		;REPARSE POINTER
	CALL RSTSTK		;RESET STACK TO REPARSE POINTER
	RET			;RETURN

;HERE WHEN COMMAND COMPLETED

CDONE:	SETZM CEXFLG
	SKIPN ICMDTY		;SKIP IF UNDER ^E
	JRST [	TXZ F,TF2	;NOT IN MIDDLE OF FILE
		MOVE D,CMDPTR   ;GET COMMAND POINTER
		CAME D,INIPTR	;COMPARE TO INITIAL POINTER
		ERROR INIRST,<%CMDPTR SHOULD EQUAL INIPTR>
		JRST .+1 ]
	MOVE D,CMDPTR		;FINAL POINTER
	CALL RSTSTK		;RESET STACK TO COMMAND POINTER
	MOVEM D,RPSPTR		;SET BACK TO COMMAND POINTER
	JRST RESTRT
;CONFIRM

CONFRM:	PUSH P,A
	PUSH P,B
	PUSH P,C		;BE TRANSPARENT
	MOVEI A,CBLK
	MOVEI B,[FLDDB. (.CMCFM)]
	COMND			;CONFIRM
	TXNE A,CM%NOP
	ERROR BMBCM1,<?NOT CONFIRMED>
	CALL JFNCFM	;WORK OVER JFN STACK
	POP P,C
	POP P,B
	POP P,A
	RET
;COMMAND HAS JUST BEEN CONFIRMED. CHECK FOR UNDER ^E
;AND SET JFNSTK POINTERS CORRECTLY FOR CIRCUMSTANCES
;ROUTINE ASSUMES IT MAY UES  AC'S A,B,C.


JFNCFM:	SKIPE ICMDTY		;SKIP IF NOT UNDER ^E
	JRST JFNCF1		;SEE IF THIS IS A CONTINUE CMD.
	MOVE A,CMDTYP		;GET TYPE
	TXNE A,TY%RPO		;SKIP IF NOT REPARSE ONLY
	JRST [	MOVE A,RPSPTR	;GET REPARSE POINTER
		MOVEM A,CURPTR 	;STORE AS CURRENT POINTER
		RET ]

	MOVE A,CURPTR		;CURRENT POINTER
	MOVEM A,RPSPTR		;BECOMES REPARSE POINTER
	RET
;THE USER HAS TYPED A COMMAND UNDER ^E. CHECK IF IT IS
;A CONTINUE OR NO-CONTINUE COMMAND. IF IT IS NO-CONTINUE,
;INFORM THE USER AND GIVE HER/HIM THE CHOICE BETWEEN THE
;OLD COMMAND AND THE CURRENT COMMAND.
;CALLED WITH A,B,C ON THE STACK AND WITH THE
;CURRENT COMMAND TYPE IN CMDTYP.

JFNCF1:	MOVE A,CMDTYP		;GET COMMAND INFORMATION
	TXNE A,TY%NOC		;SKIP IF CONTINUE-ABLE
	JRST JFNCF2		;NOT CONTINUE-ABLE
	TXNN A,TY%RPO		;SKIP IF REPARSE ONLY
	JRST [	MOVE B,RPSPTR	;GET REPARSE POINTER
		MOVEM B,CMDPTR	;USE AS COMMAND POINTER
		MOVE B,CURPTR	;CURRENT POINTER
		MOVEM B,RPSPTR	;ALSO REPARSE POINTER
		RET ]		;RETURN
	MOVE B,RPSPTR		;GET REPARSE POINTER
	MOVEM B,CURPTR		;RESET CURRENT POINTER
	RET			;RETURN


;HERE IF UNDER ^E AND NOT CONTINUEABLE

JFNCF2:	HRROI A,[ASCIZ\% Do you really want to abort your interrupted command? \]
	CALL YESNO		;GET YES OR NO
	JUMPE A,DLTNEW		;NO-- DELETE NEW COMMAND
;	JRST DLTOLD		;YES-- DELETE OLD COMMAND
;HERE TO DELETE OLD COMMAND

DLTOLD:	SAVPQ		;SAVE PERM REGS
	TXZ F,TF2	;NOT IN MIDDLE OF FILE
	MOVE D,CMDPTR	;COMMAND POINTER
	CAMN D,INIPTR	;SKIP IF JFNS TO DELETE
	JRST DLTOL2	;NONE
	CALL UNMAPB	;RESET BUFFERS
DLTOL1:	POP D,A		;GET OLD JFN
	CALL RLSJFN	;THROW AWAY
	CAME D,INIPTR	;SKIP IF DONE
	JRST DLTOL1	;LOOP
	MOVE A,INIPTR	;INITIAL POINTER
	MOVE B,CURPTR	;CURRENT POINTER
	SUB B,CMDPTR	;NEW SIZE
	HRLS B		;SIZE,,SIZE
	ADD A,B		;NEW POINTER
	MOVEM A,CURPTR  ;STORE
	HRLZ B,CMDPTR	;START BLT FROM
	HRR B,INIPTR	;BLT TO
	ADD B,[1,,1]
	BLT B,0(A)	;MOVE IT
	
	MOVE A,INIPTR
	MOVEM A,CMDPTR
DLTOL2:	MOVE A,CURPTR
	MOVEM A,RPSPTR		;UPDATE REPARSE POINTER
	MOVE A,LPTJFN		;LIST FILE JFN
	CALL RLSJFN		;RELEASE IT
	SETZM INTPC
	SETZM ICMDTY		;NO LONGER UNDER ^E
	MOVE A,INIPDL		;
	MOVE B,P		;
	SUB B,IPDLP		;# ITEMS TO GET RID OF
	HRLS B			;IN BOTH SIDES
	ADD A,B			;CONSTRUCT NEW POINTER
	MOVE P,A		;AND STORE
	HRLZ B,IPDLP		;BLT FROM
	HRR B,INIPDL		;BLT TO
	ADD B,[1,,1]
	BLT B,0(A)		;MOVE IT
	MOVE A,INIPDL
	MOVEM A,PDLP		;RESET PDLP
	HRRZS A,Q1		;OFFSET ONLY
	HRRZ B,NIJFN		;PICK UP INTERRUPTED OFFSET
	SUB Q1,B		;NEW OFF SET
	HRLS Q1			;NEW OFFSET IN BOTH SIDES
	HRLZ B,NIJFN		;BLT START OFFSET
	MOVE C,[JFNLST,,JFNLST]	;BASE FOR FIRST BLT
	ADD C,B			;FIGURE BLT START ADDRESSES
	BLT C,JFNLST(Q1)		
	ADD B,[JF2LST,,JF2LST]	;BLT START ADDRESSES
	BLT B,JF2LST(Q1)		
	MOVSI B,-NJFNL+1	;SET UP Q1
	ADD Q1,B		;...
	RET

;HERE TO FORGET NEW COMMAND

DLTNEW:	CALL REPRST		;RESET JFN STACK 
	MOVE P,PDLP		;SET PDL BACK
	SETZM CMDTYP		;NO COMMAND 
	JRST RESTRT		;GO ON
;COMMAND NAME TABLE

DEFINE CTB (DAT,FLGS,TXT)<
	XWD [ASCIZ \TXT\],[FLGS+DAT]>

CTBL:	NCTBL,,NCTBL
	CTB $AB4,,<ABEFORE>
	CTB $ACC,,<ACCOUNT>
	CTB $ASI,,<ASINCE>
	CTB $B4,,<BEFORE>
	CTB CHCK,TY%NOC+TY%MAP,<CHECK>
	CTB $CSUM,,<CHECKSUM>
	CTB $CONT,,<CONTINUE>
	CTB $CREAT,,<CREATE>
	CTB $DEN,,<DENSITY>
	CTB $LDIR,,<DIRECTORIES>
	CTB $EOT,TY%NOC+TY%MAP,<EOT>
	CTB $EXIT,TY%NOC,<EXIT>
	CTB $LFIL,,<FILES>
	CTB $FMT,,<FORMAT>
	CTB TYPHLP,,<HELP>
	CTB $INDMD,,<INDUSTRY>
	CTB $INISP,TY%RPO,<INITIAL>
	CTB $ICMOD,TY%NOC,<INTERCHANGE>
	CTB $LIST,TY%RPO,<LIST>
	CTB $MB4,,<MBEFORE>
	CTB $MSI,,<MSINCE>
	CTB $NO,,<NO>
	CTB $PAR,,<PARITY>
	CTB $DIR,TY%NOC+TY%MAP,<PRINT>
	CTB $PRO,,<PROTECTION>
	CTB $LOAD,TY%NOC+TY%MAP+TY%DBL,<RESTORE>
	CTB $REW,TY%NOC,<REWIND>
	CTB DUMP,TY%NOC+TY%MAP+TY%DBL,<SAVE>
	CTB $SET,,<SET>
	CTB $SIL,,<SILENCE>
	CTB $SINCE,,<SINCE>
	CTB $SKIP,TY%NOC+TY%MAP,<SKIP>
	CTB $SSNAM,,<SSNAME>
	CTB $SUP,,<SUPERSEDE>
	CTB $TAPE,TY%RPO,<TAPE>
IFGE <VMAJOR-4>,<
	CTB $UNL,TY%NOC,<UNLOAD>
>
NCTBL==.-CTBL-1

;INITIAL COMMAND STATE BLOCK

ICBLK:	REPAR0			;REPARSE DISPATCH
	.PRIIN,,.PRIOU
	POINT 7,[ASCIZ /DUMPER>/] ;PROMPT
	POINT 7,CBFR
	POINT 7,CBFR
	CBFSIZ*5
	0
	POINT 7,ACBFR
	ACBSIZ*5
	GJBLK
	SUBTTL COMMANDS

;DATE SETTING COMMANDS

;ACCESSED-BEFORE

$AB4:	CALL GETTAD
	MOVEM A,ABTAD
	JRST CDONE

;ACCESSED-SINCE

$ASI:	CALL GETTAD
	MOVEM A,ASTAD
	JRST CDONE

;WRITTEN-BEFORE

$B4:	CALL GETTAD
	MOVEM A,WBTAD
	JRST CDONE

;WRITTEN-SINCE

$SINCE:	CALL GETTAD
	MOVEM A,WSTAD
	JRST CDONE

;MOVED-BEFORE

$MB4:	CALL GETTAD
	MOVEM A,MBTAD
	JRST CDONE

;MOVED-SINCE

$MSI:	CALL GETTAD
	MOVEM A,MSTAD
	JRST CDONE
;GET TIME AND DATE AS NEXT FIELD

GETTAD:	MOVEI B,[FLDDB. (.CMNOI,,<TXTPTR (<DATE AND TIME>)>)]
	COMND
	MOVEI B,[FLDDB. (.CMTAD,,CM%IDA+CM%ITM,,,[FLDDB. (.CMTAD,,CM%IDA)])]
	COMND
	TXNE A,CM%NOP
	ERRORJ RESTRT,<?INVALID DATE AND TIME>
	MOVE A,B
	CALL CONFRM		;CONFIRM IT
	RET

;INTERCHANGE MODE

$ICMOD:	MOVEI B,[FLDDB. (.CMNOI,,<TXTPTR (<FORMAT>)>)]
	COMND
	CALL CONFRM
	TXNE F,NOFLG
	TXZA F,ICMODF		;NO INTERCHANGE
	TXO F,ICMODF		;INTERCHANGE 
	JRST CDONE

;(NO)CREATE DIRECTORIES FROM TAPE DATA ON RESTORE

$CREAT:	MOVEI B,[FLDDB. (.CMNOI,,<TXTPTR (<DIRECTORIES FROM TAPE DATA>)>)]
	COMND
	CALL CONFRM
	TXNE F,NOFLG
	TXZA F,USRDAT		;MEANS IGNORE USER DATA
	TXO F,USRDAT
	JRST CDONE

;(NO)INDUSTRY COMPATIBLE 36-BIT MODE, I.E. LIKE MULTICS AND BBN

$INDMD:	MOVEI B,[FLDDB. (.CMNOI,,<TXTPTR (<COMPATIBLE 36-BIT MODE>)>)]
	COMND
	CALL CONFRM
	TXNE F,NOFLG
	TXZA F,T36MOD		;NORMAL DEC 'CORE DUMP' MODE
	TXO F,T36MOD		;ELSE 2 36-BIT WORDS IN 9 FRAMES
	JRST CDONE
;INITIAL FILE SPECIFICATION FOR SAVE/RESTORE.  MUST BE FILE WITHIN
;GROUP SPECIFIED IN SAVE OR RESTORE COMMAND.  OPERATIONS 
;BEGINS WITH THIS FILE.

$INISP:	MOVEI B,[FLDDB. (.CMNOI,,<TXTPTR (<FILESPEC>)>)]
	COMND
	TXNE F,NOFLG		;NEGATED?
	JRST [	CALL CONFRM	;YES
		SETZ A,		;FLUSH ANY EXISTING INITIAL SPEC
		EXCH A,INIJFN
		RLJFN
		 JFCL
		SETZM ININUM	;CLEAR DDB FLAG
		JRST CDONE]
	CALL SETGJB		;SETUP GTJFN DEFAULTS
	MOVX A,GJ%OLD+GJ%IFG
	HLLM A,GJBLK+.GJGEN	;ALLOW STARS
	MOVEI A,CBLK
	MOVEI B,[FLDDB. (.CMFIL)]
	COMND
	TXNE A,CM%NOP
	ERRORJ RESTRT,<?INVALID FILESPEC>
	CALL ADFILE	;ADD JFN TO JFN STACK
	CALL CONFRM		;CONFIRM
	MOVEM B,INIJFN		;SAVE JFN
	SETZM ININUM		;CLEAR DDB FLAG
	JRST CDONE

;SAVESET NAME

$SSNAM:	MOVE Q1,CBLK+.CMPTR	;SAVE CURRENT LINE POINTER
	MOVEI B,[FLDDB. (.CMTXT,CM%SDH,,<ARBITRARY SAVE SET NAME TEXT>)]
	MOVEI A,CBLK
	COMND			;READ TEXT TO EOL
	TXNE A,CM%NOP
	ERROR RESTRT,<?INVALID>
	HRROI A,SSNBUF		;POINT TO BUFFER FOR NAME
	MOVE B,CBLK+.CMABP	;POINT TO ATOM BUFFER WHERE TEXT IS NOW
	MOVX C,0		;ASCIZZZZ
	SOUT			;COPY NAME
	JRST CDONE		;ALL DONE WITH $SSNAM
;SUPERSEDE ALWAYS/NEVER/OLDER

$SUP:	MOVEI B,[FLDDB. (.CMKEY,,STBL)]
	COMND			;GET NEXT KEYWORD
	TXNE A,CM%NOP
	ERROR RESTRT,<?UNRECOGNIZED KEYWORD>
	CALL CONFRM
	HRRZ B,0(B)		;GET FLAGS
	TXZ F,SSA+SSN		;MOVE THEM TO F
	IOR F,B
	JRST CDONE

STBL:	NSTBL,,NSTBL
	TB SSA,<ALWAYS>
	TB SSN,<NEVER>
	TB 0,<OLDER>
NSTBL==.-STBL-1

;PROTECTION TO BE RESTORED FROM TAPE OR SYSTEM DEFAULT

$PRO:	MOVEI B,[FLDDB. (.CMNOI,,<TXTPTR (<OF RESTORED FILES FROM>)>)]
	COMND
	MOVEI B,[FLDDB. (.CMKEY ,,ACCTB)]
	COMND			;TWO CHOICES
	TXNE A,CM%NOP
	ERROR RESTRT,<?UNRECOGNIZED ARGUMENT>
	CALL CONFRM
	HRRZ B,0(B)
	SKIPN B			;SET FLAG PER ARGUMENT
	TXZA F,RESPRO
	TXO F,RESPRO
	JRST CDONE
;ACCOUNT OF RESTORED FILES TO BE SET FROM TAPE OR SYSTEM DEFAULT

$ACC:	MOVEI B,[FLDDB. (.CMNOI,,<TXTPTR (<OF RESTORED FILES FROM>)>)]
	COMND
	MOVEI B,[FLDDB. (.CMKEY,,ACCTB)]
	COMND
	TXNE A,CM%NOP
	ERROR RESTRT,<?UNRECOGNIZED ARGUMENT>
	CALL CONFRM
	HRRZ B,0(B)
	SKIPN B			;SET FLAG PER ARG
	TXZA F,RESACC
	TXO F,RESACC
	JRST CDONE

;ARGUMENT KEYWORD TABLE FOR PROTECTION AND ACCOUNT

ACCTB:	NACCTB,,NACCTB
	TB 0,<SYSTEM-DEFAULT>
	TB 1,<TAPE>
NACCTB==.-ACCTB-1
;TAPE - SETS MTA UNIT SPECIFICATION

$TAPE:	MOVEI B,[FLDDB. (.CMNOI,,<TXTPTR (<FILESPEC>)>)]
	COMND
	MOVEI B,[FLDDB. (.CMIFI,,,<MAGTAPE DESIGNATOR,>)]
	COMND			;READ MTAX:
	TXNE A,CM%NOP
	ERRORJ RESTRT,<?INVALID FILESPEC>
	CALL ADLIST		;ADD JFN TO JFN STACK
	CALL CONFRM		;CONFIRM IT
	MOVE A,B		;PASS JFN
	CALL NTAP1		;SAVE INFO
	 JRST RESTRT		;FAILED
	JRST CDONE

NTAP1:	ACVAR <Q1>
	MOVEM A,Q1		;SAVE JFN
	DVCHR			;FIND OUT ABOUT DEVICE
	LOAD D,DV%TYP,B		;SEE WHAT TYPE
	CAIE D,.DVMTA		;MTA?
	JRST [	MOVEI A,.PRIOU	;REPORT NAME
		HRRZ B,Q1
		MOVX C,2B2+2B5+2B8+2B11+1B35
		JFNS
		TMSG < is not a magtape
>
		MOVE A,Q1
		RLJFN
		JFCL
		RET]		;RETURN FAIL
	MOVEM A,MTDSG		;SAVE DESIGNATOR
	HRROI A,MTDEV		;GET DEVICE NAME STRING
	HRRZ B,Q1
	MOVX C,1B2+1B35
	JFNS
	MOVE A,Q1		;RELEASE TEMP JFN
	RLJFN
	 JFCL
	RETSKP

;routine to get spec for second and subsequent tapes on dump and restore

NTAPE:	CALL TSTINT		;CHECK FOR INTERRUPT REQUEST
	MOVEM P,TPDLP		;TEMPORARY PLACE TO SAVE P
	MOVEI A,NTAPX1		;FIX CBLK
	MOVEM A,CBLK
	HRROI A,[ASCIZ /$ Tape filespec /]
	MOVEM A,CBLK+.CMRTY
	MOVEI A,CBLK
	MOVEI B,[FLDDB. (.CMINI)]
	COMND
NTAPX:	MOVEI A,CBLK
	MOVEI B,[FLDDB. (.CMIFI,,,<MAGTAPE DESIGNATOR,>)]
	COMND
	TXNE A,CM%NOP
	ERRORJ NTAPE,<?INVALID FILESPEC>
	CALL ADLIST		;ADD JFN TO JFN STACK
	PUSH P,A		;SAVE AC'S
	PUSH P,B
	MOVEI A,CBLK
	MOVEI B,[FLDDB. (.CMCFM)]
	COMND			;CONFIRM
	TXNE A,CM%NOP		;NO PARSE?
	ERROR BMBCM1,<?NOT CONFIRMED>
	MOVE A,RPSPTR		;REPARSE POINTER
	MOVEM A,CURPTR		;RESET TO REPARSE POINTER
	POP P,B			;RESTORE AC'S
	POP P,A			;...
	MOVE A,B		;PASS JFN
	CALL NTAP1		;SETUP FOR MTOPEN
	 JRST NTAPE		;FAILED
	RET

;REPARSE HERE

NTAPX1:	MOVE	P,TPDLP		;RESTORE PNTR
	CALL	REPRST		;RESET JFN STACK
	JRST	NTAPX		;CONTINUE
;SET COMMAND

$SET:	MOVEI B,[FLDDB. (.CMKEY,,SETTBL)]
	COMND			;GET KEY WORD
	TXNE A,CM%NOP
	ERROR RESTRT,<?UNRECOGNIZED KEYWORD>
	HRRZ B,0(B)
	MOVE B,(B)
	MOVEM B,CMDTYP		;STORE AS CURRENT COMMAND TYPE
	JRST 0(B)		;AND GO ON

SETTBL: NSETTB,,NSETTB
IFGE <VMAJOR-4>,<
	CTB SETBLK,,<BLOCKING-FACTOR>
>
	CTB TAPNUM,,<TAPE-NUMBER>
NSETTB==.-SETTBL-1

;SET TAPE NUMBER --SETS REEL #

TAPNUM:	MOVEI B,[FLDDB. (.CMNOI,,<TXTPTR (<DECIMAL NUMBER>)>)]
	COMND
	MOVEI B,[FLDDB. (.CMNUM,,^D10)]
	COMND
	TXNE A,CM%NOP
	ERROR RESTRT,<?NOT A DECIMAL NUMBER>
	CALL CONFRM
	MOVEM B,TAPNO
	MOVEM B,RTAPNO		;IN CASE USER IS READING
	TXO F,TNSF		;USER SET TAPE NUMBER
	JRST CDONE


;SET BLOCKING-FACTOR

SETBLK:	MOVEI B,[FLDDB. (.CMNOI,,<TXTPTR (<TO>)>)]
	COMND
	MOVEI B,[FLDDB. (.CMNUM,,^D10,<NUMBER OF RECORDS,>)]
	COMND
	TXNE A,CM%NOP
	ERROR RESTRT,<?NOT A DECIMAL NUMBER>
	PUSH P,B
	MOVEI B,[FLDDB. (.CMNOI,,<TXTPTR (<RECORDS>)>)]
	COMND
	CALL CONFRM
	POP P,B
	CAIGE B,1		;MUST BE 1 OR GREATER
	 ERROR RESTRT,<?BLOCKING-FACTOR MUST BE GREATER THAN 0>
	CAILE B,MAXBKF		;MUST BE WITHIN LIMIT
	 ERROR RESTRT,<?BLOCKING-FACTOR TOO LARGE>
	MOVEM B,SETBKF		;REMEMBER BLOCKING-FACTOR
	JRST CDONE
;TAPE PARAMETERS

;DENSITY

$DEN:	MOVEI B,[FLDDB. (.CMNOI,,<TXTPTR (<OF MAGTAPE>)>)]
	COMND
	MOVEI B,[FLDDB. (.CMKEY,,DENTAB)]
	COMND
	TXNE A,CM%NOP
	ERROR RESTRT,<?UNRECOGNIZED DENSITY VALUE>
	CALL CONFRM
	HRRZ B,0(B)		;GET DENSITY CODE
	MOVEM B,DENSIT		;SAVE FOR OPEN
	JRST CDONE

DENTAB:	NDENTB,,NDENTB
	TB .SJD16,<1600-BPI>
	TB .SJDN2,<200-BPI>
	TB .SJDN5,<556-BPI>
	TB .SJD62,<6250-BPI>
	TB .SJDN8,<800-BPI>
	TB .SJDDN,<JOB-DEFAULT>
NDENTB==.-DENTAB-1

;PARITY

$PAR:	MOVEI B,[FLDDB. (.CMNOI,,<TXTPTR (<OF MAGTAPE>)>)]
	COMND
	MOVEI B,[FLDDB. (.CMKEY,,PARTAB)]
	COMND
	TXNE A,CM%NOP
	ERROR RESTRT,<UNRECOGNIZED PARITY VALUE>
	CALL CONFRM
	HRRZ B,0(B)		;GET PARITY CODE

	MOVEM B,PARITY		;SAVE FOR OPEN
	JRST CDONE

PARTAB:	NPARTB,,NPARTB
	TB .SJPRE,<EVEN>
	TB .SJPRO,<ODD>
NPARTB==.-PARTAB-1

;FORMAT SPECIFICATION - USEFUL IF STARTING IN MIDDLE OF TAPE

$FMT:	MOVEI B,[FLDDB. (.CMNOI,,<TXTPTR (<VERSION NUMBER IS>)>)]
	COMND
	MOVEI B,[FLDDB. (.CMNUM,,^D10)]
	COMND
	TXNE A,CM%NOP
	ERROR RESTRT,<?NOT A DECIMAL NUMBER>
	CALL CONFRM
	MOVEM B,FORMAT		;SAVE SPECIFIED NUMBER
	JRST CDONE
;'NO' - INVERTS MEANING OF FOLLOWING COMMAND

$NO:	TXO F,NOFLG		;NOTE INVERSION
	MOVEI B,[FLDDB. (.CMKEY,,NOTBL,<COMMAND NAME>)]
	COMND			;ONLY CERTAIN COMMANDS AFTER NO
	JRST NO1		;JOIN NORMAL CASE

NOTBL:	NNOTB,,NNOTB
	CTB $CSUM,,<CHECKSUM>
	CTB $CREAT,,<CREATE>
	CTB $LDIR,,<DIRECTORIES>
	CTB $LFIL,,<FILES>
	CTB $INDMD,,<INDUSTRY>
	CTB $INISP,,<INITIAL>
	CTB $ICMOD,,<INTERCHANGE>
	CTB $LIST,,<LIST>
	CTB $SIL,,<SILENCE>
NNOTB==.-NOTBL-1

;'HELP'

TYPHLP:	CALL CONFRM
	MOVX A,GJ%OLD+GJ%SHT
	HRROI B,[ASCIZ /SYS:DUMPER.HLP/]
	GTJFN			;GET HELP FILE
	 JRST [	TMSG <? DUMPER help file not available, use "?" for list of commands.
>
		JRST BMBCMD]
	MOVEM A,JFN
	MOVX B,<FLD(7,OF%BSZ)+OF%RD>
	OPENF
	 JRST [	MOVE A,JFN
		RLJFN
		 JFCL
		CALL JSERR1
		JRST BMBCMD]
TYPHL1:	MOVE A,JFN		;COPY FILE TO TERMINAL
	BIN
	JUMPN B,[MOVEI A,.PRIOU
		BOUT
		JRST TYPHL1]
	CLOSF			;NULL, ASSUME EOF
	 JFCL
	JRST RESTRT

;EXIT

$EXIT:	CALL CONFRM
	HALTF
	SKIPE MTJFN		;MTA OPEN?
	CALL MTCLS		;YES - CLOSE IT THEN
	JRST RESTRT		;IF CONTINUED
;TAPE POSITION COMMANDS

;REWIND

$REW:	CALL CONFRM		;CONFIRM
	MOVX B,OF%RD
	CALL MTOPEN		;OPEN TAPE FOR READ
	CALL REWIND
	CALL MTCLS
	JRST CDONE

;UNLOAD

$UNL:	CALL CONFRM		;CONFIRM
	MOVX B,OF%RD
	CALL MTOPEN
	CALL UNLOAD
	CALL MTCLS
	JRST CDONE

;SKIP TO END OF TAPE, I.E. TO JUST BEFORE TAPE TRAILER RECORD

$EOT:	CALL CONFRM		;CONFIRM
	SETOM CEXFLG		;ALLOW INTERRUPT
	MOVX B,OF%RD
	CALL MTOPEN		;OPEN TAPE FOR READ
EOT1:	CALL MTRED		;READ NEXT RECORD
	 JRST [	TMSG <, record ignored
>
		JRST EOT1]
	MOVN A,TYP		;CHECK TYPE
	CAIE A,CTPHX
	CAIN A,TPHDX		;TAPE HEADER?
	JRST [	CALL TYHEDR	;YES, TYPE INFO
		JRST EOT1]
	CAIE A,TPTRX		;TAPE TRAILER?
	JRST EOT1		;NO, KEEP SCANNING
	CALL BACKSP		;YES, BACK OVER IT
	CALL MTCLS		;CLOSE AND DONE
	TMSG <Tape positioned at EOT
>
	JRST CDONE

$CSUM:	TXNE F,NOFLG		;SKIP IF NOT NO CHECKSUM
	JRST CSUM1		;TURN OFF ONLY
	MOVEI B,[FLDDB. (.CMNOI,,<TXTPTR (<FILES >)>)]
	COMND
	MOVEI B,[FLDDB. (.CMKEY,,CSMTAB)]
	COMND
	TXNE A,CM%NOP
	ERROR RESTRT,<?UNRECOGNIZED CHECKSUM TYPE>
CSUM1:	CALL CONFRM
	HRRZ B,0(B)
	TXZ F,CHKSM+CS%SEQ	;TURN OFF FLAGS
	TXNN F,NOFLG		;SKIP IF 'NO CHECKSUM'
	IOR F,B
	JRST CDONE
CSMTAB:	NCKTBL,,NCKTBL
	TB CHKSM,<BY-PAGES>
	TB CHKSM+CS%SEQ,<SEQUENTIAL>
NCKTBL==.-CSMTAB-1
;SKIP N SAVESETS

$SKIP:	MOVEI B,[FLDDB. (.CMNOI,,<TXTPTR (<NUMBER OF SAVESETS>)>)]
	COMND
	MOVEI B,[FLDDB. (.CMNUM,,^D10)]
	COMND			;GET NUMBER
	TXNE A,CM%NOP
	ERROR RESTRT,<?NOT A DECIMAL NUMBER>
	MOVEM B,Q1		;SAVE NUMBER
	CALL CONFRM		;CONFIRM
	MOVX B,OF%RD
	CALL MTOPEN		;OPEN TAPE FOR READ
	SETOM CEXFLG		;ALLOW INTERRUPT
	JUMPLE Q1,SKIPR		;SCAN REVERSE IF 0 OR NEG
	CALL MTRED		;READ FIRST RECORD
	 JRST SKIPF1		;BAD, IGNORE
	MOVN A,TYP
	CAIE A,CTPHX
	CAIN A,TPHDX		;SAVESET HEADER?
	AOS Q1			;YES, SKIP ONE MORE THAN SPEC
	JRST SKIPF2

SKIPF1:	CALL MTRED		;SCAN FORWARD
	 JRST [	TMSG <, record ignored
>
		JRST SKIPF1]
SKIPF2:	MOVN A,TYP		;CHECK TYPE
	CAIN A,TPTRX		;END OF TAPE?
	JRST [	CALL BACKSP	;YES, ERROR
		ERROR (BMBCMD,<%END OF TAPE ENCOUNTERED>)]
	CAIE A,TPHDX		;TAPE HEADER?
	CAIN A,CTPHX
	SKIPA
	JRST SKIPF1		;NO, KEEP SCANNING
	CALL TYHEDR		;YES, TYPE INFO
	SOJG Q1,SKIPF1		;COUNT HEADERS SEEN
	JRST SKIPD		;DONE

SKIPR:	SETZM NWTBIT		;PREVENT OVERLAP READS
	JRST SKIPR1

SKIPR2:	CALL BACKSP		;BACKSPACE ONE RECORD NET
SKIPR1:	CALL BACKSP
	CALL MTRED
	 JRST [	TMSG <, record ignored
>
		JRST SKIPR2]
	MOVN A,TYP		;CHECK TYPE
	CAIE A,TPHDX		;TAPE HEADER?
	CAIN A,CTPHX
	SKIPA
	JRST SKIPR2		;NO, KEEP SCANNING
	CALL TYHEDR		;YES, TYPE INFO
	AOJLE Q1,SKIPR2		;COUNT HEADERS SEEN
SKIPD:	CALL BACKSP		;BACK OVER LAST HEADER SEEN
	CALL MTCLS		;DONE WITH TAPE
	JRST CDONE
;LISTING CONTROL COMMANDS

;(NO)DIRECTORIES

$LDIR:	CALL CONFRM
	TXNE F,NOFLG		;NEGATED?
	TXZA F,LDIRF		;YES, NO DIRECTORIES
	TXO F,LDIRF		;DIRECTORIES
	JRST CDONE

;(NO)FILES

$LFIL:	CALL CONFRM
	TXNE F,NOFLG		;NEGATED?
	TXZA F,LFILF		;YES, "NO FILES"
	TXO F,LFILF		;"FILES"
	JRST CDONE

;(NO)SILENCE

$SIL:	CALL CONFRM
	TXNE F,NOFLG		;NEGATED?
	TXOA F,LFILF+LDIRF	;"NO SILENCE"
	TXZ F,LFILF+LDIRF	;"SILENCE"
	JRST CDONE

;SPECIFY LOG FILE

$LIST:	TXNE F,NOFLG		;NEGATED?
	JRST [	CALL CONFRM	;YES, NO FURTHER ARGS
		SETZM LSTFIL	;NO LOG FILE
		TXZ F,LTTYF+LFDSK ;NOT LOGGING TO ANYTHING
		JRST CDONE]
	MOVEI B,[FLDDB. (.CMNOI,,<TXTPTR (<LOG INFORMATION ON FILE>)>)]
	COMND
	MOVEI B,[FLDDB. (.CMOFI,,,,<LPT:DUMPER.LOG>)]
	COMND
	TXNE A,CM%NOP
	ERRORJ RESTRT,<?OUTPUT FILESPEC INVALID>
	CALL ADLIST		;ADD JFN TO JFN STACK
	CALL CONFRM
	HRROI A,LSTFIL		;PUT FILESPEC INTO BUFFER
	MOVX C,2B2+1B5+1B8+1B11+1B14+1B35
	JFNS
	MOVE A,B
	RLJFN
	 JFCL
	JRST CDONE
	SUBTTL DIRECTORY LISTING

$DIR:	MOVEI B,[FLDDB. (.CMNOI,,<TXTPTR (<DIRECTORY OF TAPE ONTO FILE>)>)]
	COMND
	MOVEI B,[FLDDB. (.CMOFI,,,,<TTY:>)]
	COMND
	TXNE A,CM%NOP
	ERRORJ RESTRT,<?OUTPUT FILESPEC INVALID>
	CALL ADLIST		;ADD JFN TO JFN STACK
	CALL CONFRM
	MOVE A,B		;PICK UP JFN
	CALL LPTOP0		;OPEN DEVICE TO RECEIVE DIRECTORY
	CALL DIRS		;DO IT VIA SUBROUTINE
	JRST CDONE

DIRS:	SETZM LSTHDR		;NO HEADER YET
	MOVEI B,OF%RD
	CALL MTOPEN
	SETOM CEXFLG		;ALLOW INTERRUPT
DIR1:	CALL MTRED		;READ NEXT RECORD, DISPATCH ON TYPE
	 JRST [	TMSG <, record ignored
>
		JRST DIR1]
	MOVN B,TYP
	CAIN B,FLHDX
	JRST DIRF		;FILE HEADER
	CAIN B,USRX
	JRST DIRU		;USER INFO
	CAIN B,TPTRX
	JRST DIRE		;END OF TAPE
	CAIE B,CTPHX
	CAIN B,TPHDX
	JRST DIRB		;BEGINNING OF TAPE
	CAIN B,FLTRX
	JRST DIRFDB		;FDB INFO
	CALL PGECSM		;CHECKSUM DATA PAGE
	JRST DIR1		
;BEGINNING OF TAPE

DIRB:	MOVE A,[POINT 7,LPTBUF]
	CALL PRHEDR		;COMPOSE HEADER IN LPTBUF
	HRROI B,LPTBUF
	CALL BTMSGQ		;TYPE AND PRINT IT
	BTMSG <
>
	HRROI A,LSTHDR		;SAVE HEADER FOR LISTING
	HRROI B,LPTBUF
	SETZ C,
	SOUT
	CALL PRTHDR
	BTMSG <

>
	JRST DIR1

;END OF TAPE

DIRE:	SKIPL PAGNO		;CONTINUED SAVE?
	 JRST DIRE01		;NO-- GO ON
	BTMSG <
End of tape, saveset continued on next reel.
>
	JRST DIRE02

DIRE01:	BTMSG <
End of tape.
>
DIRE02:	SKIPN A,LPTJFN		;SEE IF LISTING?
	JRST DIRE1		;NO
	MOVEI B,.CHFFD
	BOUT
	CLOSF
	 JFCL
DIRE1:	CALL BACKSP		;BACKSPACE OVER TAPE TRAILER
	CALL MTCLS
	RET

;USER INFO

DIRU:	BTMSG <
DDB for >
	HRROI B,BUFF+UHNAM
	CALL BTMSGQ
	BTMSG <
>
	JRST DIR1
;BEGINNING OF FILE

DIRF:	MOVEI B,FLCOL
	CALL TAB		;TAB TO NAME COLUMN
	SKIPN FORMAT		;BBN FORMAT?
	CALL FIXFMM		;YES, FIX SEMICOLON
	MOVE B,[POINT 7,BUFF]
DIRF1:	ILDB A,B		;SCAN FILESPEC
	CAIN A,";"		;END OF GENERATION?
	SETZ A,			;YES, USE NULL
	JUMPN A,DIRF1		;JUMP IF NOT END OF STRING
	DPB A,B			;TIE OFF STRING
	HRROI B,BUFF
	CALL LPMSGQ		;OUTPUT FILESPEC
	SKIPL PAGNO		;SKIP IF FILE CONTINUED
	JRST DIRF4		;GO ON
	LPMSG <
(File continued from previous reel)
>
	JRST DIR1		;DON'T RESET CHECKSUM
DIRF4:	TXNN F,CHKSM		;SKIP IF CHECKSUMMING
	JRST DIR1		;REST WILL BE PRINTED FROM TRAILER
	SETZM CHKCN0		;INITIALIZE CHECKSUM
	SETZM LSTPGE		;AND LAST PAGE #
	TXNN F,CS%SEQ		;SKIP IF SEQUENTIAL
	JRST DIR1		;GO ON
	CALL FILSZE		;FIGURE FILE SIZE
	JRST DIR1		;GO ON

;END OF FILE, FDB INFO

DIRFDB:	SKIPL PAGNO		;SKIP IF FILE CONTINUED
	JRST DIRF3		;GO ON
	LPMSG <
(File continued on next reel)
>
	JRST DIR1		;FDB PRINTER TO BE ADDED
DIRF3:	MOVEI B,WTCOL
	CALL TAB		;TAB TO WRITE COLUMN
	HRROI A,LPTBUF		;CONSTRUCT DATE STRING IN LPT BUFFER
	SKIPN B,BUFF+.FBWRT	 ;HAVE WRITE DATE?
	JRST [	LPMSG <(NEVER)>	;NO
		JRST DIRF2]
	MOVX C,1B10+1B12+1B17
	ODTIM			;YES, PRINT IT
	HRROI B,LPTBUF
	CALL LPMSGQ
DIRF2:	MOVEI B,SIZCOL
	CALL TAB		;TAB TO SIZE COLUMN
	LOAD B,FB%PGC,BUFF+.FBBYV ;GET PAGE COUNT
	MOVX C,^D10
	CALL LPNOUT		;OUTPUT SIZE
	TXNE F,CHKSM		;SKIP IF CHECKSUMMING
	CALL PRTCSM		;PRINT CHECKSUM
	LPMSG <
>
	JRST DIR1		;GO ON
SUBTTL	DUMP ROUTINES

DUMP:	CALL DUMPS
	JRST CDONE

DUMPS:	MOVEI B,[FLDDB. (.CMNOI,,<TXTPTR (<DISK FILES>)>)]
	COMND
	SETZM INCRSW		;DEFAULT NO INCREMENTAL
	SKIPE ICMDTY		;SKIP IF NOT UNDER ^E
	SKIPN Q1,NIJFN		;PICK UP POINTER, IF ANY
	MOVSI Q1,-NJFNL+1	;INIT PTR TO JFN LIST
DUMP1:	SETZ Q2,		;INDICATE FILE SPEC OK (WILL BE ERROR CODE IF NOT)
	CALL SETGJB		;SETUP GTJFN ARG BLOCK
	MOVX A,GJ%OLD+GJ%IFG	;GTJFN FLAGS - ALLOW INPUT STARS
	HLLM A,GJBLK+.GJGEN
	MOVEI A,CBLK
	MOVEI B,[FLDDB. (.CMSWI,,DSWTB,,,FILCDB)] ;ALLOW SWITCHES
	COMND			;GET FILESPEC OR SWITCH
	TXNE A,CM%NOP
	 JRST DUMP2		;NO PARSE-- SEE IF OK GTJFN ERROR
	LOAD C,CM%FNC,0(C)	;GET CODE OF BLOCK USED
	CAIE C,.CMSWI		;SWITCH?
	JRST DUMP4		;NO, MUST BE FILENAME
	HRRZ B,0(B)		;GET DISPATCH
	JRST 0(B)
;SWITCH TABLE

DSWTB:	NDSWTB,,NDSWTB
IFGE <VMAJOR-4>,<
	TB $FINC,<FULL-INCREMENTAL>
	TB $INC,<INCREMENTAL:>
>
IFL <VMAJOR-4>,<
	TB $INC,<INCREMENTAL>
>
	TB $NINC,<NOINCREMENTAL>
NDSWTB==.-DSWTB-1

$FINC:	MOVX B,-1		;-1 MEANS FULL-INCREMENTAL
	JRST $INC5		; . .

$INC:	MOVEI B,1		;ASSUME 1 TAPE FOR /INC:
IFGE VMAJOR-4,<
	TXNN A,CM%SWT		;SWITCH TERMINATOR SEEN?
>	 JRST $INC5		;NO-- USE 1
	MOVEI B,[FLDDB. (.CMNUM,,^D10,<NUMBER OF TAPES EACH FILE MUST BE ON,>,<1>)]
	COMND			;GET NUMBER OF TAPES
	TXNE A,CM%NOP		;GOT IT?
	 ERROR BMBCM1,<?INVALID NUMBER>
	CAIGE B,1		;VALID NUMBER?
	 ERROR BMBCM1,<?TAPE COUNT MUST BE GREATER THAN 0>
$INC5:	SKIPN	WHEEL		;MAKE SURE WE ARE A WHEEL
	ERROR	BMBCM1,<?WHEEL OR OPERATOR CAPABILITIES REQUIRED FOR INCREMENTAL SAVES>
	MOVEM B,INCRSW		;SAVE INCREMENTAL STATE
	JRST DUMP1

$NINC:	SETZM INCRSW		;NO INCREMENTAL
	JRST DUMP1

;COMMAND BLOCK FOR SOURCE FILE

FILCDB:	FLDDB. (.CMFIL,CM%SDH,,<FILE GROUP DESCRIPTOR>)

;LIST OF GTJFN ERRORS WHICH ALL MEAN "FILE NOT FOUND"

OKGJXL:	BYTE (18)GJFX16,GJFX17,GJFX18,GJFX19,GJFX20,GJFX24,GJFX32,GJFX35,GJFX36,GJFX38
OKGJXZ==<.-OKGJXL>*2

;INIT GTJFN ARG BLOCK

SETGJB:	MOVE A,[GJBLK,,GJBLK+1]
	SETZM -1(A)
	BLT A,GJBLK+.GJBFP	;CLEAR BLOCK
	GJINF			;GET CONN DIR NUMBER TO B
	HRROI A,CONDIR
	MOVEM A,GJBLK+.GJDEV	;SET DEFAULT AS CONNECTED STR:<DIR>
	MOVEM A,GJBLK+.GJDIR	;IN CASE NO DEVICE
	DIRST
	 CALL JSERR1
	MOVE A,[POINT 7,CONDIR]	;POINT AT STRING
SETGJ1:	ILDB B,A		;GET CHAR
	JUMPE B,[SETZM GJBLK+.GJDEV
		 JRST SETGJ3]
	CAIE B,DEVPCT		;LOOK FOR DEVICE TERMINATOR
	JRST SETGJ1		;...
	MOVEI B,0		;OVERWRITE WITH NULL
	DPB B,A
	IDPB B,A		;AND NEXT CHAR (DIRBP)
	MOVEM A,GJBLK+.GJDIR	;POINT AT START OF DIR STRING
SETGJ2:	ILDB B,A		;LOOK FOR END OF DIRECTORY
	CAIE B,DIREP
	JRST SETGJ2		;LOOP
	MOVEI B,0		;TIE OFF ASCIZ STRING
	DPB B,A			;...
SETGJ3:	HRROI A,[ASCIZ /*/]
	SKIPE WHEEL		;WHEEL?
	MOVEM A,GJBLK+.GJDIR	;YES, DIRECTORY DEFAULT IS *
	MOVEM A,GJBLK+.GJNAM	;NAME AND EXT DEFAULT TO *
	MOVEM A,GJBLK+.GJEXT
	MOVE A,[.PRIIN,,.PRIOU]
	MOVEM A,GJBLK+.GJSRC
	MOVEI A,.GJALL		;DEFAULT VERSION TO *
	HRRM A,GJBLK+.GJGEN
	RET
;HERE WHEN FIRST FILSPEC TYPED, BUT WAS IN ERROR.
;CHECK FOR "OK" GTJFN ERROR:  ALL POSSIBLE "FILE NOT FOUND" CODES.
;ERROR CODE IN B, COMND FLAGS IN A

DUMP2:	TXNE A,CM%ESC		;USER ATTEMPTED RECOGNITION?
	 JRST DUMP22		;YES-- GIVE HIM THE ERROR NOW
	MOVE C,[POINT 18,OKGJXL] ;GET POINTER TO LIST OF OK CODES
	MOVEI D,OKGJXZ		;GET SIZE OF LIST
DUMP21:	ILDB A,C		;GET A CODE FROM TABLE
	CAME A,B		;MATCH ERROR GIVEN?
	 SOJG D,DUMP21		;NO-- LOOP FOR ALL POSSIBLE OK ERRORS
	JUMPLE D,DUMP22		;NOT AN OK ERROR-- TYPE ERROR MESSAGE
	MOVE Q2,B		;ERROR IS FILE NOT FOUND-- REMEMBER CODE TO BE
				; PUT IN JF2LST AND CHECKED WHILE SCANNING
	MOVX A,GJ%OFG		;SET UP TO PARSE-ONLY THE NOT-FOUND FILESPEC
	HLLM A,GJBLK+.GJGEN	; . .
	MOVEI A,CBLK		;GET COMMAND STATE BLOCK ADDRESS
	MOVEI B,[FLDDB. (.CMFIL)] ;ONLY PARSE FILE-SPEC
	COMND			; . .
	TXNE A,CM%NOP		;THIS SHOULD ALWAYS SUCCEED!!
DUMP22:	 ERRORJ BMBCM1,<?NOT A SWITCH OR FILESPEC>

;HERE WHEN FIRST FILESPEC HAS BEEN TYPED
;JFN OF FILE IN B

DUMP4:	CALL ADLIST		;ADD FILE TO JFNSTACK
	SKIPN Q2		;DON'T CHECK DEVICE IF FILE-NOT-FOUND
	 CALL CHKDVC		;DO A DVCHR FOR LEGAL DEVICE
	JUMPGE Q1,[ERROR (BMBCM1,<?TOO MANY ITEMS IN FILESPEC LIST>)]
	MOVEM B,JFNLST(Q1)	;SAVE JFN
	MOVEM Q2,JF2LST(Q1)	;SET NO DESTINATION YET, ZERO OR ERROR CODE IF FILE-NOT-FOUND
	AOBJN Q1,.+1
	TXNN F,USRDAT		;"CREATE" SPECIFIED?
	TXNE B,GJ%DIR		;* FOR DIRECTORY?
	TXO F,SAVUSF		;YES, IMPLIES USER INFO ALSO

;HERE TO TRY FOR COMMA OR END OF LIST

	MOVEI B,[FLDDB. (.CMNOI,,<TXTPTR (<AS>)>)]
	COMND
	MOVX B,GJ%OFG
	HLLM B,GJBLK+.GJGEN	;PARSE ONLY
	CALL OFNAME		;MAKE UP OUTPUT NAME DEFAULT
	MOVEI B,LIT1
	MOVEI A,CBLK
	COMND
	TXNE A,CM%NOP
	ERRORJ BMBCM1,<?INVALID FILE GROUP DESCRIPTOR>
	LOAD C,CM%FNC,0(C)	;GET CODE USED
	CAIN C,.CMCMA		;COMMA?
	JRST DUMP1		;YES
	CAIN C,.CMCFM		;TERMINATOR?
	JRST DUMP5		;YES
	CALL ADLIST		;OUTPUT FILE SPEC
	SKIPN JF2LST-1(Q1)	;FIRST SPEC NOT FOUND?
	 MOVEM B,JF2LST-1(Q1)	;NO-- SAVE THIS JFN AS DESTINATION
DUMP5:	MOVEI A,CBLK		
	MOVEI B,[FLDDB. (.CMCFM,,,,,[FLDDB. (.CMCMA)])]
	COMND
	TXNE A,CM%NOP
	ERROR BMBCM1,<?COMMA OR CARRIAGE RETURN REQUIRED>
	LOAD C,CM%FNC,0(C)	;GET CODE USED
	CAIE C,.CMCFM		;TERMINATOR?
	JRST DUMP1		;NO, ASSUME COMMA. TRY AGAIN
	CALL JFNCFM		;FIX UP JFN STACK
	SETOM CEXFLG		;INDICATE INTERRUPTABLE COMMAND
	MOVEM Q1,NIJFN		;SAVE IN CASE OF ^E 
	MOVNI Q1,0(Q1)		;SAVE NUMBER OF JFNS SETUP
	MOVEM Q1,NJFN
	GTAD			;GET NOW
	MOVEM A,BGNTAD		;KEEP TIME AT START OF SAVE
	SETZM TOTFIL		;INIT DUMP COUNTS
	SETZM TOTCNT
	SETZM LSTDIR		;RESET LAST DIRECTORY NAME
	SETZM INIPGN		;RESET CONTINUED FILE PAGE
	TXNN F,TNSF		;SKIP IF TAPE # SET
	SETZM TAPNO		; START AFTER TAPE 0

;LOOP THROUGH JFNLST FOR ALL FILESPECS TYPED

	TXZ F,DMPFLF		;INDICATE NO VALID JFNS FOUND YET
	HRLZ P5,NJFN		;SET TO SCAN JFN LIST

;IF THIS JFN HAD A "FILE-NOT-FOUND", THEN PRINT WARNING

DUMPL1:	MOVE B,JF2LST(P5)	;GET ERROR CODE OR OUTPUT JFN
	TXNN B,1B18		;ERROR CODE (6XXXXX) OR JFN?
	 JRST DUMPL2		;JFN, IT'S OK
	TMSGC <% >
	MOVX A,.PRIOU		;SET TTY
	MOVE B,JF2LST(P5)	;GET ERROR CODE BACK
	HRLI B,.FHSLF		;MYSELF, ERROR CODE NOW IN B
	MOVX C,0		;NO LIMIT
	ERSTR			;TYPE ERROR MESSAGE
	 JFCL			; . .
	 JFCL			; . .
	TMSG < - >
	MOVX A,.PRIOU		;OUTPUT FILESPEC THAT FAILED
	MOVE B,JFNLST(P5)	;GET JFN FOR IT
	MOVX C,0		;DEFAULT OUTPUT
	JFNS			;TYPE FILE SPEC
	TMSG <
>
	JRST DUMPL5		;IGNORE THE FILE

;VALID JFN-- SEE IF OUTPUT DIRECTORY HAS CHANGED

DUMPL2:	TXNE B,GJ%DIR		;SKIP IF OUTPUT DIRECTORY NOT WILD
	JRST DUMPL3
	HRROI A,ODRNAM		;OUTPUT DIR NAME
	MOVX C,<FLD(.JSAOF,JS%DEV)+FLD(.JSAOF,JS%DIR)+JS%PAF>
	JFNS
	HRROI A,DIRNAM		;OUTPUT DIR NAME
	MOVE B,JFNLST(P5)	;INPUT JFN
	JFNS
	HRROI A,ODRNAM		;OUTPUT DIR NAME
	HRROI B,DIRNAM		;INPUT DIRECTORY NAME
	STCMP
	SKIPN A			;SKIP IF STRINGS ARE DIFFERENT
DUMPL3:	TXZA F,DIRCHG		;OUTPUT DIR SAME AS INPUT DIRECTORY
	TXO F,DIRCHG		;DIRECTORY IS DIFFERENT

;SCAN THIS JFN FILE GROUP FOR ALL ITS FILES

	TXON F,DMPFLF		;INDICATE A VALID JFN FOUND, FIRST ONE?
	 CALL DMPFI1		;YES-- START NEW TAPE
	MOVE A,JFNLST(P5)	;PICK UP JFN
	SKIPE INIJFN		;SKIP IF NO INITIAL JFN
	JRST [	HRR A,INIJFN	;GET INITIAL JFN
		SETZM INIJFN	;USED UP NOW
		SETOM ININUM	;FLAG BEGUSR CODE
		JRST .+1]
	CALL SCNJFG		;SCAN THIS GROUP
DUMPL5:	AOBJN P5,DUMPL1		;LOOP FOR ALL GROUPS

;ALL DONE WITH ALL FILESPECS

	TXNN F,DMPFLF		;ANY VALID JFN'S FOUND?
	 ERROR DUMPL9,<%No files dumped>
	CALL ENDTAP		; TERMINATE TAPE
	CALL MTCLS		;CLOSE MAGTAPE
	BTMSG <

Total files dumped = >
	MOVE B,TOTFIL
	MOVEI C,12
	CALL BTNOUT
	BTMSG <
Total pages dumped = >
	MOVE B,TOTCNT
	MOVEI C,12
	CALL BTNOUT
	BTMSG <
>
DUMPL9:	SKIPN A,LPTJFN
	RET			;DONE IF NO LISTING
	CLOSF
	 JFCL
	RET
;SCAN FILE GROUP DESCRIPTOR
; A/ JFN

SCNJFG:	TXO A,GN%DIR+GN%NAM+GN%EXT ;NOTE ALL FIELDS CHANGED
	MOVEM A,SCNJFN		;SAVE JFN AND FLAGS
	HRROI A,DEVNAM		;GET CURRENT FULL FILE-SPEC,
	MOVE B,SCNJFN		; INCLUDING WILDCARDS, FOR FIXBCK
	MOVX C,<FLD(.JSAOF,JS%DEV)+FLD(.JSAOF,JS%DIR)+FLD(.JSAOF,JS%NAM)+FLD(.JSAOF,JS%TYP)+FLD(.JSAOF,JS%GEN)+JS%PAF>
	JFNS
	HRROI A,RCDSTR		;SET TO BUILD STR:<*>, FOR RCDIR
	MOVX C,<FLD(.JSAOF,JS%DEV)+FLD(.JSAOF,JS%DIR)+JS%PAF>
	MOVE B,SCNJFN
	JFNS			;GET STRUCTURE NAME
	SETZM RCDNUM		;NONE YET
SCNLUP:	MOVE A,SCNJFN
	HRRZM A,JFN		;SETUP SINGLE JFN FOR ROUTINES
	TXNE A,GN%DIR		;DIRECTORY CHANGED?
	CALL BEGUSR		;YES
	CALL DMPFIL		;DO THE FUNCTION
	MOVE A,SCNJFN
	GNJFN			;STEP TO NEXT FILE
	 JRST ENDU		;NO MORE
	XOR A,SCNJFN		;SET CHANGED BITS
	ANDX A,GN%DIR+GN%NAM+GN%EXT
	XORB A,SCNJFN
	TXNE A,GN%DIR		;DIRECTORY CHANGED?
	CALL ENDUSR		;YES, CLEANUP USER
	JRST SCNLUP
;END OF GROUP

ENDU:	CALL ENDUSR		;CLEAN UP LAST USER
	TXNN F,SAVUSF		;DOING USER DATA?
	JRST ENDU2		;NO - SKIP THIS
ENDU1:	MOVX A,RC%STP!RC%AWL	;MAKE SURE WE GOT ALL DIRECTORIES
	HRROI B,RCDSTR
	MOVE C,RCDNUM		;LAST NUMBER
	RCDIR			;STEP
	TXNN A,RC%NMD		;MORE?
	JRST [	MOVEM C,RCDNUM	;YES - SAVE NUMBER
		CALL DMPUSR	;DUMP USER INFO
		JRST ENDU1]	;LOOP TILL DONE
ENDU2:	SKIPN INCRSW		;INCREMENTAL?
	RET			;NO, DONE
	MOVX A,GJ%OLD+GJ%IFG+GJ%PHY+GJ%SHT
	HRROI B,DEVNAM		;GET JFN FOR ALL FILES ON THIS DEVICE
	GTJFN
	 JSERR
	MOVEM A,SCNJFN
SCNLU1:	HRRZ A,SCNJFN
	CALL FIXBCK		;NOTE INCREMENTAL DUMP COMPLETED FOR FILE
	MOVE A,SCNJFN
	GNJFN			;STEP JFN
	 JRST [	CAIE A,GNJFX1	;DONE?
		CALL JSERR1	;NO, SCREWUP
		RET]
	JRST SCNLU1
;BEGIN NEW TAPE

DMPFI1:	MOVSI A,(1B1)		;SAY MUCHO TAPE LEFT
	MOVEM A,TAPLFT
	CALL LPTOPN		;REOPEN LPT
	MOVEI B,1
	MOVEM B,LPTPAG		;INIT PAGE NUMBER
	MOVX B,OF%WR
	CALL MTOPEN		;REOPEN MTA
	TXZN F,TNSF		;SKIP IF TAPE NUMBER SET
	AOS TAPNO		;COUNT TAPES
	CALL UNMAPB		;RESET BUFFERS
	MOVEI B,CURFMT		;THE CURRENT FORMAT
	MOVEM B,BUFF		;TO THE HEADER
	MOVE B,BGNTAD		;BEGINNING TAD
	MOVEM B,BUFF+BFTAD
	MOVEI B,BFMSG		;OFFSET FOR MESSAGE
	MOVEM B,BUFF+BFMSGP	;TO THE HEADER AS WELL
	MOVE A,[POINT 7,BUFF+BFMSG] ;LOC IN HEADER FOR SSNAME
	MOVE B,[POINT 7,SSNBUF]
	MOVEI C,0
	SOUT			;COPY SET NAME TO HEADER
	MOVNI A,TPHDX
	SKIPE B,INIPGN		;SKIP IF NOT CONTINUED FILE
	MOVNI A,CTPHX		;CONTINUED TAPE HEADER
	MOVEM B,PAGNO		;SAVE INITIAL PAGE NUMBER
	MOVEM A,TYP
	CALL MTOUT
	MOVE A,[POINT 7,LSTHDR]	;SET TO BUILD LISTING HEADER MESSAGE
	CALL PRHEDR		;BUILD IT
	HRROI B,LSTHDR
	CALL BTMSGQ		;TYPE AND PRINT IT
	BTMSG <
>
	LPMSG <
Directory (number)
>
PRTHDR:	MOVEI B,FLCOL
	CALL TAB		;POSITION FILE COLUMN HEADING
	LPMSG <file>
	MOVEI B,WTCOL		;DO LIST COLUMN HEADINGS
	CALL TAB
	LPMSG <last write>
	MOVEI B,SIZCOL
	CALL TAB
	LPMSG <size (pages)>
	MOVEI B,CSCOL		;TAB TO CHECKSUM COLUMN
	CALL TAB		;TAB OVER
	LPMSG <checksum
>
	RET
;DUMP ONE FILE

DMPFIL:	MOVEI A,[CALL NDMESS	;PRINT REASON FOR ERROR
		 CALL UNMAPB	;RESET BUFFERS
		 TMSG <% File skipped
>
		 JRST DMPFIX]	;SKIP TO NEXT FILE
	CALL SETTRP		;SET TRAP FENCE
	MOVE A,JFN
	MOVE B,[.FBLN0,,0]
	MOVEI C,FDB
	GTFDB			;READ ENTIRE FDB
	 ERJMP [CALL JSERR1	;FAILED
		RET]
	MOVE B,FDB+.FBCTL	;GET BITS
	TXNE B,FB%NXF!FB%NEX!FB%DEL!FB%TMP
	JRST DMPFIZ
	TXNE	F,ICMODF	;SKIP IF NOT INTERCHANGE MODE
	JRST DMPFI2		;SKIP IT
	HRR A,JFN		;PIC UP FILE JFN
	HRLI A,.GFAUT
	HRROI B,FDBAUT		;STORE AUTHOR HERE
	GFUST
	 ERJMP [SETZM FDBAUT	;SET AS NULL
		JRST .+1]
	HRLI A,.GFLWR		;FUNCTION IS LAST WRITER
	HRROI B,FDBLWR
	GFUST			;GET LAST WRITER
	 ERJMP [SETZM FDBLWR
		JRST .+1]
DMPFI2:	MOVE A,[POINT 7,NAMBUF]
	MOVEI C,0
	HRROI B,DIRNAM		;COPY CURRENT DIRECTORY NAME
	SOUT
	MOVEM A,NAMPTR
	MOVE B,JFN
	MOVX C,1B8+1B11+1B14+1B35
	JFNS
	MOVE B,FDB+.FBCTL
	TXNE B,FB%NOD		;IS THIS FILE NOT TO BE DUMPED?
	JRST NODUMP		;YES, DONT DUMP IT
	MOVE A,FDB+.FBCRE	;GET LAST MODIFICATION DATE
	CAMG A,MBTAD		;NOT 'BEFORE'?
	CAMGE A,MSTAD		;NOT 'SINCE'?
	JRST NODUMP		;YES, DON'T DUMP
	MOVE A,FDB+.FBWRT	;GET LAST WRITE DATE
	CAMG A,WBTAD		;NOT 'BEFORE'?
	CAMGE A,WSTAD		;NOT 'SINCE'
	JRST NODUMP		;YES, DON'T DUMP
	CAMGE A,FDB+.FBREF	;GET MOST RECENT OF WRITE, READ
	MOVE A,FDB+.FBREF
	CAMG A,ABTAD		;NOT 'BEFORE'?
	CAMGE A,ASTAD		;NOT 'SINCE'?
	JRST NODUMP		;YES, DON'T DUMP
	; ..
	; ..
	SKIPLE A,INCRSW		;SKIP IF NOT INCREMENTAL OR /FULL-INCREMNTAL
	 JRST [	HLRZ B,FDB+.FBCNT ;GET COUNT OF WRITES
		HLRE C,FDB+.FBBK0 ;GET TAPE COUNT AND FLAG
IFL <VMAJOR-4>,<
		CAIN C,0	;OLD TAPE, SAVE COUNT= 0?
		 MOVEI C,1	;YES-- ASSUME ONE
>
		HRRZ D,FDB+.FBBK0 ;GET LAST WRITE COUNT OF SAVE
		CAMN B,D	;SAME WRITE COUNT?
		CAMGE C,A	;YES-- HAS IT BEEN SAVED ENOUGH TIMES?
		 JRST .+1	;NO-- DUMP THE FILE
		JRST NODUMP]	;YES-- DON'T DUMP IT

;FILE WILL BE DUMPED

	CALL TSTEOT		;CHECK TO MAKE SURE FILE WILL FIT ON TAPE
	SKIPN INIPGN		;SKIP IF CONTINUED FILE
	JRST DMPF4		;NO
	LPMSG <
(File continued from previous reel)
>
DMPF4:	CALL GOFNAM		;MAKE UP TAPE FILE NAME
	MOVEI B,FLCOL
	CALL TAB		;TAB TO FILESPEC COLUMN
	MOVE B,ONMPTR		;PRINT FILE NAME
	CALL LPMSGQ		;NAME TO LISTING
	MOVEI B,WTCOL		;TAB TO WRITE COLUMN
	CALL TAB
	SKIPN NOFILS		;FIRST FILE THIS USER?
	CALL TDRNAM		;TYPE DIRECTORY NAME
	TXNE F,LFILF		;TYPE FILE NAMES REQUESTED?
	TXNE F,LTTYF		;AND NOT LOGGING TO TTY?
	JRST DMPF2		;NO
	MOVE B,NAMPTR		;YES, TYPE NAME
	CALL TMSGQ
	TMSG < (AS) >
	MOVE B,ONMPTR
	CALL TMSGQ		;TYPE OUTPUT NAME
DMPF2:	MOVE A,JFN
	HRLOM A,LASTID		;REMEMBER FILE IN CASE ERROR ON OPENF
	MOVX 2,OF%RD+OF%PDT	;READ AND PRESERVE ACCESS DATES
	OPENF
	 JRST [	MOVE A,JFN
		MOVX B,OF%RD+OF%THW+OF%PDT ;TRY THAW MODE
		OPENF
		 JRST [ CALL NDMESS ;PRINT REASON
			RET]
		JRST .+1]
	MOVE A,[POINT 7,BUFF]	;SET TO PUT NAME IN FILE HEADER
	HRROI B,ONMBUF
	SETZ C,
	SOUT			;COPY FILESPEC THROUGH VERSION
	CALL GOFPAT		;GET OUTPUT PROTECTION, ACCOUNT AND ;T
	MOVEI B,0
	IDPB B,A
	MOVE A,[FDB,,BUFF+FHFDB]
	BLT A,BUFF+FHFDB+.FBLN0-1+20 ;COPY FDB TO HEADER
	TXNE F,CHKSM		;SKIP IF NOT CHECKSUMMING
	CALL [	SKIPE INIPGN	;SKIP IF START OF FILE
		RET		;MIDDLE OF FILE
		SETZM CHKCN0	;INITIALIZE CHECKSUM
		SETZM LSTPGE	;AND PAGE #
		CALL FILSZE	;FIGURE FILE SIZE
		RET]
	MOVNI A,FLHDX
	MOVEM A,TYP
	CALL MTOUT
	SKIPN LPTJFN
	JRST DMPF1
	HRROI A,LPTBUF		;SET TO GET WRITE TAD STRING
	SKIPN B,FDB+.FBWRT	;HAVE ONE?
	JRST [	LPMSG <(NEVER)>	;NO
		JRST DMPF1]
	MOVX C,1B10+1B12+1B17
	ODTIM			;CONVERT TO STRING
	HRROI B,LPTBUF
	CALL LPMSGQ		;COPY TO LISTING
DMPF1:	MOVEI B,SIZCOL		;TAB TO NEXT COLUMN
	CALL TAB
	SKIPGE A,INIPGN		;SKIP IF NOT MIDDLE OF FILE
	JRST [	HRL A,JFN	;GET JFN 
		MOVE B,INICNT	;SAVE SAVED COUNTER
		MOVEM B,CNTR	;STORE IT
		JRST DMPF3]
	MOVE A,FDB+.FBBYV	;GET SIZE
	HRRZM A,CNTR
	HRLZ A,JFN
	AOS NOFILS
DMPF3:	SETZM INIPGN		;BE SURE INIPGN OFF
	SETZM CURBUF		;NO PAGES MAPPED YET
	; ..
DMPLUP:	MOVEM A,PAGNO		; SAVE IN CASE NO PAGES ARE FOUND
	SKIPG TAPLFT		;ANY TAPE LEFT?
	JRST DMPEOT		;NO, CLOSE OUT REEL
	MOVE A,PAGNO
	RPACS			;GET PAGE ACCESS BITS
	MOVEM B,ACCESS		;SAVE IT
	TXNE B,PA%PEX		;PAGE EXISTS?
	JRST DMPIT		;YES - DUMP IT
	FFUFP			;NO - SEARCH FOR FIRST EXISTING
	 JRST DMPLUX		;NONE FOUND - DONE
	RPACS			;GET ACCESS INFO
	MOVEM B,ACCESS		;...
	MOVEM A,PAGNO		;UPDATE PAGE NUMBER
DMPIT:	SKIPN CURBUF		;FIRST TIME HERE?
	JRST DMPL1		;YES - SET UP WINDOW
	HRRZ B,A		;GET PAGE DESIRED
	HRRZ C,LASTID		; BASE PAGE # IN WINDOW
	SUB B,C			;SEE IF INSIDE WINDOW
	CAMGE B,NBUF		;...
	JRST [	IMULI B,PGSIZ	;YES - CALC BUFFER ADDRS
		ADDI B,BUF0	;BASE ADDR
		HRRZM B,CURBUF	;SET BUFFER ADDRS
		JRST DMPL2]	;CONTINUE
DMPL1:	MOVEM A,LASTID		;SAVE BASE PAGE INFO
	MOVE B,[.FHSLF,,BUF0PG]
	MOVX C,PM%RD!PM%PLD!PM%CNT
	HRR C,NBUF		;NUMBER OF PAGES TO MAP
	PMAP
	 ERJMP .+1		;IN CASE NON-EX PT
	MOVEI B,BUF0		;SETUP CURBUF
	MOVEM B,CURBUF
DMPL2:	SETZM TYP
	TXNE F,CHKSM		;SKIP IF NOT CHECKSUMMING
	CALL [	HRRZ A,CURBUF	;CURRENT BUFFER
		LSH A,-11	;PAGE #
		HRLI A,.FHSLF
		MOVE B,[.FHSLF,,BUFPAG]
		MOVX C,PM%RD
		PMAP		;POINT TO CURRENT BUFFER
		CALLRET PGECSM]
	CALL MTOUT
	SOS CNTR
	AOS A,PAGNO		;INCREMENT PAGE #
	TRNE A,777777
	JRST DMPLUP
DMPLUX:	TXNE F,ICMODF		;SKIP IF NOT INTERCHANGE MODE
	TRNE A,777777		;ZERO LENGTH FILE ?
	JRST DMPLX2		;NOT INTERCHANGE OR NOT ZERO 
				;LENGTH FILE
	MOVEI A,BUFF		;USE THIS BUFFER
	MOVEM A,CURBUF		;...
	SETZM TYP		;DATA TYPE PAGE
	CALL MTOUT
DMPLX2:	SKIPG CNTR
	JRST DMPLX1
	BTMSG <
% Cannot find all the pages of file >
	HRROI B,NAMBUF
	CALL BTMSGQ		;TYPE FILESPEC
	BTMSG <
>
	; ..
DMPLX1:	CALL UNMAPB		;RESET BUFFERS
	MOVE A,[FDB,,BUFF]
	BLT A,BUFF+.FBLN0-1+20	;COPY FDB TO TRAILER BLOCK
	MOVNI 1,FLTRX
	MOVEM 1,TYP
	SKIPE INCRSW		;INCREMENTAL?
	 JRST [	HLRZ B,BUFF+.FBCNT	;GET COUNT OF WRITES
		MOVE C,BUFF+.FBBK0	;GET LAST BACKUP WORD
		CAIN B,(C)		;SAME WRITE COUNT AS LAST SAVE?
		SKIPGE INCRSW		;YES-- BUT FULL-INCREMENTAL?
		 HRRZ C,B		;FULL OR NEW WRITE-- SET TAPE COUNT TO 0
					; AND WRITE COUNT TO NEW WRITE COUNT
		TXO C,1B0		;INDICATE INCOMPLETE DUMP
		MOVE A,JFN
		HRLI A,.FBBK0
		TXO A,CF%NUD		;SUPPRESS DIRECTORY UPDATE
		MOVNI B,1		;CHANGE ALL BITS
		CHFDB			;NOTE DUMP PARTIALLY DONE
		TXZ C,1B0		;STORE FDB ON TAPE
		ADD C,[XWD 1,0]		; AS IF
		MOVEM C,BUFF+.FBBK0	; DUMP COMPLETED SUCCESSFULLY
		JRST .+1]
	CALL MTOUT		;OUTPUT TRAILER RECORD
	TXNE F,LFILF		;TYPE FILE NAMES ?
	TXNE F,LTTYF		;AND NOT LOGGINT TO TTY?
	 JRST DMPLX3
	TMSG <	[OK]
>
DMPLX3:	HRRZ B,FDB+.FBBYV	;GET SIZE
	ADDM B,USRCNT		;COUNT PAGES FOR THIS DIR
	MOVEI C,^D10
	CALL LPNOUT		;OUTPUT SIZE TO LISTING
	TXNE F,CHKSM		;SKIP IF NOT CHECKSUMMING
	CALL PRTCSM		;PRINT CHECKSUM
	LPMSG <
>
DMPFIX:	MOVE A,JFN
	TXO A,CO%NRJ		;NO RELEASE JFN
	CLOSF			;CLOSE FILE
	 JFCL
NODUMP:
DMPFIZ:	RET			;DONE WITH FILE
;FILE NOT DUMPED

NDMESS:	TMSG <
% File >
	HRROI B,NAMBUF
	CALL TMSGQ		;TYPE FILESPEC
	TMSG < not dumped because:
  >
	CALL JSERRM		;PRINT REASON SYSTEM GAVE
	HRROI B,[ASCIZ /not dumped/]
	CALL LPMSGQ
	RET			;RETURN
;ENCOUNTERED END OF TAPE IN THE MIDDLE OF FILE.
;REMEMBER CURRENT FILE POSITION FOR NEXT REEL.

DMPEOT:	CALL UNMAPB		;RESET BUFFERS
	MOVE A,[FDB,,BUFF]
	BLT A,BUFF+.FBLN0-1+20	;COPY FDB TO FILE TRAILER
	MOVNI 1,FLTRX
	MOVEM 1,TYP		;SET RECORD TYPE TO FILE TRAILER
	HRROS B,PAGNO		;GET CURRENT PAGE NUMBER
	MOVEM B,INIPGN		;MARK TO CONTINUE FILE ON NEXT REEL
	MOVE B,CNTR		;SAVE COUNTER
	MOVEM B,INICNT		;...
	CALL MTOUT		;WRAP UP FILE IN USUAL WAY
	LPMSG <
(File continued on next reel)
>
	MOVE A,JFN
	HRLI A,(1B0)		;SAY DON'T RELEASE JFN
	CLOSF			;CLOSE THE FILE
	 JFCL
	CALL TSTEOT		;START NEW TAPE
	JRST DMPFIL		;RESTART THIS FILE


;ROUTINE TO CONTINUE SAVE ON NEXT TAPE IF NO TAPE LEFT

TSTEOT:	SKIPLE TAPLFT		;ANY TAPE LEFT?
	 RET			;YES-- ALL OK
	SETOM PAGNO		;INDICATE CONTINUED TAPE TRAILER
	CALL ENDTAP
	CALL UNLOAD
	CALL MTCLS		;CLOSE MTA
	SKIPN A,LPTJFN		;SKIP IF LISTING
	JRST TSTET1
	CLOSF			;CLOSE LISTING FILE
	 JFCL
TSTET1:	TMSG <
$ End of tape, continue save on
>
	CALL NTAPE		;GET NEW TAPE SPEC
	CALLRET DMPFI1		;START NEXT TAPE, RETURN FROM TSTEOT
;ROUTINE TO RESET FILE WINDOW AND CURBUF

UNMAPB:	SETO A,
	MOVE B,[.FHSLF,,BUF0PG]
	MOVX C,PM%CNT		;SET NUMBER OF PAGES
	HRR C,NBUF
	PMAP			;REMOVE THEM
	HRRI B,BUFPAG
	SETZ C,			;ONLY ONE PAGE
	PMAP
	MOVEI A,BUFF		;SET THIS TO BE CURRENT BUFFER
	MOVEM A,CURBUF
	RET			;RETURN
BEGUSR:	TXNE F,DIRCHG		;SKIP IF SAVING AS SAME DIRECTORY
	JRST BEGUS1
	HRROI A,DIRNAM
	HRRZ B,JFN		;GET CURRENT DIRECTORY NAME STRING
	MOVX C,1B2+1B5+1B35
	JFNS
	HRROI B,DIRNAM
	MOVX A,RC%EMO		;EXACT MATCH ONLY
	RCDIR
	 ERJMP BEGUS3		;RCDIR FAILURE
	TXNE A,RC%NOM!RC%AMB
	JRST BEGUS3		;REPORT ERROR
	MOVEM C,DIRNUM		;SAVE DIRECTORY NUMBER
	TXNN F,SAVUSF		;WANT USER DATA?
	JRST BEGU2		;NO - SKIP THIS
BEGU1:	MOVX A,RC%AWL		;ALLOW WILDCARDS
	SKIPE C,RCDNUM		;FIRST TIME HERE?
	TXO A,RC%STP		;NO - STEP DIRECTORIES
	HRROI B,RCDSTR
	RCDIR
	TXNE A,RC%NMD
	JRST [	TMSGC <?RCDIR out of sync on directories
>
		TXZ F,SAVUSF	;TURN THIS OFF
		JRST BEGU2]
	MOVEM C,RCDNUM		;SAVE WHERE WE ARE
	SKIPE ININUM		;HAD INITIAL FILESPEC
	JRST [	CAME C,DIRNUM	;CAUGHT UP?
		JRST BEGU1	;NO - CONTINUE
		SETZM ININUM	;DONE WITH INITIAL DDB
		JRST BEGU1A]	;DUMP THIS DIRECTORY
	CAME C,DIRNUM		;THE ONE WE WANT?
	JRST [CALL DMPUSR	;NO - DUMP A DIR
		JRST BEGU1]	;LOOP TO CATCH UP
BEGU1A:	CALL DMPUSR		;YES - DUMP USER INFO AND PROCEED
BEGU2:	LPMSG <
>
	SETZM USRCNT
	SETZM NOFILS
	HRROI B,DIRNAM
	CALL LPMSGQ		;PRINT DIR NAME
	LPMSG < (>
	HRRZ B,DIRNUM
	MOVEI C,^D8
	CALL LPNOUT		;PRINT DIR NUM FOR INFO
	LPMSG <)

>
	RET

;HERE IF DIRECTORY NAME ON DISK .NE. DIRECTORY NAME ON TAPE
BEGUS1:	HRROI A,ODRNAM		;CURRENT DIRECTORY NAME
	HRROI B,LSTDIR		;LAST DIRECTORY NAME
	STCMP
	JXE A,SC%LSS+SC%SUB+SC%GTR,BEGUS2
	CALL TSTEOT		;SEE IF ROOM ON TAPE FOR THIS DDB
	HRROI B,ODRNAM		;NEW DIRECTORY
	HRROI A,LSTDIR
	SETZ C,
	SOUT
	SETZM USRCNT
	SETZM NOFILS		;RESET # FILES
	HRROI B,ODRNAM		;NAME OF DIRECTORY
	CALL LPMSGQ
	LPMSG <

>
	SETZM BUFF
	MOVE B,[XWD BUFF,BUFF+1]
	BLT B,BUFF+777
	MOVE B,[XWD ODRNAM,BUFF+UHNAM]
	BLT B,BUFF+UHNAM+17
	MOVNI A,USRX
	MOVEM A,TYP		;STORE RECORD TYPE
	CALL MTOUT
BEGUS2:	RET

;RCDIR FAILURE - PRINT MESSAGE

BEGUS3:	TMSGC <?RCDIR failure for - >
	HRROI A,DIRNAM		;TELL ON DIRECTORY
	PSOUT
	TMSG <
>
	RET			;RETURN
;DUMP USER INFORMATION

DMPUSR:	STKVAR <DMPNUM>
	MOVEM C,DMPNUM		;SAVE NUMBER OF DIRECTORY
	CALL TSTEOT		;MAKE SURE WE HAVE SOME TAPE FOR DDB
	SETZM BUFF
	MOVE B,[XWD BUFF,BUFF+1]
	BLT B,BUFF+777
	TXNE F,SAVUSF		;NOT WHEEL OR USER DATA NOT WANTED?
	SKIPN WHEEL
	JRST DMPUS1		;YES, DON'T DUMPER DIR INFO
	MOVEI A,BUFF+CDSG	;SET UP BUFFER TO RECEIVE SUB GROUPS
	MOVEM A,BUFF+.CDCUG
	MOVEI A,BUFF+CDUG	;SET UP BUFFER TO RECEIVE USER GROUPS
	MOVEM A,BUFF+.CDUGP
	MOVEI A,BUFF+CDDG	;SET UP BUFFER TO RECEIVE DIR GROUPS
	MOVEM A,BUFF+.CDDGP
	MOVEI A,UGLEN		;LENGTH OF BUFFERS FOR GROUPS
	MOVEM A,BUFF+CDUG
	MOVEM A,BUFF+CDDG
	MOVEM A,BUFF+CDSG
	HRROI A,BUFF+UHACT	;POINT TO ACCOUNT STRING SPACE
	MOVEM A,BUFF+.CDDAC
	MOVEI A,.CDDAC+1	;CURRENT MAX SIZE
	MOVEM A,BUFF+.CDLEN
	MOVE A,DMPNUM
	MOVEI B,BUFF
	MOVE C,[POINT 7,BUFF+UHPSW]
	GTDIR
	 ERJMP [JSERR]
	MOVEI B,UHPSW		;SET PASSWORD OFFSET
	MOVEM B,BUFF+.CDPSW
	MOVEI B,UHACT		;SET POINTER TO ACCOUNT STRING
	MOVEM B,BUFF+.CDDAC
DMPUS1:	HRROI A,BUFF+UHNAM	;POINT TO NAME BUFFER
	MOVE B,DMPNUM		;THIS DIRECTORY NUMBER
	DIRST			;CONVERT TO STRING
	 JSHLT			;CANT HAPPEN
	MOVNI A,USRX
	MOVEM A,TYP
	CALL MTOUT
	RET
ENDUSR:	LPMSG <
>
	MOVEI B,FLCOL
	CALL TAB		;INDENT TOTAL
	SKIPN NOFILS
	JRST [	LPMSG <No files
>
		RET]
	LPMSG <Total >
	MOVX C,^D10
	MOVE B,NOFILS
	ADDM B,TOTFIL
	CALL LPNOUT
	LPMSG < files, >
	MOVX C,^D10
	MOVE B,USRCNT
	ADDM B,TOTCNT
	CALL LPNOUT
	LPMSG < pages
>
	SKIPN NOFILS		;SKIP IF FILES THIS DIRECTORY
	RET
	TXNN F,LFDSK		;SKIP IF LOGGING TO NON-SPOOLED
				;DISK FILE
	RET
	SKIPN A,LPTJFN		;GET LISTING JFN
	JRST ENDUS1		;NONE - RETURN
	TXO A,CO%NRJ		;KEEP JFN
	CLOSF			;UPDATE FILE
	ERROR ENDUS1,<?CANNOT CLOSE LOG FILE>
	HRRZ A,LPTJFN		;LOG FILE JFN
	MOVX B,<FLD (7,OF%BSZ)+OF%APP>
	OPENF
	SKIPA
ENDUS1:	RET
	MOVE A,LPTJFN
	RLJFN
	JFCL
	JRST LPTNAV
;OPEN LPT FOR LISTING FILE.  DONE AT BEGINNING OF EACH TAPE

LPTOPN:	SKIPN LSTFIL		;HAVE LOG FILE SPEC?
	JRST LPTOP1		;NO
	MOVX A,GJ%MSG+GJ%SHT	;MESSAGE AND SHORT FORM
	HRROI B,LSTFIL
	GTJFN
	 JRST LPTNAV
LPTOP0:	MOVEM A,LPTJFN
	DVCHR			;SEE WHAT DEVICE
	LOAD C,DV%TYP,A
	CAIN C,.DVTTY		;TTY?
	TXOA F,LTTYF		;YES
	TXZ F,LTTYF		;NO
	CAIE C,.DVDSK		;DISK?
	TXZA F,LFDSK		;LOG FILE NOT TO DISK
	TXO F,LFDSK		;IS DISK
	MOVE A,LPTJFN
	MOVX B,<FLD(7,OF%BSZ)+OF%APP>
	OPENF
	 JRST [	MOVE A,LPTJFN
		RLJFN
		JFCL
		JRST LPTNAV]
	SETZM LPTPOS		;INIT LIST VARIABLES
	SETZM LPTLIN
	RET

LPTNAV:	TMSGC <% Log file not available, >
	CALL JSERRM
LPTOP1:	TXZ F,LFDSK+LTTYF	;NOT DISK OR TTY
	SETZM LPTJFN		;SAY NO LISTING
	RET

;FIXUP FDB BACKUP WORD AFTER DUMP COMPLETED SUCCESSFULLY

FIXBCK:	MOVE A,JFN
	MOVE B,[XWD 1,.FBBK0]
	MOVEI C,C
	GTFDB
	JUMPGE C,R
	TXNN C,1B1		;NEGATIVE SAVE COUNT
	 TXZ C,1B0		;NO-- CLEAR THE PARTIAL DUMP FLAG
	ADD C,[XWD 1,0]		;INCREMENT TAPE COUNT
	HRLZI B,-1
	HRLI A,.FBBK0
	TXO A,CF%NUD		;NO UPDATE DIRECTORY
	CHFDB
	RET
	SUBTTL PSEUDO INTERRUPT ROUTINES

CHNMSK:	1B<CECHN>+1B<.ICPOV>+1B<.ICDAE>+17B<.ICIEX>+1B<.ICMSE>+1B<.ICQTA> ;CHANNELS USED

;TERMINAL INTERRUPT - ^E

CEINT:	MOVEM 17,INT3AC+17	;SAVE ACS
	MOVEI 17,INT3AC
	BLT 17,INT3AC+16
	MOVE P,[IOWD NINTPD,INT3PD]
	SKIPN CEXFLG		;EXECUTING COMMAND?
	JRST [	TMSGC <% No interruptable command in progress
>
		JRST CEINT1]
	SKIPE INTRQ		;ALREADY REQUEST PENDING?
	JRST [	TMSGC <% Interrupt request already in progress.
>
		JRST CEINT1]
	TMSG <
Interrupting...
>
	SETOM INTRQ		;REQUEST INTERRUPT
CEINT1:	MOVSI 17,INT3AC		;RESTORE ACS
	BLT 17,17
	DEBRK

;TEST FOR INTERRUPT REQUEST, RETURN IMMEDIATELY IF NONE.
;OTHERWISE, ENTER COMMAND INPUT AND RETURN WHEN 'CONTINUE' GIVEN

TSTINT:	SKIPN INTRQ		;INT REQUEST?
	RET			;NO
	POP P,INTPC		;YES, SAVE PC AND NOTE INTERRUPTED
	MOVE A,CMDTYP		;GET CURRENT COMMAND TYPE
	TXNN A,TY%DBL		;SKIP IF SAVE OR RESTORE COMMAND
	SETZM NIJFN		;DON'T SAVE JFNLST POINTER
	MOVEM A,ICMDTY		;SAVE AS INTERRUPTED COMMAND TYPE
	MOVEM P,IPDLP		;SAVE PUSH DOWN POINTER
	SETZM	INTRQ		;CLEAR INTERRUPT REQUEST
	MOVE A,CURPTR
	MOVEM A,CMDPTR
	SETZM CEXFLG		;COMMAND NO LONGER IN PROGRESS
	MOVE A,TRAPJ		;GET TRAP STUFF
	MOVEM A,ITRAPJ		;SAVE TRAP STUFF
	MOVE A,TRAPSP		;..
	MOVEM A,ITRAPS		;..
	JRST RESTRT		;GO TO COMMAND LEVEL

;'CONTINUE' COMMAND

$CONT:	CALL CONFRM
	SKIPN INTPC		;WERE INTERRUPTED?
	ERROR RESTRT,<?CANNOT CONTINUE>
	MOVE A,ICMDTY		;GET INTERRUPTED COMMAND TYPE
	MOVEM A,CMDTYP		;AND RESTORE
	SETZM ICMDTY		;INDICATE NO INTERRUPTED COMMAND
	MOVE A,ITRAPJ		;RESTORE TRAP STUFF
	MOVEM A,TRAPJ		;...
	MOVE A,ITRAPS		;...
	MOVEM A,TRAPSP		;...
	MOVE A,INIPTR		;RESET CMDPTR
	MOVEM A,CMDPTR		;...
	MOVE P,IPDLP		;RESTORE PDL
	SETOM CEXFLG		;YES, NOTE RESUMING EXECUTION
	MOVE A,INTPC		;GET PC
	SETZM INTPC		;ZERO INTERRUPT PC
	JRST 0(A)		;RETURN TO POINT OF INTERRUPTION

;CLEAR INTERRUPTED STATE AND PREVENT CONTINUATION.  USED AT TOP
;OF ALL ACTION COMMANDS
;UNEXPECTED TRAP LOGIC

;SET FENCE FOR TRAPS
; A/ WHERE TO GO IF UNEXPECTED TRAP

SETTRP:	POP P,CX		;GET LOCAL PC OFF STACK
	PUSH P,TRAPJ		;SAVE PREVIOUS FENCE
	PUSH P,TRAPSP
	MOVEM A,TRAPJ		;SAVE DISPATCH
	MOVEM P,TRAPSP		;SAVE STACK FENCE
SETTR1:	PUSHJ P,0(CX)		;CONTINUE ROUTINE
	 SKIPA			;NO SKIP RETURN
	AOS -2(P)
	POP P,TRAPSP		;RESTORE PREVIOUS FENCE
	POP P,TRAPJ
	RET

;UNEXPECTED TRAP HANDLERS

;ILLEG INSTRUCTION

ITRAP:	JSR EINT1		;SWITCH CONTEXT
	SKIPE TRAPJ		;TRAP FENCE?
	JRST ITRAP1		;YES - SKIP SYSTEM MESSAGE
	TMSGC <?>
	CALL JSERRM		;DO JSYS ERROR MESSAGE
ITRAP1:	SKIPE A,TRAPJ		;HAVE TRAP FENCE?
	JRST [	MOVEM A,INT1AC+CX ;YES, SETUP DISPATCH ADDRESS
		TMSG <
>
		MOVE A,TRAPSP	;AND RESET STACK TO FENCE
		MOVEM A,INT1AC+P
		MOVEI A,SETTR1	;DEBREAK ADDRESS
		JRST BADIXP]
	TMSG <  Command aborted
>
	MOVEI A,BMBCMD		;DEBREAK TO BOMB COMMAND
BADIXP:	MOVEM A,LPC1		;SET DEBREAK ADDRESS
BADIX:	MOVSI 17,INT1AC		;RESTORE ACS
	BLT 17,17
	DEBRK

BADINT:	TMSG <?PC = >
	HRRZ B,LPC1
	MOVEI C,^D8
	CALL TTNOUT		;PRINT PC
	TMSG <
>
	JRST ITRAP1

;HERE IF NO RECOVERY

BADEX:	HALTF
	JRST .-1		;CANT CONTINUE

;MEMORY READ TRAP

MEMRTP:	JSR EINT1		;SWITCH CONTEXT
	TMSGC <? Unexpected memory read trap in DUMPER
>
BADIVA:	TMSG <?VA = >
	MOVEI A,.FHSLF		;GET ADDRESS OF BAD REFERENCE
	GTRPW
	HRRZ B,A
	MOVEI C,^D8
	CALL TTNOUT		;REPORT IT
	TMSG <
>
	JRST BADINT		;CONTINUE AS FOR ITRAP

;MEMORY WRITE, EXECUTE TRAPS

MEMWTP:	JSR EINT1		;SWITCH CONTEXT
	TMSGC <? Unexpected memory write trap in DUMPER
>
	JRST BADIVA

MEMXTP:	JSR EINT1		;SWITCH CONTEXT
	TMSGC <? Unexpected memory execute trap in DUMPER
>
	JRST BADIVA

;MACHINE SIZE EXCEEDED

MSETRP:	JSR EINT1		;SWITCH CONTEXT
	TMSGC <?Disk full or quota exceeded. Type <CR> to attempt to continue >
	CALL RDLIN
	JRST BADIX		;DEBREAK WITHOUT CHANGING PC

;PDL OVERFLOW

PDLOV:	JSR EINT1		;SWITCH CONTEXT
	TMSGC <? PDL overflow trap in DUMPER
>
	JRST BADINT

;SETUP LEVEL 1 PSI CONTEXT
;	JSR EINT1

EINT1A:	MOVEM 17,INT1AC+17	;SAVE ACS
	MOVEI 17,INT1AC
	BLT 17,INT1AC+16
	MOVE P,[IOWD NINTPD,INT1PD] ;SETUP LOCAL STACK
	JRST @EINT1
LEVTAB:	LPC1
	LPC2
	LPC3

CHNTAB:	PHASE 0
	0
CECHN:!	3,,CEINT		;^E
	0
	0
	0
	0

	0
	0
	0
	1,,PDLOV		;STACK OVERFLOW
	1,,MSETRP		;QUOTA EXCEEDED
	2,,MEMERR		;FILE DATA ERROR

	0
	0
	0
	1,,ITRAP		;ILLEG INSTRUCTION TRAP
	1,,MEMRTP		;MEM READ
	1,,MEMWTP		;MEM WRITE

	1,,MEMXTP		;MEM XCT
	0
	1,,MSETRP		;MACHINE SIZE EXCEEDED
	REPEAT ^D35-.ICMSE,<0>
	DEPHASE
;PSI RECEIVED ON IO ERROR CHANNEL

MEMERR:	MOVEM 17,INT2AC+17
	MOVEI 17,INT2AC
	BLT 17,INT2AC+16
	MOVE P,[IOWD NINTPD,INT2PD] ;SETUP LOCAL STACK
	PUSH P,40
	MOVE 1,LASTID
	CAMN 1,LSTERO
	JRST MEMXIT
	MOVEM 1,LSTERO
	BTMSGC <? Disk error in file >
	HLRZ 1,LASTID
	GTSTS
	TLNN 2,(1B10)
	JRST [	BTMSG <(Unknown file name)>
		JRST MEMERZ]
	HRROI B,NAMBUF
	CALL BTMSGQ		;TYPE FILE NAME
	HRRZ 2,LASTID		;GET PAGE NUMBER
	CAIN 2,-1		;ON OPENF?
	JRST [	BTMSG <, page table>
		JRST MEMERZ]
	BTMSG <, page >
	HRRZ 2,LASTID
	MOVEI 3,^D10
	CALL TTNOUT		;TYPE PAGE NUMBER
	CALL LPNOUT		;PRINT "
MEMERZ:	BTMSG <
>
MEMXIT:	POP P,40
	MOVSI 17,INT2AC
	BLT 17,17
	DEBRK
SUBTTL	LOAD AND CHECK

LIT1:	FLDDB. (.CMFIL,CM%SDH,,<FILE GROUP DESCRIPTOR>,,LIT2)
LIT2:	FLDDB. (.CMCMA,,,,,LIT3)
LIT3:	FLDDB. (.CMCFM)


CHCK:	SETOM CHECK
	SETOM NJFN1		;FAKE ACTIVE JFN
	SKIPA
$LOAD:	SETZM CHECK
	SKIPE CHECK		;CHECK FUNCTION?
	JRST [	MOVEI B,[FLDDB. (.CMNOI,,<TXTPTR (<ALL MTA FILES>)>)]
		COMND
		MOVEI B,[FLDDB. (.CMCFM)]
		COMND		;YES, NO FURTHER QUESTIONS
		TXNE A,CM%NOP
		ERROR (RESTRT,<?CHECK TAKES NO PARAMETERS>)
		CALL JFNCFM		;FIX UP JFN STACK
		JRST LOAD2]
	MOVEI B,[FLDDB. (.CMNOI,,<TXTPTR (<MTA FILES>)>)]
	COMND
	SKIPE ICMDTY		;SKIP IF NOT UNDER ^E
	SKIPN Q1,NIJFN		;PICK UP OLD POINTER, IF ANY
	MOVSI Q1,-NJFNL+1	;INIT PTR TO JFN LIST
LOAD1:	CALL SETGJB		;SETUP JFN DEFAULTS
	MOVX A,GJ%OFG		;SET PARSE-ONLY FOR GTJFN
	HLLM A,GJBLK+.GJGEN
	MOVX A,.GJALL		;RESET * DEFAULT GEN
	HRRM A,GJBLK+.GJGEN
	MOVEI A,CBLK
	MOVEI B,[FLDDB. (.CMFIL,CM%SDH,,<FILE GROUP DESCRIPTOR>)]
	COMND			;GET AT LEAST ONE FILESPEC
	TXNE A,CM%NOP
	ERRORJ BMBCM1,<?INVALID FILE GROUP DESCRIPTOR>
	CALL ADLIST		;ADD FILE TO JFNSTACK
	JUMPGE Q1,[ERROR (BMBCM1,<?TOO MANY ITEMS IN FILESPEC LIST>)]
	MOVEM B,JFNLST(Q1)	;SAVE A JFN
	SETZM JF2LST(Q1)
	AOBJN Q1,.+1
	MOVEI B,[FLDDB. (.CMNOI,,<TXTPTR (<TO>)>)]
	COMND
	CALL OFNAME		;SETUP OUTPUT DEFAULTS
	MOVX B,GJ%OFG
	HLLM B,GJBLK+.GJGEN
	MOVX B,.GJNHG
	TXNE F,SSA		;SUPERSEDE ALWAYS?
	HRRM B,GJBLK+.GJGEN	;YES, DEFAULT GEN IS NEXT HIGHER
	MOVEI B,LIT1
	MOVEI A,CBLK		;POINT TO COMMAND BLOCK
	COMND			;GET MORE FILESPECS OR TERMINATOR
	TXNE A,CM%NOP
	ERRORJ BMBCM1,<?INVALID FILE GROUP DESCRIPTOR>
	LOAD C,CM%FNC,0(C)	;GET CODE USED
	CAIN C,.CMCMA		;COMMA?
	JRST LOAD1		;YES, ANOTHER SOURCE SPEC
	CAIE C,.CMCFM		;TERMINATED?
	JRST [	CALL ADFILE	;ADD JFN TO JFN STACK
		MOVEM B,JF2LST-1(Q1) ;NO, OUTPUT FILESPEC. SAVE JFN
		MOVEI B,[FLDDB. (.CMCMA,,,,,[FLDDB. (.CMCFM)])]
		COMND
		TXNE A,CM%NOP	;COMMA OR CR?
		ERROR BMBCM1,<?NOT A COMMA OR CR>
		LOAD C,CM%FNC,0(C) ;YES, SEE WHICH
		CAIE C,.CMCFM
		JRST LOAD1	;COMMA, DO MORE
		JRST .+1]	;CR, DONE
	CALL JFNCFM		;FIX UP JFN STACK FOR CONFIRM
	MOVEM Q1,NIJFN		;SAVE IN CASE OF ^E
	HRRZM Q1,NJFN1		;SAVE NUMBER ACTIVE JFNS
	MOVNI Q1,0(Q1)		;SAVE NUMBER OF JFNS SETUP
	MOVEM Q1,NJFN
LOAD2:	TXNN F,TNSF		;SKIP IF TAPE NUMBER SET
	SETZM RTAPNO
	SETZM LSTDIR		;NO LAST DIRECTORY
	SETOM CDIRN		;NO CONNECTED DIR NOW
	TXZ F,TF2		;CLEAR THIS (NO FILE YET)
	; ..
;BEGIN LOADING OF A TAPE

LODFI1:	SETZM CEXFLG		;CLEAR INTERRUPT
	MOVX B,OF%RD
	CALL MTOPEN
	SETOM CEXFLG		;ALLOW INTERRUPT
	TXZN F,TNSF		;SKIP IF TAPE NUMBER SET
	AOS RTAPNO		;COUNT TAPES
	TMSG <
>
	CALL MTRED
	 JRST [	TMSG < in tape header, record skipped
>
		JRST LODHX1]
	MOVN A,TYP		;GET RECORD TYPE
	CAIE A,TPHDX		;TAPE HEADER?
	CAIN A,CTPHX		; OR CONTINUATION
	JRST LODHX3		;OK - PROCEED
	ERROR LODHX2,<% Tape does not start with header, continuing...>
LODHX3:	CALL TYHEDR		;TYPE HEADER INFO
	MOVE A,RTAPNO
	CAMN A,TAPNO
	JRST LODHX1
	TXNN F,TF2		;SKIP IF IN MIDDLE OF FILE
	JRST LODHX5
	TMSGC <? Tapes not in order, cannot restore continued file >

	HRROI B,TFNAME		;FILE NAME
	CALL TMSGQ		;TYPE FILE NAME
	TMSG <
% Mount correct tape >
	CALL MTCLS	;CLOSE MTA
	CALL NTAPE	;GET SPEC
	JRST LODHX6	;TRY AGAIN
LODHX5:	TMSGC <% Tapes not in order, continuing
>
LODHX6:	MOVE A,TAPNO
	MOVEM A,RTAPNO
LODHX1:
	; ..
;LOAD THE NEXT FILE

LODFIL:	SKIPN NJFN1		;ANY ACTIVE JFNS LEFT?
	JRST [	CALL BACKSP	;UNDO ONE READ AHEAD
		CALL MTCLS	;DONE
		JRST CDONE]
	CALL MTRED
	JRST [	TMSG < while searching for file 
>
		JRST LODFIL]

;LOOK FOR BEGINNING OF NEXT FILE OR END OF TAPE

LODHX2:	MOVN A,TYP		;GET TYPE CODE
	CAIN A,TPTRX		;TAPE TRAILER?
	JRST LODEND		;YES
	CAIE A,CTPHX
	CAIN A,TPHDX		;HEADER?
	JRST [	TMSG <
End of saveset
>
		CALL BACKSP	;BACK OVER SAVESET HEADER
		CALL MTCLS
		JRST CDONE]
	CAIN A,USRX		;USER BLOCK?
	JRST LODUSR		;YES
	CAIE A,CTPHX		;GO ON IF CONTINUED SAVE
	CAIE A,FLHDX		;FILE HEADER?
	JRST LODFIL		;NO, ASSUME DATA RECORD BEING SKIPPED
	CALL LODSBR		;YES, LOAD IT
	 JRST LODFIL		;LOADED OK - GET NEXT FILE
	JRST LODHX2		;TRAILER RECORD MISSING - ANALYZE THIS RECORD


LODEND:	SETOM CDIRN
	SKIPL PAGNO		;SKIP IF TRAILER NOT END OF SAVESET
	JRST [	TMSG <
End of saveset
>
		CALL BACKSP	;BACK OVER TAPE TRAILER
		CALL MTCLS	;NO
		JRST CDONE]
	TMSG <
$ End of tape, mount next reel >
	TXNN F,TF2		;SKIP IF FILE BEING RESTORED
				;IS CONTINUED ON NEXT REEL
	JRST LODEN1
	TMSG <
% File >
	HRROI B,TFNAME		;FILE NAME
	CALL TMSGQ
	TMSG < continued on next reel>
LODEN1:	CALL UNLOAD
	CALL MTCLS		;CLOSE MTA
	CALL NTAPE		;YES, GET SPEC
	JRST LODFI1		;OPEN MTA AND CONTINUE
;HAVE USER INFO BLOCK

LODUSR:	SKIPE WHEEL		;WHEEL LOADING?
	SKIPE CHECK
	JRST LODFIL		;NO, DON'T CREATE DIRECTORIES
	SKIPE BUFF+.CDNUM	;INFORMATION PRESENT?
	TXNN F,USRDAT		;LOAD DDB REQUESTED?
	JRST LODFIL		;NO, IGNORE
	SKIPN B,JF2LST		;HAVE OUTPUT DEFAULT?
	JRST LODUSD		;GET NAME FROM TAPE (OR DSK:)
	HRROI A,DIRNAM
	HRRZS B			;JFN ONLY
	MOVX C,<FLD(.JSAOF,JS%DEV)+JS%PAF>
	JFNS			;GET DEVICE NAME:
LODUSA:	MOVEI B,"<"		;OPEN BRACKET
	IDPB B,A		;STASH
	MOVE B,A		;SETUP OUTPUT PNTR IN B
	MOVE A,[POINT 7,BUFF+UHNAM] ;BEG OF NAME ON TAPE
	MOVE C,FORMAT		;SEE WHICH FORMAT
	CAIGE C,FMTV3		;HAVE FULL DIR SPEC?
	JRST LODUS2		;NO - JUST COPY NAME
LODUS1:	ILDB C,A		;YES - LOCATE DIRECTORY NAME
	CAIE C,"<"
	JRST LODUS1		;LOOP TILL OPEN BRACKET FOUND
LODUS2:	ILDB C,A		;GET CHAR IN NAME
	CAIE C,">"		;LOOK FOR CLOSE BRACKET OR NULL
	JUMPN C,[IDPB C,B	;COPY CHAR IN NOT NULL
		 JRST LODUS2]
	MOVEI C,">"		;TERMINATE DIRECTORY NAME
	IDPB C,B
	MOVEI C,0		;ADD NULL TO STRING
	IDPB C,B		;...
	HRROI B,BUFF
	ADDM B,BUFF+.CDPSW	;SET PASSWORD STRING ADDRESS
	SKIPE BUFF+.CDLEN	;CHECK FOR LENGTH
	ADDM B,BUFF+.CDDAC	;SET DEFAULT ACCOUNT ADDRS
	MOVX A,RC%EMO		;CHECK FOR ALREADY EXISTING DIR
	HRROI B,DIRNAM		;...
	RCDIR
	TXNN A,RC%NOM!RC%AMB	;EXISTS?
	HRRM C,BUFF+.CDNUM	;YES - USE EXISTING NUMBER
	MOVE B,CRDWRD		;CRDIR FLAG WORD
LODUST:	SKIPE BUFF+.CDLEN	;OLD FORMAT?
	TXO B,CD%SDQ!CD%DAC!CD%CUG ;NEW BITS
	MOVX A,CD%NSQ		;DO NOT UPDATE SUPERIOR'S QUOTA
	IORM A,BUFF+.CDLEN	; NOR CHANGE THE SUPERIOR DIR'S QUOTA
	HRROI A,DIRNAM		;LOCATION OF DIRECTORY TO CREATE
	CRDIR
	 ERJMP LODUS9		;CHECK LOSAGE
	HRROI B,DIRNAM
	CALL TMSGQ		;TYPE NAME
	TMSG < created
>
	JRST LODFIL

LODUSD:	MOVE C,FORMAT		;SEE IF DEVICE NAME ON TAPE
	CAIGE C,FMTV3		;...
	JRST LODUSF		;USE DSK:
	MOVE A,[POINT 7,DIRNAM]	;INIT POINTER
	MOVE B,[POINT 7,BUFF+UHNAM]
LODUSE:	ILDB C,B		;GET A CHAR
	JUMPE C,LODUSF		;NO DEVICE - USE DSK:
	IDPB C,A		;COPY CHARACTER
	CAIE C,":"		;COLON?
	JRST LODUSE		;NO - GET MORE
	JRST LODUSA		;YES - DONE

LODUSF:	MOVE C,[ASCII "DSK:"]
	MOVEM C,DIRNAM		;V2 OR EARLIER - USE DSK:
	MOVE A,[POINT 7,DIRNAM,27]
	JRST LODUSA		;PROCEED

;HERE ON CRDIR FAILURE - CHECK REASON AND TRY AGAIN IF INCORRECT
;DIRECTORY NUMBER

LODUS9:	SKIPN BUFF+.CDNUM	;HERE BEFORE?
	JRST LODU91		;YES - FAIL NOW
	MOVEI A,.FHSLF		;GET ERROR
	GETER
	HRRZS B			;ERROR ONLY
	CAIE B,CRDIX2		;ILLEGAL NUMBER?
	CAIN B,CRDIX8
	SKIPA B,CRDWRD		;GET CRDIR FLAG WORD
	JRST LODU91		;REAL ERROR
	TXZ B,CD%NUM		;TRY TO NOT SPECIFY NUMBER
	SETZM BUFF+.CDNUM
	HRRZS BUFF+.CDLEN	;RESET HEADER
	JRST LODUST		;TRY AGAIN

LODU91:	TMSG <? Directory >
	HRROI B,DIRNAM
	CALL TMSGQ
	TMSG < not created because,
>
	CALL JSERRM
	JRST LODFIL	;TRY TO CONTINUE

CRDWRD:	777740,,BUFF		;CRDIR FLAGS AND BUFFER ADDRS
LODSBR:	MOVEI A,[CALL CANTLD	;PRINT MESSAGE
		 TMSG <% File skipped
>
		 JRST LODCLZ]	;TRAP ACTION
	CALL SETTRP		;SET TRAP FENCE
	CALL LODTST		;TEST THIS FILE FOR LOADING AND GET JFN
	 RET			;DON'T WANT IT
	TXNE F,TF2		;SKIP IF FILE NOT CONTINUED
	JRST [	SKIPGE A,PAGNO	;GET PAGE NO
		CAME A,INIPGN	;SHOULD MATCH
		CALL MISFPG	;MISSING PAGES IN FILE
		JRST LODSB1 ]
	SKIPL PAGNO		;CONTINUED FILE-DONT LOAD
	JRST LODSB1		;FILE NOT CONTINUED
	TMSGC <% Partial file >
	HRROI B,BUFF
	CALL TMSGQ
	TMSG < skipped 
>
	RET			;GO BACK

LODSB1:	MOVE A,JFN		;PICK UP JFN
	MOVX B,OF%RD+OF%WR
	SKIPE CHECK
	MOVX B,OF%RD+OF%PDT
	OPENF
	 JRST [	CALL CANTOP
		RET ]		;SKIP FILE

;MAIN LOAD LOOP - READ RECORD, MAP PAGE INTO FILE

LODLUP:	CALL MTRED
	 JRST [	TMSG < in data or trailer of file >
		MOVEI A,.PRIOU
		MOVE B,JFN
		MOVE C,[1B2+1B5+1B8+1B11+1B14+1B21+1B35]
		JFNS
		TMSG <.
>
		JRST LODLUP]
	SKIPE TYP		;DATA RECORD?
	JRST LODEFL		;NO
	HRLZ B,JFN		;CONSTRUCT IDENT FOR PAGE
	HRR B,PAGNO
	SKIPE CHECK		;CHECKING?
	JRST CHKLUP		;YES
	MOVE A,[.FHSLF,,BUFPAG]	;PUT PAGE INTO FILE
	MOVX C,PM%RD!PM%WR!PM%EX
	PMAP
	JRST LODLUP
;HERE WHEN ENCOUNTERED NON-DATA RECORD, LOOK FOR FILE TRAILER

LODEFL:	MOVNI A,FLTRX
	CAME A,TYP
	JRST LODEOF
	SKIPE CHECK
	JRST CHKFDB
	SETZM INIPGN		
	SKIPL A,PAGNO		;SKIP IF FILE NOT COMPLETE
	TXZA F,TF2		;BE SURE BIT OFF
	JRST [	TXO F,TF2	;NOTE FILE IS CONTINUED
		MOVEM A,INIPGN	;REMEMBER PAGE #
		JRST .+1]
	MOVSI P1,-.FBLN0
FIXFDB:	MOVE A,JFN		;SETUP FDB PROPERLY
	MOVE 3,BUFF(P1)
	SKIPN WHEEL
	SKIPA 2,NWMASK(P1)
	MOVE 2,MASK(P1)
	TXNE F,ICMODF		;INTERCHANGE MODE?
	MOVE B,ICMASK(P1)	;YES, DIFFERENT MASK
	HRL A,P1
	TXO A,CF%NUD		;NO UPDATE DIRECTORY
	SKIPE 2
	CHFDB
	 ERJMP [ERRORJ (.+1,<% CHFDB failure>)]
	AOBJN P1,FIXFDB
	TXNE F,ICMODF		;SKIP IF NOT INTERCHANGE MODE
	JRST FIXFD1		;DON'T SET AUTHER WRITER
	MOVE A,FORMAT		;GET TAPE FORMAT
	CAIGE A,FMTV3		;SKIP IF FMTV3 OR LATER
	CALL GTUNS		;CONVERT DIRECTORY #'S TO
				;STRINGS FOR OLD TAPES
	MOVE A,JFN		;GET FILE'S JFN
	HRLI A,.SFAUT		;SET AUTHOR IS FUNCTIN
	HRROI B,BUFF+.FBLN0 ;PONT TO NAME
	SFUST
	 ERJMP .+1		;IGNORE ERROR (MAYBE WRONG SYSTEM)
	SKIPN WHEEL		;SET LAST WRITER ONLY IF
				;PRIVELEGED OR OPERATOR
	JRST FIXFD1
	HRLI A,.SFLWR		;SET LAST WRITER IS FUNCTION
	HRROI B,BUFF+.FBLN0+10	;POINT TO NAME
	SFUST
	 ERJMP .+1
FIXFD1:	TXNE F,TF2		;SKIP IF FILE COMPLETE
	JRST LODCLZ		;NOT FINISHED
				;C(P5) := INDEX INTO JFNLST
				;  SETUP IN LODTST
	MOVE A,JFNLST(P5)	;THE SOURCE FILESPEC WHICH MATCHED
	TXNN A,GJ%DEV+GJ%DIR+GJ%NAM+GJ%EXT+GJ%VER ;ANY STARS IN IT?
	JRST [	SETZ A,		;NO, THEN DONE WITH IT
		EXCH A,JFNLST(P5)
		RLJFN
		 JFCL
		SOS NJFN1	;NOTE ONE LESS ACTIVE JFN IN LIST
		JRST .+1]
	TXNE F,LFILF		;TYPE FILE NAMES ?
	TXNE F,LTTYF		;AND NOT LOGGINT TO TTY?
	JRST LODCLZ
	TMSG <	[OK]
>
LODCLZ:	MOVE A,JFN
	CLOSF
	 JFCL
	RET

LODEOF:	TXNE F,ICMODF		;SKIP IF NOT INTERCHANGE MODE
	JRST LODEO1
	TMSGC <% File trailer missing for file >
	MOVEI A,.PRIOU
	MOVE B,JFN		;JFN OF FILE
	SETZ C,
	JFNS			;NAME OF FILE
	TMSG <
>
LODEO1:	CALL LODCLZ		;CLOSE FILE
	RETSKP			;SKIP RETURN TO INDICATE TRAILER MISSED

;CONVERT DIRECTORY NUMBER TO STRING FOR OLD TAPES

GTUNS:	HLRZ B,BUFF+.FBUSE	;LAST WRITER FIELD OF OLD .FBUSE
				;WORD OF FDB
	HRLI B,USRLH		;SAY IT IS A USER #
	HRROI A,BUFF+.FBLN0+10	;STORE IN LAST WRITER FIELD
	SETZM 0(A)		;IN CASE FAILURE - USE NULL
	DIRST
	 ERJMP .+1
	HRRZ B,BUFF+.FBUSE	;AUTHOR FIELD OF OLD .FBUSE 
				;WORD OF FDB
	HRLI B,USRLH		;SAY IT IS A USER NUMBER
	HRROI A,BUFF+.FBLN0	;STORE IN AUTHOR FIELD
	SETZM 0(A)		;USE NULL IF FAILURE
	DIRST
	 ERJMP .+1
	RET
;TEST NEXT FILE ON TAPE FOR INCLUSION IN CURRENT LOAD SPEC
; RETURN +1: DON'T LOAD
; RETURN +2: LOAD

LODTST:	SKIPG FORMAT		;NEW FORMAT VERSION PUNCTUATION?
	CALL FIXFMM		;NO, FIXUP FIRST
	SKIPE CHECK		;check?
	JRST [	HRROI A,ONMBUF	;YES-- COPY FILE NAME
		HRROI B,BUFF	; FROM TAPE BUFFER
		MOVX C,0	; . .
		SOUT		; . .
		MOVX A,GJ%OLD+GJ%SHT
		HRROI B,ONMBUF	;LOOKUP EXACTLY AS ON TAPE
		GTJFN
		 JRST CANNOT
		MOVEM A,JFN
		CALL FILSZE	;COMPUTE FILE SIZE
		JRST LODCHK]
	MOVX A,GJ%OFG+GJ%SHT	;SET TO PARSE NAME
	HRROI B,BUFF
	GTJFN
	 JRST [	CALLRET JSERR1]	;SHOULDN'T FAIL
	MOVEM A,JFN
	HRLZ P5,NJFN		;SCAN ALL SPECS GIVEN TO LOAD
LODTS3:	SKIPN JFNLST(P5)	;JFN STILL HERE?
	JRST [	AOBJN P5,LODTS3	;NO, IT WAS COMPLETED
		JRST LODTNO]	;DONE ALL FILESPECS, FAILED TO MATCH
	MOVSI Q1,-NFFLD		;SCAN ALL FIELDS OF FILESPEC
	AOBJN Q1,.+1		;SKIP DEVICE FIELD
LODTS2:	HRROI A,FBUF1		;GET STRINGS FOR NEXT FIELD
	MOVE B,JFN
	MOVE C,FFLDT(Q1)
	JFNS			;FOR FILE ON TAPE...
	HRROI A,FBUF2
	MOVE B,JFNLST(P5)
	MOVE C,FFLDT(Q1)
	JFNS			;FOR LOAD FILESPEC
	MOVE A,[POINT 7,FBUF1]
	MOVE B,[POINT 7,FBUF2]
	CALL CHKWLD		;SEE IF THIS FILE SPEC MATCHES
	JRST [AOBJN P5,LODTS3	;NOT EQUAL, STEP TO NEXT FILESPEC
		JRST LODTNO]	;DONE ALL FILESPECS, FAILED TO MATCH ANY
LODTS1:	AOBJN Q1,LODTS2		;STEP TO NEXT FIELD
	; ..
;MATCHED ALL FIELDS, THIS FILENAME OK TO LOAD.  NOW CHECK DATES

	MOVE A,BUFF+FHFDB+.FBCRE ;GET MODIFIED DATE
	CAMG A,MBTAD		;NOT 'BEFORE'?
	CAMGE A,MSTAD		;NOT 'AFTER'?
	JRST LODTNO
	MOVE A,BUFF+FHFDB+.FBWRT ;GET WRITE TAD
	CAMG A,WBTAD		;NOT 'BEFORE'?
	CAMGE A,WSTAD		;NOT 'SINCE'
	JRST LODTNO		;YES, FAIL
	CAMGE A,BUFF+FHFDB+.FBREF ;GET MOST RECENT OF WRITE, READ
	MOVE A,BUFF+FHFDB+.FBREF
	CAMG A,ABTAD		;NOT 'BEFORE'
	CAMGE A,ASTAD		;NOT 'SINCE'
	JRST LODTNO		;YES, FAIL

;NOW COOK UP APPROPRIATE OUTPUT NAME
; P5/ INDEX TO JFNLST AND JF2LST TABLES

	CALL GOFNAM		;GET OUTPUT NAME INTO ONMBUF
	TXNN F,TF2		;CONTINUED FILE?
	 JRST LODNM6		;NO-- ALL OK
	PUSH P,A		;SAVE CURRENT POINTER
	MOVE A,OGNPTR		;YES-- GET GENERATION POINTER
	ILDB B,A		;GET START OF GENERATION
	CAIE B,"."		;SPECIFIED?
	 JRST LODNM5		;NO-- SKIP CHECK FOR NEXT HIGHEST VERSION
	MOVX C,^D10		;YES-- GET IT
	NIN			;IN DECIMAL
	 JRST LODNM5		;NO SUCH LUCK
	AOJN B,LODNM5		;IF NOT -1, DON'T CHANGE IT
	MOVE A,OGNPTR		;GEN IS -1 (NEXT HIGHEST):  MUST USE HIGHEST SO
	MOVEM A,(P)		; DON'T SPECIFY GEN, GTJFN WILL GET HIGHEST
	IDPB B,A		;MARK END OF FILENAME WITHOUT GENERATION
LODNM5:	POP P,A			;RESTORE POINTER TO FILE STRING
LODNM6:	CALL GOFPAT		;GET PROTECTION, ACCOUNT, ;T
	; ..
	
	; ..
LODNM7:	HRROI A,TFNAME	;TAPE FILE NAME BUFFER
	MOVE B,JFN		
	SETZ C,
	JFNS			;STORE FILE NAME FOR LATER
	MOVE A,JFN		;DONE WITH LOCAL JFN ON  NAME FROM TAPE
	RLJFN
	 JFCL

;CHECK SUPERSEDE RULE

	TXNE F,SSA!TF2		;SUPERCEDE ALWAYS OR MIDDLE OF FILE?
	JRST LODNM3		;YES, NO CHECK
LODNM8:	ILDB D,OGNPTR		;GET FIRST BYTE OF GENERATION
	MOVX A,0		;STORE A NULL,
	DPB A,OGNPTR		; SO WE LOOKUP HIGHEST EXISTING GENERATION
	MOVX A,GJ%OLD!GJ%SHT	;LOOKUP EXISTING FILE OF SAME NAME
	HRROI B,ONMBUF		; . .
	GTJFN			;GET MOST RECENT VERSION
	 JRST [	DPB D,OGNPTR		;ISN'T ONE, RESTORE BYTE OF GENERATION
		JRST LODNM3]		; AND GO LOAD FILE
	DPB D,OGNPTR		;RESTORE THE BYTE WE BIT
	MOVEM A,JFN
	TXNE F,SSN		;SUPERSEDE NEVER?
	JRST LODTNO
	MOVSI B,.FBLN0
	MOVEI C,FDB
	GTFDB			;GET FDB OF EXISTING FILE
	 ERJMP [CALL JSERR1	;SCREWUP...
		JRST .+1]
	MOVE B,FDB+.FBWRT	;GET WRITE DATE OF EXISTING FILE
	CAML B,BUFF+FHFDB+.FBWRT ;WHICH FILE IS NEWER?
	JRST LODTNO		;DISK FILE IS NEWER, DON'T LOAD FROM TAPE
	LOAD B,FB%GEN,BUFF+FHFDB+.FBGEN ;GET GEN NUMBER OF TAPE FILE
	LOAD C,FB%GEN,FDB+.FBGEN ;GET GEN NUMBER OF EXISTING DISK FILE
	CAML B,C		;NEWER (TAPE) FILE HAS HIGHER GEN NO?
	JRST LODNM9		;YES, OK
	TMSG <% File >		;No, must delete disk file to prevent
	MOVX A,.PRIOU		; GENERATION MIS-ORDERING
	MOVE B,JFN
	MOVX C,1B2+1B5+1B8+1B11+1B14+1B35
	JFNS			;TYPE WARNING MESSAGE
	TMSG < deleted while superseding
>
	MOVE A,JFN
	DELF			;DELETE (NO EXPUNGE) DISK FILE
	 CALL JSERR1
	JRST LODNM8		;SEE IF OTHER DISK FILES NEED DELETING
LODNM9:	MOVE A,JFN		;NOW DONE WITH LOCAL JFN
	RLJFN
	 JFCL

;NOW GET JFN FOR ACTUAL DISK FILE TO BE WRITTEN

LODNM3:	MOVX A,GJ%SHT		;SET TO GET JFN FOR FILE TO BE WRITTEN
	TXNN F,TF2		;CONTINUED FILE?
	 TXO A,GJ%FOU		;NO-- USE NEXT HIGHEST GEN IF 0 SUPPLIED
	HRROI B,ONMBUF		;POINT TO FILENAME STRING
	GTJFN
	 SKIPA			;ERROR-- CHECK IT OUT
	JRST LODN39		;GOT IT-- GO ON

;ERROR FROM GTJFN-- SEE IF BECAUSE OF INVALID ACCOUNT

	CAIE A,VACCX0		;FAILED-- INVALID ACCT?
	 JRST CANNOT		;NO-- GIVE UP
	MOVE D,OACPTR		;YES-- GET POINTER TO ACCT
	ILDB A,D		;GET FIRST CHARACTER OF ACCT
	CAIE A,";"		;IS ACCT SPECIFIED?
	 JRST CANNOT		;NO-- GIVE UP
	TMSG <% Invalid account for file >
	HRROI B,ONMBUF		;POINT TO FILE SPEC
	CALL TMSGQ		;TYPE FILE SPEC
	TMSG <, system default used
>
	MOVX A,0		;USE
	DPB A,D			; SYSTEM DEFAULT
	JRST LODNM3		; AND TRY AGAIN

LODN39:	MOVEM A,JFN

;SEE IF THIS FILE GOING TO DIFFERENT DIRECTORY THAN LAST FILE

	HRROI A,DIRNAM
	MOVE B,JFN
	MOVX C,<FLD(.JSAOF,JS%DEV)+FLD(.JSAOF,JS%DIR)+JS%PAF>
	JFNS
	HRROI A,DIRNAM
	HRROI B,LSTDIR
	STCMP			;CHECK DIR NAME STRINGS
	JXE A,SC%LSS+SC%SUB+SC%GTR,LODNM4
	HRROI B,DIRNAM		;STRINGS DIFFERENT, SET NEW CURRENT DIR
	HRROI A,LSTDIR
	SETZ C,
	SOUT
	TMSG <Loading file(s) into >
	MOVEI A,.PRIOU
	MOVE B,JFN
	MOVX C,<FLD(.JSAOF,JS%DEV)+FLD(.JSAOF,JS%DIR)+JS%PAF>
	JFNS			;TYPE NEW DIRECTORY
	TMSG <
>
	; ..
;type file name if requested

LODNM4:	TXNN F,LFILF		;TYPE FILE NAMES?
	JRST LODNMX		;NO
	HRROI B,BUFF		;YES, SOURCE
	CALL TMSGQ
	TMSG < (TO) >
	MOVEI A,.PRIOU
	MOVE B,JFN
	MOVX C,2B2+2B5+1B8+1B11+1B14+1B35
	JFNS			;DESTINATION
	JRST LODNMX

LODCHK:	TXNN F,LFILF		;SKIP IF WANT FILE NAMES
	JRST LODNMX		;NOPE
	HRROI  B,BUFF		;SOURCE
	CALL TMSGQ		;TYPE NAME
	TMSG <
>
LODNMX:	MOVE A,JFN		;RETURN THE OUT JFN
	RETSKP			;PASSES ALL TESTS, LOAD IT

;RETURN NO-LOAD AND RELEASE LOCAL JFN

LODTNO:	TXZE F,TF2		;SKIP IF NOT MIDDLE OF FILE
	CALL MISFPG		;MISSING PAGES IN FILE
	MOVE A,JFN
	RLJFN
	 JFCL
	RET
;ROUTINE TO CHANGE ";" TO "."

FIXFMM:	PUSH P,A		;SAVE REGS
	PUSH P,B		;""
	MOVE A,[POINT 7,BUFF]	;WHERE THE NAME IS
FIXF1:	ILDB B,A		;GET BYTE
	JUMPE B,FIXF2		;JUMP IF END
	CAIN B,"V"-100		;QUOTE?
	JRST [	ILDB B,A	;WASTE A BYTE
		JRST FIXF1]	;AND LOOP
	CAIE B,";"		;VERSION?
	JRST FIXF1		;NO
	MOVEI B,"."		;REPLACE IT
	DPB B,A			;""
FIXF2:	POP P,B			;RESTORE REGS
	POP P,A			;""
	RET			;AND DONE
CHKLUP:	MOVE A,B
	MOVE B,[XWD 400000,BF2PAG]
	MOVSI 3,100000
	PMAP
	TXNN F,ICMODF		;SKIP IF INTER CHANGE FORMAT
	JRST CHKLP1		;CHECK EVERYTHING
	SOSGE FPGCNT		;DECREMENT PAGE COUNT
	JRST CHKLP2		;DONE WITH ALL FULL PAGES
CHKLP1:	MOVSI P1,-1000
CMPLUP:	MOVE A,BUFF(P1)
	CAME A,BUFF2(P1)
	JRST CMPERR
	AOBJN P1,CMPLUP
CMPLP2:	HRLZ A,JFN
	HRR A,PAGNO
	RPACS
	XOR B,ACCESS
	AND B,[XWD 170000,0]
	TXNE F,ICMODF		;INTERCHANGE MODE?
	ANDX B,PM%RD+PM%WT	;YES, READ AND WRITE ONLY
	JUMPE B,LODLUP
	TMSG <% Access error>
	JRST CMPER1

CMPERR:	TMSG <% Compare error>
CMPER1:	TMSG <, page >
	HRRZ B,PAGNO
	MOVEI C,12
	CALL TTNOUT
	TMSG <, file >
	MOVE B,JFN
	MOVEI C,0
	JFNS
	TMSG <
>
	JRST LODLUP

CHKLP2:	SKIPN P1,RMRPGE		;SKIP IF PARTIAL PAGE
	JRST CMPLP2		;ALL DONE
	MOVNS P1		;SET UP FOR AOBJN LOOP
	HRLZS P1
	SETZM RMRPGE		;DONT TRY AGAIN
	JRST CMPLUP		;CHECK PARTIAL PAGE
CHKFDB:	MOVNI A,1
	MOVE B,[.FHSLF,,BF2PAG]
	SETZ C,
	PMAP
	MOVE A,JFN
	MOVE B,[XWD 25,0]
	MOVEI 3,BUFF2
	GTFDB
	MOVSI P1,-25
CHKFDL:	MOVE A,BUFF(P1)
	XOR A,BUFF2(P1)		;COMPARE WORDS
	AND A,CKMASK(P1)	;BUT CHECK ONLY CERTAIN BITS
	TXNE F,ICMODF		;INTERCHANGE MODE?
	AND A,ICMASK(P1)		;YES, FEWER BITS PERTINENT
	JUMPN A,FDBERR		;JUMP IF COMPARED BITS DIFFERENT
CHKFD0:	AOBJN P1,CHKFDL
	MOVE A,FORMAT		;GET CURRENT FORMAT
	CAIL A,FMTV3		;SKIP IF OLD TAPE
	TXNE F,ICMODF		;SKIP IF NOT INTERCHANGE FORMAT
	JRST LODCLZ		;DON'T CHECK AUTHER &LAST WRITER
	HRR A,JFN		;JFN OF FILE
	HRLI A,.GFAUT		;FUNTCION IS GET AUTHOR
	HRROI B,FBUF1		;STORE STRING HERE
	GFUST
	 ERJMP [SETZM FBUF1
		JRST .+1]
	HRROI A,FBUF1	;AUTHOR
	HRROI B,BUFF+.FBLN0	;COMPARE TO TAPE
	STCMP
	SKIPE A			;SKIP IF STRINGS ARE SAME
	CALL [	TMSG <% File author differs for file >
		MOVE B,JFN
		MOVEI A,101
		MOVEI C,0
		JFNS
		TMSG <
>
		RET ]
	HRR A,JFN
	HRLI A,.GFLWR		;GET LAST WRITER
	HRROI B,FBUF1
	GFUST
	 ERJMP [SETZM FBUF1
		JRST .+1]
	HRROI A,FBUF1		;LAST WRITER
	HRROI B,BUFF+.FBLN0+10		;CHECK AGAINST TAPE
	STCMP
	SKIPE A			;SKIP IF SAME
	CALL [	TMSG <% File last-writer differs for file >
		MOVE B,JFN
		MOVEI A,101
		MOVEI C,0
		JFNS
		TMSG <
>
		RET ]
	JRST LODCLZ

FDBERR:	TMSG <% Difference in >
	MOVE B,FDBNAM(P1)
	MOVEI A,0
	ROTC A,6
	JUMPE A,FDBER9
	ADDI A,40
	PBOUT
	JRST .-5

FDBER9:	TMSG < of file >
	MOVE B,JFN
	MOVEI 1,101
	MOVEI C,0
	JFNS
	TMSG <
>
	JRST CHKFD0
;FAILED TO GTJFN FOR FILE TO BE LOADED

CANNOT:	TMSGC <% Cannot get JFN for file >
	JRST CANT1

CANTOP:	MOVE A,JFN
	RLJFN
	 JFCL
	TMSGC <% Cannot open file >
	JRST CANT1

CANTLD:	TMSGC <% Cannot load file >

CANT1:	HRROI B,ONMBUF		;FILESPEC STRING
	CALL TMSGQ
	TMSG < because:
  >
	CALL JSERRM
	RET
;TYPE HEADER INFORMATION

TYHEDR:	MOVEI A,.PRIOU
	CALL PRHEDR		;HEADER TO PRIMARY OUT
	TMSG <
>
	MOVE B,FORMAT
	CAIN B,CURFMT		;CURRENT FORMAT?
	JRST TYH1		;YES
	TMSG <% Tape is format version >
	MOVE B,FORMAT
	MOVX C,^D10
	CALL TTNOUT
	TMSG <, not current
>
TYH1:	RET

;CONSTRUCT HEADER INFORMATION
; A/ OUT DESIGNATOR

PRHEDR:	STKVAR <OUTD>
	HRROI B,[ASCIZ /
DUMPER tape # /]
	SETZ C,
	SOUT
	MOVE B,TAPNO		;BUMP TAPE NUMBER
	MOVEI C,^D10
	NOUT			;PUT IT IN MESSAGE
	 JSERR
	HRROI B,[ASCIZ /, /]
	SETZ C,
	SOUT
	MOVEM A,OUTD		;SAVE OUT DESIG
	CALL SETHDR		;CHECK FORMAT TYPE AND GET TEXT ADR
	HRROI B,BUFF(A)
	MOVE A,OUTD
	SOUT			;INCLUDE SAVE SET NAME
	SKIPN FORMAT		;BBN FORMAT?
	RET			;YES, NO MORE INFORMATION
	HRRZ B,BUFF+BFMSGP	;NO, GET MSG OFFSET
	CAIG B,BFTAD		;BEYOND TAD WORD?
	RET			;NO, THEREFORE NO TAD WORD
	HRROI B,[ASCIZ /, /]
	SOUT
	MOVE B,BUFF+BFTAD	;GET BEGINNING TAD
	MOVX C,3B2+1B10+1B12
	ODTIM			;PUT IT IN MESSAGE
	RET

;ROUTINE TO LOOK AT TAPE HEADER AND DETERMINE FORMAT TYPE
;RETURN +1 ALWAYS, A/ OFFSET ADR TO TITLE STRING

SETHDR:	MOVE B,BUFF		;GET FIRST WORD OF BUFFER
	SETZ A,			;ASSUME OLD FORMAT
	SETZM FORMAT		;""
	TLNE B,(177B6)		;IS IT ASCII?
	RET			;YES
	MOVEM B,FORMAT		;SAVE DATA FORMAT
	MOVE A,BUFF+BFMSGP	;GET OFFSET FOR THE TITLE
	RET			;RETURN
	SUBTTL MAGTAPE BUFFERED IO ROUTINES

;OPEN MAGTAPE

MTOPEN:	MOVEM B,TMODE		;SAVE MODE REQUEST
	SKIPE MTJFN		;ALREADY OPEN?
	JRST [	MOVE A,MTJFN	;GET JFN
		GTSTS
		TXNE B,GS%OPN
		CALL MTCLS	;CLOSE IT 
		JRST .+1]
	SKIPN A,RWFRK		;CLOSE FORK EXISTS?
	JRST MTOP1		;NO
	WFORK			;YES, WAIT FOR IT
	KFORK
	SETZM RWFRK
MTOP1:	SKIPE A,MTJFN		;SKIP IF NO JFN ASSIGNED
	CALL RLSJFN		;RELEASE JFN
	MOVE A,MTDSG		;GET LAST MTA DESIGNATOR
	JUMPE A,MTOP4		;NO TAPE COMMAND GIVEN SO FAR
	MOUNT
	 ERROR MTOFAI,<?FAILED TO MOUNT MTA, >
	HRROI B,MTDEV
	MOVX A,GJ%SHT
	GTJFN
	 ERROR MTOFAI,<?FAILED TO FIND MTA, >
	MOVEM A,MTJFN		;SAVE JFN
	MOVX B,<FLD 17,OF%MOD>	;REQUEST DUMP MODE
	HRR B,TMODE		;READ/WRITE AS SPECIFIED BY CALLER
	OPENF
	 ERROR MTOFAI,<?FAILED TO OPEN MTA, > ;NO
	MOVEM A,MTJFN
	MOVEI B,.MOSDN		;SET DENSITY PER REQUEST
	MOVE C,DENSIT
	MTOPR
	 ERJMP [TMSG <%UNABLE TO SET DENSITY AND PARITY, JOB DEFAULTS TAKEN
>
		JRST MTOP2]
	MOVEI B,.MOSPR		;SET PARITY PER REQUEST
	MOVE C,PARITY
	MTOPR
	 ERJMP .+1
	MOVEI B,.MOSDM		;SET DATA MODE...
	MOVEI C,.SJDMC		;USE CORE DUMP UNLESS...
	TXNE F,T36MOD		;36-BIT MODE REQUESTED
	MOVEI C,.SJDM8		;THEN USE INDUSTRY COMPAT
	MTOPR
	 ERJMP .+1

;SET BLOCKING-FACTOR

MTOP2:	TXNE F,ICMODF		;FOR INTERCHANGE FORMAT,
	 JRST [	MOVX A,1		; USE BLOCKING FACTOR
		MOVEM A,TAPBKF		; OF 1 ALWAYS
		JRST MTOPB9]		; . . .
	MOVE A,TMODE		;GET I/O MODE
	TXNE A,OF%WR		;WRITE?
	SKIPE TAPBKF		;YES-- TAPE BLOCKING FACTOR ALREADY KNOWN?
	 JRST MTOPB9		;YES-- (OR READ) USE EXISTING TAPBKF
	MOVE A,MTJFN		;GET TAPE JFN
	MOVX B,.MORDN		;READ DENSITY
	MTOPR			; THAT HAS BEEN SET
	 ERJMP MTOPB4		;NOT AVAILABLE-- DON'T CHECK BLOCKING-FACTOR LIMITS
	MOVSI B,-DNBKTZ		;AOBJN POINTER TO DNBKTB (DENSITY/BLOCKING-FACTOR
				; LIMIT TABLE)
MTOPB3:	HRRZ A,DNBKTB(B)	;GET A DENSITY
	CAMN A,C		;MATCH TAPE DENSITY?
	 JRST [	HLRZ A,DNBKTB(B)	;YES-- USE LIMIT FOR THIS DENSITY
		JRST MTOPB6]		; . . .
	AOJN B,MTOPB3		;NO-- LOOP THROUGH TABLE FOR TAPE DENSITY
				;TAPE DENSITY NOT FOUND IN TABLE
MTOPB4:	MOVE A,SETBKF		;USE BLOCKING FACTOR SET BY USER (OR DEFAULT)
MTOPB6:	CAMLE A,SETBKF		;USER SET A LOWER BLOCKING-FACTOR?
	 MOVE A,SETBKF		;YES-- USE USER'S VALUE
	MOVEM A,TAPBKF		;REMEMBER THE BLOCKING-FACTOR
	CAME A,SETBKF		;ARE WE USING USER'S VALUE?
	 CALL [	TMSG <% BLOCKING-FACTOR too high for current tape density
% Tape will be written with BLOCKING-FACTOR of >
		MOVE B,TAPBKF		;NO-- TELL USER WHAT WE WILL USE
		MOVX C,^D10		; IN DECIMAL
		CALL TTNOUT		; . . .
		TMSG <
>
		RET]
MTOPB9:

;INITIALIZE FLAGS AND VARIABLES

	TXZ F,LREOF+LRERR+ICMT1	;CLEAR FLAGS
	SETZM MTRACT
	SETZM MTBUFF		;INIT VARIABLES
	SETZM BLKCNT		;INDICATE MTBUF EMPTY
	MOVE B,NWTBT0		;INIT NORMAL OVERLAP MODE
	MOVEM B,NWTBIT
	CALLRET SETIOW		;SETUP DUMPI/O COMMAND LIST AND RETURN FROM MTOPEN
;OPEN FAILURE

MTOFAI:	CALL JSERRM		;SAY WHY
	HRROI A,[ASCIZ\Try again? \]
	CALL YESNO
	JUMPN A,MTOP1		;YES
	JRST CLRST		;NO

MTOP4:	MOVX A,GJ%OLD+GJ%SHT
	HRROI B,[ASCIZ /MTA-DUMPER:/]
	GTJFN			;TRY DEFAULT LOGICAL NAME
	 JRST MTOP3		;N.G.
	MOVEM A,MTJFN		;SAVE JFN
	CALL NTAP1		;SETUP
	 JRST MTOP3		;NOT A MTA
	JRST MTOP1		;TRY AGAIN

MTOP3:	TMSG <Tape specification needed,
>
	CALL NTAPE
	JRST MTOP1


;DENSITY/BLOCKING-FACTOR LIMIT TABLE
; *** THESE LIMITS WERE ESTABLISHED UNDER THE FOLLOWING ASSUMPTIONS:
;	1)  2 RECORDS NEED TO BE WRITTEN AFTER EOT (REFLECTIVE STRIP).
;	2)  14 RETRYS OF EACH RECORD MAY BE NEEDED.
;	3)  EACH RETRY ERASES (3 INCHES) RECORD IN ERROR, THEN REWITES RECORD.
;	4)  500 INCHES OF TAPE ARE AVAILABLE AFTER REFLECTIVE STRIP.
;	    (THIS IS NOT TRUE.  ONLY 300 INCHES (25 FEET) AVAILABLE,
;	     BUT ALL THOSE RETRIES ARE WORST CASE.  300 INCH LIMITS
;	     ARE IN PARENTHESES.)

DNBKTB:	XWD ^D1,.SJDN2		;200 BPI:  LIMIT 1 (1)
	XWD ^D3,.SJDN5		;556:  3 (1)
	XWD ^D4,.SJDN8		;800:  4 (2)
	XWD ^D8,.SJD16		;1600:  8 (4)
	XWD ^D35,.SJD62		;6250:  35 (17)
DNBKTZ==.-DNBKTB
;CLOSE MAGTAPE USING FORK TO WAIT FOR REWIND COMPLETION
;	CALL MTCLS
; RETURN +1 ALWAYS

MTCLS:	SKIPN A,RWFRK		;HAVE FORK NOW?
	JRST [	MOVSI A,(1B1)	;NO, CREATE ONE
		CFORK
		 ERROR R,<%CANNOT CREATE LOWER FORK>
		MOVEM A,RWFRK
		MOVSI A,.FHSLF
		HRLZ B,RWFRK
		MOVE C,[1B0+7B4+200]
		PMAP		;MAP PROGRAM INTO LOWER FORK
		MOVE A,RWFRK
		JRST .+1]
	WFORK			;WAIT IN CASE PREVIOUS REWIND NOT FINISHED
	PUSH P,MTJFN
	POP P,FRKJFN		;PUT JFN WHERE FORK WILL FIND IT
	MOVEI B,MTCLS1
	SFORK			;START FORK AT CLOSE
	SETZM MTJFN		;NOTE JFN GONE
	RET

MTCLS1:	MOVE A,FRKJFN
	CLOSF			;THIS WAITS FOR REWIND TO FINISH
	 JFCL
	HALTF
;REWIND, UNLOAD FUNCTIONS

UNLOAD:	SKIPA B,[EXP .MORUL]	;UNLOAD FUNCTION

REWIND:	 MOVEI B,.MOREW		;REWIND CODE
	MOVE A,MTJFN
	MTOPR
;	CALLRET MTBOT		;SAY NOW AT BOT, RETURN FROM REWIND/UNLOAD


;SET PARAMETERS FOR BOT OR NEW TAPE

MTBOT:	SETZM TAPBKF		;INDICATE NO BLOCKING-FACTOR FOR TAPE YET
	SETZM RSEQ		;RESET SEQUENCE NUMBERS
	SETZM SEQ
	RET			;RETURN FROM MTBOT


;MARK END OF TAPE

ENDTAP:	CALL MTFILL		;FILL LAST PHYSICAL RECORD OUT SO THAT
				;TAPE TRAILER IS A SINGLE PHYSICAL RECORD
	MOVNI A,TPTRX
	MOVEM A,TYP
	CALL MTOUT
	TXNE F,ICMODF		;INTERCHANGE MODE?
	CALL ICOFIN		;YES, FINISH BUFFERS
	CALL MTFILL		;FORCE TRAILER RECORD TO BE WHOLE PHYSICAL RECORD
	CALL ENDFIL
	CALL ENDFIL		;WRITE 2 EOF'S
	MOVEI D,3
	TXNE F,ICMODF		;INTERCHANGE?
	MOVEI D,2		;YES, BACK OVER EOF'S ONLY
ENDTA1:	CALL BACKSP		;BACK OVER 2 EOF'S AND TRAILER RECORD
	SOJG D,ENDTA1
	RET

;WRITE FILE MARK

ENDFIL:	PUSH P,A
	PUSH P,B
	MOVEI B,.MOEOF		;REQUEST WRITE EOF
	CALL XMTOPR
	MOVE A,TAPBKF		;COUNT EOF AS PHYSICAL RECORD
	ADDB A,RSEQ		; . .
	MOVEM A,SEQ		;KEEP READ SEQ UP TO DATE
	POP P,B
	POP P,A
	RET

;BACKSPACE ONE RECORD

BACKSP:	MOVEI B,.MOBKR
	CALL XMTOPR		;DO BACKSPACE
	MOVE A,MTJFN
	GDSTS
	TXNE B,MT%BOT		;NOW AT BOT?
	ERROR MTBOT,<%BEGINNING OF TAPE ENCOUNTERED>
				;YES-- GIVE WARNING, RESET SEQ #'S, AND RETURN FROM BACKSP
	MOVN A,TAPBKF		;GET NEGATIVE BLOCKING FACTOR, A RECORD'S
				; WORTH OF SEQUENCE NUMBERS
	SKIPE BLKCNT		;READ PART OF A RECORD?
	 SUBI A,1		;YES-- ACCOUNT FOR PART OF RECORD ALREADY READ
	ADD A,BLKCNT		; . . .
	ADDB A,RSEQ		;UPDATE RECORD NUMBER
	SETZM BLKCNT		;NOW AT BEGINNING OF RECORD
	MOVEM A,SEQ		;KEEP TAPE SEQ UP TO DATE
	RET
;MTOPR FUNCTION - CHECK PREVIOUS OPERATION FIRST
; B/ FUNCTION FOR MTOPR

XMTOPR:	PUSH P,B		;SAVE FUNCTION CODE
	MOVE A,MTJFN
	SKIPN NWTBIT
	JRST XMTOP1		;NOT OVERLAPPING
	MOVE B,TMODE		;CHECK CURRENT MODE
	TXNN B,OF%WR		;WRITE?
	JRST [	CALL MTBKRA		;NO, READ-- BACK OVER READ-AHEAD
		JRST XMTOP1]
	CALL WFERR		;WRITE-- RECOVER FROM ANY ERRORS THAT HAVE OCCURED

XMTOP1:	POP P,B			;RECOVER FUNCTION CODE
	MOVE A,MTJFN
	MTOPR			;DO FUNCTION
	RET


;FILL REST OF PHYSICAL RECORD WITH FILLER RECORDS

MTFILL:	SKIPN BLKCNT		;JUST WROTE A PHYSICAL RECORD?
	 RET			;YES-- RETURN NOW FROM MTFILL
	MOVNI A,FILLX		;GET FILLER TYPE
	MOVEM A,TYP		;SET RECORD TYPE
	CALL MTOUT		;WRITE FILLER RECORD
	JRST MTFILL		;SEE IF DONE YET
;MAGTAPE OUTPUT ROUTINE.  REQUESTS ONE TRANSFER AHEAD

MTOUT:	PUSH P,A
	PUSH P,B
	CALL TSTINT		;CHECK FOR INTERRUPT REQUEST
	SKIPG BLKCNT		;TIME FOR A NEW BUFFER?
	 CALL SETNXB		;YES-- SET UP ADDRESS AND BLOCK COUNT
	JXN F,ICMODF,[
		MOVE A,MTBPTR	;GET POINTER TO CURRENT BUFFER
		CALL ICOCNV	;INTERCHANGE MODE, DO CONVERSION
		 JRST MTOUT3	;NO OUTPUT
		JRST MTOUT1]	;DATA NOW IN BUFFER, GO WRITE IT
	AOS A,RSEQ
	MOVEM A,SEQ		;KEEP READ SEQ UP TO DATE
	SETZM CHKSUM
	HRRZ B,CURBUF		;POINT TO CURRENT BUFFER
	CALL COMCKB		;CHECKSUM IT
	SETCAM A,CHKSUM
	MOVE A,MTBPTR		;GET CURRENT BUFFER POINTER
	HRLI A,XBUFF		;COPY HEADER FIRST
	MOVEI B,NHEAD(A)
	BLT A,-1(B)		;...
	HRL B,CURBUF		;SET UP BLT PNTR
	MOVEI A,PGSIZ(B)	;LAST ADDRS
	BLT B,-1(A)		;MOVE IT
MTOUT1:	MOVEI A,NHEAD+PGSIZ	;ADVANCE BUFFER POINTER
	ADDM A,MTBPTR		; TO NEXT RECORD
	SOSLE BLKCNT		;FILLED THIS PHYSICAL RECORD?
	 JRST MTOUT3		;NO-- ALL DONE FOR NOW
MTOUT2:	MOVEI A,MTBUF1-1	;SETUP DUMPO START ADDRESS
	SKIPE MTBUFF
	MOVEI A,MTBUF2-1
	HRRM A,MTCOMS
	MOVEI B,MTCOMS
	TDO B,NWTBIT		;SET OVERLAP IO BIT OR 0
	MOVE A,MTJFN
	DUMPO
	 JRST [	CALL WFERR	;WRITE ERROR, RECOVER IT
		SKIPE NWTBIT	;OVERLAPPING?
		JRST MTOUT2	;YES, TRY TRANSFER AGAIN
		JRST .+1]	;NO, ACTUAL TRANSFER RECOVERED
MTOUT3:	POP P,B
	POP P,A
	RET
;WRITE ERROR HANDLER.  ANY DATA ERROR IS HANDLED BY RE-WRITING THE
;SAME RECORD.  CERTAIN OTHER FLAG CONDITIONS (E.G. EOT) ARE
;IGNORED EXCEPT FOR PASSING STATUS BACK TO MAIN FORK.  TAPE
;IS *NEVER* BACKSPACED.
;IF NO ERRORS ARE DETECTED, THEN NO ACTION IS TAKEN.

WFERR:	CAIN A,DUMPX3		;BUFFER TOO BIG?
	 ERROR CLRST,<? Not enough monitor table space for current BLOCKING-FACTOR>
	CALL TSTINT		;CHECK FOR INTERRUPT REQUEST
	CALL XGDSTS		;GET AND CLEAR ERROR FLAGS
	TXNE B,MT%ILW		;ILLEG WRITE?
	JRST [	HRROI A,[ASCIZ /? Tape is write protected, type <CR> when ready to try again. /]
		CALLRET WFTRYM]
	TXNE B,MT%DVE		;DRIVE OFF-LINE?
	JRST [	HRROI A,[ASCIZ /? Drive probably off-line, type <CR> when ready to try again. /]
		CALLRET WFTRYM]
	TXNE B,MT%EOT		;EOT?
	SETZM TAPLFT		;YES, FLAG MAIN FORK
	TXNE B,MT%DAE		;DATA ERROR?
	JRST [	TMSGC <% Write error on tape, record >
		MOVEI B,XSEQ	;SEQ WORD IN RECORD
		TXNE F,ICMODF	;UNLESS INTERCHANGE MODE
		MOVEI B,G$SEQ	;IN WHICH CASE IT IS THIS
		SKIPE NWTBIT	;GET SEQ FROM OTHER BUFFER UNLESS
		SKIPE MTBUFF	;NOT OVERLAPPING
		SKIPA B,MTBUF1(B)
		MOVE B,MTBUF2(B)
		MOVEI C,^D10
		CALL TTNOUT	;REPORT IT
		TMSG <, writing duplicate record.
>
		CALLRET WFTRY]
	RET			;UNKNOWN ERROR, IGNORE
;TRY ERRONEOUS TRANSFER AGAIN.  THIS WILL BE A DUPLICATE RECORD IF
;PREVIOUS ATTEMPT FAILED BECAUSE OF DATA ERROR.

WFTRYM:	PUSH P,A		;HERE IF MSG IN A TO TYPE FIRST
	MOVEI A,101
	DOBE			;WAIT FOR ANY MAIN FORK OUTPUT TO FINISH
	POP P,B
	CALL TMSGQC
	CALL RDLIN		;GET CR FROM USER

;HERE TO TRY AGAIN WITHOUT MSG

WFTRY:	SKIPE NWTBIT		;WRITE FROM OTHER BUFFER UNLESS
	SKIPE MTBUFF		;NOT OVERLAPPING
	SKIPA A,[MTBUF1-1]
	MOVEI A,MTBUF2-1
	HRRM A,MTCOMS
	MOVEI B,MTCOMS
	TDO B,NWTBIT		;SET BIT IF OVERLAPPING
	MOVE A,MTJFN
	DUMPO
	 JRST WFERR		;FAILED AGAIN
	RET			;RETRY REQUESTED OK
;MAG TAPE READ - REQUESTS ONE BUFFER IN ADVANCE

MTRED:	PUSH P,A
	PUSH P,B
	CALL TSTINT		;CHECK FOR INTERRUPT REQUEST
	TXZE F,ICMT1		;INTERCHANGE MODE REPEAT RECORD?
	JRST [	CALL ICICN1	;YES
		 JRST MTRED5	;GET ANOTHER RECORD
		JRST MTRED2]	;DATA NOW IN BUFF
MTRED5:	TXZE F,LRERR		;LAST RECORD HAD ERROR?
	JRST MTRED3		;YES, CURRENT RECORD WAITING IN BUFF
	MOVEI A,NHEAD+PGSIZ	;BUMP ADDRESS
	ADDM A,MTBPTR		; OF CURRENT RECORD
	SOSLE BLKCNT		;ANY RECORDS LEFT IN THIS PHYSICAL RECORD?
	 JRST MTRED4		;YES-- USE IT

;READ NEXT RECORD FROM TAPE

	CALL SETNXB		;SET NEXT BUFFER ADDRESS
	TXZ F,LREOF		;NO EOF
	MOVEI P1,NRETRY		;INIT RETRY COUNT
MTRED1:	MOVEI B,MTBUF1-1	;SELECT BUFFER
	SKIPE MTRACT		;NOW TO DO READ-AHEAD?
	 JRST [	SKIPN MTBUFF		;YES-- USE OTHER BUFFER
		 MOVEI B,MTBUF2-1	; . .
		JRST MTRD12]		; . .
	SKIPE MTBUFF
	 MOVEI B,MTBUF2-1
MTRD12:	HRRM B,MTCOMS
	MOVEI B,MTCOMS
	SKIPE TAPBKF		;DON'T OVERLAP IF RECORD LENGTH NOT YET KNOWN
	 TDO B,NWTBIT
	MOVE A,MTJFN
	DUMPI			;REQUEST INPUT
	 JRST MTRERR		;READ ERROR
	SKIPE NWTBIT		;OVERLAPPING?
	SKIPE MTRACT		;YES-- NO READ-AHEAD YET?
	 JRST MTRED4		;NO-- NOW RETURN DATA TO BUFF
	SKIPN TAPBKF		;BLOCKING-FACTOR KNOWN?
	 JRST MTRED4		;NO-- DON'T READ-AHEAD UNTIL WE FIND IT
	SETOM MTRACT		;YES-- TIME TO DO READ-AHEAD
	JRST MTRED1		; SO GO BACK AND DO IT

MTRED4:	HRLZ A,MTBPTR		;POINT TO CURRENT RECORD
	TXNE F,T36MOD		;36-BIT MODE?
	CALL W36CNV
	TXNE F,ICMODF		;INTERCHANGE MODE?
	JRST [	CALL ICICNV	;YES, REFORMAT RECORD
		 AOSA RSEQ	;RECORD BEING SKIPPED, ADJUST SEQ
		JRST MTRED2	;DATA NOW IN BUFF
		JRST MTRED5]	;GET ANOTHER RECORD
	HRRI A,BUFF-NHEAD	;COPY BUFFER
	BLT A,BUFF+PGSIZ-1
	CALL COMCHK		;CHECK CHECKSUM
	JUMPN A,MTRCSE		;JUMP IF CHECKSUM ERROR
MTRED2:	AOSGE A,RSEQ		;BUMP RECORD NUMBER, IN SEQUENCE RECOVERY?
	JRST [	CALL MTRRCK	;YES
		 JRST MTRERX	;FAILURE, RETURN ERROR
		JRST MTRED3]	;OK
	CAMN A,SEQ		;SAME AS TAPE?
	 JRST MTRED3		;YES-- OK
	CALL MTRSQE		;NO-- CHECK IT OUT
	 JRST [	SETZM BLKCNT		;DUPLICATE RECORD--
		JRST MTRED5]		; IGNORE IT

MTRED3:	MOVN A,TYP		;GET CURRENT RECORD TYPE
	CAIN A,FILLX		;FILLER?
	 JRST MTRED5		;YES-- IGNORE IT
	POP P,B
	POP P,A
	RETSKP

;ERROR RETURN

MTRERX:	TXO F,LRERR		;NOTE BUFFER NOT RETURNED, DATA IN BUFF IS NEXT RECORD
	POP P,B
	POP P,A
	RET

;CONVERT FROM 36-BIT TAPE FORMAT

W36CNV:	ACVAR <Q1>
	HLRZ B,A		;CONVERT BUFFER IN PLACE
	HRLI B,(POINT 8,0)
	HLRZ C,A
	HRLI C,(POINT 4,0)
	MOVEI Q1,^D<<NHEAD+PGSIZ>*9/2> ;SOURCE BYTE COUNT
W36C1:	ILDB D,B		;ONE SOURCE BYTE...
	ROT D,-4		; ... BECOMES TWO DEST BYTES
	IDPB D,C
	ROT D,4
	IDPB D,C
	SOJG Q1,W36C1
	RET
;ERROR HANDLING STRATEGY:

;1. DEVICE ERRORS WHICH DO NOT READ ANY DATA (E.G. OFF-LINE) WAIT
;	FOR CONFIRMATION FROM USER THEN TRY AGAIN.
;2. DEVICE DATA ERRORS ARE RETRIED HERE BECAUSE WE HAVE
;	SUPPRESSED THE MONITOR ERROR CORRECTION LOGIC.
;3. CHECKSUM IS CHECKED ONLY IF DEVICE REPORTS NO ERRORS IN DATA.
;	CHECKSUM ERROR PRODUCES LOCAL RETRY SINCE THE MONITOR DID NOT
;	KNOW OF THE ERROR.
;4. ANY HARD DATA ERROR WILL SET A FLAG WHICH CAUSES THE NEXT RECORD
;	TO BE READ AND ITS SEQUENCE NUMBER CHECKED.  IF IT IS THE
;	SAME AS THE EXPECTED SEQUENCE NUMBER OF THE ERRONEOUS RECORD,
;	THEN THE ERROR WAS ALSO DETECTED ON WRITE AND A DUPLICATE
;	RECORD WAS THEN WRITTEN.  THIS CONSTITUTES FULL
;	RECOVERY AND IS SO REPORTED.

;ERROR REPORTED BY MAGTAPE

MTRERR:	CAIN A,DUMPX3		;BUFFER TOO BIG?
	 JRST [	HLRE A,MTCOMS		;YES-- GET CURRENT WORD COUNT
		ADDI A,PGSIZ+NHEAD	;COUNT DOWN A BUFFER'S WORTH
		HRLM A,MTCOMS		;PUT IT BACK
		CAMGE A,[EXP -<PGSIZ+NHEAD>] ;CAN WE STILL READ A WHOLE RECORD?
		SKIPE TAPBKF		;YES-- ARE WE ALSO STILL LOOKING FOR BLOCKING-FACTOR?
		 ERROR CLRST,<? Not enough monitor table space>
		JRST MTRED1]		;YES-- TRY DUMPI AGAIN
	CALL TSTINT		;CHECK FOR INTERRUPT REQUEST
	CALL XGDSTS		;GET AND CLEAR ERROR FLAGS
	TXNE B,MT%DVE!MT%DAE!MT%EOF ;ANY TRANSFER-ABORT CONDITIONS?
	 SETZM MTRACT		;YES-- NOTE NO OUTSTANDING REQUEST
	TXNE B,MT%DVE		;OFF-LINE?
	JRST [	CALL MTRSQR	;MAKE SURE SEQ RECOVERY FINISHED
		TMSGC <? Device error, possible incorrect density.
  Type <CR> to try again. >
		CALL RDLIN	;GET CR FROM USER
		JRST MTRED1]
	TXNE B,MT%DAE		;DATA ERROR?
	JRST [	CALL MTRSQR	;MAKE SURE SEQ RECOVERY FINISHED
		TMSGC <? MTA data error>
		CALL TSEQN	;REPORT SEQ NUMBER
		JRST MTREX1]	;YES, GO SETUP RETRY
	TXNE B,MT%EOF		;EOF?
	JRST [	MOVE B,TAPBKF	;YES-- COUNT THE EOF
		ADDM B,RSEQ	; AS A PHYSICAL RECORD
		TXON F,LREOF	;SET EOF AND CHECK FOR TWO SEQUENTIAL
		JRST MTRED1	;IGNORE
		MOVX B,-TPTRX	;TWO EOF'S, SIMULATE EOT RECORD
		MOVEM B,TYP
		MOVE B,RSEQ
		MOVEM B,SEQ
		JRST MTRED3]	;AND EXIT
	TXNE B,MT%IRL		;RECORD LENGTH DISAGREES?
	JRST MTRERL		;YES
	TXNE B,MT%EOT		;EOT???
	JRST MTRED4		;YES, IGNORE ERROR
	CALL MTRSQR		;FINISH SEQ RECOVERY
	TMSGC <? MTA unknown error>
	CALL TSEQN		;REPORT SEQ NUMBER

;ATTEMPT TO RECOVER ASSUMING ERROR WAS ALSO SEEN ON WRITE AND
;THAT DUPLICATE RECORD WAS WRITTEN.  IF NEXT RECORD HAS SAME
;SEQUENCE NUMBER AS WAS EXPECTED FOR BAD RECORD, THEN PROBLEM
;HAS BEEN RECOVERED.

MTREX1:	SKIPN RSEQ		;AT BOT?
	JRST [	TMSG <
% Tape may be wrong format>
		JRST .+1]
	MOVSI A,(1B0)		;SET FLAG IN SEQ
	IORM A,RSEQ
	MOVEI P1,NRETRY		;REINIT RETRY COUNT
	JRST MTRED1		;GO READ NEXT RECORD

;RECORD LENGTH ERROR REPORTED.  MONITOR DOES NOT RETRY ON THIS
;BECAUSE SOME PROGRAMS DON'T KNOW HOW LONG THEIR RECORDS ARE.
;WE DON'T KNOW WHAT THE BLOCKING FACTOR WILL BE, SO THE MAXIMUM SIZE
;RECORD IS READ THE FIRST TIME AND WILL COME THROUGH HERE.
;IF WE HAVE ALREADY READ AT LEAST ONE RECORD, WE KNOW THE BLOCKING
;FACTOR AND THE RECORD LENGTH, SO ANY A RECORD LENGTH ERROR
;IS A GENUINE ERROR AND WE WILL TRY TO RE-READ THE RECORD.
;AC C/ XWD # FRAMES READ, 0 (FROM GDSTS)

MTRERL:	SKIPE TAPBKF		;BLOCKING-FACTOR KNOWN?
	 JRST MTRRL1		;YES-- MUST BE REAL ERROR
	HLRZ A,C		;GET WORDS ACTUALLY READ
	IDIVI A,NHEAD+PGSIZ	;COMPUTE NUMBER OF RECORDS READ
	JUMPN B,MTRRL1		;NOT AN INTEGRAL NUMBER OF RECORDS-- REAL ERROR
	MOVEM A,TAPBKF		;SAVE RECORD BLOCKING FACTOR
	MOVEM A,BLKCNT		;ALSO SET AS CURRENT BLOCK COUNT IN BUFFER
	CALL SETIOW		;SET DUMPI COMMAND LIST FOR RIGHT SIZE
	JRST MTRED4		;IGNORE THE ERROR, PROCESS RECORD

;HERE WITH REAL RECORD LENGTH ERROR

MTRRL1:	SOJG P1,MTRTRY		;COUNT ATTEMPTS AND TRY AGAIN
	CALL MTRSQR		;FINISH SEQ RECOVERY
	TMSGC <? MTA record length error>
	CALL TSEQN		;REPORT SEQ NUMBER
	JRST MTREX1		;TRY TO RECOVER BY SEQ NUMBER

;HERE WHEN TRYING TO RECOVER ERROR BY SEQUENCE NUMBER
;AFTER NEXT RECORD HAS BEEN READ. THIS RECORD WILL BE USED IN ANY CASE.

MTRRCK:	MOVSI C,(1B0)
	ANDCAB C,RSEQ		;CLEAR RETRY FLAG
	MOVE B,SEQ		;GET SEQ NUM OF RECORD JUST READ
	CAME B,C		;DESIRED NUMBER?
	JRST [	MOVEM B,RSEQ	;NO, RESET NUMBER
		RET]
	TMSG <, recovered.
>
	RETSKP


;HERE WHEN WE WANT TO REPORT ANOTHER ERROR.
;IF ALREADY IN SEQUENCE RECOVERY, TYPE ", RECORD IGNORED." TO
;COMPLETE LAST ERROR MESSAGE.

MTRSQR:	SKIPL RSEQ		;IN SEQUENCE RECOVERY?
	 RET			;NO-- ALL OK
	TMSG <, record ignored.
>
	RET			;RETURN FROM MTRSQR
;HERE IF SEQUENCE NUMBERS DISAGREE UNEXPECTEDLY.
;IF ACTUAL IS BLOCKING-FACTOR LESS THAN EXPECTED, PROBABLY GOT ERROR ON WRITE
;WHICH DIDN'T APPEAR ON READ, SO DUPLICATE RECORD WAS WRITTEN.
;THE DUPLICATE RECORD IS IGNORED (+1 RETURN).
;IF ACTUAL IS 1 AND EOF JUST READ, PROBABLY NEW SAVESET. PROCEED QUIETLY.
;ANYTHING ELSE IS AN ERROR.

MTRSQE:	MOVE C,RSEQ
	MOVE B,SEQ		;GET NUMBER JUST READ
	MOVEM B,RSEQ		;RESET NUMBERS
	SUB C,B			;COMPUTE DIFFERENCE
	CAMN C,TAPBKF		;ACTUAL 1 LESS THAN EXPECTED?
	JRST [	TMSGC <% Duplicate record encountered, record >
		MOVE B,RSEQ	;REPORT NUMBER
		MOVEI C,^D10
		CALL TTNOUT
		TMSG <, ignored.
>
		RET]		;RETURN +1 FROM MTRSQE TO IGNORE RECORD
	TXNE F,LREOF		;LAST RECORD FILE MARK?
	 JRST [	CAIN B,1		;YES-- NEW SAVESET?
		 RETSKP			;YES-- ASSUME OK
		JRST .+1]		;NO-- REAL SEQUENCE ERROR
	TMSGC <? Sequence error, record >
	MOVE B,RSEQ		;REPORT NUMBER
	MOVEI C,^D10
	CALL TTNOUT
	TMSG <, continuing.
>
	RETSKP
;HERE ON CHECKSUM ERROR.  CHECKSUM ERROR MAY ARISE ONLY WITHOUT
;CONCURRENT DEVICE DATA ERROR.  SINCE NO DEVICE ERROR APPEARED, THEN
;DEVICE HAS GONE AHEAD TO READ NEXT RECORD AND WE WILL HAVE TO
;BACKSPACE 2.

MTRCSE:	CALL TSTINT		;CHECK FOR INTERRUPT REQUEST
	CALL XGDSTS		;WAIT FOR BACKUP OPERATION
	SOJG P1,MTRTRY		;TRY AGAIN WITH 2-RECORD BACKSPACE
	TMSGC <? Checksum error>
	CALL TSEQN
	CALL MTBKRA		;BACK UP OVER READ-AHEAD (IF ANY)
	JRST MTREX1		;TRY SEQ NUMBER RECOVERY

;HERE TO BACKSPACE BEFORE RETRY

MTRTRY:	CALL MTBKRA		;BACK OVER READ-AHEAD, IF ANY
	CALL MTRBKR		;BACK FOR RETRY
	JRST MTRED1		;START FROM TOP

;BACK OVER READ-AHEAD, IF ANY

MTBKRA:	SKIPN MTRACT		;READ-AHEAD OUTSTANDING?
	 RET			;NO-- DO NOTHING
	SETZM MTRACT		;RESET FLAG
;	CALLRET MTRBKR		;BACK OVER RECORD AND RETURN FROM MTBKRA

;BACKSPACE A RECORD

MTRBKR:	MOVE A,MTJFN		;GET MTA JFN
	MOVX B,.MOBKR		;BACKSPACE RECORD FUNCTION
	MTOPR			; . . .
	RET			;RETURN FROM MTRBKR
;REPORT SEQUENCE NUMBER

TSEQN:	TMSG < record >
	MOVE B,RSEQ
	TXZ B,1B0		;CLEAR FLAG IF ANY
	AOS B			;COMPUTE EXPECTED SEQ NUMBER
	MOVEI C,^D10
	CALLRET TTNOUT

;COMPUTE CHECKSUM FOR RECORD.  CHECKSUM WORD IS INCLUDED IN
;COMPUTATION.  ON WRITE, IT IS SET TO 0 BEFORE THE CHECKSUM IS
;COMPUTED, THEN THE CHECKSUM IS STORED COMPLEMENTED.  HENCE ON
;READ, THE CHECKSUM COMPUTATION SHOULD PRODUCE 0.

COMCHK:	MOVEI B,BUFF-NHEAD	;ENTER HERE FOR STANDARD BUFFER
	HRLI B,-1000-NHEAD
	MOVEI A,0
COMCHA:	JCRY0 COMCH1
COMCH1:	ADD A,0(B)
	JCRY0 [AOJA A,.+1]
	AOBJN B,COMCH1
	CAMN A,[EXP -1]
	AOS A
	RET

;ROUTINE TO CHECKSUM DISJOINT BUFFER (PAGE ADDRS IN B)

COMCKB:	MOVE C,[-NHEAD,,XBUFF]
	MOVEI A,0		;INIT CHECKSUM
	JCRY0 COMCB1
COMCB1:	ADD A,0(C)
	JCRY0 [AOJA A,.+1]
	AOBJN C,COMCB1
	HRLI B,-PGSIZ		;SET UP FOR REMAINDER OF RECORD
	JRST COMCHA

;GET ERROR FLAGS AND THEN CLEAR SYSTEM COPY OF THEM

XGDSTS:	MOVE A,MTJFN
	GDSTS			;GET ERROR BITS
	PUSH P,B		;SAVE STATUS BITS
	MOVEI B,0
	MTOPR			;NOP TO CLEAR ERROR FLAGS
	POP P,B
	RET

;SETUP DUMPI/O COMMAND LIST

SETIOW:	MOVSI A,-PGSIZ-NHEAD	;SETUP BLOCK SIZE
	TXNE F,ICMODF		;INTERCHANGE MODE?
	MOVSI A,-PGSIZ-NIHEAD	;YES
	SKIPN B,TAPBKF		;GET BLOCKING-FACTOR
	 JRST [	MOVSI A,-MTBFSZ		;NONE SET YET-- USE MAX BUFFER SIZE
		JRST SETIO1]		; . . .
	IMUL A,B		;RECORD-SIZE TIMES BLOCKING-FACTOR
	JXN F,T36MOD,<[IMULI A,^D9		;ADJUST FOR TAPE FORMAT
		IDIVI A,^D8
		JRST .+1]>
SETIO1:	MOVEM A,MTCOMS		;CONSTRUCT DUMPI/O COMMAND LIST
	SETZM MTCOMS+1
	RET			;RETURN FROM SETIOW


;SET NEXT BUFFER ADDRESS AND BLOCK COUNT

SETNXB:	SKIPE NWTBIT		;OVERLAPPING I/O?
	 SETCMM MTBUFF		;YES-- SWITCH BUFFERS
	MOVEI A,MTBUF1		;SELECT BUFFER
	SKIPE MTBUFF		; . . .
	 MOVEI A,MTBUF2		; . . .
	MOVEM A,MTBPTR		;SAVE AS CURRENT BUFFER POINTER
	MOVE A,TAPBKF		;SET BLOCK COUNT
	MOVEM A,BLKCNT		; FOR THIS PHYSICAL RECORD
	RET			;RETURN FROM SETNXB
	SUBTTL INTERCHANGE CONVERSION

;ROUTINES TO CONVERT BACKUP/INTERCHANGE FORMAT RECORD INTO DUMPER
;FORMAT.
; A/ SOURCE BUFFER ADR,,0

ICICNV:	ACVAR <Q1,Q2>

	HLRZ Q1,A		;KEEP SOURCE BUFFER ADR
	MOVE A,[BUFF-NHEAD,,BUFF-NHEAD+1]
	SETZM -1(A)		;CLEAR DEST BUFFER FIRST
	BLT A,BUFF+PGSIZ-1
	MOVE A,G$SEQ(Q1)	;MOVE COMMON ITEMS - SEQ NUMBER
	MOVEM A,SEQ
	MOVE A,G$RTNM(Q1)	;TAPE NUMBER
	MOVEM A,TAPNO
	MOVE A,G$TYPE(Q1)	;DISPATCH ON TYPE
	CAIN A,T$LBL
	JRST T.LBL		;LABEL
	CAIN A,T$BEG
	JRST T.BEG		;BEGINNING OF SAVE SET
	CAIN A,T$END
	JRST T.END		;END OF SAVE SET
	CAIN A,T$FIL
	JRST T.FIL		;FILE DATA
	CAIN A,T$UFD
	JRST T.UFD		;DIRECTORY INFO
	CAIN A,T$CON
	JRST T.CON		;CONTINUATION
	TMSG <%UNRECOGNIZED RECORD TYPE ON INTERCHANGE TAPE, RECORD SKIPPED
>
	RET

;HERE FOR SECOND AND SUBSEQUENT PROCESSING OF SAME SOURCE RECORD

ICICN1:	ACVAR <Q1,Q2>
	SOS RSEQ		;KEEP SAME SEQ NUM
	MOVEI Q1,MTBUF1		;SETUP BFR ADR AGAIN
	SKIPE MTBUFF
	MOVEI Q1,MTBUF2
	MOVE A,[BUFF,BUFF+1]
	SETZM -1(A)		;CLEAR DATA AREA
	BLT A,BUFF+PGSIZ-1
	MOVE A,G$TYPE(Q1)	;GET TYPE
	CAIE A,T$FIL		;FILE?
	RET			;NO, ???
	MOVE A,G$FLAG(Q1)
	TXNE A,GF$SOF		;START OF SHORT FILE?
	JRST TFIL0		;YES, GET DATA
	TXNE A,GF$EOF		;LAST RECORD?
	JRST TFIL8		;YES
	RET			;UNKNOWN, ???

;RECORD TYPES IGNORED, LBL, UFD, END

T.END:
T.UFD:
T.LBL:	RET

;BEGINNING, END, OR CONTINUATION OF SAVESET

T.CON:
T.BEG:	MOVX A,-TPHDX		;MEANS TAPE HEADER
	MOVEM A,TYP
	MOVE A,S$DATE(Q1)	;TAD OF SAVE
	MOVEM A,BUFF+BFTAD
	MOVEI A,BFMSG		;USUAL MESSAGE PTR
	MOVEM A,BUFF+BFMSGP
	MOVEI A,CURFMT		;USUAL FORMAT
	MOVEM A,BUFF
	MOVEI D,NIHEAD(Q1)	;SET TO SCAN DATA AREA
TBEG1:	SKIPN 0(D)		;MORE TO COME?
	JRST TBEG2		;NO
	HLRZ A,0(D)		;GET BLOCK TYPE
	CAIN A,O$SSNM		;SAVESET NAME?
	JRST TBEG3		;YES
	HRRZ A,0(D)		;NO, STEP TO NEXT BLOCK
	ADDM A,D
	JRST TBEG1

TBEG3:	HRROI A,BUFF+BFMSG
	HRROI B,1(D)		;COPY SAVESET NAME STRING
	SETZ C,
	SOUT
TBEG2:	RETSKP
;FILE DATA RECORD

T.FIL:	MOVE A,G$FLAG(Q1)
	TXNE A,GF$SOF		;FIRST RECORD?
	JRST TFIL1		;YES
TFIL0:	MOVX A,GF$SOF
	ANDCAB A,G$FLAG(Q1)	;NOTE NOT FIRST RECORD NOW
	SKIPG G$SIZ(Q1)		;ANY DATA IN RECORD?
	JRST [	TXNN A,GF$EOF	;NO, EOF?
		RET		;NO, IGNORE RECORD
		JRST TFIL8]	;YES, HANDLE EOF
	MOVEI A,NIHEAD(Q1)	;LOCATION OF DATA
	ADD A,G$LND(Q1)		;PLUS OFFSET IF ANY
	HRLZ A,A		;SOURCE FOR BLT
	HRRI A,BUFF		;DEST FOR BLT
	MOVEI B,BUFF
	ADD B,G$SIZ(Q1)		;NUMBER OF WORDS TO TRANSFER
	BLT A,-1(B)		;COPY DATA 
	SETZM TYP		;DUMPER FILE TYPE
	MOVE A,F$RDW(Q1)	;WORD NUMBER
	IDIVI A,PGSIZ		;CONVERT TO PAGE NUMBER
	MOVEM A,PAGNO
	MOVX A,PM%RD+PM%WT
	MOVEM A,ACCESS		;USUAL ACCESS
TFIL9:	MOVE A,G$FLAG(Q1)
	TXNE A,GF$EOF		;LAST RECORD?
	TXO F,ICMT1		;YES, REPEAT IT
	RETSKP

;FIRST RECORD OF FILE

TFIL1:	MOVX A,-FLHDX		;SAY DUMPER FILE HEADER
	MOVEM A,TYP
	MOVEI D,NIHEAD(Q1)	;SET TO SCAN DATA
	HRLI D,-F$NND		;SIZE OF NON-DATA AREA
TFIL2:	HLRZ A,0(D)		;GET BLOCK TYPE
	CAIN A,O$NAME		;NAME?
	JRST TFIL2N		;YES
	CAIN A,O$FILE		;ATTRIBUTES?
	JRST TFIL2F		;YES
TFIL7:	HRRZ A,0(D)		;STEP BLOCK
	HRL A,A
	ADDM A,D
	SKIPE 0(D)		;END OF DATA?
	JUMPL D,TFIL2		;OR END OF BLOCK?
	SKIPLE G$SIZ(Q1)	;YES, DATA IN THIS BLOCK ALSO?
	TXO F,ICMT1		;YES, REPEAT IT
	JRST TFIL9		;CHECK FOR LAST REC AND RETURN
;FILE NAME BLOCK

TFIL2N:	MOVE A,[POINT 7,BUFF+FHNAM] ;SET TO CONSTRUCT NAME IN BUFF
	MOVEI B,.FCDIR
	CALL SCNBF		;FIND DIRECTORY BLOCK
	 JRST TFIL3		;NONE
	MOVEM B,Q2		;SAVE PTR TO IT
	MOVEI B,DIRBP		;DO DIR PUNCTUATION
	IDPB B,A
	HRLI Q2,(POINT 7,0)	;SET TO COPY STRING
TFIL32:	ILDB B,Q2
	JUMPE B,TFIL31		;END ON NULL
	CAIN B,","		;PPN SEPARATOR?
	MOVEI B,"-"		;YES, TRANSLATE
	IDPB B,A
	JRST TFIL32

TFIL31:	MOVEI B,DIREP
	IDPB B,A		;CLOSE DIR PUNCT
TFIL3:	MOVEI B,.FCNAM
	CALL SCNBF		;FIND NAME BLOCK
	 JRST TFIL4		;NONE
	HRROI B,0(B)
	SETZ C,
	SOUT			;COPY IT
TFIL4:	MOVEI B,EXTPCT
	IDPB B,A		;PUNCTUATE EXTENSION
	MOVEI B,.FCEXT
	CALL SCNBF		;FIND EXTENSION BLOCK
	 JRST TFIL5		;NONE
	HRROI B,0(B)
	SETZ C,
	SOUT			;COPY IT
TFIL5:	MOVEI B,GENPCT
	IDPB B,A		;PUNCTUATE GENERATION
	MOVEI B,.FCGEN
	CALL SCNBF		;FIND GEN
	 JRST TFIL6		;NONE
	HRROI B,0(B)
	MOVEM B,Q2		;SAVE PTR TO GEN STRING
	SETZ C,
	SOUT			;COPY IT
	MOVE A,Q2		;GET PTR TO GEN STRING
	MOVEI C,^D10
	NIN			;CONVERT GEN TO NUMBER
	 CALL JSERR1
	STOR B,FB%GEN,BUFF+FHFDB+.FBGEN ;PUT IN FDB
TFIL6:	JRST TFIL7		;DONE WITH NAME
;ROUTINE TO SCAN NAME BLOCK LOOKING FOR SPECIFIED SUB-BLOCK
; B/ DESIRED BLOCK TYPE
; D/ PTR TO BLOCK
;RETURN +1,
;  B/ PTR TO DATA

SCNBF:	STKVAR <TT1>
	MOVEM D,TT1		;SAVE MAIN PTR
	MOVN C,0(D)		;GET LENGTH OF BLOCK
	HRL D,C			;SET LIMIT
	AOBJN D,.+1		;STEP PAST HEADER
SCNBF1:	HLRZ C,0(D)		;GET SUB-BLOCK TYPE
	CAMN C,B		;REQUESTED ONE?
	JRST [	MOVEI B,1(D)	;YES, RETURN PTR TO DATA
		MOVE D,TT1	;RESTORE D
		RETSKP]
	HRRZ C,0(D)		;BUMP SUB-BLOCK
	HRL C,C
	ADDM C,D
	SKIPE 0(D)		;END OF DATA?
	JUMPL D,SCNBF1		;JUMP UNLESS END OF BLOCK
	MOVE D,TT1		;RESTORE D
	RET			;TYPE NOT FOUND

;ATTRIBUTE BLOCK

TFIL2F:	MOVEI C,1(D)		;POINT TO DATA PORTION
	MOVE A,A$WRIT(C)	;COPY ITEMS - WRITE DATE
	MOVEM A,BUFF+FHFDB+.FBWRT
	MOVE A,A$BSIZ(C)
	STOR A,FB%BSZ,BUFF+FHFDB+.FBBYV
	PUSH P,C		;SAVE C
	SKIPN A			;IS BYTE SIZE ZERO?
	 MOVEI A,^D36		;YES-- ASSUME 36 BIT BYTES
	MOVEI B,^D36		;BITS IN A WORD
	IDIV B,A		;BYTES IN A WORD
	POP P,C			;RESTOR C
	MOVE A,A$LENG(C)
	MOVEM A,BUFF+FHFDB+.FBSIZ
	ADDI A,-1(B)		;ROUND UP
	IDIV A,B		;WORDS IN FILE
	ADDI A,PGSIZ-1		;ROUND UP
	IDIVI A,PGSIZ		;FULL PAGES IN FILE
	STOR A,FB%PGC,BUFF+FHFDB+.FBBYV
	MOVE A,[BUFF+FHFDB,,ICFDB]
	BLT A,ICFDB+.FBLN0-1	;SAVE FDB FOR EOF
	JRST TFIL7

;LAST RECORD OF FILE, DATA ALREADY COPIED

TFIL8:	MOVE A,[ICFDB,,BUFF]	;COPY FDB SAVED FROM FIRST RECORD
	BLT A,BUFF+.FBLN0
	MOVX A,-FLTRX		;FILE TRAILER
	MOVEM A,TYP
	RETSKP
;DUMPER FORMAT TO INTERCHANGE FORMAT CONVERSION ON OUTPUT
; A/ DUMP BUFFER ADDRESS

ICXBUF=ICOBUF+NHEAD		;DATA AREA OF LOCAL BUFFER

ICOCNV:	ACVAR <Q1>
	MOVEM A,Q1		;SAVE BUFFER ADDRESS
	TXZ F,TF1		;NOTE NO OUTPUT DATA YET
	TXZN F,ICMT1		;HAVE PREVIOUS BUFFER?
	JRST ICOCNX		;NO, RETURN IMMEDIATELY
	MOVEI A,1(Q1)		;CLEAR DEST BUFFER
	HRL A,Q1
	SETZM -1(A)
	BLT A,NIHEAD+PGSIZ-1(Q1)
	MOVE A,ICOBUF+XTAPNO	;COPY STANDARD ITEMS - TAPE NUMBER
	MOVEM A,G$RTNM(Q1)
	MOVX A,GF$NCH		; - FLAGS, NO CHECKSUM
	MOVEM A,G$FLAG(Q1)
	MOVN A,ICOBUF+XTYP	;DISPATCH ON TYPE
	CAIN A,DATAX		;DATA RECORD?
	JRST ICODAT
	CAIE A,CTPHX
	CAIN A,TPHDX		;TAPE HEADER?
	JRST ICOTPH
	CAIN A,FLHDX		;FILE HEADER?
	JRST ICOFLH
	CAIN A,FLTRX		;FILE TRAILER?
	JRST ICOFLT
	CAIN A,TPTRX		;TAPE TRAILER?
	JRST ICOTPT
	CAIN A,USRX		;USER DATA?
	JRST ICOUSR
	JRST ICOCNX		;(IMPOSSIBLE)

;STANDARD RETURNS, VALID DATA IN DEST BUFFER

ICOCNY:	TXO F,TF1		;NOTE DATA IN BUFFER
	AOS A,RSEQ		;COMPUTE NEXT SEQ NUMBER
	MOVEM A,G$SEQ(Q1)	;LEAVE IT IN BUFFER

;NO DATA IN DEST BUFFER

ICOCNX:	HRLZ A,CURBUF		;CURRENT DATA BUFFER
	HRRI A,ICOBUF+NHEAD	; TO TEMP BUFFER
	BLT A,ICOBUF+NHEAD+PGSIZ-1 ;COPY BUFFER
	MOVE A,[XBUFF,,ICOBUF]	;NOW COPY HEADER
	BLT A,ICOBUF+NHEAD-1
	TXO F,ICMT1		;NOTE ICOBUF VALID
	TXNN F,TF1		;DEST BUFFER VALID?
	RET			;NO
	RETSKP			;YES
;FINISH PENDING OUTPUT - DONE AT END OF TAPE

ICOFIN:	CALL MTOUT		;CAUSE PENDING RECORD TO BE WRITTEN
	TXZ F,ICMT1		;NO PENDING RECORD NOW
	RET

;FILE TRAILER, USER DATA - PRODUCE NO OUTPUT

ICOFLT:
ICOUSR:	JRST ICOCNX

;TAPE HEADER

ICOTPH:	MOVX A,T$BEG		;SAVESET BEGIN
ICOTP1:	MOVEM A,G$TYPE(Q1)
	MOVE A,ICXBUF+BFTAD	;TAD
	MOVEM A,S$DATE(Q1)
	MOVX A,BKFMT		;BACKUP FORMAT VERSION
	MOVEM A,S$FMT(Q1)

;S$BVER, S$MON, S$SVER, S$APR, S$DEV, S$MTCH NOT PROVIDED

	HRROI A,NIHEAD+1(Q1)	;DEST FOR SAVESET NAME
	HRROI B,ICXBUF+BFMSG	;SOURCE OF SAVESET NAME
	SETZ C,
	SOUT			;COPY SAVESET NAME TO DEST BFR
	SUBI A,NIHEAD-1(Q1)	;COMPUTE NUMBER WORDS USED
	MOVEM A,NIHEAD(Q1)	;SETUP ONE-WORD HEADER
	MOVEM A,G$LND(Q1)	;NOTE SIZE OF NON-DATA AREA
	MOVX A,O$SSNM		;INCLUDE CODE
	HRLM A,NIHEAD(Q1)
	JRST ICOCNY		;RETURN VALID BUFFER

;TAPE TRAILER

ICOTPT:	MOVX A,T$END		;SAVESET END
	JRST ICOTP1		;SAME AS HEADER

;DATA RECORD

ICODAT:	MOVX A,T$FIL		;TYPE CODE
	MOVEM A,G$TYPE(Q1)
	MOVEI A,PGSIZ		;ASSUME FULL PAGE OF DATA HERE UNLESS...
	CAMLE A,ICOLEN		;NOT THAT MUCH LEFT IN FILE
	MOVE A,ICOLEN		;USE WHATEVER IS LEFT
	MOVEM A,G$SIZ(Q1)	;SET DATA WORD COUNT THIS RECORD
	MOVN A,A
	ADDM A,ICOLEN		;UPDATE REMAINING COUNT
	MOVX A,GF$EOF
	MOVN B,TYP		;CHECK TYPE OF NEXT RECORD
	CAIN B,FLTRX		;IS IT FILE TRAILER?
	IORM A,G$FLAG(Q1)	;YES, NOTE THIS LAST RECORD OF FILE
	HRRZ A,ICOBUF+XPAGNO	;COMPUTE RELATIVE WORD NUMBER
	IMULI A,PGSIZ
	MOVEM A,F$RDW(Q1)
	MOVSI A,ICXBUF		;COPY DATA TO DEST BUFFER
	HRRI A,NIHEAD(Q1)
	BLT A,NIHEAD+PGSIZ-1(Q1)
	JRST ICOCNY		;RETURN BUFFER
;FILE HEADER

ICOFLH:	MOVX A,T$FIL		;RECORD TYPE
	MOVEM A,G$TYPE(Q1)
	MOVEI A,F$NND		;NOTE SIZE OF NON-DATA AREA THIS RECORD
	MOVEM A,G$LND(Q1)
	MOVX A,GF$SOF		;FLAGS - START OF FILE
	IORM A,G$FLAG(Q1)
	MOVEI D,NIHEAD+1(Q1)	;BEG OF AREA FOR FILENAME
	MOVX A,O$NAME		;INDICATE NAME BLOCK
	HRLM A,-1(D)
	MOVX A,F$NND/2		;STANDARD SIZE
	HRRM A,-1(D)
	MOVE B,[POINT 7,ICXBUF+FHNAM] ;PTR TO NAME
ICOFH1:	ILDB C,B		;FIND START OF DIRECTORY
	CAIE C,DIRBP
	JRST ICOFH1
	MOVX A,.FCDIR		;INDICATE DIR BLOCK
	HRLM A,0(D)
	MOVEI A,DIREP
	CALL ICOFHC		;COPY DIRECTORY STRING
	MOVX A,.FCNAM		;INDICATE NAME BLOCK
	HRLM A,0(D)
	MOVEI A,EXTPCT
	CALL ICOFHC		;COPY NAME STRING
	MOVX A,.FCEXT
	HRLM A,0(D)		;INDICATE EXT BLOCK
	MOVEI A,GENPCT
	CALL ICOFHC		;COPY EXT STRING
	MOVX A,.FCGEN		;INDICATE GENERATION BLOCK
	HRLM A,0(D)
	MOVEI A,ATTPCT
	CALL ICOFHC		;COPY GENERATION STRING
	MOVEI D,NIHEAD+F$NND/2+1(Q1) ;BEG OF AREA FOR ATTRIBUTES
	MOVX A,O$FILE		;INDICATE ATTRIBUTE BLOCK
	HRLM A,-1(D)
	MOVX A,F$NND/2		;STANDARD SIZE
	HRRM A,-1(D)
	MOVE A,ICXBUF+FHFDB+.FBWRT
	MOVEM A,A$WRIT(D)	;COPY WRITE DATE
	LOAD B,FB%BSZ,ICXBUF+FHFDB+.FBBYV ;GET FILE BYTE SIZE
	SKIPN B			;BYTE SIZE ZERO?
	 JRST [			;YES-- USE 36
		LOAD A,FB%PGC,ICXBUF+FHFDB+.FBBYV ;GET PAGE COUNT
		IMULI A,PGSIZ		;GET ACTUAL SIZE IN WORDS
		MOVEM A,ICXBUF+FHFDB+.FBSIZ ;AND USE AS FILE BYTE COUNT
		MOVEI B,^D36		;GET BYTE SIZE
		JRST .+1]
	MOVEM B,A$BSIZ(D)
	MOVEI A,^D36
	IDIV A,B		;COMPUTE ACTUAL BYTES/WD
	MOVE B,ICXBUF+FHFDB+.FBSIZ ;GET FILE BYTE COUNT
	MOVEM B,A$LENG(D)	;SET BYTE COUNT
	IDIV B,A		;CONVERT BYTE COUNT TO 36-BIT BYTES
	SKIPE C			;REMAINDER?
	AOS B			;YES, ACCOUNT FOR PARTIAL WORD
	MOVEM B,ICOLEN		;KEEP LOCAL COUNT
	MOVEM B,A$ALLS(D)	;USE IT AS ALLOCATION ALSO
	MOVX A,.DMIMG		;USE STANDARD MODE
	MOVEM A,A$MODE(D)
	JRST ICOCNY

;LOCAL ROUTINE TO COPY FILESPEC STRING
; A/ TERMINATING CHARACTER FOR CURRENT FIELD
; B/ SOURCE STRING PTR
; D/ DEST ADDRESS

ICOFHC:	ACVAR <Q1>
	MOVEM A,Q1		;SAVE TERMINATOR
	MOVEI A,1(D)		;CONSTRUCT STRING PTR
	HRLI A,(POINT 7,0)
ICOFC1:	ILDB C,B		;GET CHAR
	CAME C,Q1		;TERMINATOR?
	 JUMPN C,[IDPB C,A	;NO, APPEND IT TO DEST
		JRST ICOFC1]
	SUBI A,-1(D)		;YES, COMPUTE WORDS IN BLOCK
	HRRM A,0(D)		;PUT COUNT IN BLOCK HEADER
	ADDI D,0(A)		;BUMP DEST PTR
	RET
	SUBTTL	ROUTINE TO CHECK SPECS AGAINST A WILDCARD STRING



;THE FOLLOWING ROUTINE WAS RIPPED OUT FROM THE MONITOR MODULE
;LOOKUP.  WHENEVER A JSYS IS WRITTEN TO DO THIS FUNCTION, THIS
;ROUTINE SHOULD BE REPLACED WITH THAT JSYS CALL.

; THIS SUBROUTINE COMPARES A STRING TO A GENERALIZED WILD-CARD
;MASK. A IS A POINTER TO THE STRING AND B IS A POINTER TO THE
;MASK.
; RETURNS +1 IF THE MASK CANNOT MATCH THE STRING. RETURNS +2
;IF IT DOES MATCH

CHKWLD:	SAVEQ		;SAVE PERMANENT ACS
	STKVAR <SVPTR,SVMSK> ;POINTERS TO LAST STAR POSITION
	SETZ Q2,	;NO PREVIOUS ON THE FIRST BYTE
	SETZM SVMSK	;NO PREVIOUS
MRTEST:	MOVE Q3,Q2	;SAVE PREVIOUS CHARACTER
	ILDB Q2,B	;GET NEXT MASK CHARACTER
	JUMPE Q2,EMASK	;END OF MASK
	CAIN Q2,"%"	;A SINGLE CHARACTER WILD CARD?
	JRST SNGL	;YES
	CAIN Q2,"*"	;ANY WILD MATCH?
	JRST ANY	;YES
	CALL GETSRC	;GET NEXT STRING BYTE
	 RET		;END OF STRING AND FAILURE
	CAIN Q2,(C)	;MATCH?
	 JRST MRTEST	;YES. GO ON
FAIL:	SKIPN B,SVMSK	;NO. HAVE A PREVIOUS "*" ?
	RET		;NO. CANT MATCH THESE TWO
	IBP SVPTR	;STRETCH THE MASK
	MOVE A,SVPTR	;MAKE IT CURRENT POINTER
	JRST MRTEST	;AND TRY AGAIN

;GET SOURCE BYTE

GETSRC:	ILDB C,A	;GET IT
	JUMPE C,R	;IF END OF STRING, FAIL RETURN
	RETSKP		;GOT ONE

;END OF MASK ROUTINE

EMASK:	CAIN Q3,"*"	;DID MASK END IN A "*"
	RETSKP		;YES. IT IS A MATCH
	CALL GETSRC	;NO. AT END OF SOURCE TOO?
	 RETSKP		;YES. A MATCH
	JRST FAIL	;NO. TRY TO STRETCH THE MASK


;FOUND A "%" IN THE MASK

SNGL:	CALL GETSRC	;GET A SOURCE BYTE
	 RET		;NO MORE BYTES
	JRST MRTEST	;GO GET MORE

;FOUND A "*" IN THE STRING

ANY:	MOVEM A,SVPTR	;SAVE POINTER TO STRING
	MOVEM B,SVMSK	;SAVE MASK POINTER
	JRST MRTEST	;GO DO THE REST
	SUBTTL UTILITY SUBROUTINES

;READ LINE INTO LINBUF
;	CALL RDLIN
; RETURN +1 ALWAYS

RDLIN:	CALL TSTINT		;CHECK FOR INTERRUPT REQUEST
	HRROI A,LINBUF
	MOVE B,[RD%BRK+RD%BEL+RD%RAI+NLINB*5]
	SETZ C,
	RDTTY
	 JSERR
	MOVEI B,.CHCRT		;TIE OFF LINE IN CASE ESC OR ^Z
	IDPB B,A
	MOVEI B,.CHLFD
	IDPB B,A
	RET

;ROUTINE TO ACCEPT YES/NO ANSWER FROM USER.  REQUIRES USER TO
;TYPE Y OR N.  RETURNS "TRUE" (NON-0) ON Y, "FALSE" (0) ON N IN AC1.
;CALL WITH PROMPT STRING IN A

YESNO:	MOVEM A,CBLK+.CMRTY	;SAVE PROMPT STRING
YESNO0:	PUSH P,CBLK+.CMRTY	;SAVE PROMPT STRING
	CALL TSTINT		;CHECK FOR INTERRUPT REQUEST
	POP P,CBLK+.CMRTY	;SETUP PROMPT STRING
	MOVEI A,YESNO1		;REPARSE ADDRESS
	MOVEM A,CBLK		;STORE
	MOVEI A,CBLK
	MOVEI B,[FLDDB. (.CMINI)]
	COMND			;SET UP FOR NEW COMMAND
YESNO1:	MOVEI B,[FLDDB. (.CMKEY,,YNTBL)]
	COMND
	TXNE A,CM%NOP
	ERROR YESNO0,<?YES or NO only>
	HRRZ D,0(B)		;GET DATA
	MOVEI B,[FLDDB. (.CMCFM)]
	COMND
	TXNE A,CM%NOP		;CONFIRMED?
	 ERROR YESNO0,<?NOT CONFIRMED>
	MOVE A,D		;GET DATA BACK
	RET			;RETURN FROM YESNO, 1= YES, 0= NO IN A

YNTBL:	XWD YNTBLZ,YNTBLZ
	TB 0,<NO>
	TB 1,<YES>
YNTBLZ==.-YNTBL-1



TDRNAM:	TXNE F,LDIRF	;YES, TYPE DIR NAMES REQUESTED?
	TXNE F,LTTYF	;AND NOT LOGGING TO TTY?
	RET		;NO
	HRROI B,DIRNAM	;YES, TYPE DIR NAME
	CALL TMSGQ
	TXNN F,DIRCHG 	;SKIP IF DIRECTORY NAMES CHANGE
	JRST TDRNA1	;NO
	TMSG < (AS) >
	HRROI B,ODRNAM		;OUTPUT DIRECTORY NAME
	CALL TMSGQ
TDRNA1:	TMSG <
>
	RET
;STANDARD JSYS ERROR HANDLER

JSER00:	CALL JSERR1		;PRINT MESSAGE
	HALTF			;FATAL, HALT

;PRINT STANDARD ERROR MSG AND RETURN

JSERR1:	CALL NOCTRO		;TURN OFF CONTROL O
	HRROI A,[ASCIZ /
?JSYS error: /]
	PSOUT

;ENTRY TO PRINT ERROR MESSAGE ONLY

JSERRM:	MOVEI A,101
	HRLOI B,400000		;SAY THIS FORK,,LAST ERROR
	SETZ C,
	ERSTR
	 JFCL
	 JFCL
	HRROI A,[ASCIZ /
/]
	PSOUT
	RET
;TURN OFF CONTROL O (IN CASE IT IS ON) FOR ERROR MESSAGE

NOCTRO: PUSH P,A
	PUSH P,B
	MOVEI A,.PRIOU		;PRIMARY OUTPUT
	RFMOD
	TLZ B,(TT%OSP)		;TURN OFF
	SFMOD
	POP P,B
	POP P,A
	RET

;HERE IF CHANGED REELS IN MIDDLE OF RESTORING FILE AND PAGE #'S
;MISSING OR DON'T MATCH
MISFPG:	TMSGC <? File >
	HRROI B,TFNAME		;FILE NAME
	CALL TMSGQ
	TMSG < continued from previous reel has missing page(s)
>
	RET
;USE INPUT FIELDS AS DEFAULTS FOR OUTPUT SIDE
; Q1-1/ INDEX TO JFNLST AND JF2LST TABLES

OFNAME:	MOVSI D,-NFFLD		;SETUP NUMBER OF FIELDS TO CONSTRUCT
OFNAM1:	MOVE B,JFNLST-1(Q1)	;GET INPUT JFN
	HRRO A,FSTRT(D)	;SETUP ADR OF DEFAULT STRING
	MOVEM A,GJBLK+.GJDEV(D) ;IN GTJFN BLOCK ALSO
	MOVE C,FFLDT(D)	;REQUEST FIELD FROM JFNS
	JFNS			;SETUP DEFAULT STRING
OFNAM2:	AOBJN D,OFNAM1		;DO ALL FIELDS
	RET			;HAVE DEFAULT OUTPUT NAME


;NOW COOK UP APPROPRIATE OUTPUT NAME
; P5/ INDEX TO JFNLST AND JF2LST TABLES

OUTFIL:	MOVSI Q1,-NFFLD		;SETUP NUMBER OF FIELDS TO CONSTRUCT
	SKIPN D,JF2LST(P5)	;HAVE AN OUTPUT SPEC?
	JRST [	SETZM GJBLK+.GJDEV ;NO, USE DEFAULT DEVICE
		MOVX D,GJ%DEV+GJ%DIR+GJ%NAM+GJ%EXT+GJ%VER ;ASSUME ALL STARS
		JRST .+1]
OUTFI1:	MOVE B,D		;USE OUTPUT JFN UNLESS...
	HLLZ A,FSTRT(Q1)	;GET STAR BIT FOR THIS FIELD
	TDNE D,A		;OUTPUT STAR HERE?
	HRRZ B,JFN		;YES, USE INPUT FIELD
	HRRO A,FSTRT(Q1)	;SETUP ADR OF DEFAULT STRING
	MOVEM A,GJBLK+.GJDEV(Q1) ;IN GTJFN BLOCK ALSO
	MOVE C,FFLDT(Q1)	;REQUEST FIELD FROM JFNS
	JFNS			;SETUP DEFAULT STRING
OUTFI2:	AOBJN Q1,OUTFI1		;DO ALL FIELDS
	SETZM GJBLK+.GJPRO	;ASSUME SYSTEM DEFAULT PRO AND ACCT
	RET


;HERE GET FULL OUTPUT FILE SPEC, DEVICE THROUGH GENERATION
;STORE IN ONMBUF

GOFNAM:	HRROI A,ONMBUF		;STORE NAME HERE
	MOVX D,GJ%DEV		;DEVICE
	MOVX C,<FLD(.JSAOF,JS%DEV)+JS%PAF>
	CALL .JFNS		;DO JFNS
	MOVX D,GJ%DIR		;DIRECTORY
	MOVX C,<FLD(.JSAOF,JS%DIR)+JS%PAF>
	CALL .JFNS
	MOVX D,GJ%NAM		;NAME
	MOVX C,<FLD(.JSAOF,JS%NAM)+JS%PAF>
	MOVEM A,ONMPTR		;SAVE NAME POINTER
	CALL .JFNS
	MOVX D,GJ%EXT		;EXTENSION
	MOVX C,<FLD(.JSAOF,JS%TYP)+JS%PAF>
	CALL .JFNS
	MOVX D,GJ%VER		;GENERATION #
	MOVX C,<FLD(.JSAOF,JS%GEN)+JS%PAF>
	MOVEM A,OGNPTR		;SAVE GENERATION POINTER
;	CALLRET .JFNS		;GET GEN # AND RETURN FROM GOFNAM

.JFNS:	TDNN D,JF2LST(P5)	;OUTPUT * HERE?
	SKIPN B,JF2LST(P5)	;NO, USE OUTPUT FIELD
	HRRZ B,JFN		;PICKUP INPUT FIELD
	JFNS
	RET

;GET REST OF OUTPUT FILE NAME: PROTECTION, ACCOUNT, AND ;T

GOFPAT:	MOVX D,GJ%PRO		;PROTECTION
	MOVX C,<FLD(.JSAOF,JS%PRO)+JS%PAF>
	TXNE F,RESPRO		;USE SYSTEM DEFAULT?
	 CALL .JFNSX		;NO-- GET SPECIFIED VALUE
	MOVX D,GJ%TFS		; ;T
	MOVX C,<JS%TMP+JS%PAF>
	CALL .JFNSX		;GET ;T
	MOVEM A,OACPTR		;REMEMBER WHERE ACCOUNT STARTS
	MOVX D,GJ%ACT		;ACCOUNT
	MOVX C,<FLD(.JSAOF,JS%ACT)+JS%PAF>
	TXNE F,RESACC		;USE SYSTEM DEFAULT?
	 CALL .JFNSX		;NO-- GET SPECIFIED VALUE
	RET			;RETURN FROM GOFPAT

.JFNSX:	TXNE F,ICMODF		;INTERCHANGE MODE?
	TDNE D,JF2LST(P5)	;YES-- BUT IS OUTPUT SPECIFIED?
	 SKIPA			;OUTPUT SPECIFIED OR NOT INTERCHANGE-- OK
	  RET			;INTERCHANGE MODE AND NO OUTPUT SPEC-- USE SYSTEM DEFAULT
	TDNE D,JF2LST(P5)	;OUTPUT SPECIFIED HERE?
	SKIPN B,JF2LST(P5)	;YES, USE OUTPUT FIELD
	HRRZ B,JFN		;PICKUP INPUT FIELD
	JFNS
	RET

;FILESPEC FIELD TABLES

FSTRT:	GJ%DEV+DEFDEV		;STAR FOR DEVICE ,, DEFAULT DEVICE STRING
	GJ%DIR+DEFDIR		;STAR FOR DIRECTORY
	GJ%NAM+DEFNAM		; " NAME
	GJ%EXT+DEFEXT		; " EXTENSION
	GJ%VER+DEFVER		; " VERSION

FFLDT:	1B2			;JFNS PRINT DEVICE
	1B5			;JFNS PRINT DIRECTORY
	1B8			; " NAME
	1B11			; " EXTENSION
	1B14			; " VERSION
NFFLD==.-FFLDT
;HERE TO FIGURE FILE SIZE IN PAGES AND REMAINDER

FILSZE:	LOAD A,FB%BSZ,BUFF+FHFDB+.FBBYV
	MOVEI B,44	;BITS IN A WORD
	IDIV B,A	;BYTES IN A WORD
	MOVE C,BUFF+FHFDB+.FBSIZ  ;BYTES IN FILE
	IDIV C,B	;WORDS IN FILE
	SKIPE D		;SKIP IF NO REMAINDER
	AOS C
	IDIVI C,PGSIZ	;PAGES IN FILE
	MOVEM C,FPGCNT	;FILE PAGE COUNT
	MOVEM D,RMRPGE	;REMAINDER PAGE
	RET

;HERE FOR CHECKSUM OF PAGE

PGECSM:	TXNE F,CS%SEQ	;SKIP IF NOT SEQUENTIAL CHECKSUM
	JRST SEQCSM	;DO SEQUENTIAL CHECKSUM
	HRRZ D,PAGNO	;GET PAGE #
	SUB D,LSTPGE	;SEE IF HOLE
	SOJLE D,PCHKS1		;JUMP IF NO HOLE
	MOVNI C,(D)		;YES, GET -PAGE #
	HRL C,D			;MAKE IT PAGE #,,-PAGE #
	PUSH P,C		;STUFF WORD ONTO STACK
	MOVSI C,-1
	HRRI C,-BUFF(P)	;ARRANGE TO POINT AT IT
	CALL CHKSOM		;CHECKSUM 1 WORD
	POP P,(P)		;RESTORE STACK
PCHKS1:	MOVSI C,-1000		;SETUP AOBJN POINTER TO WHOLE PAGE
	CALL CHKSOM		;CHECKSUM IT
	MOVE A,PAGNO		;GET PAGE #
	HRRZM A,LSTPGE		;STORE
	RET			;DONE WITH PAGE
;HERE FOR SEQUENTIAL CHECKSUM
SEQCSM:	SOSGE FPGCNT		;DECREMENT WHOLE PAGE CONT
	JRST SEQCS1		;NO WHOLE PAGES LEFT
	MOVSI C,-1000		;WORDS TO CHECKSUM
	CALLRET CHKSOM		;CHECKSUM PAGE

SEQCS1:	SKIPN C,RMRPGE		;GET REMAINDER TO CHECK
	RET			;NOTHING TO CHECK
	MOVNS C			;NEGATE WORDS TO CHECK
	HRLZS C			;...
	SETZM RMRPGE		;DON'T CHECK AGAIN
	CALLRET CHKSOM		;CHECK SUM PAGE

;HERE TO CHECKSUM COUNT OF WORDS IN C
CHKSOM:	MOVE D,CHKCN0
CHKSM1:	ROT D,1
	ADD D,BUFF(C)
	AOBJN C,CHKSM1		;LOOP ON WORD COUNT
	MOVEM D,CHKCN0
	RET
;ROUTINES TO MANIPULATE JFN STACK

;ADD JFN TO JFN STACK
;ALL AC'S PRESERVED
;	B HAS JFN IN RIGHT HALF

ADLIST: PUSH P,D		;SAVE AC
	HLRZ D,CURPTR		;CHECK FOR STACK OVERFLOW
	CAIN D,-1		;SKIP IF NOT FULL
	ERROR START,<?JFN STACK OVERFLOW>
	MOVE D,CURPTR		;PICK UP STACK POINTER
	PUSH D,B		;PUT JFN ON STACK
	MOVEM D,CURPTR		;STORE UPDATED STACK POINTER
	POP P,D			;RESTORE D
	RET			;RETURN

;HERE TO RELEASE JFN STORED ON STACK
;	A HAS JFN IN RH

RLSJFN:	HRRZS A			;CLEAR LEFT HALF
	GTSTS			;GET JFN STATUS
	TXNN B,GS%NAM		;SKIP IF JFN OWNED
	RET			;NOTHING TO DO
	TXNN B,GS%OPN		;SKIP IF JFN IS OPEN
	JRST [RLJFN		;RELEASE IT IF NOT
		ERROR START,<?CANNOT RELEASE JFN>
		RET]
	CLOSF			;CLOSE AND RELEASE JFN
	ERROR START,<?CANNOT CLOSE AND RELEASE JFN>
	RET

;HERE TO ADD A FILE--BE SURE IT IS A DISK FILE

ADFILE:	CALL ADLIST		;ADD TO JFN STACK
	CALL CHKDVC		;CHECK FOR DEVICE DISK
	RET

;ROUTINE TO TAKE JFN'S OFF STACK
;	D HAS FINAL DESIRED POINTER
;	RETURNS FINAL DESIRED POINTER IN D
;ASSUMES A,B,C,D ARE FREE

RSTSTK:	CAMN D,CURPTR		;SEE IF ANYTHING THERE
	RET			;NOPE
	PUSH P,D		;SAVE FINAL POINTER
	MOVE D,CURPTR		;CURRENT POINTER
RSTST1:	POP D,A			;GET JFN OFF STACK
	CALL RLSJFN		;RELEASE JFN
	CAME D,(P)		;COMPARE POINTERS
	JRST RSTST1		;NOT DONE
	POP P,D			;GET FINAL POINTER
	MOVEM D,CURPTR		;USE AS CURRENT POINTER
	RET			;RETURN
;HERE TO BOMB THE CURRENT COMMAND
;IF COMMAND IS CONFIRMED, ENTER AT BMBCMD
;IF COMMAND IS NOT CONFIRMED, ENTER AT BMBCM1

BMBCMD:	MOVE D,CMDTYP		;GET COMMAND TYPE
	TXNE D,TY%MAP		;NOSKIP IF COMMAND MAPS BUFPAG
	CALL UNMAPB		;RESET BUFFERS
BMBCM1:	MOVE P,PDLP		;RESET PDL TO TOP OF COMMAND
	MOVE D,CMDPTR		;RESET TO TOP OF COMMAND
	CALL RSTSTK		;RESET STACK TO TOP OF COMMAND
	MOVEM D,RPSPTR		;REPARSE POINTER RESET
	MOVEI A,.PRIIN		;PRIMARY INPUT DEVICE
	CFIBF			;CLEAR BUFFER
	JRST RESTRT		;TOP OF NEW COMMAND

;HERE TO CHECK THAT THE USER MEANS DISK FILES ALWAYS
;PRESERVES ALL AC'S-- JFN TO CHECK IN B

CHKDVC:	PUSH P,A	;SAVE AC'S
	PUSH P,B
	HRRZ A,B	;GET JFN TO CHECK
	DVCHR
	LOAD A,DV%TYP,B
	CAIE A,.DVDSK	;SHOULD ALWAYS BE A DISK FILE TYPE
	ERROR BMBCM1, <?DEVICE MUST BE DISK>
	POP P,B
	POP P,A
	POPJ P,

;HERE TO RESET BACK TO INIPTR

INIRST:	MOVE D,INIPTR		;FINAL POINTER
	CALL RSTSTK		;RESET STACK TO START OF WORLD
	MOVEM D,RPSPTR		;RESET REPARSE POINTER
	MOVEM D,CMDPTR		;COMMAND POINTER
	JRST RESTRT		;RESTART THE WORLD
TTNOUT:	MOVEI A,.PRIOU
	NOUT
	 JSERR
	RET

BTNOUT:	TXNN F,LTTYF		;LISTING TO TTY?
	CALL TTNOUT		;NO, DO TTY FIRST
LPNOUT:	SKIPN LPTJFN		;SKIP IF LISTING
	RET
	HRROI A,LPTBUF		;PUT NUMBER IN LOCAL BUFFER FIRST
	NOUT
	 JSERR
	PUSH P,B
	PUSH P,C
	MOVE B,[POINT 7,LPTBUF]
	CALL LPMSGQ		;TRANSMIT TO LPT
	POP P,C
	POP P,B
	RET

TMSGQC:	PUSH P,B
	MOVEI 1,.PRIOU
	DOBE
	RFPOS
	TRNN B,-1
	 JRST TMSGC1
	TMSG <
>
TMSGC1:	POP P,B

TMSGQ:	MOVEI 1,.PRIOU
	MOVEI C,0
	SOUT
	RET

BTMSQC:	PUSH P,B
	TXNE F,LTTYF
	SKIPN A,LPTJFN
	 JRST BTMSC1
	DOBE
	RFPOS
	TRNN B,-1
	 JRST BTMSC2
BTMSC1:	LPMSG <
>
BTMSC2:	MOVE B,(P)
	TXNN F,LTTYF
	 CALL TMSGQC
	POP P,B
	CALLRET LPMSGQ

BTMSGQ:	PUSH P,B
	TXNN F,LTTYF		;NOT TO TTY IF LOGGING IS TO TTY
	CALL TMSGQ
	POP P,B
LPMSGQ:	SKIPN LPTJFN
	RET
	MOVE A,LPTLIN
	CAIL A,PAGLEN		;AT END OF LISTING PAGE?
	CALL LNEWPG		;YES, START A NEW ONE
	MOVE A,LPTJFN
	MOVEI C,0
	PUSH P,B		;SAVE PTR
	SOUT
	POP P,B			;RECOVER PTR
	HLRZ A,B		;NORMALIZE IT
	CAIN A,-1
	HRLI B,(POINT 7,0)
LPTM1:	ILDB A,B		;ACCOUNT LINE POSITION
	JUMPE A,R		;NULL, DONE
	CAIN A,.CHLFD		;EOL
	JRST [	SETZM LPTPOS	;RESET
		AOS LPTLIN	;COUNT LINES
		JRST LPTM1]
	CAIN A,.CHTAB		;TAB?
	JRST [	MOVEI A,7	;YES, BUMP
		IORM A,LPTPOS
		JRST .+1]
	AOS LPTPOS		;COUNT ONE SPACE
	JRST LPTM1

;START NEW LISTING PAGE

LNEWPG:	SKIPE LPTJFN
	SKIPE LPTPOS		;DON'T OUTPUT HEADER UNLESS AT START OF LINE!
	RET
	PUSH P,B
	MOVE A,LPTJFN
	MOVEI B,.CHFFD		;SEND A FORMFEED
	BOUT
	HRROI B,LSTHDR		;SEND PAGE HEADER
	SETZ C,
	SOUT
	HRROI B,[ASCIZ /   Page /]
	SOUT			;SEND PAGE NUMBER
	AOS B,LPTPAG
	MOVEI C,^D10
	NOUT
	 JSERR
	HRROI B,[ASCIZ /

/]
	SETZ C,
	SOUT			;FINISH HEADER
	MOVEI B,2		;INIT LINE COUNT TO NUMBER LINES
	MOVEM B,LPTLIN		; PRINTED ABOVE
	POP P,B
	RET

;TAB TO SPECIFIED COLUMN IN LISTING FILE
; B/ COLUMN

TAB:	SKIPN LPTJFN
	RET
	MOVE A,LPTLIN
	CAIL A,PAGLEN		;AT END OF LISTING PAGE?
	CALL LNEWPG		;YES, START A NEW ONE
	SUB B,LPTPOS		;COMPUTE NUMBER SPACES NEEDED
	JUMPLE B,R		;MAYBE NONE
	ADDM B,LPTPOS		;UPDATE POSITION
	MOVE A,LPTJFN
	MOVN C,B
	HRROI B,SPACES
	SOUT			;OUTPUT THEM
	RET

SPACES:	ASCII /                                                  /
	ASCII /                                                  /
;HERE TO PRINT CHECKSUM OF FILE

PRTCSM:	MOVEI B,CSCOL		;CHECKSUM COLUMN
	CALL TAB		;TAB TO CHECKSUM
	HLRZ B,CHKCN0
	HRRZ C,CHKCN0
	ADD C,B			;MAKE IT 18-BITS WORTH
	HLRZ B,C		;...
	ADDI B,(C)		;...
	MOVEI C,^D8		;OCTAL RADIX
	TXO C,NO%LFL+NO%ZRO
	TLO C,6			;6 COLUMNS
	CALL LPNOUT
	TXNN F,CS%SEQ		;SKIP IF SEQUENTIAL CHECKSUM
	LPMSG < P>		;FLAG AS BY-PAGES CHECKSUM
	RET
MASK:	0
	FB%PRM+FB%NOD+FB%FCF
	0
	0
	0
	777777777777
	0			;OLD AUTHOR WRITER WORD
	0
	0
	777717000000
	777777777777
	777777777777
	777777777777
	777777777777
	777777777777
	0			;.FBBK0
	0
	0
	0
	0
	777777777777
	0
	0
	0
	0			;.FBLWR POINTER
IFN .-MASK-.FBLEN,<PRINTX ** FDB MASK ARRAY SIZE WRONG **>

NWMASK:	0
	FB%TMP+FB%PRM+FB%NOD+FB%FCF
	0
	0
	0
	0
	0
	0
	0
	777717000000
	777777777777
	777777777777
	777777777777
	777777777777
	0
	0
	0
	0
	0
	0
	777777777777
	0
	0
	0
	0			;.FBLWR POINTER WORD
IFN .-NWMASK-.FBLEN,<PRINTX ** FDB NWMASK ARRAY SIZE WRONG **>
;FDB MASK FOR INTERCHANGE MODE RESTORE

ICMASK:	0			;FBHDR
	0			;FBCTL
	0			;FBEXL
	0			;FBADR
	0			;FBPRT
	0			;FBCRE
	0			;FBAUT
	0			;FBGEN/FBDRN
	0			;FBACT
	007700,,0		;FBBYV
	-1			;FBSIZ
	0			;FBCRV
	-1			;FBWRT
	0			;FBREF
	0			;FBCNT
   REPEAT 5,<0>			;FBBK0-FBBK4
	0			;FBUSW
	0			;FBGNL
	0			;FBNAM
	0			;FBEXT
	0			;FBLWR
   IFN .-ICMASK-.FBLEN,<PRINTX ** FDB ICMASK ARRAY SIZE WRONG **>

;FDB MASK FOR CHECK

CKMASK:	0			;FBHDR
	FB%TMP+FB%PRM+FB%NOD+FB%FCF ;FBCTL
	0			;FBEXL
	0			;FBADR
	0,,777777		;FBPRT
	-1			;FBCRE
	0			;FBAUT
	0			;FBGEN/FBDRN
	0			;FBACT
	777717,,0		;FBBYV
	-1			;FBSIZ
	-1			;FBCRV
	-1			;FBWRT
	-1			;FBREF
	-1			;FBCNT
   REPEAT 5,<0>			;FBBK0-FBBK4
	-1			;FBUSW
	0			;FBGNL
	0			;FBNAM
	0			;FBEXT
	0			;FBLWR
   IFN .-CKMASK-.FBLEN,<PRINTX ** FDB CKMASK ARRAY SIZE WRONG **>

FDBNAM:	SIXBIT /HEADER/
	SIXBIT /.FBCTL/
	SIXBIT /.FBEXT/
	SIXBIT /.FBADR/
	SIXBIT /.FBPRT/
	SIXBIT /.FBCRE/
	SIXBIT /.FBAUT/
	SIXBIT /.FBVER/
	SIXBIT /.FBACT/
	SIXBIT /.FBBYV/
	SIXBIT /.FBSIZ/
	SIXBIT /.FBCRV/
	SIXBIT /.FBWRT/
	SIXBIT /.FBREF/
	SIXBIT /.FBCNT/
	SIXBIT /.FBBK0/
	SIXBIT /.FBBK1/
	SIXBIT /.FBBK2/
	SIXBIT /.FBBK3/
	SIXBIT /.FBBK4/
	SIXBIT /.FBUSW/
	SIXBIT /.FBGNL/
	SIXBIT /.FBNAM/
	SIXBIT /.FBEXT/
	SIXBIT /.FBLWR/

PAT..::
PATS:	BLOCK 100		;PATCH SPACE

	END <3,,ENTVEC>