 
*  EE1/BFMGR    40 - col      Jul / 11 / 93
*-----------------------
*  Minimum Function
 
*--------------------------------------------*
*  BLWP Vectors for Buffer Manager services  *
*--------------------------------------------*
 
DLBLOC DATA BUFMWS,DBLC00     Delete contiguous block of lines
DELTLN DATA BUFMWS,DELETL     Delete a single line
CPBLOC DATA BUFMWS,CPBL00     Copy block of lines to end of buffer
INSTLN DATA BUFMWS,INSRT0     Insert a line
UPDTLN DATA BUFMWS,UPDATL     Update a line
GETLN  DATA BUFMWS,GTTLIN     Fetch and unsquish a line
 
 
*-------------------------------------*
*  BL subroutines for Buffer Manager  *
*-------------------------------------*
 
 
*  Final irrevocable exit
*------------------------
 
ELDCON EQU  $
       BL   @MOVE             Restore FW to CPU RAM
       DATA FWSTOR,FWPOSN     VDP storage
       DATA FWBLEN
 
       BLWP @VMBWF            Restore original cursor
       DATA FCSRP,FCSR,8
       LI   R0,>2000          Load with blanks
       BLWP @VFILF            Clear GM I screen
       DATA 0,>300
 
       MOV  @COLCH,@INCOL
       LWPI FWREG             R11 prelaoded
       RT
 
 
*  MoveLine pointer shuffle - direct BL in SCNWS
*-----------------------------------------------
 
MVLINS  EQU  $
        LI   R12,TBL          Convert line #s to table pointers
        SLA  R6,1             x 2
        SLA  R8,1
        SLA  R9,1
        NEG  R6               Table grows downward
        NEG  R8
        NEG  R9
        A    R12,R6           Offset for start
        A    R12,R8
        A    R12,R9
 
MVLN10  MOV  R8,R10           Copy middle for use
        MOV  R9,R12           Copy upper for use
        S    R6,R10           Length of lower segment
        JEQ  MVLN40           None left
        S    R8,R12           Length of upper segment
        JEQ  MVLN40           None left
        C    R10,R12          Which is larger ?
        JLT  MVLN30           Lower is - swap this part first
 
MVLN20  DECT R8               Adjust lower pointer
        DECT R9               Adjust upper pointer
        MOV  *R8,R14          Working copy
        MOV  *R9,*R8          Transfer word
        MOV  R14,*R9          Copy over where it came from
        DECT R12              Count off
        JGT  MVLN20           Not done yet
        JMP  MVLN10           Now it is
 
MVLN30  MOV  *R6,R14          Copy to temp
        MOV  *R8,*R6+         Transfer & adjust pointer
        MOV  R14,*R8+         Copy temp and adjust pointer
        DECT R10              Count off
        JGT  MVLN30           More
        JMP  MVLN10
 
MVLN40  RT
 
 
*  Convert line # to ASCII
*-------------------------
 
BINDEC EQU  $
       LI   R12,8            Number of digits x 2
NXDIG  CLR  R8               Initialize for DIV
       DIV  @TENM2(R12),R8   R9 has the #
       SLA  R8,8             Byte adjust
       AI   R8,>3000         Convert to ASCII
       MOVB R8,*R10+         Move to output
       DECT R12              Count of digit pointer
       JGT  NXDIG
 
       MOVB @DSPACE,*R10+    Spaces after #
       MOVB @DSPACE,*R10+
       RT
 
*  RLE encoding of line for buffer storage
*  Length byte includes itself - min 1, max 81
*  USA - Repeated character flagged with MSBit set
*   Repeat byte shows # chars in run (min 2)
*  Eliminate trailing repeated blanks
*-------------------------------------------
 
SQUISH EQU  $
       MOV  @BUFADR,R8        Fetch 80 byte line buffer pointer
       MOV  R8,R7             Copy for use
       AI   R7,80             Compute and of line buffer
       LI   R3,SQSBUF         Set pointer to squish buffer
       MOV  R3,R9             Copy as destination pointer
       SETO R0                Initialize comparison byte to >FF
       LI   R12,>0180         Byte saver and bit mask
