;***********************************************
;* TYPEB.M68 - Types a .TXT file BACKWARDS.
;*
;* Useage: TYPEB {filename} or TYPEB {filename.ext}
;*                (default extension is .TXT)
;*
;* NOTES:   1)  The filename has the default of
;*		"TXT". This program will ONLY
;*		work on SEQUENTIAL file types!!!!
;*          2)  If the file is bigger than the
;*	        buffer provided, then the program
;*              'tosses out' a full buffer and begins
;*              'reloading' the buffer from where it
;*              left off, so all of the file may not
;*              be present.
;*          3)  Does not work well on BASIC source code
;*              files that include many TABS etc.
;*          4)  Origionally designed for an 85K memory
;*              partition...MAY NEED TO 'SHRINK' BUFF
;*
;* by DAVE HEYLIGER - AMUS Staff
;*
;***********************************************

	SEARCH SYS
	SEARCH SYSSYM
	SEARCH TRM
	SEARCH CRT

;-- Version Goodies - please update when modifying
;
	VMAJOR=1.
	VMINOR=0.
	VEDIT=100.	;10-85: original creation
	VEDIT=101.	;03-86: clears screen upon a return after TYPEB.

;-- Define the impure storage area for the file DDB and a BUFFer
;
.OFINI
.OFDEF	FILE,D.DDB
.OFDEF	BUFF,50000.			;THIS EXPECTS AN 85K MEMORY PARTITION!
.OFSIZ	IMPSIZ				;global replace 50000. with smaller #
					;and 49999. too if necessary.

;-- Define Program Header, get impure area, and do some screen junk
;
START:	PHDR	-1,0,PH$REE!PH$REU	;Program is reentrant and reuseable
	GETIMP	IMPSIZ,A5		;A5 will be used to point to FILE
	CALL 	CLEAR			;Short subroutine to clear the screen
	TYPE  	Just a second or two...	;For display purposes only


;-- Get the name of the file to TYPEB
;
NAME:	BYP				;Bypass all 'white space'
	FSPEC	FILE(A5),TXT		;and get the name of the FILE
	BYP				;Again, bypass all white space
	TRM				;and check for a terminator
	JNE	QUIT 			;Quit if there isn't one

;-- Open the file, and set up pointers to a BUFFer we are going to employ
;
OPEN:	INIT	FILE(A5)		;Initialize the FILE we are to TYPEB
	OPENI	FILE(A5)		;Open the FILE
 	LEA	A2,BUFF(A5)		;Let A2 point to the start of the BUFF
 	LEA	A3,BUFF(A5)		;Same goes for A3, but....
	ADD	#49999.,A3		; ... it points to the END of the BUFF
	MOV	#0,(A2)+		;A "0" is used to signal End-of-Line

;-- Start reading the file characters. A "0" is used to mark an End-of-Line.
;   An End-of-Line in a .TXT file is recognized by a 15 followed by a 12.
;
READ:	CMP	A2,A3			;See if A2 now points to END of BUFF
	BNE	EMPTY			;If NOT, then continue
	CALL	FULL			;...else reset A2 to start of BUFF
EMPTY:	CTRLC	QUIT			;If ^C hit, quit
	FILINB	FILE(A5)		;Grab the first char in the FILE
	TST	FILE+D.SIZ(A5)		;See if we are at the End-of-File
	BEQ	EOF			;If YES, then GOTO label EOF
	CMPB	D1,#15			;...else see if we get an octal 15
	BNE 	CONT			;If NOT, store the valid character
	FILINB	FILE(A5)		;If octal 15, get the next character
	CMPB	D1,#12			;If its a 12, then 15,12 := [return]
	BEQ	EOLN			;...so store an End-of-Line marker
CONT:	MOVB	D1,(A2)+		;All valid chars. get stored in BUFF
	JMP	READ			;Time for the next character in FILE
EOLN:	MOVB	#0,(A2)+		;Store an End-of-Line marker
	JMP	READ			;Time for the next character in FILE

;-- End-of-File has been reached, set up pointers for TYPEB
;
EOF:	LEA   	A3,BUFF(A5)		;Point A3 to start of BUFF
	DEC	A2			;Point A2 to last character in BUFF
	CALL	CLEAR			;Clear the screen again
	CRLF				;Carriage-Return-Line-Feed

;-- Decrement A2 until an End-of-Line marker is reached. When reached, time
;   to type out this line.
;
TYPEB:	CTRLC	QUIT			;QUIT on a ^C
	CMPB	-(A2),#0		;Decrement A2, Does A2 ^ point to 0?
	BEQ	RETURN			;If YES, simulate a 'return'
	JMP	TYPEB			;If not, continue decrementing A2

;-- Time to type out the line of characters pointed to by A2. If we are all
;   through typing out our BUFFer, then quit.
;
RETURN:	CMP	A3,A2			;See if A3=A2 (A3 ^s to start of BUFF)
	BEQ	QUIT			;If YES, Quit
	INC	A2			;Don't have A2 ^ing to the zero!
	TTYL	@A2			;Type out the line ^ed to by A2
	DEC	A2			;Repoint A2 back to where it was
	CALL	CNTRLB			;blast in a line
	JMP	TYPEB			;Time for the next line to TYPEB

QUIT:	CALL CNTRLB			;Blast in a line...
	TYPE	<Press RETURN to clear screen>
	KBD
	CALL CLEAR
	EXIT

;-- I call this Control-B because it acts just like a control-B in VUE
;
CNTRLB:	MOVB	#377,D1			;A minus one
	LSLW	D1,#8.			;Shift it left 8 bits
	MOVB	#2,D1			;Print tab (-1,2) : Cursor to col. 1
	TCRT				;This actually does the trick
	MOVB	#377,D1			;Another -1
	LSLW	D1,#8.			;Shift it left 8 bits
	MOVB	#16.,D1			;Print tab (-1,16) : insert a line
	TCRT				;The actual trick
	RTN

;-- CLEAR is a short subroutine that simulates a PRINT TAB (-1,0)
;
CLEAR: 	MOVB	#377,D1			;A minus one
	LSLW	D1,#8.			;Shift it left 8 bits
	MOVB	#0,D1			;Print tab (-1,0) : Clear screen
	TCRT				;This actually does the trick
	RTN				;Return from the CALL

;-- FULL is a short subroutine that will 'blow away' all characters that
;   were stored in the BUFFer, and re-start storing characters that are
;   located further into the file.
;
FULL:	TYPE	buffer overload..	;For fancy output
 	LEA	A2,BUFF(A5)		;Repoint A2 to start of BUFF
 	LEA	A3,BUFF(A5)		;Repoint A3 to the start too
	ADD	#49999.,A3		;Now point A3 to END of BUFF
	MOV	#0,(A2)+		;Store an End-of-Line marker
	RTN				;Return from the CALL


	END