NEW
  AUTO 3,1
*--------------------------------
MOVE.LF LDA POSV
       CMP MAXV          IS HE ON *EOF*
       BCS .2            YES, DONT CHANGE POSH
       LDY POSH
       CPY #START.COL    IF ALREADY ON BEGINNING
       BEQ .2            DON'T MOVE LEFT
       CPY LEFT.MARGIN   IF NOT ON CURRENT MARGIN
       BNE .1            GO MOVE LEFT
       JSR LEFT.PAGE     OTHERWISE PAGE LEFT
       DEC POSH          THEN MOVE LEFT
       RTS               SHOW SCREEN SINCE HORIZONTAL PAGE
.1     DEC POSH          MOVE LEFT
.2     INC NO.SHOW.FLAG  DON'T SHOW SCREEN
       RTS               UNLESS A HORIZONTAL PAGE DONE
*--------------------------------
MOVE.RT LDA POSV
       CMP MAXV          IS HE ON *EOF*
       BCS INC.FLG       YES, DONT CHANGE POSH
       LDA RT.FENCER     DON'T MOVE RIGHT IF
       CMP POSH            HE IS ON LAST COLUMN
       BEQ INC.FLG
       LDY RIGHT.MARGIN  GET RIGHT MARGIN
       DEY
       CPY POSH          IS HE IS NOT ON IT
       BNE .1            THEN MOVE RIGHT
       JSR RIGHT.PAGE    ELSE HORIZONTAL PAGE
       LDY RIGHT.MARGIN
       DEY
       CPY POSH          SEE IF HE IS
       BEQ .3              STILL ON RIGHT MARGIN
       INC POSH          MOVE RIGHT IF NOT
.3     RTS
.1     INC POSH          MOVE RIGHT
INC.FLG INC NO.SHOW.FLAG  DON'T SHOW SCREEN UNLESS
       RTS               HORIZONTAL PAGE DONE
*--------------------------------
RIGHT.PAGE LDA LEFT.MARGIN  HORIZONTAL PAGE RIGHT
       CLC
       ADC HORT.PAGE
       CMP RT.FENCEL     UNLESS PAST RIGHTMOST LIMIT
       BCS .1            YES, PAST LIMIT
       CMP POSH          SEE IF POSH STILL ON SCREEN
       BCC .2            YES
       STA POSH          NO, MAKE IT FIT ON LEFT MARGIN
       BCS .2            ...ALWAYS
.1     LDA LEFT.MARGIN
       CMP RT.FENCEL     WAS HE ALREADY ON RIGHTMOST LIMIT
       BEQ INC.FLG       YES, LET HIM HANG THERE
       LDA POSH          COMPUTE NEW POSH
       SEC               REMOVE LEFT MARGIN BIAS
       SBC LEFT.MARGIN
       CLC
       ADC RT.FENCEL     ADD RIGHTMOST MARGIN LIMIT BIAS
       STA POSH
       LDA RT.FENCEL     SET NEW LEFT MARGIN
.2     JMP SET.MARGIN
*--------------------------------
LEFT.PAGE LDA #START.COL SEE IF DOING A LEFT PAGE
       CLC               MAKES LEFT MARGIN BEFORE THE
       ADC HORT.PAGE     FIRST COLUMN
       CMP LEFT.MARGIN
       BEQ .1            DO THE LEFT PAGE
       BCC .1            DO THE LEFT PAGE
       LDA #START.COL    SET LEFT MARGIN TO COL 1
       CMP LEFT.MARGIN   UNLESS IT IS ALREADY THERE
       BNE LIMITM        NOT COL 1, SO USE COL 1
       BEQ INC.FLG       YES COL 1, SO STAY THERE
.1     LDA LEFT.MARGIN   LEFT.MARGIN - HORT.PAGE
       SEC               IS NEW LEFT MARGIN
       SBC HORT.PAGE
LIMITM JSR SET.MARGIN    SET NEW LEFT MARGIN
**** RIGHT.MARGIN IS IN A REG
LIMITR CMP POSH          IF RIGHT.MARGIN <= POSH
       BEQ .1              THEN SET NEW POSH
       BCS .2            ELSE EXIT
.1     SEC               SET NEW POSH = RM-1
       SBC #1            TO KEEP THE CURSOR
       STA POSH          STILL ON SCREEN