SQSH10 C    R8,R7             All the line buffer read ?
       JHE  SQSH40            Yes
 
       MOVB *R8+,R0           Fetch a byte from line to MSB of R0
       ANDI R0,>7FFF          Strip MSByte for safety
       STWP R10               Point to R0
       CB   *R10+,*R10        Compare MSB (new char) to LSB (last char)
       JEQ  SQSH20            Repeated char
 
       INC  R9                Next target byte
       MOVB R0,*R9            Write byte to squish buffer
       SWPB R0                Move byte over for comparison use
       CLR  R6                Reset repeated char flag
       JMP  SQSH10            Go get another character
 
SQSH20 ABS  R6                Already a repeated char ?
       JNE  SQSH30            Yes
 
       SETO R6                Flag repeat has started
       SOCB @BUFMWS+25,*R9+   Set MSBit to flag repeats
       MOVB R12,*R9           Initialize repeat counter at 1
SQSH30 AB   R12,*R9           Add to repeat count  (Min = 2)
       JMP  SQSH10
 
SQSH40 CB   @-1(R9),@BA0      Repeated spaces at end ?
       JNE  SQSH50            No
 
       DECT R9                Omit last 2 bytes
SQSH50 S    R3,R9             Chars written
       INC  R9                Include length byte itself
       MOV  R9,R6             Copy for the record
       SLA  R9,8              Byte adjust
       MOVB R9,*R3            Write to length byte
       RT                     RETURN
 
 
*  Calculates LINEN (R1) from line #.
*  Sets R6 up with the length byte as word
*  Accumulates line table offset for block routines
*  Accumulates length in R10 with CKLN20 entry for blocks
*--------------------------------------------------------
 
 
CKLIN  EQU  $
       INC  @LINENO           Advance main line pointer
       MOV  @LINENO,R4        Copy to find pointer
CKLN10 MOV  R4,R9             Save copy for GETLN
       CLR  R10               Initialize Edit buffer block size
       CLR  R7                Initialise line table block size
       SLA  R4,1              Multiply line # by 2
       NEG  R4                Compute actual table address
       AI   R4,TBL            Table start growing downwards
CKLN20 MOV  *R4,R5            R5 = LNADDR in Edit Buf
       MOVB *R5,R6            R6 = Length Byte
       SRL  R6,8              Adjust to count
       INCT R7                Line table block
       A    R6,R10            Edit buffer block
       C    R9,@MKTBL         Comparison for marker check
       RT
 
 
*  Routine to delete a line from Edit Buffer and adjust
*  all table entries.  However it does not delete the line
*  from the table so that UPDATE can use the same routine.
*---------------------------------------------------------
 
MOVMEM EQU  $
       MOV  R11,R0            Save return
       MOV  R2,R12            R2 = EDBFNDM end of Edit Buf
       MOV  R5,R9             LNADDR -> DADDR
       MOV  R9,R8             Copy for use
       A    R10,R8            SADDR = DADDR + LENGTH
       S    R8,R12            Last Line ?
       JEQ  MOVM40            Yes
 
       BL   @FLOOPC           Mass-move code in PAD
       MOV  R9,R2             Update end of buffer pointer
 
*  Go thru table and decrement address's by length, if
*  address was bigger than R5 = LNADDR.
 
       LI   R8,TBL            Start at top of table
MOVM20 C    *R8,R5            TBL ADDR > LNADDR ?
       JL   MOVM30            No
 
       S    R10,*R8           Yes, it was moved so adjust
MOVM30 DECT R8                Move down the table
       C    R8,R1             End of table ? (TBLND)
       JHE  MOVM20            No
 
       B    *R0
MOVM40 MOV  R9,R2             Delete last line simply
       B    *R0               Update ptr., no move.
 
 
*  Check there is room for next line copy
*----------------------------------------
 
CKCOPY EQU  $
       MOV  R10,R9            Copy length indicated so far
       A    R7,R9             Add increase of LINTBL LEngth
       JMP  CKRM10            Use existing code
 
 
