	.TITLE	RD10MT  READ DEC-10 TAPES
	.SBTTL	PROGRAM DESCRIPTION
	.IDENT	/V0001A/
;
;	MODIFIED TO THROW OUT GARBAGE FILES NOVEMBER 13, 1978
;	BY J. THOMPSON INTERMETRICS
;
;
;
;
;
	.SBTTL	SET LISTING OPTIONS
;
	.NLIST	MEB
	.NLIST	BEX
;
;
;
	.SBTTL	ASSIGNMENT VARIABLES
;
;
ERRCNT = 0	;ERROR IS USED FOR SEQUENCING ERROR HANDLING ROUTINES
DSW = 0		;THE DSW IS AT VIRTUAL ZERO
;
;
;
	.SBTTL	GLOBAL MACRO CALLS
;
;
	.MCALL	QIOW$,EXIT$S,QIOSY$,DIR$
	.MCALL	CSI$,CSI$1,CSI$2,FSRSZ$
	.MCALL	FDBDF$,FDAT$A,FDOP$A,FDBF$A,NMBLK$
	.MCALL	OPEN$,FDOF$L,FCSBT$,CLOSE$,PUT$
;
;
;
;	DEFINE SYMBOLS LOCALLY
;
;
	QIOSY$
	FDOF$L
	FCSBT$
	.PAGE
	.SBTTL	LOCAL MACRO DEFINITIONS
;
;
;
	.MACRO	ERRTST	STATUS	;TEST ERROR STATUS OF I/O OPERATIONS
	GEN	\ERRCNT,STATUS	;GENERATE THE CODE
	ERRCNT = ERRCNT + 1
	.ENDM	ERRTST
;
;
	.MACRO	GEN	CNT,STATUS
	TST	DSW		;SUCESSFUL DIRECTIVE?
	BMI	DRER'CNT		;NO , PRINT ERROR
	TSTB	STATUS		;SEE IF THE I/O COMPLETED OK
	BMI	IOER'CNT		;NOT SUCESSFUL - REPORT ERROR
	BR	XZX$'CNT
;
;
;
DRER'CNT:	MOV	#CNT,R0	;INDICATE WHICH ERROR CALL
	MOV	DSW,R1	;PUT ERROR INDICATOR IN R1
	NEG	R1	;MAKE IT READABLE
	BPT		;TERMINATE TASK ABNORMALLY
;
;
IOER'CNT:	MOV	#CNT*100,R0	;INDICATE WHICH I/O HAD ERROR
	MOV	STATUS,R1	;GET 1ST WORD OF ERROR STATUS
	MOV	STATUS+2,R2	;GET 2ND WORD OF ERROR STATUS
	BPT		;ABNORMALLY TERMINATE TASK
;
;
XZX$'CNT:
	.ENDM	GEN
;
;
;
	.PAGE
	.SBTTL	ANNOUNCE THE PROGRAM
;
;
;
;
;
;	ANNOUNCE THE PROGRAM
;
;
START:
	DIR$	#QIO1
	ERRTST	STAT
;
;
;	ASK FOR THE FILE NAME
;
;
GETNAME:
	DIR$	#QIO2
	ERRTST	STAT
;
;
;	NOW GET THE NAME
;
;
	DIR$	#QIO3
	ERRTST	STAT
	TST	STAT+2		;IF THE COUNT IS ZERO , ALL DONE
	BEQ	EXIT
	JMP	PARSE		;IF NOT ZERO , PARSE THE NAME
;
;	COUNT IS ZERO , EXIT
;
EXIT:	EXIT$S
	JMP	PARSE
	.PAGE
;
;
;
;
	.EVEN
