Google
 

Trailing-Edge - PDP-10 Archives - bb-d868a-bm - 3-sources/dumper.mac
There are 42 other files named dumper.mac in the archive. Click here to see a list.
;<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==0		;MINOR VERSION NUMBER
VEDIT==163		;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##>


;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

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>

;LOCATIONS IN UPPER ADR SPACE

N.JFN==2*PGSIZ			;DOUBLE LENGTH BUFFER (JFNSTK)
CBFSIZ==<2*PGSIZ>/5		;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

BUFF2=601000
BF2PAG==<BUFF2>B44

BUFF=600000
BUFPAG==<BUFF>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

;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

INIPDL:	IOWD NPDL,PDL		;INITIAL PUSH DOWN LIST
STGBGN:				;BEGINNING OF STORAGE CLEARED AT STARTUP

CURBUF:	BLOCK 1		;CURRENT OUTPUT BUFFER
FORMAT:	BLOCK 1			;DATA FORMAT
ICOBUF:	BLOCK PGSIZ+NHEAD	;CONVERSION OUTPUT BUFFER
MTBUF1:	BLOCK <PGSIZ+MXHEAD>*^D9/^D8	;ALTERNATING BUFFERS FOR MTA IO
MTBUF2:	BLOCK <PGSIZ+MXHEAD>*^D9/^D8
MTBUFF:	BLOCK 1			;BUFFER SWITCH
MTRACT:	BLOCK 1			;BACKUP REQUEST ISSUED
LRERR:	BLOCK 1			;LAST RECORD HAD ERROR
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 10		;DEFAULT DEVICE
DEFDIR:	BLOCK 10		;DEFAULT DIRECTORY
DEFNAM:	BLOCK 10		;DEFAULT NAME
DEFEXT:	BLOCK 10		;DEFAULT EXTENSION
DEFVER:	BLOCK 10		;DEFAULT VERSION
DEFPRO:	BLOCK 10		;DEFAULT PROTECTION
DEFACC:	BLOCK 10		;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
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			;NON-0 IF INCREMENTAL DUMP
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

;STANDARD RETURNS

RSKP:	AOS 0(P)
R:	RET

DEFINE JSERR<
	JSP CX,JSERR0>

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

DEFINE ERRORJ (TAG,MSG)<
	JRST [	TMSG <
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 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 CLRST1		;REENTER LOCATION
	VDUMPR			;VERSION NUMBER

START:	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
	SETZ F,
	TXO 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
	RESET
	MOVEI A,CURFMT		;DEFAULT IS CURRENT FORMAT
	MOVEM A,FORMAT
	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:	SKIPE A,MTJFN		;GET MAG TAPE JFN
	CALL RLSJFN		;RELEASE JFN
	SETZM MTJFN
CLRST1:	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::	TMSG	<
% Do you really want to abort your interrupted command?>
JFNCF3:	MOVEI A,JFNCF3		;REPARSE ADDRESS
	MOVEM A,CBLK		;STORE
	HRROI A,[ASCIZ /Yes or No? /]
	MOVEM A,CBLK+.CMRTY
	MOVEI A,CBLK
	MOVEI B,[FLDDB. (.CMINI)]
	COMND			;SET UP FOR NEW COMMAND
	MOVEI B,[FLDDB. (.CMKEY,,ATBL)]
	COMND
	TXNE A,CM%NOP
	ERROR JFNCF3,<?Yes or No only>
	HRRZ B,0(B)
	JRST (B)

ATBL:	NATBL,,NATBL
	TB	DLTNEW,<NO>
	TB	DLTOLD,<YES>
NATBL==.-ATBL-1
;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>
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)]
	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 
	TXNE F,ICMODF		;NOW IN INTERCHANGE MODE?
	TXZA F,RESPRO+RESACC	;YES, NO ACCOUNTS OR PROTECTIONS FROM TAPE
	TXO F,RESPRO+RESACC	;NO, RESET DEFAULTS
	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>
	MOVE Q2,[POINT 7,SSNBUF]