.2     RTS
*--------------------------------
LN.TOGL LDA #START.COL   TOGGLE LINE NUMBERS ON/OFF
       EOR LN.FLAG       BY EOR WITH COL 1 POSN
       STA LN.FLAG       TOGGLES BETWEEN 0 AND 6
       STA RM.ADJUST     TOGGLES BETWEEN 0 AND 6
       LDA LEFT.MARGIN   SET NEW LEFT MARGIN
       BNE LIMITM        AND LIMIT POSH INSIDE WINDOW
*--------------------------------
MOVE.UP LDA POSV         ARE WE ON TOP LINE
       CMP FIRST.LINE
       BNE .1            NO
       JSR FIND.LAST.PAGE  GET LAST 32 LINES LENGTHS
       JMP GET.LINE      AND PULL 1 LINE OFF SCROLL STACK
.1     DEC POSV          MOVE POSV UP
       INC NO.SHOW.FLAG
       RTS
*--------------------------------
MOVE.DN LDA POSV
       CMP MAXV          ARE WE ON *EOF*
       BCS .2            YES, STAY THERE!
       CMP LAST.LINE     ARE WE ON BOTTOM LINE
       BCC .1            NO SO MOVE DOWN
       JMP POP.LINE      ELSE PUT LINE ON SCROLL STACK
.1     INC POSV          MOVE DOWN
       LDA POSV
       CMP MAXV          IF MOVED DOWN TO *EOF*
       BNE .2            NO
       LDA LEFT.MARGIN   YES, CURSOR TO LEFT
       STA POSH          DONT LET IT DANGLE PAST *EOF*
.2     INC NO.SHOW.FLAG  DONT SHOW NEW SCREEN
       RTS
*--------------------------------
ROLL.U100 LDA ROLL.VALUE2  GET LONG SCROLL VALUE
       BNE ROLL.U
ROLL.UP JSR GET.ROLL.VALUE GET SHORT SCROLL VALUE
ROLL.U STA CTR           PUT IN COUNTER
.1     JSR POP.LINE      PUT LINES ON SCROLL STACK
       DEC CTR           UNTIL CTR GOES ZERO
       BNE .1
       RTS
*--------------------------------
ROLL.D100 LDA ROLL.VALUE2  GET LONG SCROLL VALUE
       BNE ROLL.D
ROLL.DN JSR GET.ROLL.VALUE GET SHORT SCROLL VALUE
ROLL.D SEC
       SBC #32           IS THERE AT LEAST 32 LINES
       BCC .1            NO
       PHA               YES, DO BLOCKS OF 32 LINES
       LDA #32           UNTIL LESS THAN 32 TO DO
       JSR .90           ROLL DOWN 32 LINES
       PLA
       JMP ROLL.D        GO TRY FOR NEXT 32 LINES
.1     ADC #32           ADD BACK OFFSET
       BEQ .99           EXIT IF EXACTLY 32 LINES
.90    STA CTR           ROLL DOWN LINES
       JSR FIND.LAST.PAGE  FIND LAST 32 LINE LENGTHS
.91    JSR GET.LINE      GET THEM FROM SCROLL STACK
       DEC CTR
       BNE .91
.99    RTS
*--------------------------------
GET.ROLL.VALUE
       LDA LAST.LINE     IF L-F+1 < ROLL
       SEC                 THEN USE L-F+1
       SBC FIRST.LINE      ELSE USE ROLL
       CLC
       ADC #1
       CMP ROLL.VALUE
       BCC RTS2
       LDA ROLL.VALUE
RTS2   RTS
*--------------------------------
POP.LINE LDA PP.BEG
       STA PTR1          PTR1=PP.BEG
       CMP PP.END        PP.BEG<PP.END?
       LDA PP.BEG+1
       STA PTR1+1
       SBC PP.END+1
       BCS RTS2          NOT LESS
       LDA SP.END        PTR2=SP.END
       STA PTR2          SP.END=SP.END+SIZE
       LDY #0
       CLC
       ADC (PTR1),Y
       STA SP.END
       LDA SP.END+1
       STA PTR2+1
       ADC #0
       STA SP.END+1
       CLC               PP.BEG=PP.BEG+SIZE
       LDA (PTR1),Y
       ADC PP.BEG
       STA PP.BEG
       LDA #0
       ADC PP.BEG+1
       STA PP.BEG+1
       JMP MOVE12        MOVE LINE (PTR1) TO (PTR2)