QIO1:	QIOW$	IO.WVB,5,1,,STAT,,<HI,HISZ,66>
;
;
;
STAT:	.BLKW	2
;
;
HI:
	.BYTE	15,12,12
	.ASCII	/  THIS PROGRAM READS MAG TAPES CREATED ON THE/
	.BYTE	15,12,12
	.ASCII	/   DEC SYSTEM-10(OR 20) USING PIP, AND THE STANDARD/
	.BYTE	15,12,12
	.ASCII	/   MAG TAPE FORMAT.  EACH FILE ON THE MAG TAPE IS/
	.BYTE	15,12,12
	.ASCII	/   PUT INTO A SEPERATE FILE ON THE DISK./
	.BYTE	15,12,12,12,12
	.ASCII	/***  REWIND MAG TAPE , AND ENTER FIRST FILE NAME./
	.BYTE	15,12,12
;
;
HISZ = . - HI
	.PAGE
;
;
;	GET THE FILE NAME
;
;
	.EVEN
QIO2:	QIOW$	IO.WVB,5,1,,STAT,,<ASK,ASKSZ,44>
;
;
ASK:
	.BYTE	15,12,12
	.ASCII	/FILE NAME: /
ASKSZ = . - ASK
;
;
;
;
;
;
	.EVEN
QIO3:	QIOW$	IO.RVB,5,1,,STAT,,<FILE,80.>
;
;
;
	.EVEN
FILB:	.BYTE 15,12
FILE:	.BLKB	80.
;
;
;
	.PAGE
	.SBTTL	OPEN THE DISK FILE
;
;
	.EVEN
;
;
PARSE:
	CSI$1	#COMMAND , #FILE , STAT+2
	BCS	FILERR
	CSI$2	#COMMAND,OUTPUT
	BCS	FILERR
;
;
;
	MOV	#DSKFDB,R0	;SET UP PARAMETER FOR OPEN
	OPEN$
	BCS	OPNERR
	DIR$	#QIO300		;WRITE FILENAME
;	CLEAN OUT FILENAME BUFFER
	MOV	#FILE,R2
	MOV	#20.,R1
CLEAN:	CLRB	(R2)+
	SOB	R1,CLEAN
;
;	OPEN OK , READ THE TAPE
;
	JMP	TAPE
	.PAGE
	.SBTTL	COMMAND PARSE BUFFERS AND FDB
;
;
;
;
	CSI$
	.EVEN
COMMAND:
	.BLKB	C.SIZE
;
;
	FSRSZ$	1,2048.
;
;
DSKFDB:	FDBDF$
	FDAT$A	R.VAR,FD.CR
	FDOP$A	1,COMMAND+C.DEVD,DEFUNM,FO.WRT!FA.NSP
	FDBF$A	12.,,4,FD.WBH
;
;
DEFUNM:	NMBLK$	DEC10,FOR,1,SY,0
	.PAGE
	.SBTTL	DISK FILE PARSE AND OPEN ERROR HANDLING
;
;
	.EVEN
;
;
FILERR:	DIR$	#QIO4
	ERRTST	STAT
	JMP	GETNAME
;
;
OPNERR:
	MOVB	DSKFDB+F.ERR,R1
	TST	R1		;ERROR MAY BE POSITIVE OR NEGATIVE ,
	BPL	10$		;  DEPENDING ON THE TYPE OF ERROR
	NEG	R1		;IF NEGATIVE , MAKE IT POSITIVE , AND
	MOVB	#'-,ERCODE-1	;  PUT A MINUS SIGN INTO THE MESSAGE
10$:
	MOV	#3,R2
	MOV	#ERCODE,R3	;OUTPUT BUFFER FOR MESSAGE
	CALL	BYOCDE		;CONVERT OCTAL TO DIGITS (BYTES)
;
;
	DIR$	#QIO5
	ERRTST	STAT
	JMP	GETNAME
;
;
;
;
	.EVEN
QIO4:	QIOW$	IO.WVB,5,1,,STAT,,<FERR,FERRSZ,66>
;
;
	.EVEN
QIO5:	QIOW$	IO.WVB,5,1,,STAT,,<OERR,OERRSZ,66>
;
;
;
;
	.EVEN
QIO100:
	QIOW$	IO.WVB,5,1,,STAT,,<BAD,BADSZ,40>
	.EVEN
BAD:	.BYTE	15,12
	.ASCII	/**ERROR ENCOUNTERED ON PUT, DATA IGNORED,  PROCEEDING.**/
BADSZ=.-BAD
	.EVEN
QIO200:
	QIOW$	IO.WVB,5,1,,STAT,,<BIG,BIGSZ,40>
	.EVEN
BIG:	.BYTE	15,12
	.ASCII	/**RECORD TOO LONG, DATA LOST, PROCEEDING.**/
BIGSZ = .-BIG
	.EVEN