*  Check there is room left for new entry
*----------------------------------------
 
CKROOM EQU  $
       MOV  R6,R9             R9 = Length of record to be added
CKRM10 A    R2,R9             R9 = Next end of Edit Buf
       C    R9,R1             Current end of table
       JHE  MEMFUL            Edit will write over table !!
       RT
 
MEMFUL LWPI SCNWS
       B    @DSRERR           ABORT
 
 
*----------------------------------------*
*  BLWP Buffer Manager service routines  *
*----------------------------------------*
 
 
*  Copy a block of lines after buffer end
*----------------------------------------
 
CPBL00 EQU  $
       BL   @CKLIN            Set source pointers
       MOV  R2,R8             Avoid disturbing pointer if buffer full
       MOV  R1,R3             Copy current line table end
CPBL10 DEC  @R13+R13(R13)     Count off a line in caller's R13
       JLT  CPBL30            Minimum of one to start with
 
       BL   @CKCOPY           Check for space before copying
       DECT R3                Set for next entry
       MOV  R8,*R3            New pointer is last end of buffer
CPBL20 MOVB *R5+,*R8+         Copy line
       DEC  R6                Length count
       JGT  CPBL20            More
 
       DECT R4                Next line in Copy block
       BL   @CKLN20           Fetch data for this
       JMP  CPBL10            Do it all again
 
CPBL30 MOV  R8,R2             New end of Edit buffer
       DECT R7
       NEG  R7                Trick to add using delete code
       JMP  DLBL20            Do it
 
 
*  Delete a block from Edit buffer and also from dircctory table
*  Return with CPU status <=> reset when all sub-blocks done
*---------------------------------------------------------------
 
 
DBLC00 EQU  $                 Multi-line delete
       ANDI R15,>DFFF         Force JNE on return as default
       BL   @CKLIN            Get current line info
       MOV  R4,R9             Copy for line table start pointer
       MOV  R5,R12            Copy for Edit block start pointer
DBLC10 DEC  @24(R13)          Count off one line in R12 of caller
       JEQ  DBLC20            Delete block exhausted
 
       MOV  R10,R11           Copy running total block length
       A    R12,R11           Advance from start of block
       C    @-2(R4),R11       Is this the same as the next pointer ?
       JNE  DBLC15            Yes - they match - keep going
 
       DECT R4                Next line
       BL   @CKLN20           Fetch next line pointer and length
       JMP  DBLC10
 
DBLC15 ORI  R15,>2000         On return JEQ shows Delete not complete
DBLC20 MOV  R12,R5            Restore block start pointer
       MOV  R9,R4
       JMP  DELTB
 
*  Delete a line from Edit buffer and also from dircctory table
*--------------------------------------------------------------
 
DELETL EQU  $                 Single-line delets
       BL   @CKLIN            Convert line# to address
       JHE  DELTB             Do check for marker
       DEC  @MKTBL
DELTB  BL   @MOVMEM           Delete line from Edit buffer
 
*  Delete directory table entry
*  R4 = Address of table entry to delete (LINEN)
*  R1 = Old end of table address (TBLND)
 
       MOV  R4,R9             Move line address to DADDR
       MOV  R4,R8             Set up SADDR for move
       S    R7,R8             Source start address for block
DELT10 MOV  *R8,*R9
       DECT R8
       DECT R9
       C    R8,R1             R1 = TBLND
       JHE  DELT10
 