SSNA1:	CAMN Q1,CBLK+.CMPTR	;UP TO CURRENT PTR?
	JRST [	SETZ A,		;YES, TIE OFF STRING
		IDPB A,Q2
		JRST CDONE]
	ILDB A,Q1		;COPY TEXT TO BUFFER
	CAIN A,.CHLFD		;NL?
	JRST SSNA1		;YES, FLUSH
	IDPB A,Q2		;COPY CHAR
	JRST SSNA1
;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:	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
	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
;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 .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

;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 TSTINT		;TEST FOR INTERRUPT REQUEST
	CALL MTRED		;READ NEXT RECORD
	 JRST [	TMSG <, record ignored
>
		JRST EOT1]
	MOVE A,TYP		;CHECK TYPE
	CAME A,[-CTPHX]
	CAMN A,[-TPHDX]		;TAPE HEADER?
	JRST [	CALL TYHEDR	;YES, TYPE INFO
		JRST EOT1]
	CAME 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
	MOVE A,TYP
	CAME A,[-CTPHX]
	CAMN A,[-TPHDX]		;SAVESET HEADER?
	AOS Q1			;YES, SKIP ONE MORE THAN SPEC
	JRST SKIPF2

SKIPF1:	CALL TSTINT		;TEST FOR INTERRUPT REQUEST
	CALL MTRED		;SCAN FORWARD
	 JRST [	TMSG <, record ignored
>
		JRST SKIPF1]
SKIPF2:	MOVE A,TYP		;CHECK TYPE
	CAMN A,[-TPTRX]		;END OF TAPE?
	JRST [	CALL BACKSP	;YES, ERROR
		ERROR (BMBCMD,<%END OF TAPE ENCOUNTERED>)]
	CAME A,[-TPHDX]		;TAPE HEADER?
	CAMN 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 TSTINT		;TEST FOR INTERRUPT REQUEST
	CALL BACKSP
	CALL MTRED
	 JRST [	TMSG <, record ignored
>
		JRST SKIPR2]
	MOVE A,TYP		;CHECK TYPE
	CAME A,[-TPHDX]		;TAPE HEADER?
	CAMN 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
	TXZ F,LTTYF!LFDSK
	JRST CDONE

DIRS:	SETZM LSTHDR		;NO HEADER YET
	MOVEI B,OF%RD
	CALL MTOPEN
	SETOM CEXFLG		;ALLOW INTERRUPT
DIR1:	CALL TSTINT		;TEST FOR INTERRUPT REQUEST
	CALL MTRED		;READ NEXT RECORD, DISPATCH ON TYPE
	 JRST [	TMSG <, record ignored
>
		JRST DIR1]
	MOVE B,TYP
	CAMN B,[-FLHDX]
	JRST DIRF		;FILE HEADER
	CAMN B,[-USRX]
	JRST DIRU		;USER INFO
	CAMN B,[-TPTRX]
	JRST DIRE		;END OF TAPE
	CAME B,[-CTPHX]
	CAMN B,[-TPHDX]
	JRST DIRB		;BEGINNING OF TAPE
	CAMN 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:	BTMSG <
End of tape.
>
	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:	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,FILCDB		;SET TO ACCEPT FILESPEC
	SKIPE WHEEL		;WHEEL?
	MOVEI B,[FLDDB. (.CMSWI,,DSWTB,,,FILCDB)] ;YES, ALLOW SWITCHES
	COMND			;GET FILESPEC OR SWITCH
	TXNE A,CM%NOP
	ERRORJ BMBCM1,<?NOT A SWITCH OR FILESPEC>
	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
	TB $INC,<INCREMENTAL>
	TB $NINC,<NOINCREMENTAL>
NDSWTB==.-DSWTB-1

$INC:	SETOM INCRSW		;INCREMENTAL
	JRST DUMP1

$NINC:	SETZM INCRSW		;NO INCREMENTAL
	JRST DUMP1

;COMMAND BLOCK FOR SOURCE FILE

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

;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 FILESPEC HAS BEEN TYPED