QIO300:	QIOW$	IO.WVB,5,1,,STAT,,<FILB,16.,40>
FERR:
	.BYTE	15,12,12
	.ASCII	/***  FILE SPECIFICATION ERROR  ***/
FERRSZ = . - FERR
;
;
OERR:
	.BYTE	15,12,12
	.ASCII	/***  ERROR OPENING FILE   /
ERCODE:	.BLKB	3	;I/O CODE BUFFER
	.ASCII	/  ***/
OERRSZ = . - OERR
;
;
	.PAGE
	.SBTTL	READ THE TAPE
;
;
	.EVEN
;
;
TAPE:
;
;
;	THE CONVERSION PORTION OF THE PROGRAM USES THE FOLLOWING:
;
;		R0 - HOLDS THE CARRIGE RETURN CHAR <15> FOR COMPARES
;		R1 - CURRENT SCAN POSITION IN THE BUFFER
;		R2 - NUMBER OF CHARS LEFT IN THE BUFFER
;		R3 - SCRATCH REGISTER , USED IN UNPACKING DEC-10 CHARS
;		R4 - SCRATCH REGISTER , USED IN UNPACKING DEC-10 CHARS
;		R5 - COUNT OF CHARS IN THE CURRENT OUTPUT RECORD
;	    BUFPTR - BEGINNING ADDRESS OF THE CURRENT OUTPUT RECORD
;
;
	CLR	EOFLAG
	CLR	RECORD
	MOV	#15,R0		;PUT A <LF> IN R0 FOR COMPARATOR
	MOV	#TAPBUF,BEGPTR	;START OF THE OUTPUT RECORD
	CLR	R5		;COUNT OF THE CHARACTERS IN THE OUT BUFFER
;
;
GETAPE:
	TST	EOFLAG
	BNE	FILDONE		;IF THE EOF FLAG IS SET, THIS IS THE LAST BLOCK
	DIR$	#MTQIO
	TST	DSW
	BMI	MTDRER
	TSTB	STATTP
	BMI	TPIERR
	CLR	EOFLAG
;
;
DOTAPE:
	MOV	#TAPBUF,R1	;SET UP THE CURRENT POSITION POINTER
	MOV	STATTP+2,R2	;GET THE NUMBER OF CHARS IN THE BUFFER
	JMP	UNPACK
;
;
;	THE END-OF-FILE HAS BEEN FOUND ON THE TAPE , CLOSE THE DISK FILE
;
;
FILDONE:
	CLOSE$	#DSKFDB
	JMP	GETNAME		;SEE IF THERE IS ANOTHER FILE ON THE TAPE
;
;
;
MTQIO:
	.EVEN
	QIOW$	IO.RLB,3,1,,STATTP,,<TAPBUF,4096.>
STATTP:	.BLKW	2
EOFLAG:	.WORD	0
;
;
MTDRER:
	MOV	#7777,R0
	MOV	DSW,R1
	NEG	R1
	BPT
	.PAGE
BLERR:
	MOV STATTP,R0
	BPT
	CMPB	#IE.BLK,STATTP
	BNE TERROR
	JMP DOTAPE	;FORGET BLOCK #'S OUT OF SEQUENCE
;
;
TPIERR:
	CMPB	#IE.EOF,STATTP
	BNE	BLERR
	TST	EOFLAG		;IS THIS A SUCESSIVE EOF?
	BEQ	TPEOF1		;NO , THIS IS THE FIRST
;
;
;	SECOND END-OF-FILE IN A ROW , ASSUME END-OF-TAPE
;
;
	DIR$	#QIODONE
	ERRTST	STAT
;
;
REWIND:
	DIR$	#MTREW
	TST	DSW
	BMI	MTDRER
;
	JMP	FILDONE
;
;
;
;
;	FIRST END-OF-FILE
;
;
TPEOF1:
	INC	EOFLAG
	BR	DOTAPE
;
;
;
TERROR:
	MOVB	STATTP,R1	;PICK UP THE ERROR CODE
	NEG	R1
	MOV	#3,R2		;CONVERT THE OCTAL TO DIGITS
	MOV	#TERBUF,R3
	CALL	BYOCDE
;
;
	DIR$	#TERQIO
	ERRTST	STAT
;
;
	DIR$	#QUEST
	ERRTST	STAT
	CMPB	#'Y,ANSWER
	BNE	REWIND		;IF ANSWER IS NO , REWIND THE TAPE
