.MCall .Module .Module KEDSCL RELEASE=X01 VERSION=08 COMMENT=,IDENT=NO,AUDIT=NO ; Copyright (c) 1998 by Mentec, Inc., Nashua, NH. ; All rights reserved ; ; This software is furnished under a license for use only on a ; single computer system and may be copied only with the ; inclusion of the above copyright notice. This software, or ; any other copies thereof, may not be provided or otherwise ; made available to any other person except for use on such ; system and to one who agrees to these license terms. Title ; to and ownership of the software shall at all times remain ; in Mentec, Inc. ; ; The information in this document is subject to change without ; notice and should not be construed as a commitment by Digital ; Equipment Corporation, or Mentec, Inc. ; ; Digital and Mentec assume no responsibility for the use or ; reliability of its software on equipment which is not supplied ; by Digital or Mentec, and listed in the Software Product ; Description. .Enable LC .Enable GBL ; ;MODULE: KEDSCL ; ;ABSTRACT: ; ; This module contains the file scroller routines for the KED ; keypad editor. All the primitive file manipulation routines ; used by the command module are here. ; ;AUTHOR: DARRELL DUFFY ; ;DATE: 18-JULY-77 ; ; X01.01 29-JAN-78 From V04.06 of SCROLR.MAC ; X01.02 6-MAR-78 Strip parity of input chars ; X01.03 11-APR-78 Fix inconsistancy in inspect mode in ; RDBKW to ignore nulls and strip parity ; X01.04 20-APR-78 Minor changes for KED X01.03 ; Fix RDBKW for insert mode ; X01.05 16-JUN-78 Error message macro change ; X01.06 19-JUN-78 Setup for overlayed error messages ; X01.07 22-JUN-78 Fix inspect mode to not ignore nulls ; so it will work ; X01.08 7-JUL-78 SAVREG removed from this module ; X01.09 18-AUG-78 Remove overlay conditional ; 19-SEP-78 Cosmetic comment changes ; X01.10 27-SEP-78 Bum and fix bug in insert ; X01.11 18-OCT-78 Add hooks for quick screen update ; X01.12 16-FEB-79 Remove abs impure area for transport to RSX ; ;MODIFIED BY: ; ; Cheryl Vedoe ; ; 8-March-79 Check for writing to file instead of inspect mode ; to handle temporary file created for RSX. ; Modify error macro to come from macro library. ; All other macros defined in library. ; ; 14-March-79 Remove option of repeating file I/O after error. ; ; 20-July-79 Don't call $CSI from FILSET. ; ; 10-Sept-79 Fix inspect mode bug which causes data to be lost ; at end of file. ; .MCall AbtOn AbtOff IsAbt .MCall JouOn JouOff IsJou .MCall SavReg PSect Push Pop .Br .MCall $ReadW $WritW ...... .SbTtl EQUATED SYMBOLS ; ; Definitions for scroller playground management ; ScBMin == 512. ;Minimum number of bytes for ;scroller I/O SpcMin == 1024. ;Minimum screen space to maintain ;at each end of playground Hystrs == 200. ;Hysterisis for moves to prevent ;excessive I/O .SbTtl Define error macro $KED$ = 1 ;Defined here but not in error module ; ;The following code is included as an error section so that it will be ;pulled out and assembled in the error module also. In this module, the ;error macro is defined to print the error message. In the error module, ;the macro is defined to assemble the message text. ;+ ;ERROR ; .IIf NDF,$KED$, .Page .IIf NDF,$KED$, .SbTtl Errors from KEDSCL module ; ;Define the error macro for this module ; .MCall ErrDef ErrDef S,ERR ;Invoke macro to define error macro ;- .SbTtl .SbTtl PSECT DEFINITIONS ; ; PSect definitions ; PSect KEDSCL ;CODE PSect PSect IMPURE ;DATA PSect PSect KEDSCL .SbTtl .SbTtl IMPURE DATA AREA ;++ ; IMPURE AREA FOR SCROLLER ; ; The scroll file is maintained as a pair of stacks, ; one is the backward stack and one is the forward stack. ; The area in memory is known as the playground and holds ; the portion of both stacks currently in memory. ; The backward stack is made up of the backward playground ; (BKW PLYGND) and the initial part of the output file ; pointed to by BKWBLK. The forward stack is made up of ; the FWD PLYGND and the portion of the input or output ; file pointed to by FWDBLK. ; ; Pointers (FCP,BCP) point to stacks in the PDP-11 ; sense, that is the pointer points to the data item ; at the extremity of the stack not to the first free ; item. BCP=PLYGND-1 means BKWPLYGND empty. FCP= ; PLYEND means FWDPLYGND empty. FCP-BCP-1 = free space ; in playground for inserts etc. ; ; The block numbers are handled as stack pointers ; they always point to a block of good data ; block numbers in file are 0-N-1 where there are ; N blocks in the file. BKWBLK = -SCBLKS means that there ; are no more blocks in backward direction and ; FWDBLK = N means that no more blocks remain in that ; direction. ;-- PSect IMPURE FCP:: .BlkW 1 ;Forward char pointer BCP:: .BlkW 1 ;Backward char pointer PLyGnd::.BlkW 1 ;Pointer to start of play ground PlyEnd::.BlkW 1 ;To end of playground RbCr:: .BlkW 1 ;Last deleted char BlkMax::.BlkW 1 ;Max block number in file FwdBlk::.BlkW 1 ;Forward block pointer BkwBlk: .BlkW 1 ;Backward block pointer InFlg: .BlkW 1 ;0 for input file in use InBlk: .BlkW 1 ;Next to read block in input file MxIBlk::.BlkW 1 ;Max block of input file MxOBlk::.BlkW 1 ;Max block of output file FwdChn: .BlkW 1 ;Forward channel- OU$CHN for output ;IN$CHN for input BkwChn: .BlkW 1 ;Backward channel Inspct::.BlkW 1 ;Non 0 for inspect mode WrtFil::.BlkW 1 ;0 If writing to output or temp file ;1 Otherwise ScBlks::.BlkW 1 ;Blocks to move by (256. wds) ScWds:: .BlkW 1 ;Words to move by ScByts::.BlkW 1 ;Bytes to move by ScnSpc: .BlkW 1 ;Bytes to assure for screen watch ChrCtr::.BlkW 2 ;Double precision count for free ;chars SlctQ:: .BlkW 1 ;Select enabled if non zero SlctC:: .BlkW 2 ;Select count low,high CtrlC:: .BlkW 1 ;Double Ctrl/C (set minus) Area:: .BlkW 1 ;Area for prg req- address .BlkW 20. ;Data area .BlkW 1 ;Buffer zone for safety PSect KEDSCL .SbTtl .SbTtl ERR - ERROR ROUTINE FOR THIS MODULE ;++ ;ERR ; ;FUNCTIONAL DESCRIPTION: ; ; Module wide error routine ; ;This routine always goes to FATAL to save some words here ;This is the only code in this module which is not pure code ; ;Note that the error routine overlays this code with the error messages ;but this code is back in before return here. Note also that the ;contents of 10$ is thereby blown but this does not matter since it ;is not used after the call. ; ;INPUT: ; Jsr R4,ERR ; .Word ERRMSG ;Address of error message ; ;OUTPUT: NONE ;-- .Enable LSB Err: Mov (R4)+,ErrorX ;Impure store the error address Jsr R4,ErrorV ;Call routine in command module Pop ;Restore R4 .Br Fatal .SbTtl FATAL - FATAL ERROR ENTRY ;++ ;FATAL ; ;FUNCTIONAL DESCRIPTION: ; ; Fatal error entry point ; Entry taken on all non recoverable errors ; ;INPUT: NONE ; ;OUTPUT: NONE ;-- Fatal: Jmp $Fatal ;Entry to command module .............. .Dsabl LSB .SbTtl SETUP - INITIALIZE ALL THINGS ;++ ;SETUP ; ;FUNCTIONAL DESCRIPTION: ; ; Initialize impure data for scroller operation ; ;INPUT: ; R0 = start of playground ; R1 = end of playground ; R2 = blocking factor (N*SCBMIN) ; ;OUTPUT: ; All registers preserved ; No errors ;-- .Enable LSB Setup:: SavReg Mov R0,PlyGnd Dec R0 ;Char before Mov R0,BCP ;Backward pointer Mov R1,FCP ;End of play area pointer Mov R1,PlyEnd ;And rememberance of it ClrB @BCP ;Safe char at start of playgnd Mov R2,ScByts ;Bytes to scroll by Asr R2 ;Words to R/W Mov R2,ScWds Mov #SpcMin,ScnSpc ;Minimum screen space ; ; Make actual number of blocks to R/W ; Our blocks are 256 wds, R2 contains SCWDS ; Bit #377,R2 ;Make sure of words Bne 10$ ;Inconsistant word count SwaB R2 Mov R2,ScBlks ;Save blocks to R/W Mov #Area,R3 ;Make address of area Tst (R3)+ ;Point to actual data area Mov R3,R4 ;Get copy of addr Mov R4,-(R3) ;Save address to it Return ...... 10$: ;+ ;ERROR ERROR ,F ;Allocation routine $ALLOC returned blocking factor which was not an ;integral number of blocks. Logic error. ;- .Dsabl LSB .SbTtl FILSET - SETUP FILE DATA FOR SCROLLING ;++ ;FILSET ; ;FUNCTIONAL DESCRIPTION: ; ; Setup file data for scrolling ; ;INPUT: ; R0 = Maximum block in input file;-1 for no file ; R1 = Maximum block in output file;-1 for no file ; ;OUTPUT: ; Files setup ;-- .Enable LSB FilSet:: SavReg ;Save registers Mov R0,MxIBlk ;Max block for input file Clr InFlg ;Input file in use Mov #In$Chn,FwdChn ;Input file fwd channel Mov R1,MxOBlk ;Max block in output file Mov #Ou$Chn,BkwChn ;Assume back channel is output file Tst WrtFil ;Writing to output or temp file? Beq 10$ ;Br if so Mov #In$Chn,BkwChn ;Else back channel is input file 10$: Mov R0,BlkMax ;Save for all time Clr FwdBlk ;Setup block numbers for use Clr InBlk ;Input block number Mov ScBlks,R0 ;Make first bkw block Neg R0 ;As minus backward block Mov R0,BkwBlk ;No backward blocks to read Mov PlyGnd,BCP ;Initialize char pointers Dec BCP ; Mov PLYEND,FCP ; Call SclStr ;Startup for scrolling ;>>> huh? why here??? Call $SpOn ;Special mode on again Clc ;Return with no error Return ;On error return C set ...... .Dsabl LSB .SbTtl SCLSTR - START FILE SCROLLING ;++ ;SCLSTR ; ;FUNCTIONAL DESCRIPTION: ; ; Memory is loaded from file by four blocks if minimum size ; playground is in use else two reads are done if space ; is available. ; ;INPUT: NONE ; ;OUTPUT: ; File data is available ;-- .Enable LSB SclStr:: .Rept 2 ;Fill as much space as possible Call RdFwd ;Read a block Bcs 10$ ;Signal error .EndR Cmp ScByts,#ScBMin ;Got enough?? Bhi 10$ ;Yes- there is no more space ;in PLYGND Call RdFwd ;Read two more to fill screen space Bcs 10$ ; Call RdFwd ;With text from file 10$: Return ; ...... .Dsabl LSB .SbTtl SCLXIT - SCROLL FILE EXIT ;++ ;SCLXIT ; ;FUNCTIONAL DESCRIPTION: ; ; All of playground is written to the file and the ; playground looks empty. ; ;INPUT: NONE ; ;OUTPUT: ; C set if Ctrl/C stopped exit ;-- .Enable LSB SclXit:: Mov #-1,R0 ;Assume no file for output Tst Inspct ;Inspect mode? Bne 30$ ;Yes- no foolishness 10$: Call MvFwd ;Move by characters Bcc 10$ ;No error Tst CtrlC ;Last chance to stop us Sec ;Set for error indicator Bmi 40$ ;Also movfl stops on Ctrl/C 20$: Call WrBkw ;Write out remainder of file Bcc 20$ ;Til no more to write Mov BkwBlk,R0 ;Max block in output file 30$: Call $Cls ;Close the output file Clc ;Just in case $CLS leaves a C set 40$: Return ...... .Dsabl LSB .SbTtl MOVFWD - MOVE FORWARD BY LOGICAL CHARACTER ;++ ;MOVFWD ; ;FUNCTIONAL DESCRIPTION: ; ; Move forward by a logical character (a byte or crlf pair) ; ;INPUT: NONE ; ;OUTPUT: ; R0 = char at FCP ; C set if error ;-- .Enable LSB MovFwd:: Call MvFwd ;Ahead one character Bcs 10$ ;No good, error Call NlChk ;Check for split newline Bne 10$ ;Nope Call MvFwd ;Step beyond LF 10$: Return ...... .SbTtl MOVBKW - MOVE BACKWARD BY A LOGICAL CHARACTER ;++ ;MOVBKW ; ;FUNCTIONAL DESCRIPTION: ; ; Move backward by one logical character (byte or crlf pair) ; ;INPUT: NONE ; ;OUTPUT: ; R0 = char at BCP ; C set if error ;-- .Enable LSB MovBkw:: Call MvBkw ;Back one Bcs 10$ ;Nope Call NlChk ;Split a NL Bne 10$ ;Nope Call MvBkw ;Back one more 10$: Return ...... .SbTtl NLCHK - CHECK FOR NEW LINE SPLIT ;++ ;NLCHK ; ;FUNCTIONAL DESCRIPTION: ; ; Check for cursor between CR and LF ; ;INPUT: ; FCP and BCP -> characters in playground ; ;OUTPUT: ; Z set if cursor between CR and LF ;-- .Enable LSB NlChk: CmpB #,@FCP ;Look forward Bne 10$ ;Nope CmpB #,@BCP ;Look backward 10$: Clc ;So we don't return an error Return ...... .SbTtl MVFWD - MOVE FORWARD BY PHYSICAL CHARACTER ;++ ;MVFWD ; ;FUNCTIONAL DESCRIPTION: ; ; Move forward by a physical character (one byte) ; ;INPUT: NONE ;;OUTPUT: ; R0 = char at FCP ; C set if error or Ctrl/C typed ;-- .Enable LSB MvFwd:: Tst CtrlC ;Abort set? Bmi 20$ ;Yes- return error Call ChkAbt Cmp FCP,PlyEnd ;End of playground?? Bhis 20$ ;Yes Inc BCP ;Point forward MovB @FCP,@BCP ;Move char Inc FCP ;Post increment MovB @BCP,R0 ;Get the char moved over Call QukChk ;Check for line terminator MovB @FCP,R0 ;Fcp char is cursor char Add #1,PosCtr ;Increment relative position counter Adc PosCtr+2 ;And overflow Tst SlctQ ;Select enabled? Beq 10$ ;Nope Add #1,SlctC ;Increment count Adc SlctC+2 ;And overflow 10$: Call BFCFwd ;Check forward chars Tst (PC)+ ;Skip and clear carry 20$: Sec ;Return error Return ...... .SbTtl MVBKW - MOVE BACKWARD BY PHYSICAL CHARACTER ;++ ;MVBKW ; ;FUNCTIONAL DESCRIPTION: ; ; Move backward by a physical character ; ;INPUT: NONE ; ;OUTPUT: ; R0 = char at BCP ; C set if error or Ctrl/C typed ;-- .Enable LSB MvBkw:: Tst CtrlC ;Abort? Bmi 20$ ;Yes - return error Call ChkAbt Cmp BCP,PlyGnd ;Beginning of playground Blo 20$ ;Yes Dec FCP ;Step forward pointer back MovB @BCP,@FCP ;Move the character Dec BCP ;Step backw pointer back MovB @FCP,R0 ;Get char moved over Call QukChk ;Check for screen destroyed MovB @BCP,R0 ;Return new bkw char Sub #1,PosCtr ;Decrement relative position counter Sbc PosCtr+2 ;And underflow Tst SlctQ ;Select enabled Beq 10$ ;Nope Sub #1,SlctC ;Keep count Sbc SlctC+2 ;Double precision 10$: Call BFCBkw ;Check back chars Tst (PC)+ ;No error 20$: Sec ;Error signal for no-can-move Return ...... .SbTtl CHKABT - Keep track of aborted commands for journal ;CHKABT ; ;functional description: ; ;If we are journaling a session, for each command that is processed, we ;keep a count of the basic operations that it takes to complete the command. ;If the command is aborted by a Control/C, an abort record is written to ;the journal file preceeding the aborted command. This routine is called by ;the routines that perform the basic operations to keep the count. ; ;When we are recovering a file and encounter an abort record, ; ; .Enabl LSB ChkAbt:: IsAbt ;Are we recovering an aborted command? Beq 10$ ;No Sub #1,AbtAt ;Yup, decrement the step counter Sbc AbtAt+2 ;Is it time to stop yet? Bne 10$ ;Branch if not Tst AbtAt Bne 10$ Bis #<100000>,CtrlC ;If so, then turn on control/C flag ; so that next time thru we'll act ; like we got ctrl-C'd AbtOff ;Turn off abort mode Br 20$ ;And return ........... 10$: IsJou ;Are we journaling? Beq 20$ ;No Add #1,StpCtr ;Yes, count steps in each function Adc StpCtr ; - double precision ;>>>*JMP* need a better route for overflow Bcc 20$ Tst (SP)+ ;Return to callers caller with c=1 20$: Return .DsAbl LSB .SbTtl DELCHR - DELETE LOGICAL CHAR RIGHT ;++ ;DELCHR ; ;FUNCTIONAL DESCRIPTION: ; ; Delete a logical character to the right ; ;INPUT: NONE ; ;OUTPUT: ; R0 = char deleted ; C set if error ;-- .Enable LSB DelChr:: Call DlChr ;Delete a char Bcs 20$ ;Bad CmpB #,R0 ;Just did in a CR Bne 10$ ;Nope CmpB #,@FCP ;Next a linefeed? Bne 10$ ;Nope Call DlChr ;Do it in too 10$: Clc ;Clean up carry 20$: Return ...... .SbTtl RUBCHR - DELETE LOGICAL CHAR LEFT ;++ ;RUBCHR ; ;FUNCTIONAL DESCRIPTION: ; ; Delete logical character to the left ; ;INPUT: NONE ;;OUTPUT: ; R0 = next character to be deleted, 0 if none ; C set if error or Ctrl/C typed ;-- .Enable LSB RubChr:: Call RbChr ;Delete one Bcs 20$ ;Bad CmpB #,RbCr ;LF just zapped Bne 10$ ;Nope CmpB #,R0 ;CR next Bne 10$ ;Nope Call RbChr ;Zapp it Mov #,RbCr ;Fake last char rubbed to LF 10$: Clc ;Return clean carry 20$: Return ...... .SbTtl INSRT - INSERT CHARACTER ;++ ;INSRT ; ;FUNCTIONAL DESCRIPTION: ; ; Insert character at BCP ; ;INPUT: ; R0 = character to be inserted ; ;OUTPUT: ; C set if no room or Ctrl/C typed ;-- .Enable LSB Insrt:: Tst Inspct ;Inspect a file?? Bne 30$ ;Yes- return error Tst ChrCtr ;Check low order count Bne 10$ ;Ok Tst ChrCtr+2 ;High order Beq 30$ ;No space left to insert 10$: Push ;Bkw pointer Inc @SP ;Fwd one Cmp @SP,FCP ;Room?? Beq 40$ ;Nope Sub #1,ChrCtr ;Keep track of count Sbc ChrCtr+2 ;High order too Pop ;Put pointer back MovB R0,@BCP ;Put away char Tst PosCtr+2 ;Forward or back relative position? Bmi 15$ ;Backward, don't change relative postn Add #1,PosCtr ;Increment relative position counter Adc PosCtr+2 ;And overflow 15$: Tst SlctQ ;Select enabled? Beq 20$ ;Nope Tst SlctC+2 ;Which type of range Bmi 20$ ;Left range Add #1,SlctC ;Keep the count for right range Adc SlctC+2 ;Double 20$: Call QukChk ;Check for screen destroyed Call BFCIns ;Check backchars Tst CtrlC ;Ctrl/C typed Bmi 30$ ;Return error Call ChkAbt ;Is this command to be aborted? Clc Return ;Return with or without error ...... 40$: Pop <> ;Dump stack contents 30$: Sec ;Signal error Return ...... .SbTtl DLCHR - DELETE PHYSICAL CHAR RIGHT ;++ ;DLCHR ; ;FUNCTIONAL DESCRIPTION: ; ; Delete physical character to the right ; ;INPUT: NONE ; ;OUTPUT: ; R0 = character deleted ; C set if error ;-- .Enable LSB DLCHR:: Tst CtrlC ;Abort? Bmi 20$ ;Yes- return error Call ChkAbt ;Is this command to be aborted? Tst Inspct ;Inspect the file?? Bne 20$ ;Yes- error return Cmp FCP,PlyEnd ;End of play space?? Bhis 20$ ;Sure is Add #1,ChrCtr ;Keep track of count Adc ChrCtr+2 MovB @FCP,R0 ;Save deleted char Mov R0,RbCr ;Save for posterity Inc FCP ;Advance pointer Tst PosCtr+2 ;Forward or back relative position? Bpl 15$ ;Foreward, don't change relative postn Add #1,PosCtr ;Reduce relative position counter Adc PosCtr+2 ;And overflow 15$: Tst SlctQ ;Select enabled Beq 10$ ;Nope Tst SlctC+2 ;Which way? Bpl 10$ ;Right Add #1,SlctC ;Reduce left range Adc SlctC+2 ;Double 10$: Call QukChk ;Check for screen destroyed Call BFCFwd ;Check forward chars Call UnStuf ;Save deleted char via command module Return ;Return ...... 20$: Sec ;Signal error ...... Return ;Return .SbTtl RBCHR - DELETE PHYSICAL CHAR LEFT ;++ ;RBCHR ; ;FUNCTIONAL DESCRIPTION: ; ; Delete physical character to the left ; ;INPUT: NONE ; ;OUTPUT: ; R0 = next character to be rubbed, 0 if none ; C set on error or Ctrl/C typed ;-- .Enable LSB RbChr:: Tst CtrlC ;Abort? Bmi 50$ ;Yes- return error Call ChkAbt ;Is this command to be aborted? Tst Inspct ;Inspect a file Bne 50$ ;Yes- return error Cmp BCP,PlyGnd ;Begining of sandbox?? Blo 50$ ;Yes Add #1,ChrCtr ;Keep track of space Adc ChrCtr+2 MovB @BCP,RbCr ;Save rubbed char for posterity Dec BCP ;Backup pointer MovB @BCP,R0 ;Return backward char Tst PosCtr+2 ;Forward or back relative position? Bpl 10$ ;Backward,doesn't chng relative postn Bmi 20$ ;Backward,doesn't chng relative postn Tst PosCtr ;Is there any change yet? Beq 20$ ;Nope, no adjustment needed 10$: Sub #1,PosCtr ;Reduce relative position counter Sbc PosCtr+2 ;And underflow 20$: Tst SlctQ ;Select range enabled? Beq 40$ ;Nope Tst SlctC+2 ;Which way Bmi 40$ ;Left- ok Bpl 30$ ;Right - adjust it Tst SlctC ;Any change at all? Beq 40$ ;Nope, no adjustment needed 30$: Sub #1,SlctC ;Reduce right range Sbc SlctC+2 ;Double 40$: Call BFCBkw ;Check backward chars Push ;Save the char MovB RbCr,R0 ;Get rubbed char Call QukChk ;Screen destroyed?? Call UnStuf ;Save deleted char in undelete buffer Pop ,SAVE=*C* ;*C* restore the char Return ;Return ...... 50$: Sec ;Signal error Return ...... .Dsabl LSB .SbTtl RUBLN - DELETE LINE TO LEFT ;++ ;RUBLN ; ;FUNCTIONAL DESCRIPTION: ; ; Delete a line to the left ; ;INPUT: NONE ; ;OUTPUT: ; R0 = character at BCP, line terminator ; C set if error or Ctrl/C typed ;-- .Enable LSB RubLn:: Call RbChr ;Rub a char always first Bcs 50$ ;No more Br 20$ ;Check for line ........... 10$: Call RbChr ;Rub another Bcs 40$ ;No more to rub 20$: Call LTerm ;Line terminator Bne 10$ ;Nope 30$: Clc ;No error Return ...... 40$: Cmp BCP,PlyGnd ;Beginning of buffer? Blo 30$ ;Yes- no error Sec ;Else error 50$: Return ...... .SbTtl MOVBL - MOVE BACKWARD A LINE ;++ ;MOVBL ; ;FUNCTIONAL DESCRIPTION: ; ; Move backward by one line ; ;INPUT: NONE ; ;OUTPUT: ; R0 = terminator character of previous line ; C set if error or Ctrl/C typed ;-- .Enable LSB MovBL:: Call MvBkw ;Start back Bcs 40$ ;Nowhere to go Br 20$ ;Check for lineterm ........... 10$: Call MvBkw ;Back one char Bcs 30$ ;No more to move 20$: Call LTerm ;Line terminator Bne 10$ ;Nope 30$: Clc ;No error 40$: Return ...... .SbTtl MOVFL - MOVE FORWARD A LINE ;++ ;MOVFL ; ;FUNCTIONAL DESCRIPTION: ; ; Move forward by one line ; ;INPUT: NONE ; ;OUTPUT: ; R0 = line terminator for line passed ; C set on error or Ctrl/C typed ;-- .Enable LSB MovFL:: MovB @FCP,R0 ;First char to look at Br 20$ ;Check to see if its a lterm ........... 10$: Call MvFwd ;Forward one character Bcs 30$ ;No more chars 20$: Call LTerm ;Line term? Bne 10$ ;Nope Push ;Save line term for return Call MvFwd ;Move over line term Pop ;Restore line term 30$: Return ...... .SbTtl LTERM - CHECK R0 FOR LINE TERMINATOR ;++ ;LTERM ; ;FUNCTIONAL DESCRIPTION: ; ; Check if R0 contains a line terminator character ; ;INPUT: ; R0 = character to be checked ; ;OUTPUT: ; Z set if line terminator ;-- .Enable LSB ;>>>duplicated elsewhere? LTerm: CmpB R0,# ;L terms are LF through FF Blo 10$ ;Nope CmpB R0,# ; Bhi 10$ ;nope Sez ;Yep 10$: Return ...... .SbTtl QUKCHK - SCREEN UPDATE OPTIMISE CHECK ;++ ;QUKCHK ; ;FUNCTIONAL DESCRIPTION: ; ; Set QUKFLG zero if the screen needs major update work. ; That is if we have just passed a line terminator ; ;INPUT: ; R0 = character of interest ; ;OUTPUT: ; QUKFLG = 0 IF R0 = line terminator ;-- .Enable LSB QukChk: Tst QukFlg ;Screen already blown Beq 10$ ;Yes Call LTerm ;Check for line terminator Bne 10$ ;Ok leave it alone Clr QukFlg ;Is changed 10$: Return ...... .SbTtl .SbTtl SCROLLING I/O ROUTINES .SbTtl .SbTtl BFCFWD - CHECK FORWARD PLAYGROUND ;++ ;BFCFWD ; ;FUNCTIONAL DESCRIPTION: ; ; Check forward playground for enough characters left ; and read more data if available. ; Called when move or delete caused any reduction in ; forward playground. ; ;INPUT: NONE ; ;OUTPUT: NONE ;-- .Enable LSB BFCFwd: Push ;Enough space left?? Sub FCP,@SP ;PLYEND-FCP Cmp (SP)+,ScnSpc ;Screen space check Bhis 30$ ;Ok Tst InFlg ;Input in progress?? Bne 10$ ;No- read beyond end Cmp FwdBlk,BlkMax ;More blocks to read? Bhi 30$ ;Nope ; ; DO NOT INCUR SAVE REGISTER OVERHEAD UNTIL ABSOLUTELY REQUIRED ; 10$: SavReg ;Save all regs Clr QukFlg ;Screen blown Mov FCP,R1 ;Enough space to just read?? Sub BCP,R1 ;FCP-BCP-1 Dec R1 Cmp R1,ScByts ;Scroll bytes Bhi 20$ ;Yes- just read Call WrBkw ;Write backwards 20$: Call RdFwd ;Read forwards 30$: Return ...... .SbTtl BFCBKW - CHECK BACKWARD PLAYGROUND ;++ ;BFCBKW ; ;FUNCTIONAL DESCRIPTION: ; ; Check backward playground for enough characters left ; and read more if available. ; Called when any move or delete caused reduction in ; backward playground characters. ; ;INPUT: NONE ; ;OUTPUT: NONE ;-- .Enable LSB BFCBkw: Push ;Enough space?? Sub PlyGnd,@SP ;BCP-PLYGND+1 Inc @SP Cmp (SP)+,ScnSpc ;Enough for screen Bhis 20$ ;Fine Tst BkwBlk ;More available Blt 20$ ;Nope SavReg Clr QukFlg ;Screen blown Mov FCP,R1 ;Write first?? Sub BCP,R1 ;FCP-BCP-1 Dec R1 Cmp R1,ScByts ;Space required Bhi 10$ ;Ok Call WrFwd ;Make room by write forward 10$: Call RdBkw ;Read backward 20$: Return ...... .SbTtl BFCINS - CHECK PLAYGROUND AFTER INSERT ;++ ;BFCINS ; ;FUNCTIONAL DESCRIPTION: ; ; Check playground space after insert. More space if ; left preferentially in backward playground. ; Called when any insert occurs into playground. ; inserts are always via INSRT routine. ; ;INPUT: NONE ; ;OUTPUT: NONE ;-- .Enable LSB BFCIns: Push ;Space Sub BCP,@SP ;FCP-BCP-1 Dec (SP)+ Bne 20$ ;Space left- ok SavReg ;Make it clean ; ; Write backwards if we can ; Clr QukFlg ;Screen blown Mov BCP,R1 ;BKW chars Sub PlyGnd,R1 ;BCP-PLYGND+1 Inc R1 ;The +1 Sub ScByts,R1 ;Enough after write?? Blo 10$ ;Not enough to write Cmp R1,ScnSpc ;Enough for screen?? Blos 10$ ;Write forward Call WrBkw ;Write backward Br 20$ ........... 10$: Call WrFwd ;Write forward 20$: Clc ;Return no error Return ...... .SbTtl SPCFRE - COMPUTE FREE SPACE IN FILE ;++ ;SPCFRE ; ;FUNCTIONAL DESCRIPTION: ; ; Compute free space available in the file ; ; Formula: CHRCTR = - ; *512. - <+> ; This formula is only valid if input file is active ; or input not present (create) ; ;INPUT: NONE ; ;OUTPUT: ; CHRCTR, CHRCTR+2 = characters available in file ;-- .Enable LSB SpcFre: SavReg Tst Inspct ;Inspect mode? Bne 40$ ;Yes- use zero chars left Tst InFlg ;Input file active? Bne 30$ ;No- ignore call Mov MxOBlk,R0 ;Blocks in output file Sub BkwBlk,R0 Sub ScBlks,R0 ;Correct for position of block number Inc R0 ;One more for number of blocks Mov MxIBlk,R1 ;Input file left Inc R1 ;Number of blocks left in input Sub FwdBlk,R1 Ble 10$ ;None left Sub R1,R0 ;Adjust for it 10$: Mov PlyEnd,R1 ;Forward PLYGND chars Sub FCP,R1 Add BCP,R1 ;Bckw PLYGND chars Sub PlyGnd,R1 ;BCP-PLYGND+1 (see next instr) Com R1 ;Make minus +1 Clr ChrCtr+2 ;In case none at all Mov R1,ChrCtr ;Save chars (minus) in PLYGND Beq 20$ ;Truly no chars in the buffer Mov #-1,ChrCtr+2 ;High word, for the lack of sxt 20$: SwaB R0 ;Blocks * 256. MovB R0,R1 ;To high word ClrB R0 Asl R0 ;And shift one more to make 512. Rol R1 Add R0,ChrCtr ;And add to PLYGND chars Adc ChrCtr+2 Add R1,ChrCtr+2 Blt 50$ ;Less than no chars left 30$: Return ...... ; ; If inspect mode we come here ; 40$: Clr ChrCtr ;If inspect mode Clr ChrCtr+2 ;Use zero chars left Return ...... 50$: ;+ ;ERROR ERROR ,F ;Computation of characters free for insertion is wrong. ;Program logic error. Immediate exit. ;- .Dsabl LSB .SbTtl RDFWD - READ BLOCKS FORWARD ;++ ;RDFWD ; ;FUNCTIONAL DESCRIPTION: ; ; Read a group of blocks in the forward direction. ; ;INPUT: NONE ; ;OUTPUT: ; C set if no more data to read ;-- .Enable LSB RdFwd: SavReg Mov FCP,R1 ;Enough space to read Sub BCP,R1 ;FCP-BCP-1 = space Dec R1 Cmp R1,ScByts ;Amount to read Blo 110$ ;Not enough 10$: Cmp FwdBlk,BlkMax ;Any more to read? Bgt 90$ ;Nope Mov FCP,R1 ;Empty fwdplygnd Cmp R1,PlyEnd ;?? Beq 40$ ;Yep Bhi 120$ ;Pointer corrupt- fatal Mov R1,R2 ;Copy to dst Sub ScByts,R2 ;Adjust for move down Bit #1,R2 ;Byte at first?? Beq 30$ ;Nope MovB (R1)+,(R2)+ ;Move and align Br 30$ ;Check first now ........... 20$: Mov (R1)+,(R2)+ ;Word move is faster 30$: Cmp R1,PlyEnd ;Til all moved Blo 20$ 40$: Mov PlyEnd,R1 ;Make address to read Sub ScByts,R1 ;Into $ReadW Area,FwdChn,R1,ScWds,FwdBlk Bcc 50$ ;Br on success Jmp IoErr ;Else fatal error .............. 50$: Add ScBlks,FwdBlk ;Step block on Sub ScByts,FCP ;Adjust pointer ; ; Pack out all nulls in newly read data ; Mov PlyEnd,R1 Mov R1,R2 ; ; And adjust for possible partial reads ; remember .READW leaves words read in R0 on return ; Cmp R0,ScWds ;Partial read?? Beq 60$ ;Nope- ok Neg R0 ;*2 Add ScWds,R0 ;Make words to packout Asl R0 ;Make bytes Sub R0,R1 ;Correct byte src 60$: Cmp R1,FCP ;All done Beq 80$ ;Yes MovB -(R1),R0 ;Pick a char ;>>> change for 8bit Bic #^C177,R0 ;Strip parity Tst WrtFil ;Writing to output or temp file? Bne 70$ ;If not leave nulls, else pack out Tst R0 ;Look at the char Beq 60$ ;Null?? 70$: MovB R0,-(R2) ;No- plop it down Br 60$ ;Continue ........... 80$: Mov R2,FCP ;End address after pack Call SpcFre ;Compute free space again Clc ;No error signal Return ...... 90$: Tst InFlg ;Input file active? Beq 100$ ;Yes- signal error Mov InBlk,FwdBlk ;Switch to input file Mov MxIBlk,BlkMax ;For more data Clr InFlg ;To input Mov #In$Chn,FwdChn ;Channel for input Br 10$ ;Back to check blocks ........... 100$: Call SpcFre ;Compute free space incase ;Create file Sec ;Signal error- no data Return ...... 110$: ;+ ;ERROR ERROR ,F ;Insufficient space was found to read the next group of blocks into ;the playground. Logic error. ;- 120$: ;+ ;ERROR ERROR ,F ;Playground was found empty on entry here. Logic error. ;- .Dsable LSB .SbTtl WRFWD - WRITE BLOCKS FORWARD ;++ ;WRFWD ; ;FUNCTIONAL DESCRIPTION: ; ; Write blocks from playground in the forward direction ; ;INPUT: NONE ; ;OUTPUT: NONE ;-- .Enable LSB WrFwd: SavReg Tst InFlg ;Input file?? Bne 10$ ;Nope Tst WrtFil ;Writing to output or temp file? ; Bne 10$ ;if not don't switch Beq 5$ ;Br if so else don't switch files Mov BlkMax,R1 ;Get maximum relative block Inc R1 ;Plus 1 Cmp FwdBlk,R1 ;Is FWDBLK higher than that Blos 10$ ;Br if not Mov R1,FwdBlk ;Else FWDBLK = MAXBLK + 1 so new ; FWDBLK corresponds to amount of ; data we forget Br 10$ ;Use that ........... 5$: Mov FwdBlk,InBlk ;Switch to output file Mov MxOBlk,R1 ;For write at end of it Mov R1,BlkMax ;Fix max check Inc R1 ;One more for FWDBLK Mov R1,FwdBlk Mov SP,InFlg ;Set to output file Mov #Ou$Chn,FwdChn ;Output channel 10$: Mov FwdBlk,R1 ;Check block for ok Sub ScBlks,R1 ;Illegal? Ble 60$ ;Yes Mov R1,R2 ;Make clash block number Sub ScBlks,R2 ;FWDBLK-SCBLKS Cmp R2,BkwBlk ;Block overrun?? Ble 50$ ;Yes Mov PlyEnd,R2 ;Enough data to write Sub FCP,R2 ;PLYEND-FCP Cmp R2,ScByts ;Ok?? Blo 70$ ;Nope - fatal Mov PlyEnd,R2 ;Address to write Sub ScByts,R2 Tst WrtFil ;Writing to output or temp file? Bne 20$ ;If not don't write $WritW Area,#Ou$Chn,R2,ScWds,R1 Bcc 20$ ;Br on success Jmp IoErr ;Else fatal error .............. 20$: Mov R1,FwdBlk ;Save block no Mov PlyEnd,R1 ;Move data down toward end Mov R1,R2 Sub ScByts,R1 ;Make src Br 40$ ........... ; ; Note word alignment is not needed and one more ; byte is moved with last word but who cares ; 30$: Mov -(R1),-(R2) ;Words are faster 40$: Cmp R1,FCP ;Check til done Bhis 30$ Add ScByts,FCP ;Adjust fcp pointer Clc ;No signal error Return ...... 50$: ;+ ;ERROR ERROR ,F ;Attempt to write over data in file. Logic error or full file ;- 60$: ;+ ;ERROR ERROR ,F ;Computed block number is negative or zero. Logic error. ;- 70$: ;+ ;ERROR ERROR ,F ;Insufficient data in playground to write. Logic error. ;- .Dsabl LSB .SbTtl RDBKW - READ BLOCKS BACKWARD ;++ ;RDBKW ; ;FUNCTIONAL DESCRIPTION: ; ; Read blocks into playground from behind ; ;INPUT: NONE ; ;OUTPUT: ; C set if no more data ;-- .Enable LSB RdBkw: SavReg Mov FCP,R1 ;Compute space Sub BCP,R1 ;FCP-BCP-1 Dec R1 Cmp R1,ScByts ;Enough?? Blo 70$ ;Nope- fatal Tst BkwBlk ;Block number ok Blt 60$ ;No more data- c set rtn Mov BCP,R1 ;Empty bkw playground?? Cmp R1,PlyGnd ;Check the the start of plygnd Blo 30$ ;Yes- no need to make space Inc R1 ;Setup for pre decrement Mov R1,R2 Add ScByts,R2 ;Dst addr Bit #1,R1 ;Even?? Beq 20$ ;Yes- setup for word MovB -(R1),-(R2) ;Move and set for word moves Br 20$ ;Compare first ........... 10$: Mov -(R1),-(R2) ;Move words are faster 20$: Cmp R1,PlyGnd ;Til done Bhi 10$ 30$: $ReadW Area,BkwChn,PlyGnd,ScWds,BkwBlk Bcc 40$ ;Br on success Jmp IoErr ;Else fatal error .............. 40$: Add ScByts,BCP ;Adjust pointer Sub ScBlks,BkwBlk ;Adjust block number 50$: Clc Return ...... 60$: Sec ;C set if no more data Return ...... 70$: ;+ ;ERROR ERROR ,F ;Not enough space in playground to read next buffer ;Logic error. ;- .Dsabl LSB .SbTtl WRBKW - WRITE BLOCKS BACKWARD ;++ ;WRBKW ; ;FUNCTIONAL DESCRIPTION: ; ; Write blocks from playground in backward direction ; ;INPUT: NONE ; ;OUTPUT: ; C set if no more data to write, that is playground empty ;-- .Enable LSB WrBkw: SavReg Mov BkwBlk,R1 ;Look for block overrun Add ScBlks,R1 ;Next target Mov R1,R2 ;Make clash block Blt 70$ ;Bad block number Add ScBlks,R2 ;BKWBLK+2*SCBLKS Mov BCP,R3 ;BCP-PLYGND+1 Sub PlyGnd,R3 ;Data to write Inc R3 Cmp R3,ScByts ;Whole block?? Blo 40$ ;Nope- partial Tst InFlg ;Input in use?? Beq 10$ ;Yes- dont check for overrun Cmp R2,FwdBlk ;Block overrun?? Bhis 60$ ;Yes 10$: Tst R1 ;Block no ok?? Blt 70$ ;Nope- fatal error Cmp R1,MxOBlk ;Watch for overwrite of end Bhi 70$ ;MXOBLK=-1 if inspect Tst WrtFil ;Writing to output or temp file? Bne 20$ ;If not don't write $WritW Area,#Ou$Chn,PlyGnd,ScWds,R1 Bcs IoErr ;Br on error 20$: Mov R1,BkwBlk ;Thats the right block Mov PlyGnd,R1 ;Packout written data Mov R1,R2 Add ScByts,R1 ;How much did we write?? 30$: Mov (R1)+,(R2)+ ;Ok to start with word moves here Cmp R1,BCP ;Til all moved Blos 30$ Sub ScByts,BCP ;Adjust BCP pointer Clc ;Exit Return ...... ; ; Partial write of backward playground ; 40$: Cmp FCP,PlyEnd ;File empty?? Bne 80$ ;Fatal inconsistancy Mov BCP,R2 ;Adjust BCP to get word Inc R2 ;Make to even word with ClrB (R2)+ ;Zero byte Sub PlyGnd,R2 ;Byte count Asr R2 ;Word count Beq 55$ ;No words to write- so skip it Tst WrtFil ;Writing to output or temp file? Bne 50$ ;If not don't write $WritW Area,#OU$CHN,PlyGnd,R2,R1 Bcs IoErr ;Br on error 50$: Add #377,R2 ;Round words up to blocks Bic #377,R2 ;Chop to blocks SwaB R2 ;Make blocks 55$: Dec R2 ;Reduce to make block increment Add R2,R1 ;Make number of last block in file Mov R1,BkwBlk ;Last block in file Mov PlyGnd,BCP ;Empty bkwplygnd Dec BCP ;Is PLYGND-1 Sec ;Say no more Return ...... 60$: ;+ ;ERROR ERROR ,F ;Attempt to write over data in file. Logic error or file full. ;- 70$: ;+ ;ERROR ERROR ,F ;Computed block number was minus or beyond end of file. Logic error. ;- 80$: ;+ ;ERROR ERROR ,F ;Partial write attempted with data in fwd PLYGND. Logic error. ;- .Dsabl LSB .SbTtl IOERR - FILE I/O ERROR ;++ ;IOERR ; ;FUNCTIONAL DESCRIPTION: ; ; If a file I/O error occurs, an error message is printed and ; the editor takes the fatal exit. ;-- IoErr: ;+ ;ERROR ; ERROR ,F ; ;An I/O or device error was encountered doing file I/O. ;- .End