DUMP4:	CALL ADFILE		;ADD FILE TO JFNSTACK
	CALL CHKDVC		;DO A DVCHR FOR LEGAL DEVICE
	JUMPGE Q1,[ERROR (BMBCM1,<?TOO MANY ITEMS IN FILESPEC LIST>)]
	MOVEM B,JFNLST(Q1)	;SAVE JFN
	SETZM JF2LST(Q1)	;NO DESTINATION JFN NOW
	AOBJN Q1,.+1
	TXNE B,GJ%DIR		;* FOR DIRECTORY?
	TXO F,USRDAT		;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
	MOVEM B,JF2LST-1(Q1)
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
	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
	; ..
	; ..
	TXNN F,TNSF		;SKIP IF TAPE # SET
	SETZM TAPNO		; START AFTER TAPE 0
	CALL DMPFI1
	SETOM CEXFLG		;ALLOW INTERRUPT
	HRLZ P5,NJFN		;SET TO SCAN JFN LIST
DUMPL1:	MOVE B,JF2LST(P5)	;GET NEXT JFN
	TXNE B,GJ%DIR		;SKIP IF 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
	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]
DUMPL2:	CALL SCNJFG		;SCAN THIS GROUP
	AOBJN P5,DUMPL1		;LOOP FOR ALL GROUPS
	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 <