;
;
	DIR$	#CONT	;SHOULD WE SKIP THE BAD BLOCK OR TRY TO PROCESS IT?
	ERRTST	STAT
	DIR$	#QUEST
	ERRTST	STAT
	CMPB	#'Y,ANSWER	;IF YES , SKIP THE BLOCK
	BNE	10$
	JMP	GETAPE		;GET THE NEXT BLOCK
10$:	JMP	DOTAPE		;TRANSLATE THIS BLOCK
;
;
;
	.EVEN
MTREW:	QIOW$	IO.RWU,3,1,,STATTP
	.EVEN
QIODONE:
	QIOW$	IO.WVB,5,1,,STAT,,<DONE,DONESZ,66>
;
;
DONE:
	.BYTE	15,12,12
	.ASCII	/  ***  END OF TAPE , MOUNT NEXT TAPE TO CONTINUE/
	.BYTE	15,12,12
DONESZ = . - DONE
;
;
;
	.EVEN
TERQIO:	QIOW$	IO.WVB,5,1,,STAT,,<TERR,TERRSZ,44>
;
TERR:
	.BYTE	15,12,12
	.ASCII	/  *****   MAG TAPE ERROR  -/
TERBUF:	.BLKB	3
	.ASCII	/   *****/
	.BYTE	15,12,12,12
	.ASCII	/     DO YOU WANT TO CONTINUE WITH THIS TAPE?/
	.BYTE	15,12,12
	.ASCII	/          YES (Y) OR NO (N) :/
TERRSZ = . - TERR
;
;
;
	.EVEN
CONT:	QIOW$	IO.WVB,5,1,,STAT,,<CNTM,CNTMSZ,44>
;
CNTM:	.BYTE	15,12,12,12
	.ASCII	/     DO YOU WANT TO SKIP THE ERROR BLOCK (CURRENT BLOCK)/
	.BYTE	15,12,12
	.ASCII	/          YES (Y) OR NO (N) :/
CNTMSZ = . - CNTM
;
;
;
	.EVEN
QUEST:	QIOW$	IO.RVB,5,1,,STAT,,<ANSWER,1>
ANSWER:	.BLKB	2
;
;
;
	.PAGE
	.SBTTL	UNPACK THE DEC-10 TAPE FORMAT
;
;
	.EVEN
;
;
UNPACK:
;
;
;	UNPACK ASSUMES THAT THE ADDRESS OF THE BUFFER IS IN R1 AND
;	  THE NUMBER OF CHARACTERS TO BE TRANSLATED IS IN R2.
;
;	THE CHARACTERS ARE TRANSLATED AND OVERLAID BACK INTO THE
;	  ORIGINAL BUFFER.
;
;
	INC	R1		;SKIP OVER 1ST CHARACTER
	MOVB	(R1)+,R3
	SWAB	R3
	CLRB	R3
	BISB	(R1)+,R3
	MOVB	(R1)+,R4
	SWAB	R4
	CLRB	R4
	BISB	(R1),R4
;
;
	CLC
	RORB	-4(R1)	;CHAR 1
	ROR	R3
	ROR	R4
;
	CLC
	ROR	R3	;CHAR 2
	ROR	R4
;
;
	CLRB	R4
	BISB	(R1),R4
	ROLB	R4
	ROLB	R4
;
	CLC
	RORB	R3	;CHAR 3
	ROR	R4
;
	CLC
	ROR	R4	;CHAR 4
;
	CLC
	RORB	R4	;CHAR 5
;
;
	MOVB	R4,(R1)
	SWAB	R4
	MOVB	R4,-(R1)
	MOVB	R3,-(R1)
	SWAB	R3
	MOVB	R3,-(R1)
	DEC	R1
	.PAGE
	.SBTTL	SCAN FOR THE END OF RECORD
;
;
;	SCAN THE TRANSLATED CHARS FOR A <LF> (THE END-OF-RECORD CHAR)
;
;	NULL CHARACTERS ARE SKIPPED UNTIL A NON-NULL IS FOUND.  NULL
;	  CHARS MAY THEN BE INTERMIXED UNTIL THE NEXT <LF> IS FOUND.
;
;	OUTPUT RECORDS INCLUDE THE TERMINATING <CR><LF>
;
;
SCAN:
	MOV	#5,R3		;FIVE CHARS TO PROCESS
	TST	RECORD		;IS RECORD IS ZERO , LOOK FOR THE 1ST CHAR
	BEQ	SKIP		;  OF A NEW RECORD