*--------------------------------
GET.LINE LDY INDEX       GET LN.CNT INDEX
       DEY               POSITION TO PREV LINE ENTRY
       TYA
       AND #$1F          MASK TO MAKE INDEX CIRCULAR
       TAY
       STY INDEX
       LDA LN.CNT,Y      GET LENGTH OF LINE
       STA PTR2
       BEQ RTS2          NO MORE LINES
       LDA SP.END        PTR1=SP.END-SIZE
       SEC               SP.END=PTR1
       SBC PTR2
       STA SP.END
       STA PTR1
       LDA SP.END+1
       SBC #0
       STA SP.END+1
       STA PTR1+1
       LDA PP.BEG        PTR2=PP.BEG-SIZE
       SEC               PP.BEG=PTR2
       SBC PTR2
       STA PP.BEG
       STA PTR2
       LDA PP.BEG+1
       SBC #0
       STA PP.BEG+1
       STA PTR2+1
*** FALL INTO MOVE12
*--------------------------------
MOVE12 LDY #0            GET # BYTES IN LINE
       LDA (PTR1),Y
       STA (PTR2),Y      MOVE FIRST BYTE
       TAY
       DEY               -1 FOR INDEXING
.1     LDA (PTR1),Y      MOVE A BYTE (PTR1) TO (PTR2)
       STA (PTR2),Y
       DEY               NEXT BYTE
       BNE .1
       RTS
*--------------------------------
FIND.LAST.PAGE
       LDY #31           INIT INDEX
       LDA #0
       STA INDEX
.1     STA LN.CNT,Y      ZERO LN.CNT TABLE ENTRIES
       DEY
       BPL .1
       LDA SP.BEG        SET PTR1=SP.BEG
       STA PTR1
       CMP SP.END        SEE IF END OF SCROLL STACK
       BNE .2            NOT END
       LDA SP.BEG+1
       CMP SP.END+1
       BNE .3            NOT END
       RTS               YES, END OF STACK
.2     LDA SP.BEG+1
.3     STA PTR1+1
.4     LDY #0            GET LINE LENGTH
       LDA (PTR1),Y
       PHA               SAVE IT
       LDY INDEX
       STA LN.CNT,Y      PUT IT IN TABLE
       INY               NEXT TABLE ENTRY
       TYA
       AND #$1F          WRAP ARROUND
       STA INDEX         SAVE INDEX
       PLA               RESTORE LENGTH
       CLC
       ADC PTR1          PTR1=PTR1+LENGTH
       STA PTR1
       LDA #0
       ADC PTR1+1
       STA PTR1+1
       LDA PTR1          IF PTR1=SP.END
       CMP SP.END        THEN END OF SEARCH
       BNE .4              AND TABLE HAS LAST
       LDA PTR1+1          32 LINE LENGTHS
       CMP SP.END+1
       BNE .4            SEARCH FOR MORE
       RTS               END OF SEARCH
*--------------------------------
FIX.POSV CMP POSV
       BEQ .1            IF CURSOR POSV<=LAST LINE SHOWN
       BCS .2            NO, ITS OK
.1     STA POSV          SET NEW CURSOR POSN
       LDA LEFT.MARGIN   TO *EOF* LINE
       STA POSH
       LDA POSV
.2     RTS
*--------------------------------
SHOW.EOF LDA CTR         POSITION VERTICALLY
       JSR MY.VTAB
       LDA #0            COLUMN 0
       JSR MY.HTAB
       LDA LN.FLAG       SEE IF LINE NUMBERS ON SCREEN
       BEQ .2            NO
.0     LDY #0
.1     LDA #$A0          OUTPUT BLANKS FOR LINE NUMBER
       JSR MY.COUT
       INY
       CPY RM.ADJUST
       BCC .1
.2     LDY #0
.3     LDA Q.EOF,Y       PRINT "*EOF*
       JSR MY.COUT
       INY
       CPY #5
       BCC .3
       JMP MY.CLREOP     CLEAR TO END OF PAGE
*
Q.EOF  .AS -/*EOF*/
*--------------------------------
SHOW.SCREEN
       LDA LEFT.MARGIN
       STA FILL.TO       SET BLANK FILL LIMIT
       JSR P1.INIT
       LDY #0            SHOW BANNER ON LINE 0
       JSR BANNER
       LDA FIRST.LINE    INIT FIRST DISPLAY LINE
       STA CTR
.1     JSR P1.ENDCK
       BEQ .99           END OF PROG LINES
