.MCall .Module .Module KEDSC1 RELEASE=V02 VERSION=16 COMMENT=,IDENT=NO,AUDIT=NO,GLOBAL=.KEDS1 ; 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: KEDSC1 ; ;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 S1,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 ;~d~Forward char pointer BCP:: .BlkW 1 ;~d~Backward char pointer PLyGnd::.BlkW 1 ;~d~Pointer to start of play ground PlyEnd::.BlkW 1 ;~d~To end of playground RbCr:: .BlkW 1 ;~d~Last deleted char BlkMax::.BlkW 1 ;~d~Max block number in file FwdBlk::.BlkW 1 ;~d~Forward block pointer BkwBlk::.BlkW 1 ;~d~Backward block pointer InFlg:: .BlkW 1 ;~d~0 for input file in use InBlk:: .BlkW 1 ;~d~Next to read block in input file MxIBlk::.BlkW 1 ;~d~Max block of input file MxOBlk::.BlkW 1 ;~d~Max block of output file FwdChn::.BlkW 1 ;~d~Forward channel- OU$CHN for output ;IN$CHN for input BkwChn::.BlkW 1 ;~d~Backward channel Inspct::.BlkW 1 ;~d~Non 0 for inspect mode ScBlks::.BlkW 1 ;~d~Blocks to move by (256. wds) ScWds:: .BlkW 1 ;~d~Words to move by ScByts::.BlkW 1 ;~d~Bytes to move by ScnSpc::.BlkW 1 ;~d~Bytes to assure for screen watch ChrCtr::.BlkW 2 ;~d~Double precision count for free ;chars SlctQ:: .BlkW 1 ;~d~Select enabled if non zero SlctC:: .BlkW 2 ;~d~Select count low,high CtrlC:: .BlkW 1 ;~d~Double Ctrl/C (set minus) Area:: .BlkW 1 ;~d~Area for prg req- address .BlkW 20. ;~d~Data area .BlkW 1 ;~d~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: ;~x~ Bic #T.SEr!T.Exe,TtInp ;Always allow printing Mov (R4)+,ErrorX ;Impure store the error address Jsr R4,ErrorV ;~x~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 ;~x~Entry to command module .............. .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:: ;~x~ Mov #-1,R0 ;Assume no file for output Tst Inspct ;Inspect mode? Bne 30$ ;~x~Yes- no foolishness 10$: Call MvFwd ;~x~Move by characters Bcc 10$ ;~x~No error Tst CtrlC ;Last chance to stop us Sec ;Set for error indicator Bmi 40$ ;~x~Also movfl stops on Ctrl/C 20$: Call WrBkw ;~x~Write out remainder of file Bcc 20$ ;~x~Til no more to write Mov BkwBlk,R0 ;Max block in output file 30$: Call $Cls ;~x~Close the output file Clc ;Just in case $CLS leaves a C set 40$: Return ;~x~ ...... .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:: ;~x~ Call MvFwd ;~x~Ahead one character Bcs 10$ ;~x~No good, error Call NlChk ;~x~Check for split newline Bne 10$ ;~x~Nope Call MvFwd ;~x~Step beyond LF 10$: Return ;~x~ ...... .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:: ;~x~ Call MvBkw ;~x~Back one Bcs 10$ ;~x~Nope Call NlChk ;~x~Split a NL Bne 10$ ;~x~Nope Call MvBkw ;~x~Back one more 10$: Return ;~x~ ...... .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 ;~x~Look forward Bne 10$ ;~x~Nope CmpB #,@BCP ;Look backward 10$: Clc ;~x~So we don't return an error Return ;~x~ ...... .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:: ;~x~ Tst CtrlC ;Abort set? Bmi 20$ ;~x~Yes- return error Call ChkAbt ;~x~ Cmp FCP,PlyEnd ;End of playground?? Bhis 20$ ;~x~Yes Inc BCP ;Point forward MovB @FCP,@BCP ;Move char Inc FCP ;Post increment MovB @BCP,R0 ;Get the char moved over Call QukChk ;~x~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$ ;~x~Nope Add #1,SlctC ;Increment count Adc SlctC+2 ;And overflow 10$: Call BFCFwd ;~x~Check forward chars Tst (PC)+ ;Skip and clear carry 20$: Sec ;~x~Return error Return ;~x~ ...... .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:: ;~x~ Tst CtrlC ;~x~Abort? Bmi 20$ ;~x~Yes - return error Call ChkAbt ;~x~ Cmp BCP,PlyGnd ;Beginning of playground Blo 20$ ;~x~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 ;~x~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$ ;~x~Nope Sub #1,SlctC ;Keep count Sbc SlctC+2 ;Double precision 10$: Call BFCBkw ;~x~Check back chars Tst (PC)+ ;No error 20$: Sec ;~x~Error signal for no-can-move Return ;~x~ ...... .Dsabl LSB .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:: ;~x~ IsAbt ;Are we recovering an aborted command? Beq 10$ ;~x~No Sub #1,AbtAt ;Yup, decrement the step counter Sbc AbtAt+2 ;Is it time to stop yet? Bne 10$ ;~x~Branch if not Tst AbtAt ; Bne 10$ ;~x~ 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$ ;~x~And return ........... 10$: IsJou ;~x~Are we journaling? Beq 20$ ;~x~No Add #1,StpCtr ;Yes, count steps in each function Adc StpCtr ; - double precision ;>>>*JMP* need a better route for overflow Bcc 20$ ;~x~ Tst (SP)+ ;Return to callers caller with c=1 20$: Return ;~x~ ...... .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:: ;~x~ Call DlChr ;~x~Delete a char Bcs 20$ ;~x~Bad CmpB #,R0 ;Just did in a CR Bne 10$ ;~x~Nope CmpB #,@FCP ;Next a linefeed? Bne 10$ ;~x~Nope Call DlChr ;~x~Do it in too 10$: Clc ;~x~Clean up carry 20$: Return ;~x~ ...... .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:: ;~x~ Call RbChr ;~x~Delete one Bcs 20$ ;~x~Bad CmpB #,RbCr ;LF just zapped Bne 10$ ;~x~Nope CmpB #,R0 ;CR next Bne 10$ ;~x~Nope Call RbChr ;~x~Zapp it Mov #,RbCr ;Fake last char rubbed to LF 10$: Clc ;~x~Return clean carry 20$: Return ;~x~ ...... .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:: ;~x~ Tst Inspct ;Inspect a file?? Bne 50$ ;~x~Yes- return error Tst ChrCtr ;Check low order count Bne 10$ ;~x~Ok Tst ChrCtr+2 ;High order Beq 50$ ;~x~No space left to insert 10$: Push ;~x~Bkw pointer Inc @SP ;Fwd one Cmp @SP,FCP ;Room?? Beq 40$ ;~x~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 20$ ;~x~Backward, don't change relative postn Add #1,PosCtr ;Increment relative position counter Adc PosCtr+2 ;And overflow 20$: Tst SlctQ ;~x~Select enabled? Beq 30$ ;~x~Nope Tst SlctC+2 ;Which type of range Bmi 30$ ;~x~Left range Add #1,SlctC ;Keep the count for right range Adc SlctC+2 ;Double 30$: Call QukChk ;~x~Check for screen destroyed Call BFCIns ;~x~Check backchars Tst CtrlC ;Ctrl/C typed Bmi 50$ ;~x~Return error Call ChkAbt ;~x~Is this command to be aborted? Clc ; Return ;~x~Return with or without error ...... 40$: Pop <> ;~x~Dump stack contents 50$: Sec ;~x~Signal error Return ;~x~ ...... .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:: ;~x~ Tst CtrlC ;Abort? Bmi 30$ ;~x~Yes- return error Call ChkAbt ;~x~Is this command to be aborted? Tst Inspct ;Inspect the file?? Bne 30$ ;~x~Yes- error return Cmp FCP,PlyEnd ;End of play space?? Bhis 30$ ;~x~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 10$ ;~x~Foreward, don't change relative postn Add #1,PosCtr ;Reduce relative position counter Adc PosCtr+2 ;And overflow 10$: Tst SlctQ ;~x~Select enabled Beq 20$ ;~x~Nope Tst SlctC+2 ;Which way? Bpl 20$ ;~x~Right Add #1,SlctC ;Reduce left range Adc SlctC+2 ;Double 20$: Call QukChk ;~x~Check for screen destroyed Call BFCFwd ;~x~Check forward chars Call UnStuf ;~x~Save deleted char via command module Return ;~x~Return ...... 30$: Sec ;~x~Signal error ...... Return ;~x~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:: ;~x~ Tst CtrlC ;Abort? Bmi 50$ ;~x~Yes- return error Call ChkAbt ;~x~Is this command to be aborted? Tst Inspct ;Inspect a file Bne 50$ ;~x~Yes- return error Cmp BCP,PlyGnd ;Begining of sandbox?? Blo 50$ ;~x~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$ ;~x~Backward,doesn't chng relative postn Bmi 20$ ;~x~Backward,doesn't chng relative postn Tst PosCtr ;Is there any change yet? Beq 20$ ;~x~Nope, no adjustment needed 10$: Sub #1,PosCtr ;~x~Reduce relative position counter Sbc PosCtr+2 ;And underflow 20$: Tst SlctQ ;~x~Select range enabled? Beq 40$ ;~x~Nope Tst SlctC+2 ;Which way Bmi 40$ ;~x~Left- ok Bpl 30$ ;~x~Right - adjust it Tst SlctC ;Any change at all? Beq 40$ ;~x~Nope, no adjustment needed 30$: Sub #1,SlctC ;~x~Reduce right range Sbc SlctC+2 ;Double 40$: Call BFCBkw ;~x~Check backward chars Push ;Save the char MovB RbCr,R0 ;Get rubbed char Call QukChk ;~x~Screen destroyed?? Call UnStuf ;~x~Save deleted char in undelete buffer Pop ,SAVE=*C* ;*C* restore the char Return ;~x~Return ...... 50$: Sec ;~x~Signal error Return ;~x~ ...... .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:: ;~x~ Call RbChr ;~x~Rub a char always first Bcs 50$ ;~x~No more Br 20$ ;~x~Check for line ........... 10$: Call RbChr ;~x~Rub another Bcs 40$ ;~x~No more to rub 20$: Call LTerm ;~x~Line terminator Bne 10$ ;~x~Nope 30$: Clc ;~x~No error Return ;~x~ ...... 40$: Cmp BCP,PlyGnd ;~x~Beginning of buffer? Blo 30$ ;~x~Yes- no error Sec ;Else error 50$: Return ;~x~ ...... .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:: ;~x~ Call MvBkw ;~x~Start back Bcs 40$ ;~x~Nowhere to go Br 20$ ;~x~Check for lineterm ........... 10$: Call MvBkw ;~x~Back one char Bcs 30$ ;~x~No more to move 20$: Call LTerm ;~x~Line terminator Bne 10$ ;~x~Nope 30$: Clc ;~x~No error 40$: Return ;~x~ ...... .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:: ;~x~ MovB @FCP,R0 ;First char to look at Br 20$ ;~x~Check to see if its a lterm ........... 10$: Call MvFwd ;~x~Forward one character Bcs 30$ ;~x~No more chars 20$: Call LTerm ;~x~Line term? Bne 10$ ;~x~Nope Push ;Save line term for return Call MvFwd ;~x~Move over line term Pop ;Restore line term 30$: Return ;~x~ ...... .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,# ;~x~L terms are LF through FF Blo 10$ ;~x~Nope CmpB R0,# ; Bhi 10$ ;~x~nope Sez ;Yep 10$: Return ;~x~ ...... .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 ;~x~Screen already blown Beq 10$ ;~x~Yes Call LTerm ;~x~Check for line terminator Bne 10$ ;~x~Ok leave it alone Clr QukFlg ;Is changed 10$: Return ;~x~ ...... .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 ;~x~Enough space left?? Sub FCP,@SP ;PLYEND-FCP Cmp (SP)+,ScnSpc ;Screen space check Bhis 30$ ;~x~Ok Tst InFlg ;Input in progress?? Bne 10$ ;~x~No- read beyond end Cmp FwdBlk,BlkMax ;More blocks to read? Bhi 30$ ;~x~Nope ; ; DO NOT INCUR SAVE REGISTER OVERHEAD UNTIL ABSOLUTELY REQUIRED ; 10$: SavReg ;~x~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$ ;~x~Yes- just read Call WrBkw ;~x~Write backwards 20$: Call RdFwd ;~x~Read forwards 30$: Return ;~x~ ...... .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 ;~x~Enough space?? Sub PlyGnd,@SP ;BCP-PLYGND+1 Inc @SP Cmp (SP)+,ScnSpc ;Enough for screen Bhis 20$ ;~x~Fine Tst BkwBlk ;More available Blt 20$ ;~x~Nope SavReg ;~x~ Clr QukFlg ;Screen blown Mov FCP,R1 ;Write first?? Sub BCP,R1 ;FCP-BCP-1 Dec R1 Cmp R1,ScByts ;Space required Bhi 10$ ;~x~Ok Call WrFwd ;~x~Make room by write forward 10$: Call RdBkw ;~x~Read backward 20$: Return ;~x~ ...... .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 ;~x~Space Sub BCP,@SP ;FCP-BCP-1 Dec (SP)+ Bne 20$ ;~x~Space left- ok SavReg ;~x~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$ ;~x~Not enough to write Cmp R1,ScnSpc ;Enough for screen?? Blos 10$ ;~x~Write forward Call WrBkw ;~x~Write backward Br 20$ ;~x~ ........... 10$: Call WrFwd ;~x~Write forward 20$: Clc ;~x~Return no error Return ;~x~ ...... .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 ;~x~ Tst Inspct ;Inspect mode? Bne 40$ ;~x~Yes- use zero chars left Tst InFlg ;Input file active? Bne 30$ ;~x~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$ ;~x~None left Sub R1,R0 ;Adjust for it 10$: Mov PlyEnd,R1 ;~x~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$ ;~x~Truly no chars in the buffer Mov #-1,ChrCtr+2 ;High word, for the lack of sxt 20$: SwaB R0 ;~x~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$ ;~x~Less than no chars left 30$: Return ;~x~ ...... ; ; If inspect mode we come here ; 40$: Clr ChrCtr ;~x~If inspect mode Clr ChrCtr+2 ;Use zero chars left Return ;~x~ ...... 50$: ;~x~ ;+ ;ERROR ERROR ,F ;~x~ ;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 ;~x~ Mov FCP,R1 ;Enough space to read Sub BCP,R1 ;FCP-BCP-1 = space Dec R1 Cmp R1,ScByts ;Amount to read Blo 110$ ;~x~Not enough 10$: Cmp FwdBlk,BlkMax ;~x~Any more to read? Bgt 90$ ;~x~Nope Mov FCP,R1 ;Empty fwdplygnd Cmp R1,PlyEnd ;?? Beq 40$ ;~x~Yep Bhi 120$ ;~x~Pointer corrupt- fatal Mov R1,R2 ;Copy to dst Sub ScByts,R2 ;Adjust for move down Bit #1,R2 ;Byte at first?? Beq 30$ ;~x~Nope MovB (R1)+,(R2)+ ;Move and align Br 30$ ;~x~Check first now ........... 20$: Mov (R1)+,(R2)+ ;~x~Word move is faster 30$: Cmp R1,PlyEnd ;~x~Til all moved Blo 20$ ;~x~ 40$: Mov PlyEnd,R1 ;~x~Make address to read Sub ScByts,R1 ;Into $ReadW Area,FwdChn,R1,ScWds,FwdBlk ;~x~ Bcc 50$ ;~x~Br on success Jmp IoErr ;~x~Else fatal error .............. 50$: Add ScBlks,FwdBlk ;~x~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$ ;~x~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 ;~x~All done Beq 80$ ;~x~Yes MovB -(R1),R0 ;Pick a char ;>>> change for 8bit Bic #^C177,R0 ;Strip parity Tst Inspct ;Writing to output or temp file? Bne 70$ ;~x~If not leave nulls, else pack out Tst R0 ;Look at the char Beq 60$ ;~x~Null?? 70$: MovB R0,-(R2) ;~x~No- plop it down Br 60$ ;~x~Continue ........... 80$: Mov R2,FCP ;~x~End address after pack Call SpcFre ;~x~Compute free space again Clc ;No error signal Return ;~x~ ...... 90$: Tst InFlg ;~x~Input file active? Beq 100$ ;~x~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$ ;~x~Back to check blocks ........... 100$: Call SpcFre ;~x~Compute free space incase ;Create file Sec ;Signal error- no data Return ;~x~ ...... 110$: ;~x~ ;+ ;ERROR ERROR ,F ;~x~ ;Insufficient space was found to read the next group of blocks into ;the playground. Logic error. ;- 120$: ;~x~ ;+ ;ERROR ERROR ,F ;~x~ ;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 ;~x~ Tst InFlg ;Input file?? Bne 20$ ;~x~Nope Tst Inspct ;Writing to output or temp file? Beq 10$ ;~x~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 20$ ;~x~Br if not Mov R1,FwdBlk ;Else FWDBLK = MAXBLK + 1 so new ; FWDBLK corresponds to amount of ; data we forget Br 20$ ;~x~Use that ........... 10$: Mov FwdBlk,InBlk ;~x~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 20$: Mov FwdBlk,R1 ;~x~Check block for ok Sub ScBlks,R1 ;Illegal? Ble 70$ ;~x~Yes Mov R1,R2 ;Make clash block number Sub ScBlks,R2 ;FWDBLK-SCBLKS Cmp R2,BkwBlk ;Block overrun?? Ble 60$ ;~x~Yes Mov PlyEnd,R2 ;Enough data to write Sub FCP,R2 ;PLYEND-FCP Cmp R2,ScByts ;Ok?? Blo 80$ ;~x~Nope - fatal Mov PlyEnd,R2 ;Address to write Sub ScByts,R2 Tst Inspct ;Writing to output or temp file? Bne 30$ ;~x~If not don't write $WritW Area,#Ou$Chn,R2,ScWds,R1 ;~x~ Bcc 30$ ;~x~Br on success Jmp IoErr ;~x~Else fatal error .............. 30$: Mov R1,FwdBlk ;~x~Save block no Mov PlyEnd,R1 ;Move data down toward end Mov R1,R2 ; Sub ScByts,R1 ;Make src Br 50$ ;~x~ ........... ; ; Note word alignment is not needed and one more ; byte is moved with last word but who cares ; 40$: Mov -(R1),-(R2) ;~x~Words are faster 50$: Cmp R1,FCP ;~x~Check til done Bhis 40$ Add ScByts,FCP ;~x~Adjust fcp pointer Clc ;No signal error Return ;~x~ ...... 60$: ;~x~ ;+ ;ERROR ERROR ,F ;~x~ ;Attempt to write over data in file. Logic error or full file ;- 70$: ;~x~ ;+ ;ERROR ERROR ,F ;~x~ ;Computed block number is negative or zero. Logic error. ;- 80$: ;~x~ ;+ ;ERROR ERROR ,F ;~x~ ;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 ;~x~ Mov FCP,R1 ;Compute space Sub BCP,R1 ;FCP-BCP-1 Dec R1 Cmp R1,ScByts ;Enough?? Blo 70$ ;~x~Nope- fatal Tst BkwBlk ;Block number ok Blt 60$ ;~x~No more data- c set rtn Mov BCP,R1 ;Empty bkw playground?? Cmp R1,PlyGnd ;Check the the start of plygnd Blo 30$ ;~x~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$ ;~x~Yes- setup for word MovB -(R1),-(R2) ;Move and set for word moves Br 20$ ;~x~Compare first ........... 10$: Mov -(R1),-(R2) ;~x~Move words are faster 20$: Cmp R1,PlyGnd ;~x~Til done Bhi 10$ ;~x~ 30$: $ReadW Area,BkwChn,PlyGnd,ScWds,BkwBlk ;~x~ Bcc 40$ ;~x~Br on success Jmp IoErr ;~x~Else fatal error .............. 40$: Add ScByts,BCP ;~x~Adjust pointer Sub ScBlks,BkwBlk ;Adjust block number ;>>> tst (pc)+ ... 50$: Clc ;~x~ Return ;~x~ ...... 60$: Sec ;~x~C set if no more data Return ;~x~ ...... 70$: ;~x~ ;+ ;ERROR ERROR ,F ;~x~ ;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 ;~x~ Mov BkwBlk,R1 ;Look for block overrun Add ScBlks,R1 ;Next target Mov R1,R2 ;Make clash block Blt 80$ ;~x~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$ ;~x~Nope- partial Tst InFlg ;Input in use?? Beq 10$ ;~x~Yes- dont check for overrun Cmp R2,FwdBlk ;Block overrun?? Bhis 70$ ;~x~Yes 10$: Tst R1 ;~x~Block no ok?? Blt 80$ ;~x~Nope- fatal error Cmp R1,MxOBlk ;Watch for overwrite of end Bhi 80$ ;~x~MXOBLK=-1 if inspect Tst Inspct ;Writing to output or temp file? Bne 20$ ;~x~If not don't write $WritW Area,#Ou$Chn,PlyGnd,ScWds,R1 ;~x~ Bcs IoErr ;~x~Br on error 20$: Mov R1,BkwBlk ;~x~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)+ ;~x~Ok to start with word moves here Cmp R1,BCP ;Til all moved Blos 30$ ;~x~ Sub ScByts,BCP ;Adjust BCP pointer Clc ;Exit Return ;~x~ ...... ; ; Partial write of backward playground ; 40$: Cmp FCP,PlyEnd ;~x~File empty?? Bne 90$ ;~x~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 60$ ;~x~No words to write- so skip it Tst Inspct ;Writing to output or temp file? Bne 50$ ;~x~If not don't write $WritW Area,#OU$CHN,PlyGnd,R2,R1 ;~x~ Bcs IoErr ;~x~Br on error 50$: Add #377,R2 ;~x~Round words up to blocks Bic #377,R2 ;Chop to blocks SwaB R2 ;Make blocks 60$: Dec R2 ;~x~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 ;~x~ ...... 70$: ;~x~ ;+ ;ERROR ERROR ,F ;~x~ ;Attempt to write over data in file. Logic error or file full. ;- 80$: ;~x~ ;+ ;ERROR ERROR ,F ;~x~ ;Computed block number was minus or beyond end of file. Logic error. ;- 90$: ;~x~ ;+ ;ERROR ERROR ,F ;~x~ ;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: ;~x~ ;+ ;ERROR ; ERROR ,F ;~x~ ; ;An I/O or device error was encountered doing file I/O. ;- .Dsabl LSB .End