>
	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 DEVICE/STRUCTURE NAME STRING
	HRRZ B,SCNJFN
	MOVX C,<FLD(.JSAOF,JS%DEV)>
	JFNS
	HRROI B,[ASCIZ /:<*>*.*.*/]
	SETZ C,
	SOUT			;CONSTRUCT FILESPEC FOR ALL FILES THEREON
	TXNN F,USRDAT		;WANT USER DATA?
	JRST SCNLUP		;NO - SKIP THIS
	HRROI A,RCDSTR		;SET TO BUILD STR:<*>
	MOVX C,<FLD(.JSAOF,JS%DEV)>
	HRRZ B,SCNJFN
	JFNS			;GET STRUCTURE NAME
	HRROI B,[ASCIZ /:<*>/]
	SETZ C,
	SOUT			;APPEND *
	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,USRDAT		;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 INIPGN		;SKIP IF NOT CONTINUED FILE
	MOVNI A,CTPHX		;CONTINUED TAPE HEADER
	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
	; ..
	; ..
	MOVE A,JFN
	SKIPE INCRSW
	JRST [	HLRZ B,FDB+.FBCNT ;GET COUNT OF WRITES
		CAIN B,0
		MOVEI B,1	;ASSUME AT LEAST ONE
		SKIPLE C,FDB+.FBBK0 ;BACKUP REQUESTED?
		CAME B,C	;OR DIFFERENT # WRITES THAN AT LAST BACKUP?
		JRST .+1	;YES, DUMP THIS FILE
		JRST NODUMP]
	
	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
	MOVE B,JFN
	MOVX C,1B17+1B20+1B21+1B35
	JFNS			;APPEND PROTECTION AND 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
	CALL TSTINT		;TEST FOR INTERRUPT REQUEST
	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
	HLRZ C,BUFF+.FBCNT	;GET COUNT OF WRITES
	CAIN C,0
	MOVEI C,1		;ASSUME AT LEAST ONE
	HRRZ B,BUFF+.FBBK0
	CAME B,C
	TLOA C,400000
	MOVE C,BUFF+.FBBK0
	MOVNI B,1
	MOVE A,JFN
	HRLI A,.FBBK0
	SKIPE INCRSW
	JRST [	TXO A,CF%NUD	;SUPPRESS DIRECTORY UPDATE
		CHFDB		;NOTE DUMP PARTIALLY DONE
		HRRM C,BUFF+.FBBK0 ;WRITE FDB ON TAPE
		HLLZS C		; AS IF DUMP COMPLETED SUCCESSFULLY
		LSH C,1
		HLLM C,BUFF+.FBBK0
		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.  TERMINATE CURRENT REEL, START NEW ONE.
;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 ENDTAP
	CALL REWIND
	CALL MTCLS		;CLOSE MTA
	SKIPN A,LPTJFN		;SKIP IF LISTING
	JRST DMPET1
	CLOSF			;CLOSE LISTING FILE
	 JFCL
DMPET1:	TMSG <$ End of tape, continue save on
>
	CALL NTAPE		;GET NEW TAPE SPEC
	CALL DMPFI1		;START NEXT TAPE
	JRST DMPFIL		;RESTART THIS FILE
;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,USRDAT		;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 [	TMSG <?RCDIR out of sync on directories
>
		TXZ F,USRDAT	;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
	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:	TMSG <
?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
	SETZM BUFF
	MOVE B,[XWD BUFF,BUFF+1]
	BLT B,BUFF+777
	TXNE F,USRDAT		;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:	TMSG <
% Log file not available, >
	CALL JSERRM
	TXZ F,LFDSK+LTTYF	;NOT DISK OR TTY
LPTOP1:	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
	HLLZS C
	LSH C,1
	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 [	TMSG <
% No interruptable command in progress
>
		JRST CEINT1]
	SKIPE INTRQ		;ALREADY REQUEST PENDING?
	JRST [	TMSG <
% 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
	SKIPN A,TRAPJ		;SKIP IF TRAP STUFF
	JRST RESTRT
	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
	TMSG <
?>
	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
	TMSG <
? 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
	TMSG <
? Unexpected memory wrtie trap in DUMPER
>
	JRST BADIVA

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

;MACHINE SIZE EXCEEDED

MSETRP:	JSR EINT1		;SWITCH CONTEXT
	TMSG <
?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
	TMSG <
? 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
	BTMSG <
? 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:
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]
	MOVE A,TYP		;GET RECORD TYPE
	CAME A,[-TPHDX]		;TAPE HEADER?
	CAMN 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
	TMSG <
? 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:	TMSG <
% 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 [	SKIPE NWTBIT	;OVERLAPPING?
		CALL BACKSP	;YES, UNDO ONE READ AHEAD
		CALL MTCLS	;DONE
		JRST CDONE]
	CALL TSTINT		;TEST FOR INTERRUPT PENDING
	CALL MTRED
	JRST [	TMSG < while searching for file 
>
		JRST LODFIL]

;LOOK FOR BEGINNING OF NEXT FILE OR END OF TAPE

LODHX2:	MOVE A,TYP		;GET TYPE CODE
	CAMN A,[-TPTRX]		;TAPE TRAILER?
	JRST LODEND		;YES
	CAME A,[-CTPHX]
	CAMN A,[-TPHDX]		;HEADER?
	JRST [	TMSG <
End of saveset
>
		CALL BACKSP	;BACK OVER SAVESET HEADER
		CALL MTCLS
		JRST CDONE]
	CAMN A,[-USRX]		;USER BLOCK?
	JRST LODUSR		;YES
	CAME A,[-CTPHX]		;GO ON IF CONTINUED SAVE
	CAME 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 REWIND
	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
	TMSG <
% 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 TSTINT		;TEST FOR INTERRUPT REQUEST
	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
	TMSG <
% 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 [	MOVX A,GJ%OLD+GJ%SHT
		HRROI B,BUFF	;yes, 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:	HLLZ B,FSTRT(Q1)	;GET STAR BIT FOR THIS FIELD
	TDNE B,JFNLST(P5)	;SPECIFIED JFN HAS IT?
	JRST LODTS1		;YES, MATCH
	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]
	STCMP			;COMPARE STRINGS
	JXN A,SC%LSS+SC%SUB+SC%GTR,[
		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

	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]
LODNM2:	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
LODNM1:	AOBJN Q1,LODNM2		;DO ALL FIELDS
	SETZM GJBLK+.GJPRO	;ASSUME SYSTEM DEFAULT PRO AND ACCT
	SETZM GJBLK+.GJACT
	TXNN F,RESPRO		;RESTORE PROTECTION?
	JRST LODNM6		;NO
	HRROI A,DEFPRO		;SETUP DEF STRING PTR
	MOVEM A,GJBLK+.GJPRO
	HRRZ B,JFN
	MOVX C,<FLD(.JSAOF,JS%PRO)>
	JFNS
LODNM6:	TXNN F,RESACC		;RESTORE ACCOUNT?
	JRST LODNM7		;NO
	HRROI A,DEFACC		;SETUP DEF STRING PTR
	MOVEM A,GJBLK+.GJACT
	HRRZ B,JFN
	MOVX C,<FLD(.JSAOF,JS%ACT)>
	JFNS
	; ..
	
	; ..
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
	MOVE B,[.NULIO,,.NULIO]
	MOVEM B,GJBLK+.GJSRC	;SETUP GJBLK PARAMETERS - SOURCE/DEST

;CHECK SUPERSEDE RULE

	TXNN F,TF2		;DONT CHECK SUPERCEDE IF MIDDLE 
				;OF FILE
	TXNE F,SSA		;SUPERSEDE ALWAYS?
	JRST LODNM3		;YES, NO CHECK
LODNM8:	MOVX B,GJ%OLD
	MOVEM B,GJBLK+.GJGEN	;SET TO LOOK AT MOST RECENT VERSION
	SETO B,			;NO STRING
	MOVEI A,GJBLK
	GTJFN			;GET MOST RECENT VERSION
	 JRST LODNM3		;ISN'T ONE, THEREFORE OK TO LOAD
	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:	HRROI A,DEFVER		;CONVERT VERSION STRING TO BINARY
	MOVEI C,^D10
	NIN
	 JSERR
	AOJN B,LODNMB		;CHECK FOR -1
	TXNN F,TF2		;YES - 2ND HALF OF FILE?
LODNMB:	SUBI B,1		;NO - RE-ADJUST
				;WILL HAVE 0 FOR GENERATION IF
				;2ND PART AND -1 WAS GIVEN.
	HRRM B,GJBLK+.GJGEN	;PUT IT IN GTJFN BLOCK
	MOVX B,GJ%FOU		;GTJFN FLAGS
	HLLM B,GJBLK+.GJGEN
	SETO B,
	MOVEI A,GJBLK
	GTJFN
	 JRST CANNOT		;LOSS??
	MOVEM A,JFN

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

LODNMA:	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

;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
;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:	TMSG <
% Cannot get JFN for file >
	JRST CANT1

CANTOP:	MOVE A,JFN
	RLJFN
	 JFCL
	TMSG <
% Cannot open file >
CANT1:	HRROI B,BUFF		;FILESPEC STRING
	CALL TMSGQ
	TMSG < because:
  >
	CALL JSERRM
	RET

CANTLD:	TMSG <
% Cannot load file >
	JRST CANT1
;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
MTOP2:	TXZ F,LREOF+ICMT1	;CLEAR FLAGS
	SETZM LRERR
	SETZM MTRACT
	SETZM MTBUFF		;INIT VARIABLES
	MOVSI A,-PGSIZ-NHEAD	;SETUP BLOCK SIZE
	TXNE F,ICMODF		;INTERCHANGE MODE?
	MOVSI A,-PGSIZ-NIHEAD	;YES
	JXN F,T36MOD,<[IMULI A,^D9		;ADJUST FOR TAPE FORMAT
		IDIVI A,^D8
		JRST .+1]>
	MOVEM A,MTCOMS		;CONSTRUCT DUMPI/O COMMAND LIST
	SETZM MTCOMS+1
	MOVE B,NWTBT0		;INIT NORMAL OVERLAP MODE
	MOVEM B,NWTBIT
	RET
;OPEN FAILURE

MTOFAI:	CALL JSERRM		;SAY WHY
	TMSG <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
;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 FUNCTION

REWIND:	PUSH P,A
	PUSH P,B
	MOVEI B,.MOREW		;REWIND CODE
	MOVE A,MTJFN
	MTOPR
	SETZM RSEQ
	SETZM SEQ
	POP P,B
	POP P,A
	RET

;MARK END OF TAPE

ENDTAP:	MOVNI A,TPTRX
	MOVEM A,TYP
	CALL MTOUT
	TXNE F,ICMODF		;INTERCHANGE MODE?
	CALL ICOFIN		;YES, FINISH BUFFERS
	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
	AOS A,RSEQ		;COUNTS IN SEQUENCE
	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 CLRST,<%BEGINNING OF TAPE ENCOUNTERED>
	SOS SEQ			;ADJUST SEQ NUMBERS
	SOS RSEQ
	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 [	SKIPN MTRACT	;NO, READING AHEAD?
		JRST XMTOP1	;NO, READY
		MOVEI B,.MOBKR	;YES, MUST BACK OVER ADVANCE RECORD
		MTOPR
		SETZM MTRACT
		JRST XMTOP1]
	CALL XGDSTS		;WAIT FOR OPERATION AND GET STATUS
	TRNE B,1B18+1B19+1B20+1B25 ;ERRORS?
	JRST [	CALL WFERR	;YES, RECOVER
		 JFCL
		JRST .+1]
XMTOP1:	POP P,B			;RECOVER FUNCTION CODE
	MOVE A,MTJFN
	MTOPR			;DO FUNCTION
	RET
;MAGTAPE OUTPUT ROUTINE.  REQUESTS ONE TRANSFER AHEAD

MTOUT:	PUSH P,A
	PUSH P,B
	JXN F,ICMODF,[
		MOVEI A,MTBUF1		;SELECT BUFFER
		SKIPE MTBUFF
		MOVEI A,MTBUF2
		CALL ICOCNV	;INTERCHANGE MODE, DO CONVERSION
		 JRST MTOUT2	;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
	MOVEI A,MTBUF1		;SELECT BUFFER
	SKIPE MTBUFF
	MOVEI A,MTBUF2
	HRLI A,XBUFF		;COPY HEADER FIRST
	MOVEI B,NHEAD(A)
	BLT A,-1(B)		;...
	MOVEI A,MTBUF1+NHEAD	;SELECT BUFFER
	SKIPE MTBUFF
	MOVEI A,MTBUF2+NHEAD	;...
	HRL A,CURBUF		;SET UP BLT PNTR
	MOVEI B,PGSIZ(A)	;LAST ADDRS
	BLT A,-1(B)		;MOVE IT
MTOUT1:	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 MTOUT1	;YES, TRY TRANSFER AGAIN
		JRST .+1]	;NO, ACTUAL TRANSFER RECOVERED
	SKIPE NWTBIT
	SETCMM MTBUFF		;SWITCH BUFFERS IF OVERLAPPING
MTOUT2:	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.

WFERR:	CALL XGDSTS		;GET AND CLEAR ERROR FLAGS
	TRNE B,1B18		;ILLEG WRITE?
	JRST [	HRROI A,[ASCIZ /
? Tape is write protected, type <CR> when ready to try again. /]
		CALLRET WFTRYM]
	TRNE B,1B19		;DRIVE OFF-LINE?
	JRST [	HRROI A,[ASCIZ /
? Drive probably off-line, type <CR> when ready to try again. /]
		CALLRET WFTRYM]
	TRNE B,1B25		;EOT?
	SETZM TAPLFT		;YES, FLAG MAIN FORK
	TRNE B,1B20		;DATA ERROR?
	JRST [	TMSG <
% 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,A
	PSOUT
	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
	TXZE F,ICMT1		;INTERCHANGE MODE REPEAT RECORD?
	JRST [	CALL ICICN1	;YES
		 JRST MTRED5	;GET ANOTHER RECORD
		JRST MTRED2]	;DATA NOW IN BUFF
MTRED5:	SKIPE LRERR		;LAST RECORD HAD ERROR?
	JRST [	SETZM LRERR	;YES, CURRENT RECORD WAITING IN BUFF
		JRST MTRED3]	;GO RETURN IT
	MOVEI P1,NRETRY		;INIT RETRY COUNT
MTRED1:	MOVEI B,MTBUF1-1	;SELECT BUFFER
	SKIPE MTBUFF
	MOVEI B,MTBUF2-1
	HRRM B,MTCOMS
	MOVEI B,MTCOMS
	TDO B,NWTBIT
	MOVE A,MTJFN
	DUMPI			;REQUEST INPUT
	 JRST MTRERR		;READ ERROR
	SKIPN NWTBIT
	JRST MTRED4		;DATA READY NOW IF NOT OVERLAPPING
	SETCMM MTBUFF		;SWITCH BUFFERS
	SKIPN MTRACT		;HAVE COMPLETED BUFFER?
	JRST [	SETOM MTRACT	;NO, GO REQUEST ANOTHER READ
		JRST MTRED1]
MTRED4:	TXZ F,LREOF		;NO EOF
	MOVSI A,MTBUF1		;SELECT BUFFER
	SKIPE MTBUFF
	MOVSI A,MTBUF2
	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:	SKIPGE RSEQ		;IN SEQUENCE RECOVERY?
	JRST [	CALL MTRRCK	;YES
		 JRST MTRERX	;FAILURE, RETURN ERROR
		JRST MTRED3]	;OK
	AOS A,RSEQ		;BUMP SEQ NUMBER
	CAME A,SEQ		;SAME AS TAPE?
	CALL MTRSQE		;NO
MTRED3:	POP P,B
	POP P,A
	RETSKP

;ERROR RETURN

MTRERX:	SETOM LRERR		;NOTE BUFFER NOT RETURNED
	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:	CALL XGDSTS		;GET AND CLEAR ERROR FLAGS
	SETZM MTRACT		;NOTE NO OUTSTANDING REQUEST
	SKIPE NWTBIT
	SETCMM MTBUFF		;SWITCH BUFFERS BACK
	TRNE B,1B19		;OFF-LINE?
	JRST [	TMSG <
? Device error, possible incorrect density.
  Type <CR> to try again. >
		CALL RDLIN	;GET CR FROM USER
		JRST MTRED1]
	TRNE B,1B20		;DATA ERROR?
	JRST [	MOVE A,RSEQ
		TXNE A,1B0	;ALREADY DOING ERROR RECOVERY?
		JRST MTREX1	;YES, MESSAGE ALREADY PRINTED
		TMSG <
? MTA data error>
		CALL TSEQN	;REPORT SEQ NUMBER
		JRST MTREX1]	;YES, GO SETUP RETRY
	TRNE B,1B22		;EOF?
	JRST [	AOS RSEQ	;YES, COUNT IN SEQUENCE
		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
	TRNE B,1B23		;RECORD LENGTH DISAGREES?
	JRST MTRERL		;YES
	TRNE B,1B25		;EOT?
	JRST MTRED4		;YES, IGNORE ERROR
	TMSG <
? 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.
;THIS PROGRAM IS EXPECTING ONLY ONE SIZE OF RECORD HOWEVER,
;SO IT IS A GENUINE ERROR AND WE WILL TRY TO RE-READ THE RECORD.

MTRERL:	SOJG P1,MTRTRY		;COUNT ATTEMPTS AND TRY AGAIN
	TMSG <
? MTA recored 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:	AOS RSEQ		;BUMP SEQ NUMBER TO EXPECTED RECORD
	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 IF SEQUENCE NUMBERS DISAGREE UNEXPECTEDLY.
;IF ACTUAL IS 1, PROBABLY NEW SAVESET. PROCEED QUIETLY.
;IF ACTUAL IS 1 LESS THAN EXPECTED, PROBABLY GOT ERROR ON WRITE
;WHICH DIDN'T APPEAR ON READ, SO DUPLICATE RECORD WAS WRITTEN.
;THAT'S OK, ANYTHING ELSE IS RANDOM LOSSAGE.

MTRSQE:	MOVE C,RSEQ
	MOVE B,SEQ		;GET NUMBER JUST READ
	MOVEM B,RSEQ		;RESET NUMBERS
	CAIN B,1		;BOT?
	RET			;YES, ASSUME OK
	SUB C,B			;COMPUTE DIFFERENCE
	CAIN C,1		;ACTUAL 1 LESS THAN EXPECTED?
	JRST [	TMSG <
% Duplicate record encountered, record >
		MOVE B,RSEQ	;REPORT NUMBER
		MOVEI C,^D10
		CALL TTNOUT
		TMSG <, ignored.
>
		RET]		;YES, ASSUME ALL OK
	TMSG <
? Sequence error, record >
	MOVE B,RSEQ		;REPORT NUMBER
	MOVEI C,^D10
	CALL TTNOUT
	TMSG <, continuing.
>
	RET
;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 XGDSTS		;WAIT FOR BACKUP OPERATION
	SOJG P1,MTRTR2		;TRY AGAIN WITH 2-RECORD BACKSPACE
	TMSG <
? Checksum error>
	CALL TSEQN
	SKIPN MTRACT		;BACKUP REQUEST MADE?
	JRST MTREX1		;NO
	SETZM MTRACT		;YES, CLEAR IT
	MOVEI B,.MOBKR
	MOVE A,MTJFN
	MTOPR			;MUST NOW BACKSPACE OVER IT
	JRST MTREX1		;TRY SEQ NUMBER RECOVERY

;HERE TO BACKSPACE BEFORE RETRY

MTRTR2:	SKIPN MTRACT		;BACKUP REQUEST OUTSTANDING?
	JRST MTRTRY		;NO, ONLY HAVE TO BACKUP 1 RECORD
	MOVEI B,.MOBKR		;BACKSPACE 2 RECORDS BECAUSE OF
	MOVE A,MTJFN		; READ-AHEAD
	MTOPR
	SETZM MTRACT		;NOTE NO ACTIVE REQUESTS
MTRTRY:	MOVEI B,.MOBKR		;BACKSPACE FUNCTION CODE
	MOVE A,MTJFN
	MTOPR
	JRST MTRED1		;START FROM TOP
;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,[-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
	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
	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
	IDIV A,B		;WORDS IN FILE
	SKIPE B			;SKIP IF NO PARTIAL WORDS
	AOS A			;ROUND UP
	IDIVI A,PGSIZ		;FULL PAGES IN FILE
	SKIPE B
	AOS A			;PARTIAL PAGE 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
	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?
	JRST [	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 UTILITY SUBROUTINES

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

RDLIN:	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.

YESNO:	CALL RDLIN		;READ A LINE
	LDB A,[POINT 7,LINBUF,6] ;GET FIRST CHAR OF ANSWER
	CAIN A,"Y"
	JRST [	SETO A,
		RET]		;RETURN TRUE
	CAIN A,"N"
	JRST [	SETZ A,
		RET]		;RETURN FALSE
	HRROI A,[ASCIZ / (Y or N) /]
	PSOUT			;PROMPT USER
	JRST YESNO		;TRY AGAIN

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:	TMSG <
? 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

;HERE TO RESET DEFAULTS TO CONNECTED DIRECTORY AND STARS
;IN OTHER FIELDS.

RSTDFT:	HRROI A,DEFDIR		;DEFAULT DIRECTORY
	HRROI B,CONDIR		;CONNECTED DIRECTORY
	SETZ C,
	SOUT	
	MOVE A,[ASCIZ /*/]
	MOVEM A,DEFNAM
	MOVEM A,DEFEXT
	RET

;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
;STORE IN NAMBUF

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>
	CALL .JFNS
	RET

.JFNS:	TDNN D,JF2LST(P5)	;OUTPUT * HERE?
	SKIPA B,JF2LST(P5)	;NO, USE OUTPUT FIELD
	HRRZ B,JFN		;PICKUP INPUT FIELD
	JFNS
	RET
;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

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

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:	SKIPN LPTJFN
	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
	777777777777
	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 /.FBCK1/
	SIXBIT /.FBCK2/
	SIXBIT /.FBCK3/
	SIXBIT /.FBCK4/
	SIXBIT /.FBCK5/
	SIXBIT /.FBUSW/
	SIXBIT /.FBGNL/
	SIXBIT /.FBNAM/
	SIXBIT /.FBEXT/
	SIXBIT /.FBLWR/

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

	END <3,,ENTVEC>