.2     LDA ESC.FLAG      ARE WE IN EDIT MODE?
       BEQ .4            NO
       LDA CTR
       CMP POSV          IS THIS THE EDIT LINE
       BNE .4            NO
       JSR REST.WBUF     YES SHOW THE SAVED WBUF
       JMP .5
.4     JSR GET.LINE.IN.WBUF  GET SOURCE CODE INTO WBUF
.5     JSR SHOW.LINE.IN.WBUF SHOW WBUF
       JSR P1.ADD        BUMP TO NEXT LINE
       INC CTR
       LDA CTR
       CMP LAST.LINE     END OF SCREEN
       BCC .1            NO
       BEQ .1
       CLC
       ADC #1
       STA MAXV          SET MAX = LINE 25
       BNE .7            ...ALWAYS
.99    LDA CTR
       STA MAXV          MAX IS WHERE WE ARE
       CMP LAST.LINE
       BEQ .6
       BCS .7
.6     JSR FIX.POSV      ADJUST POSV AND POSH
       JSR SHOW.EOF      PUT *EOF* ON SCREEN
.7     LDY #23           PUT BANNER ON LINE 23
*** FALL INTO BANNER
*--------------------------------
BANNER LDA FORM.FLG      IF FORM FLAG NOT ON
       BNE .1
       RTS               JUST RETURN
.1     STY CTR           ELSE SAVE LINE
       LDA #0            PUT EOL AT WBUF END
       STA WBUF+255
       LDY #254          FILL WBUF WITH
       LDA #'.           "."
.2     STA WBUF,Y
       DEY
       CPY #START.COL-1
       BNE .2
       LDA #'+
       STA WBUF+START.COL+5-1
       LDA #9            INIT N=10-1
.3     PHA               SAVE N
       CLC
       ADC #1            LNO=N+1
       STA LNO           SET NEW LINE NUM
       LDA #0
       STA LNO+1
       JSR CVRT.LNX      CVRT TO ASCII DECIMAL
       PLA               GET BACK N
       TAY
       LDA #'+
       STA WBUF+START.COL,Y  MARK OFF +00
       CPY #254-START.COL-5
       BCS .4
       STA WBUF+START.COL+5,Y   AND +05
.4     LDA WBUF+2                 MOVE 1ST DIGIT
       STA WBUF+START.COL+1,Y
       LDA WBUF+3                 MOVE 2ND DIGIT
       STA WBUF+START.COL+2,Y
       LDA WBUF+4                 MOVE 3RD DIGIT
       STA WBUF+START.COL+3,Y
       TYA
       ADC #10           N=N+10
       CMP #254-START.COL-5       SEE IF ALL DONE
       BCC .3            NO, BUILD MORE
.5     LDY #START.COL-1  FILL START WITH BLANKS
* dcj *BNE FILL.BACK     AND SHOW WBUF
*--------------------------------
FILL.BACK JSR FILL.WBUF           BACK FILL WBUF WITH BLANKS
       BEQ SHOW.LINE.IN.WBUF BA   THEN SHOW WBUF
*--------------------------------
E.SHOW.LINE LDA POSV
       STA CTR
*--------------------------------
SHOW.LINE.IN.WBUF
       LDA CTR                    SET VERT POSN
       JSR MY.VTAB
       LDA #0
       JSR MY.HTAB                START COL 0 ON SCREEN
       LDA LN.FLAG                TEST LINE NUM FLAG
       BEQ .2                     NO LINE NUMBERS
       LDY #0
.1     LDA WBUF,Y                 SHOW COL 0 THRU START.COL-1
       BEQ .99                    AS LINE NUM
       ORA #$80
       JSR MY.COUT
       INY
       CPY #START.COL
       BCC .1
***    TYA
***    JSR MY.HTAB
.2     LDY LEFT.MARGIN            START AT LEFT MARGIN
.3     LDA WBUF,Y                 IN WBUF AND PRINT ON SCREEN
       BEQ .99                    END OF WBUF
       ORA #$80
       JSR MY.COUT
       INY
       CPY RIGHT.MARGIN           GO TO RIGHT MARGIN
       BCC .3