DLBL20 A    R7,R1             TBLND = TBLND + 2 X (# lines)
       SRA  R7,1              # lines deleted
       S    R7,@EOF           Uncount lines
       JMP  SUBXIT
 
 
*  Insert new line in the table, & append to end of Edit Buffer
*--------------------------------------------------------------
 
INSRT0 EQU  $
       BL   @CKLIN            Use to get insert pointer
       JHE  INSRT1
       INC  @MKTBL
INSRT1 BL   @SQUISH           Squish from line buffer
       BL   @CKROOM           Make sure enuf room for line
 
*  Shuffle Line # table down for new entry
 
       MOV  R1,R8             TBLND -> SADDR for move
       DECT R1                Bump TBLND for inserted line
       INC  @EOF              Count the line
       MOV  R1,R9             New DADDR
       JMP  INST13            Do limit check first
 
INST10 MOV  *R8+,*R9+         Shuffle down one entry
INST13 C    R4,R9             All done ?
       JNE  INST10            Not yet
 
INST15 MOV  R2,*R4            Make *LINE = EDBFND
       MOV  R2,R9             Set up daddr to move SQSHBF to.
       A    R6,R2             Bump end of buffer ptr.
       MOV  R6,R12            Count
INST18 MOV  R3,R8             SADDR = SQSHBF or Copy-line
INST20 BL   @FLOOPC           Block-move code in PAD
SUBXIT CLR  *R13
       RTWP
 
ERRBFM SETO *R13              Indicate buffer full error with R0
       RTWP
 
 
*  Routine to modify existing line in Edit buffer.  If the
*  new length matches the old length, no moves are done.  Otherwise
*  the line is deleted from the Edit buffer and inserted at the
*  end of Edit buffer.
*--------------------------------------------------------------------
 
UPDATL EQU  $
       BL   @CKLIN            Fetch existing line data via LINENO spec
       BL   @SQUISH           Compact update line
       MOVB *R5,R12           Check SQSBUF length byte
       SRL  R12,8             R12 = Old line length
       S    R12,R6            Old length = New length ?
       JNE  UPDT20            No
 
*  Just substitute for previous line
 
       MOV  R5,R9             DADDR = LNADDR
       JMP  INST18            Use fast move code
 
*  Unequal length - buffer needs adjusting
 
UPDT20 BL   @CKROOM           Use change in length for check
       A    R12,R6            Restore new line length
       MOV  R12,R10           Use old line length for delete.
       BL   @MOVMEM           Delete line from buffer
       JMP  INST15            Insert line at end of buffer
 
 
*  New GETLN routine
*  Unsquishes line from Edit buffer to target with line #
*--------------------------------------------------------
 
GTTLIN EQU  $
       BL   @CKLIN            Skip the check for line# = 0
       C    R4,R1             End of file?
       JL   ERRBFM            Yes, line # out of range
 
*  Write line number in first 6 bytes
*
       MOV  @BUFADR,R10       Start of 86 byte line
       BL   @BINDEC           Write line# (in R9) into first 6 bytes
       MOV  R10,R9            6 bytes later after line #
       MOV  R9,R7             Construct end pointer (next line start)
       AI   R7,80             80 char lines
       MOV  R7,@BUFADR        Update buffer address for screen handler
       MOV  R5,R8             SADDR = LNADDR in Edit Buffer
       INC  R8                Advance to first char after length byte
       MOV  R5,R12            Copy for use
       A    R6,R12            Point to byte after squished record
GTTL10 C    R8,R12            Too far ?
       JHE  GTTL60            Yes
 
       MOVB *R8+,*R9+         Get character and write to target
       JLT  GTTL30            Repeat flagged
 
GTTL20 C    R9,R7             Don't overrun target buffer
       JHE  SUBXBR            Quit while ahead
       JMP  GTTL10            Get another byte
 
*  Repeat characters
 
GTTL30 DEC  R9                Back up to flagged byte
       MOVB *R9,R0            Fetch it
       ANDI R0,>7FFF          Strip MSbit
       MOVB *R8+,R10          Get repeat count from next byte
       SRL  R10,8             Word adjust
GTTL40 MOVB R0,*R9+           Repeat character in LINEBUF
       DEC  R10               Is this to be repeated ?
       JGT  GTTL40            Yes
       JMP  GTTL20            Finished with squished record
 
*  Fill rest of line if implicit blanks
 
GTTL60 C    R9,R7             Has it quit before buffer full ?
       JHE  SUBXBR            No - already filled
 
       MOVB @DSPACE,*R9+      Fill the rest with spaces
       JMP  GTTL60            Loop on the fill
 
SUBXBR B    @SUBXIT
 
       DATA >BBBB              Easy to spot
 
*------------------------------------------------------------
 
