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