.99    JMP MY.CLREOL              ZAP TO EOL
*--------------------------------
FILL.WBUF LDA #$20                SET A BLANK
.1     STA WBUF,Y                 FILL WBUF
       DEY                        UNTIL Y GOES 0
       BNE .1
       STA WBUF          (DOESN'T AFFECT STATUS)
       RTS               RETURN EQ STATUS
*--------------------------------
GET.LINE.IN.WBUF
       LDA PTR1          SRCP=PTR1
       STA SRCP
       LDA PTR1+1
       STA SRCP+1
       LDA #0
       STA RPTCNT        INIT REPEAT COUNT
       STA RPTCHR
       JSR GNBI          SRCP=SRCP+1
       JSR GNB           GET A BYTE
       STA LNO           SAVE LNO
       JSR GNB
       STA LNO+1
       LDA LN.FLAG       TEST FOR LINE NUM SHOW
       BEQ .1            NO
       LDA LNO
       ORA LNO+1
       BEQ .1            BLANK LINE NUM IF=0
       JSR CVRT.LNO      ELSE CONVERT IT TO ASCII
       LDX #START.COL
       BNE .3
.1     LDX #0            NO LINE NUM
.2     LDA #$20            SHOW BLANKS INSTEAD
       STA WBUF,X
       INX
       CPX #START.COL
       BCC .2
.3     JSR NTKN          GET A SOURCE LINE CHAR
       STA WBUF,X        PUT IT IN WBUF
       INX               NEXT POSN
       TAY               TEST FOR END CHAR
       BNE .3
       LDA #$20          MAKE SURE WBUF IS FILLED
       DEX               TO LEFT MARGIN
.4     CPX FILL.TO       WITH BLANKS
       BCS .5
       STA WBUF,X
       INX
       BNE .4            ...ALWAYS
.5     LDA #0            THEN PUT DOWN END CODE
       STA WBUF,X
       RTS
*--------------------------------
CVRT.LNX LDY #0
       LDA #1
       STA CV.DIGFLG     NO ZERO SUPPRESS
       BNE CVRT.L
CVRT.LNO LDY #0          ALLOW ZERO SUPPRESS
       STY CV.DIGFLG
CVRT.L LDX #4            5 DIGITS
.1     LDA #$30
.2     PHA
       SEC
       LDA LNO
       SBC DTBL,X
       PHA
       LDA LNO+1
       SBC DTBH,X
       BCC .3
       STA LNO+1
       PLA
       STA LNO
       PLA
       ADC #0
       BNE .2
.3     PLA
       PLA
       CPX #0
       BEQ .6
       CMP #$30
       BNE .6            NON ZERO PREVENT ZERO SUPPRESS
       LDA CV.DIGFLG     TEST ZERO SUP
       BNE .5            NONE
       LDA #$20          SUP ZERO WITH BLANK
       BNE .4
.5     LDA #$30          PRINT ZERO
.6     INC CV.DIGFLG     PREVENT ZERO SUP
.4     STA WBUF,Y        STUFF DIGIT IN WBUF
       INY
       DEX
       BPL .1            GET NEXT DIGIT
       LDA #$20          PUT BLANK AT END
       STA WBUF,Y
       RTS
DTBL   .DA #1,#10,#100,#1000,#10000
DTBH   .DA /1,/10,/100,/1000,/10000
*--------------------------------
NTKN   LDY #0
       LDA RPTCNT        GET REPEAT COUNT
       BNE .3            IF >0 USE REPEAT CHAR
       LDA (SRCP),Y      ELSE GET SOURCE CHAR
       BPL GNBI          BUMP PTR IF NORMAL ASCII
       AND #$7F          MASK HIGH BIT OF TOKEN OFF
       CMP #$40          $00-$3F IS BLANK COMPRESSION
       BCC .1            YES BLANK COMPRESSION
       JSR GNBI          POSN TO NEXT BYTE
       JSR GNB           GET BYTE
       STA RPTCNT        USE AS REP COUNT
       LDA (SRCP),Y      NEXT BYTE
       BNE .2
.1     AND #$3F          MASK COUNT
       STA RPTCNT        SAVE REP COUNT
       LDA #$20          BLANK IS REP CHAR
.2     STA RPTCHR        SET REP CHAR
       JSR GNBI          BUMP TO NEXT BYTE
.3     DEC RPTCNT        COUNT DOWN REP CHAR
       LDA RPTCHR        RETURN REP CHAR
       RTS
*--------------------------------
GNB    LDY #0            GET SOURCE BYTE
       LDA (SRCP),Y
GNBI   INC SRCP          ADD 1 TO SRCP
       BNE .1
       INC SRCP+1
.1     RTS
*--------------------------------
MAN
SAVE usr/src/fse/fse.s.3
LOAD usr/src/fse/fse.s
ASM