;
SCNLP:
	INC	R5		;INCREMENT THE RECORD CHAR COUNT
	CMPB	R0,(R1)+	;CHECK FOR THE <CR>
	BEQ	PUTREC		;FOUND , END-OF-RECORD
	SOB	R3,SCNLP
SCNDONE:
	SUB	#5,R2		;DECREMENT BUFFER COUNT.  ASSUME BUFFER HOLDS
	BGT	UNPACK		; A MULTIPLE OF 5 WORD GROUPS
;
;
NEXTREC:
	TST	RECORD		;IS A RECORD IN PROGRESS?
	BNE	10$		;IF YES , MOVE CHARS TO OVERFLOW BUFFER
	JMP	GETAPE		;IF NOT , GO GET MORE CHARS
;
10$:	MOV	R5,R3		;GET THE NUMBER OF CHARS
	MOV	R5,R4		;MAKE COPY
	SUB	#140.,R4	;BETTER BE NEGATIVE OR ZERO
	BLE	15$		;OK WHEN NEG OR ZERO
;	WE'VE GOT PROBLEMS WITH RECORD LENGTHS.  RESTART OUTPUT.
	DIR$	#QIO200		;WRITE WARNING
	CLR RECORD
	CLR R5
	MOV #TAPBUF,R1		;RESTART LOOKING FOR OUTPUT HERE
	JMP GETAPE
15$:	MOV	#TAPBUF,R4	;START AT TAPBUF AND GO BACKWARDS
20$:
	MOVB	-(R1),-(R4)
	SOB	R3,20$
;
	MOV	R4,BEGPTR	;NEW BEGINNING OF THE OUTPUT RECORD
	JMP	GETAPE
;
;
SKIP:
	TSTB	(R1)+		;IS THIS CHAR NON-NULL
	BNE	SKPCK		;  - YES -
SKPRTN:
	SOB	R3,SKIP		;  - NO  -
	BR	SCNDONE
;
SKPCK:
	CMPB	#12,-1(R1)
	BEQ	SKPRTN
	DEC	R1		;BACK UP TO THE NON-NULL CHAR
	MOV	R1,BEGPTR	;POINT TO THE BEG OF THE OUTPUT RECORD
	CLR	R5		;SET THE COUNT TO ZERO
	INC	RECORD		;WE HAVE FOUND A NON-NULL
	BR	SCNLP		;GO COUNT THE CHARS
;
;
PUTREC:
	DEC	R5		;DON'T PUT THE <CR> INTO THE RECORD
	MOV	R5,R4		;MAKE COPY
	SUB	#140.,R4
	BLE	OKREC
	MOV	#140.,R5	;LIMIT OUTPUT RECORD SIZE
	DIR$	#QIO200
OKREC:	MOV	R0,-(SP)
	PUT$	#DSKFDB,BEGPTR,R5
	BCS	BADERR
AGN:	CLR	RECORD
	CLR	R5
	MOV	(SP)+,R0
	BR	SKPRTN
BADERR:	DIR$	#QIO100
	BR	AGN
	
	.PAGE
	.SBTTL	CONVERT OCTAL TO DECIMAL (BYTES)
;
;
;
	.EVEN
BYOCDE:
	SWAB	R1	;PUT OCTAL BYTE IN TOP OF REGISTER
	CLC		;ON FIRST ROTATE, MOVE IN A ZERO
;
;
10$:
	BIC	#377,R1	;CLEAR OUT THE CHARACTER
	BIS	#6,R1	;PUT IN THE NUMERIC BIAS
	ROL	R1	;ROTATE IN THE 3 OCTAL BITS
	ROL	R1	;
	ROL	R1	;
	MOVB	R1,(R3)+	;PUT THE CONVERTED DIGIT IN THE BUFFER
	SOB	R2,10$
	RTS	PC
;
;
;
	.EVEN
RECORD:	.WORD	0
BEGPTR:	.WORD	0
OVRBUF:	.BLKB	512.
TAPBUF:	.BLKB	4096.
;
;
;
	.END	START
