.Module KEDCM1 RELEASE=V02 VERSION=47 COMMENT=,IDENT=NO,AUDIT=NO,GLOBAL=.KEDC1 ; 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. ;+ ;COND ; ; VT10$0 1 VT100 support ; VT10$0 0 VT52 support ;- ; ;MODULE: KEDCM1 ; ;ABSTRACT: ; ; This is the root command module. Keypad functions are decoded here ; and commands are dispatched from here. ; Very frequently used keypad commands are here to avoid swapping. ; ;AUTHOR: Darrell Duffy ; ;DATE: 3-July-79 ; ;REVISION HISTORY: ; ;MODIFIED BY: ; ; Cheryl Vedoe ; ; 8-March-79 Ignore nulls inserted in file. ; Default to extended commands. ; ; 19-March-79 Control keys for macro and structured tabs features ; changed to GOLD functions. ; Working message changed for VT100 to blink as it does ; for VT52 instead of using blink video attribute. ; ; Darrell Duffy ; ; 23-March-79 Fix minor bugs in wrap and fill, parameter check in ; Local, TABS becomes SET TABS. ; ; Cheryl Vedoe ; ; 27-April-79 Utilize macro library. ; Change .PRINT to $PRINT ; No message for error sizing screen. ; Insufficient memory error message moved to I/O module. ; ; 1-May-79 Move code to display error and help messages to ; the I/O module. ; Size screen only once when KED is started. ; In inspect mode, output warning message on QUIT only ; if auxiliary output file open. ; ; 2-May-79 Change case of current character if no select range. ; ; 22-May-79 Preserve screen video when KED starts. If the state is ; not known set it to dark when QUIET mode is set. ; Arrow commands changed so they don't lock keyboard ; (turn off auto-repeat). ; Bells that ring in quiet mode fixed. ; ; 12-June-79 '<>' changed to 'Repeat:' ; ; 20-June-79 Local fixed to allow local symbol block that begins ; with a symbol to end with '.ENABL LSB'. ; Local changed to allow underscore character in local ; sumbols (to support local symbols on VMS). ; ; Darrell Duffy ; ; 3-July-79 Breakup and Overlay Command Module ; Change NOECHK macro and add ENDCHK macro ; ; Cheryl Vedoe ; ; 20-July-79 Call $CSI from here instead of from KEDSCL. ; Fix video bug that causes end-of-file indicator ; to be deleted. ; Turn application keypad mode off when prompting ; for response to error message. ; ; 10-Sept-79 Change default for wrap column to 78. ; Add error message for null input with special input. ; Modify C.LFT and C.RHT to skip nulls so RT-11 version ; of KED ignores nulls. ; ; 22-Oct-79 Disable CTRL/W function when executing a macro. ; Fix Find code to check for playground boundaries. ; ; 25-Oct-79 Add entry to handle error to second level of find ; character dispatch lists (FNDLS1). ; Don't flush input buffer on errors to avoid breaking ; escape sequences and inserting spurious characters. ; Flush only before sizing the screen and after ; CTRL/C is entered. ; ; 9-Nov-79 Don't size screen on startup for a VT100 to allow for ; type ahead. Set terminal for 80 column mode. ; Take care of setting terminal input mode in $CSI. ; ; 26-Nov-79 Modify CTRL/W to erase screen. ; ; Jim Williams ; ; 3-Dec-79 Change C.DWN to get rid of 'bounce' at EOF. ; ; Cheryl Vedoe ; ; 26-Dec-79 Change arrow commands to lock keyboard. ; ; ; Jim Williams ; ; 27-Dec-79 change VT52 keypad definition ; add conditional OLD$52 to select old or new keypad ; definition. If OLD$52 = 1 use old one;= 0, new. ; ; ; moved FNDLST: et al to KEDCMD from .TXT. ; ; 16-Jan-80 changed CLS/VRS/RLS to V01.01 for release ; ; 10-Sep-80 changed search code to fix boundary condition failures ; as reported by SPR. ; .Enable LC .Enable GBL .SbTtl Error and Helper Definitions .If NE,0 ;This code is assembled in the error module ;+ ;ERROR .MCall .Module .Module KEDERR RELEASE=V02 VERSION=00 COMMENT=,IDENT=NO,AUDIT=NO,GLOBAL=.KEDER .Enable LC .Enable GBL ; COPYRIGHT 1989, 1990, 1991 BY ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ALL RIGHTS RESERVED ; ;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED ;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND 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. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY ;TRANSFERRED. ; ;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE ;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT ;CORPORATION. ; ;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS ;SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL. .Page ; ;MODULE: KEDERR ; ;ABSTRACT: ; ; This is the error message module for KED. It contains error ; message text for all errors and help message from all the ; other modules. It is created automatically to be assembled ; separately. ; ;AUTHOR: DARRELL DUFFY ; ;DATE: 3-July-1979 ; ;REVISION HISTORY: ; .Page ; ;Error message comment standard ; ; All error messages are commented with the same format so that ; a TECO macro can find them and writers know what to look for. ; All comment blocks are in the following form: ; ; ;+ (open comment block) ; ;ERROR (it's an error comment block) ; ;Error text (message and severity, not environment) ; ;Statements of problems causing message ; ;- (close comment block) ; ;Errors reported by KED are of four types: ; ; CSI errors reported from CSI state or before screen is active ; Errors so severe that the text appears on the screen even when ; it is active. RETURN is typed to continue. ; Prompts which appear on the screen and are answered to continue. ; HELP which rings the bell. The message appears once when HELP ; is pressed. These messages are contained in the KEDHLP ; file. ; ; ;The first type of error is preceded by the environment and severity ;in standard RT-11 format. Some errors of the first type may actually ;be signaled after the screen is active in which case the environment ;is not printed. ; ;Errors of the second type require the user to type RETURN to continue. ;This is to make sure the message is read. The HELP message is set to ;the message so it can be inspected once more after RETURN is typed. ; ;Prompts actually appear both from CSI state and when the screen is active. ;In CSI state the environment is appended. In screen state the environment ;is deleted. The help message is set to the prompt. ; .Page ; ; Assembly parameters ; .IIf NDF Rsts$ Rsts$=0 ; ; PSect definitions ; .MCall PSect ;KedMac.MLb PSect $ERR$ ;Error messages ;- .EndC ;NE,0 ; ;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 KEDCM1 module ; ; Module: KEDCM1 ; ; Define the error for this module ; .MCall ErrDef ErrDef C1,Error ;Invoke macro to define error macro ;- .If NE,0 ;This code is assembled in the help module ;+ ;HELPER .MCall .Module .Module KEDHLP RELEASE=V02 VERSION=00 COMMENT=,IDENT=NO,AUDIT=NO,GLOBAL=.KEDHL .Enable LC .Enable GBL ; COPYRIGHT 1989, 1990, 1991 BY ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ALL RIGHTS RESERVED ; ;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED ;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND 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. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY ;TRANSFERRED. ; ;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE ;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT ;CORPORATION. ; ;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS ;SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL. .Page ; ;MODULE: KEDHLP ; ;ABSTRACT: ; ; This is the error message module for KED. It contains error ; message text for all help messages from all the other modules. ; It is created automatically to be assembled separately. ; .Page ; ;Helper message comment standard ; ; All help messages are commented with the same format so that ; a TECO macro can find them and writers know what to look for. ; All comment blocks are in the following form: ; ; ;+ (open comment block) ; ;HELPER (it's an error comment block) ; ;Error text (message) ; ;Statements of problems causing message ; ;- (close comment block) ; ; HELP rings the bell. The message appears once when HELP ; is pressed. .Page ; ; Assembly parameters ; .IIf NDF Rsts$ Rsts$=0 ; ; PSect definitions ; .MCall PSect ;KedMac.MLb PSect $HLP$ ;Help text ;- .EndC ;NE,0 ; ;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. ; ;+ ;HELPER ; .IIf NDF,$KED$, .Page .IIf NDF,$KED$, .SbTtl Help from KEDCM1 module ; ; Module: KEDCM1 ; ; Define the error and help macros for this module ; .MCall HlpDef HlpDef C1 ;Invoke macro to define help macro ;- .SbTtl PSect definition ; ; PSect definition ; PSect KEDCMD .SbTtl .SbTtl Main entry ; ; Main entry ; ; ; Transfer is made here from I/O module ; .Enable LSB KED:: ;~x~ ; ; Setup permanent things across files ; Call $Alloc ;~x~Allocate R/W space ;error never returns Call Setup ;~x~Call scroller routine Call Context ;~x~Setup default edit session context Mov #DefFrq,JoFreq ;Init journal write frequency Clr Init ;Indicate first time thru for init ; ;Set up terminal characteristics ; RCtrlO ;~x~Enable output $Print #IniTrm ;~x~Initialize the terminal .If NE,VT10$0 ;VT100 Terminal Clr QutFlg ;Not quiet on Clr QuietQ ;Not enabled either Clr QutPtr ;We don't know if screen is ; dark or light .EndC; NE,VT10$0 ;VT100 Terminal .Br Restr ;Go to restart code .Dsabl LSB ; ; Restart loop ; .Enable LSB RESTR:: ;~x~ Call $Start ;~x~Setup things to restart ;>>> .Br ; ; *** Fall through *** ; .Dsabl LSB .SbTtl Setup file for scrolling ; ; FILSET is called in SCROLR to setup the file for scrolling ; VWATCH is called to setup the screen ; data areas for command decoding are initialized ; .Enable LSB 10$: Call $CSI ;~x~Get command line Bcs 20$ ;~x~ Bad command Call SetCom ;~x~Setup initialization command file Call SetRec ;~x~Setup recover file Call SetJou ;~x~Setup journal file Bcc 30$ ;~x~Branch if we have a good one 20$: Call ChainCk ;~x~Otherwise, exit if we were chained to Br 10$ ;~x~Don't move on until we have a valid .......... ; command line 30$: Call Active ;~x~Put editor in active mode Tst Init ;Is this the first time through? Beq 40$ ;~x~Yes, go do first time stuff IsJou OFF 60$ ;~x~Are we journaling? NO Call Context ;~x~Yes, set defaults and clear buffers Br 60$ ;~x~Br if not ........... 40$: ;~x~ ; ; Setup screen size ; .If EQ,VT10$0 ;VT100 Terminal ;To allow type ahead for V52: Call $TFlsh ;~x~Flush input buffer Call $SpOn ;~x~Turn on special input .Iff ;EQ,VT10$0 ; ; On the VT100 we need to clear the screen in case there ; are DW or DH lines on the screen ; $Print #ZapScr ;~x~To make sure all lines are SW Call SizScr ;~x~Size the VT100 screen ;>>> save width for later restore ... Bcc 50$ ;~x~Fine the screen is sized ; ; For VT100 we will now assume a screen size and try to use it ; the user may use ctrl/W to fix the screen if it's wrong ; .EndC Mov #V.Cols,R1 ;Setup columns to use Mov #V.Lin80,R2 ;And lines Call HV.Fix ;~x~And tell VWATCH the news Bcs $Fatal ;~x~Hard error 50$: ;~x~ Mov SP,Init ;First time done 60$: Call FilSet ;~x~Setup file data for scrolling ;.Assume V.Clr EQ 0 Clr R0 ;Call to setup screen and lines Call VWatch ;~x~Setup all Clr CurCmd ;Rememberances of past commands Clr LstCmd ;For arrows Clr Advanc ;Assume forward mode .If NE,VT10$0 ;VT100 Terminal Clr KbLkq ;Unlocked keyboard .EndC; NE,VT10$0 ;VT100 Terminal AbtOff ;Init aborted command flag Call RecPos ;~x~Position zero Call HlpSet ;~x~Setup help default message Call CanSlc ;~x~Reset select mode Call $Mrks ;~x~Setup data for marktime "working" Call Recovr ;~x~Process the recover file SetBsy ;~x~ Display "Working..." Call Commnd ;~x~Process the initialization file ClrBsy ;~x~ Done "Working..." for now Call IniJou ;~x~Initialize journal data CmdOff ;Begin in insert mode .Br Main ;Start program main loop .Dsabl LSB PSect IMPURE Init: .Word 0 ;~d~Non-zero if screen has been set up PSect KEDCMD .SbTtl .SbTtl Main command loop ; ; Main command loop ; .Enable LSB Main: ;~x~ 10$: ClrBsy ;~x~We are not busy now Clr R1 ;No bits for CURCMD yet Bit #InsBit,CurCmd ;Did we just optimize VWATCH?? Bne 20$ ;~x~Yes- skip calling it Mov #V.Updt,R0 ;Call to update screen Call VWatch ;~x~To show any changes Mov #InsBit,R1 ;Say we would like to optimize VWATCH 20$: KbUnlk ;~x~Unlock the keyboard TTyIn ;Get a char to R0 SetBsy ;~x~We are busy now Bis R1,CurCmd Mov FCP,InsFCP ;Save the char pointer for a check Clr CtrlC ;Clear any outstanding ctrl/C stops 30$: Clr RepCtr ;~x~No repeats now .If NE,VT10$0 Call RstQut ;~x~Restore screen if quiet mode .EndC; NE,VT10$0 Call CmdGo ;~x~Go do the command in R0 Bit #100000,CtrlC ;*C* Ctrl/C typed? ;**TRICK** Do not change carry ;with previous instr or this will ;not work Bpl 50$ ;~x~*C* Nope IsJou OFF 40$ ;~x~Are we journaling this session? NO Call $WrAbt ;~x~Write in journal that command 40$: Call Cancel ;~x~ 50$: Call BelErr ;~x~Signal bell if C set TTInR ;~x~Get TTY char without wait Bcc 30$ ;~x~Yes do it now Br 10$ ;~x~Nope- show screen .......... .Dsabl LSB ; ; Subroutine to set ctrl/C help message ; We call it to maintain control since HELPER ; returns to caller's caller ; .Enable LSB ;>>>>>>>new jmp Cancel:: ;~x~Used by AbtCmd Call RecPos ;~x~ was aborted Clr CtrlC ;Yes- clear flag Call $TFlsh ;~x~Flush all outstanding input Clr HlpDne ;Use next message ;>>>>>>> ;+ ;HELPER Helper ;~x~ ;Double ctrl/C typed during a lengthy operation causes immediate halt of ;the operation (insert, delete char, or move in either direction invoked ;by any keypad function. The cursor is left whereever it happened to be ;at the time. The bell is sounded except in the case of the function ;being top or bottom of file. In these cases the screen shows that the ;operation was not completed. Note that double ctrl/C while a function is ;in progress will not cause the abort prompt to be issued. ;The type ahead buffer is cleared when double ctrl/C is typed. ;- .Dsabl LSB ; ; Impure data for command decoding ; ; ; Equated symbols ; ; ; Bits in CURCMD and LSTCMD words ; AroCmd = 1 ;Arrow command bit HlpBit == 2 ;Help command bit WrpBit = 4 ;Word wrap bit InsBit == 10 ;Insert optimize bit ; ; Impure data ; PSect IMPURE CurCmd:: ;~d~ .BlkW 1 ;~d~Bits of current command LstCmd:: ;~d~ .BlkW 1 ;~d~Bits of last command InsFCP: .BlkW 1 ;~d~Holds FCP for last call to VWATCH PosCtr:: ;~d~ .BlkW 2 ;~d~Position change from beginning of ; command processing (double precisn) SavCtr: .BlkW 2 ;~d~Position change from beginning of ; command (double precision) StpCtr::.BlkW 2 ;~d~Count of basic operations in ; a function (used for aborted ; commands in journal) AbtAt:: .BlkW 2 ;~d~Number of basic operations that a ; function accomplished before being ; aborted (for journal) PSect KEDCMD ; ;Setup edit session default context ; .Enable LSB Context: ;~x~ Call PasSet ;~x~Setup paste buffer Call Unset ;~x~Setup undelete buffers Call SetDPa ;~x~Set default page and paragraph Call SrcSet ;~x~Search string Call TtySet ;~x~Setup macro data Call LrnClr ;~x~setup learn data Clr TbCnt ;Set tab count for not enabled Clr WrapQ ;Word wrap is off Clr HlpFlg ;Don't suppress help Clr LrnFlg ;No learning Mov #V.Cols-2,WrapC ;Setup the wrap column Return ;~x~ ...... .Dsabl LSB .SbTtl .SbTtl $FATAL - Fatal error exit ;++ ;$FATAL ; ;FUNCTIONAL DESCRIPTION: ; ; Fatal error exit called by anywhere in the program. ; This entry cleans up the terminal by sending some escape ; sequences to it and then transfers to $EXIT to return ; to the system. ; ; Note that this entry should not be called if the error ; would prevent terminal output to occur. ; ;INPUT: NONE ; ;OUTPUT: NONE ;-- .Enable LSB $Fatal:: ;~x~ $Print #AltOff ;~x~Alt keypad mode off $Print #BotScr ;~x~To the bottom of the screen Jmp $Exit ;~x~ ............. .Dsabl LSB .SbTtl ERROR - Error routine ;++ ;ERROR ; ;FUNCTIONAL DESCRIPTION: ; ; This routine is called to print an error message only if the ; screen is not active (CSI error messages) or if the error is ; fatal and the editor is going to exit immediately. ; ; The message is printed at the bottom of the screen with the ; environment prefix and is followed by a CR/LF. ; ;INPUT: ; Jsr R4,Error ; .Word MsgAdr ; ; -or- ; ; Mov #MsgAdr,ErrorX ; Jsr R4,ErrorV ; ;OUTPUT: ; ; R0 modified ;-- .Enable LSB ErrorV:: ;~x~ Push ;Save flags settings Bic #T.SEr!T.Exe,TtInp ;Always allow printing Push ;Save R4 Mov #ErrorX,R4 ;Point to error message address Call $PrtEr ;~x~Print error message w/prefix Pop ;Restore R4 Br 10$ ;~x~Join common code ........... Error:: ;~x~ Push ;Save flags settings Bic #T.SEr!T.Exe,TtInp ;Always allow printing Call $PrtER ;~x~Print error message with ; environment prefix Tst (R4)+ ;Advance R4 to return address 10$: $Print #Null ;~x~Print a CR/LF Pop ;Restore flags KbUnlk ;Unlock keyboard just in case Sec ;Return error Rts R4 ;~x~Return to caller .......... .Dsabl LSB PSect .TXT. Null: .Byte 0 ;~d~ PSect IMPURE ErrorX::.BlkW 1 ;~d~error message address for ;"variable" calls PSect KEDCMD .SbTtl ErrPmt - Error prompt routine ;++ ;ERRPMT ; ;FUNCTIONAL DESCRIPTION: ; ; This routine is called to print a message in the appropriate ; location (depending on whether or not the screen is active) and ; to prompt for a response. ; ;INPUT: ; Jsr R4,ErrPmt ; .Word Message ; ;OUTPUT: ; ; R0 modified ;-- .Enabl LSB ErrPmt:: ;~x~ Tst YSwt ;Are we still in NOQUERY on startup? Beq 10$ ;~x~No Tst (R4)+ ;Yes, advance R4 to return address Sez ;Skip query and return positive Rts R4 ;~x~ response .......... 10$: Tst EdActv ;~x~Check for screen in use Bne 20$ ;~x~Br if so Call $PrtEr ;~x~Else print message with ; environment prefix Br 30$ ;~x~Prompt for response ........... 20$: Dec HlpDne ;~x~Set for not the message to use Mov @R4,HlpTxt ;Save message in help text Inc HlpDne ;Use this help message Call BelRng ;~x~Ring the bell Call $PrtPr ;~x~Print like a help message 30$: Tst (R4)+ ;~x~Advance R4 to return address KbUnlk ;Unlock keyboard just in case $Print #AltOff ;~x~Application keypad mode off Call $Prmpt ;~x~And always prompt Beq 40$ ;~x~Save Z-bit for return Push ;Not zero (not SP for Z error avoid) Br 50$ ;~x~ ........... 40$: Push #0 ;~x~Save zero 50$: $Print #AltOn ;~x~Keypad mode on Call $JoIncl ;~x~Record answer in journal file (if ; journaling) ClrB PmtDef ;Initialize the prompt default Pop <> ;Pop stack to restore Z-bit Rts R4 ;~x~ .......... .Dsabl LSB ; ; Data for error message routines ; PSect IMPURE EdActv:: ;~d~ .BlkW 1 ;~d~Nonzero for screen active PSect KEDCMD .SbTtl HELPER - Set help text for error ;++ ;HELPER ; ;FUNCTIONAL DESCRIPTION: ; ; Set help text for error ; ; Address of help text is saved, carry is set and ; return is made to caller of the routine which ; called helper ; ;INPUT: ; Jsr R4,Helper ; .Word HlpMsg ; ;OUTPUT: ; HlpTxt = Help text adr if HlpDne is zero ; Return made to caller's caller ; Registers preserved ; HlpDne non zero ;-- .Enable LSB Helper:: ;~x~ IsSer ON 10$ ;~x~Should we keep executing past error? YES Bic #,TtInp ;Stop executing on every error 10$: Tst HlpDne ;~x~Is help already set? Bne 20$ ;~x~Yes Mov (R4)+,HlpTxt ;Set help text address Inc HlpDne ;Help now set 20$: Pop ;~x~Restore R4 Sec ;Return error Return ;~x~Return to caller's caller ...... .Dsabl LSB ; ; Data for help message routine ; PSect IMPURE HlpDne:: ;~d~ .BlkW 1 ;~d~Nonzero for help already set PSect KEDCMD .SbTtl CmdGo - Main command dispatch routine ;++ ;CMDGO CMDGO1 ; ;FUNCTIONAL DESCRIPTION: ; ; Dispatch to the appropriate command routine based on ; esc sequence or single input from the terminal ; ;INPUT: ; R0 = first char of sequence ; ;OUTPUT: ; R0,R1 destroyed ;-- .Enable LSB CmdGo:: ;~x~ Mov CurCmd,LstCmd ;Last command becomes the current one Clr CurCmd ;Current command is not special CmdGo1:: ;~x~ Clr HlpDne ;Use first help message Mov #C1Lst,R1 ;Non gold dispatch list CallR ChDsp ;~x~Dispatch to first level of commands ............. .Dsabl LSB .SbTtl BadEsc - Unknown escape sequence routine ;++ ;BADESC ; ;FUNCTIONAL DESCRIPTION: ; ; Entry for bad escape sequence or unknown command character ; ;-- .Enable LSB BadEsc: ;~x~ ;+ ;HELPER Helper ;~x~ ; An illegal escape sequence was received or an illegal ; control function ;- .Dsabl LSB .SbTtl C.CtC - CTRL/C and CTRL/Z intercept .SbTtl C.CtZ - ;++ ;C.CTC C.CTZ ; ;FUNCTIONAL DESCRIPTION: ; ; Entry for ctrl/C and ctrl/Z to issue help error ; ;-- .Enable LSB C.CtC: ;~x~ C.CtZ: IsJRe OFF 10$ ;~x~Are we recovering a journal? NO CallR $RdRec ;~x~Read the record and process it .............. 10$: IsJou OFF 20$ ;~x~Are we journaling? NO Call $WrPos ;~x~Write a position record 20$: ;~x~ ;+ ;HELPER Helper ;~x~ ;The quit command is used to restart the editor without saving files. ;Ctrl/C, Z are ignored by the editor ;- .Dsabl LSB .SbTtl SetScr - Restore screen display ;++ ;SETSCR ; ;FUNCTIONAL DESCRIPTION: ; ; Restore screen display in case he kicked the plug from the wall ; ;-- .Enable LSB SetScr:: ;~x~ IsExe ON 10$ ;~x~Executing a macro, If so, ignore ^W ClrBsy ;~x~Editor no longer busy RCtrlO ;~x~Reset ctrl/O $Print #SetTrm ;~x~Setup terminal in case of power off $Print #ZapScr ;~x~Make sure we get rid of all garbage .If NE,VT10$0 Call SizScr ;~x~Size the screen ;+ ;ERROR ;NO MESSAGE ;VT100 only ;Attempt to size the screen failed for Ctrl/W function to restore ;the screen after a size change or terminal error. ;If this returns an error it is ignored- the new screen size will ;not be used and the user will notice what is up because the display ;will be wrong. ;- .EndC; NE,VT10$0 ;VT100 Terminal $Print #AltOn ;~x~Alternate keypad on ;.Assume V.Clr EQ 0 Clr R0 ;Forget screen Call VWatch ;~x~ Mov #V.Updt,R0 ;Update Call VWatch ;~x~Call the screen manager 10$: Return ;~x~ ...... .Dsabl LSB .SbTtl ClrTop - Clear top two lines of the screen ;++ ;CLRTOP ; ;FUNCTIONAL DESCRIPTION: ; ; Clear top two lines of the screen ; ;-- .Enable LSB ClrTop:: ;~x~ Push #V.2Top ;Forget top two lines Push #Ers2Ln ;Erase two lines at the top Br 10$ ;~x~Carry on ........... .SbTtl ClrBot - Clear bottom two lines of screen ;++ ;CLRBOT ; ;FUNCTIONAL DESCRIPTION: ; ; The bottom three lines of the screen are cleared and the ; cursor is left at the beginning of next to last line. ;-- ClrBot:: ;~x~ Push #V.3Bot ;Forget bottom three lines Push #Ers3Bt ;Erase three lines at bottom Br 10$ ;~x~Carry on ........... .SbTtl ClrAll - Clear all the screen for use ;++ ;CLRALL ; ;FUNCTIONAL DESCRIPTION: ; ; Clear all the screen for use ; ;-- ClrAll:: ;~x~ ;.Assume V.Clr EQ 0 Push #0 ;Forget whole screen Push #ZapScr ;Clear the screen 10$: ;~x~ ClrBsy ;~x~We are not busy $Print (SP)+ ;~x~print the escape seq to fix screen Bic #InsBit,CurCmd ;Fix so optimization does not work Bic #InsBit,LstCmd ;So screen will be updated RCtrlO ;~x~Reenable output Pop ;Get arg for VWATCH to use Callr VWatch ;~x~The keeper of the screen .............. .Dsabl LSB .SbTtl KbLock - Lock and unlock the keyboard .SbTtl KbUnlk - ;++ ;KBLOCK, KBUNLK ; ;FUNCTIONAL DESCRIPTION: ; ; Lock and unlock the keyboard ; ; If the terminal is a VT100 the editor can turn off the ; keyboard in one of two ways when the editor is busy ; to enhance the synchronization of the editor with the ; keyboard and to prevent file corruption by the loss of ; partial esc sequences. ; The first way is with XON-XOFF to lock the keyboard. ; The second is with esc sequences which turn off auto ; repeat of the keyboard. ;-- ;++ ;KBLOCK ; ;FUNCTIONAL DESCRIPTION: ; ; Lock the keyboard ; ;INPUT: NONE ; ;OUTPUT: ; Keyboard shut off ;-- ;>>>consider using XOFF .Enable LSB KbLock:: ;~x~ .If NE VT10$0 Mov SP,KbLkQ ;Remember we locked keyboard Push ;Save a work register $Print #ARpOff ;~x~No auto repeat Pop ;Restore working reg Return ;~x~ ...... .EndC; NE VT10$0 .Dsabl LSB ;++ ;KBUNLK ; ;FUNCTIONAL DESCRIPTION: ; ; Unlock the keyboard ; ;INPUT: NONE ; ;OUTPUT: ; Keyboard unlocked ;-- .Enable LSB KbUnlk: ;~x~ .If NE VT10$0 Tst KbLkQ ;Did we lock it? Beq 10$ ;~x~ Push ;Working register $Print #ARpOn ;~x~Auto repeat on Clr KbLkQ ;Unlocked now Pop 10$: ;~x~ .EndC; NE VT10$0 Return ;~x~ ...... .Dsabl LSB ; ; Data for keyboard lock routines ; .If NE,VT10$0 ;VT100 Terminal PSect IMPURE KbLkQ: .BlkW 1 ;~d~Nonzero for locked keyboard PSect .TXT. ARpOff: .Byte ,,,, ;~d~Auto repeat off .Byte ;~d~ ARpOn:: .Byte ,,,, ;~d~Auto repeat on .Byte ;~d~ ;>>>why even? .Even PSect KEDCMD .EndC; NE,VT10$0 ;VT100 Terminal .SbTtl .SbTtl Character dispatch lists ; ; Main function list ; ;>>>should this be in a data psect? CLSize = 6 ;length of entry ; Symbols for Mod argument M.Nop = 0 ;Can't identify the command yet M.Mod = 1 ;Command modifys text M.Cur = -1 ;Command implies cursor movement only .Macro ChrLst Char,Rout,Mod .If NB .....1=0 .Irp X, .IIf EQ .....1 .Word X .IIf EQ .....1-1 .=.-1 .IIf EQ .....1-1 .Byte X .IIf GT .....1-1 .Error ;too many chars -- max 2 .....1=.....1+1 .EndR .IfF; NB .Word -1 .EndC; NB .Word Rout .Word Mod .EndM C1Lst: ;~x~ ;Null must be first!! ChrLst C.Entr ,M.Nop ;~x~Null is a 1-char nop for /REC ChrLst , C.RubW ,M.Mod ;~x~Rub a word ChrLst , C.CR ,M.Mod ;~x~Insert CR and following LF ChrLst , EscLst+1,M.Nop ;~x~Escape sequences ChrLst , C.RbCh ,M.Mod ;~x~Delete one left ChrLst <,> C.CtC ,M.Cur ;~x~Trap and signal abort prompt ChrLst , C.RubL ,M.Mod ;~x~Delete one line left ChrLst <,>, SetScr ,M.Mod ;~x~Restore the screen ChrLst , C.Tab ,M.Mod ;~x~Structured tabs ChrLst , C.Inst ,M.Mod ;~x~Insert all other chars G1Lst: ;~x~ ChrLst , C.UnDW ,M.Mod ;~x~Undelete word ChrLst , GlELst+1,M.Nop ;~x~Escape sequences ChrLst , C.UnDC ,M.Mod ;~x~Undelete char ChrLst , C.UnDL ,M.Mod ;~x~Undelete line ChrLst <,> C.CtC ,M.Cur ;~x~Trap and signal abort prompt ChrLst <,>, SetScr ,M.Mod ;~x~Restore the screen ..GldA:: ChrLst <<'A>,<'a>>, TAlgn ,M.Mod ;~x~Align the tab level ..GldD:: ChrLst <<'D>,<'d>>, TLDwn ,M.Mod ;~x~Down the tab level ..GldE:: ChrLst <<'E>,<'e>>, TLUp ,M.Mod ;~x~Up the tab level ..GldL:: ChrLst <<'L>,<'l>>, C.LCas ,M.Mod ;~x~Lower case select area ..GldM:: ChrLst <<'M>,<'m>>, C.ExS ,M.Mod ;~x~Execute a specified macro ..GldS:: ChrLst <<'S>,<'s>>, C.LStop ,M.Mod ;~x~Stop learning a macro ..GldU:: ChrLst <<'U>,<'u>>, C.UCas ,M.Mod ;~x~Upper case select area ..GldX:: ChrLst <<'X>,<'x>>, C.Exec ,M.Mod ;~x~Execute the last macro ChrLst , C.Rep ,M.Nop ;~x~Input repeat sequence from ; digits ; ; Char list for escape sequences ; .If EQ,VT10$0 ;VT52 Terminal EscLst: ;~x~ ChrLst , C.Inst ,M.Mod ;~x~Insert ESC ESC as ESC ChrLst , AltLst+1,M.Nop ;~x~Alt keypad ChrLst , C.Up ,M.Cur ;~x~Uparrow ChrLst , C.Dwn ,M.Cur ;~x~Down arrow- fwd line ChrLst , C.Rht ,M.Cur ;~x~Right- forward ChrLst , C.Lft ,M.Cur ;~x~Left- backward ChrLst , G1Lst+1 ,M.Nop ;~x~Gold meta key ChrLst , C.Help ,M.Mod ;~x~Help ChrLst , C.DelL ,M.Mod ;~x~Delete line right ChrLst , BadEsc ,M.Mod ;~x~Bad sequence GlELst: ;~x~ ChrLst , GldAlt+1,M.Nop ;~x~Alt keypad for gold key ChrLst , C.Rplc ,M.Mod ;~x~Replace ChrLst , C.Para ,M.Mod ;~x~Paragraph move ChrLst , C.Spcl ,M.Mod ;~x~Insert special code ChrLst , C.Apnd ,M.Mod ;~x~Append text ChrLst , G1Lst+1 ,M.Nop ;~x~Gold meta key ChrLst , C.Help ,M.Mod ;~x~Help ChrLst , C.UnDL ,M.Mod ;~x~Undelete line ChrLst , BadEsc ,M.Mod ;~x~Bad Sequence .IfF; NE,VT10$0 ;VT100 Terminal EscLst: ;~x~ ChrLst , C.Inst ,M.Mod ;~x~Insert ESC ESC as ESC ChrLst , AltLst+1,M.Nop ;~x~Keypad keys ChrLst , FunLst+1,M.Nop ;~x~Cursor functions ChrLst , BadEsc ,M.Mod ;~x~Bad Sequence GlELst: ;~x~ ChrLst , GldAlt+1,M.Nop ;~x~Keypad keys ChrLst , GldAro+1,M.Nop ;~x~Cursor functions ChrLst , BadEsc ,M.Mod ;~x~Bad Sequence .EndC; NE,VT10$0 ;VT100 Terminal ; ; Alt keypad list ; AltLst: ;~x~ .If EQ,VT10$0 ;VT52 Terminal ChrLst , C.Line ,M.Cur ;~x~Line move ChrLst , C.Word ,M.Cur ;~x~Word move ChrLst , C.EOL ,M.Cur ;~x~End of line move ChrLst , C.Cut ,M.Mod ;~x~cut into buffer ChrLst , C.Advn ,M.Mod ;~x~Advance mode ChrLst , C.Back ,M.Mod ;~x~Backup mode ChrLst , C.DlCh ,M.Mod ;~x~Delete char right ChrLst , C.Page ,M.Cur ;~x~Page move ChrLst , C.FNxt ,M.Cur ;~x~Find next ChrLst , C.DelW ,M.Mod ;~x~Delete word ChrLst , C.Slct ,M.Mod ;~x~Enable select range ChrLst , C.Entr ,M.Mod ;~x~A nop command .IfF; NE,VT10$0 ;VT100 Terminal ChrLst , C.Line ,M.Cur ;~x~Line move ChrLst , C.Word ,M.Cur ;~x~Word move ChrLst , C.EOL ,M.Cur ;~x~End of line move ChrLst , C.Char ,M.Cur ;~x~Char move ChrLst , C.Advn ,M.Mod ;~x~Advance mode ChrLst , C.Back ,M.Mod ;~x~Backup mode ChrLst , C.Cut ,M.Mod ;~x~Cut select range ChrLst , C.Page ,M.Cur ;~x~Page move ChrLst , C.Para ,M.Cur ;~x~Paragraph move ChrLst , C.Apnd ,M.Mod ;~x~Append select range ChrLst , C.Slct ,M.Mod ;~x~Enable select range ChrLst , C.Entr ,M.Mod ;~x~A nop command ChrLst , G1Lst+1 ,M.Nop ;~x~It's the gold key ChrLst , C.Help ,M.Mod ;~x~The help key on VT100 ChrLst , C.FNxt ,M.Cur ;~x~Search again ChrLst , C.DelL ,M.Mod ;~x~Delete line right ChrLst , C.DlCh ,M.Mod ;~x~Char right ChrLst , C.DeLw ,M.Mod ;~x~Delete a word right FUNLST: ;~x~here to catch cursor ; application mode ChrLst , C.Up ,M.Cur ;~x~ ChrLst , C.Dwn ,M.Cur ;~x~ ChrLst , C.Rht ,M.Cur ;~x~ ChrLst , C.Lft ,M.Cur ;~x~ .EndC; NE,VT10$0 ;VT100 Terminal ChrLst , BadEsc ,M.Mod ;~x~ ; ; Gold alt keypad list ; GldAlt: ;~x~ .If EQ,VT10$0 ;VT52 Terminal ChrLst , C.OpnL ,M.Mod ;~x~Open line ChrLst , C.CCas ,M.Mod ;~x~Change case of select range ChrLst , C.DelN ,M.Mod ;~x~Delete to EOL ChrLst , C.Past ,M.Mod ;~x~Paste the buffer ChrLst , C.Bot ,M.Cur ;~x~Bottom of file ChrLst , C.Top ,M.Cur ;~x~Top of file ChrLst , C.UnDC ,M.Mod ;~x~Undelete char ChrLst , C.Comn ,M.Mod ;~x~Command mode ChrLst , C.Find ,M.Mod ;~x~Find ChrLst , C.UnDW ,M.Mod ;~x~Undelete word ChrLst , C.Rest ,M.Mod ;~x~Reset gold function ChrLst , C.Subs ,M.Mod ;~x~Substitute .IfF; EQ,VT10$0 ;VT100 Terminal ChrLst , C.OpnL ,M.Mod ;~x~Open line ChrLst , C.CCas ,M.Mod ;~x~Change case of select range ChrLst , C.DelN ,M.Mod ;~x~Delete to EOL ChrLst , C.Spcl ,M.Mod ;~x~Insert special code ChrLst , C.Bot ,M.Cur ;~x~Bottom of file ChrLst , C.Top ,M.Cur ;~x~Top of file ChrLst , C.Past ,M.Mod ;~x~Paste buffer insert ChrLst , C.Comn ,M.Mod ;~x~Command mode ChrLst , WFill ,M.Mod ;~x~Word fill ChrLst , C.Rplc ,M.Mod ;~x~replace select range ChrLst , C.Rest ,M.Mod ;~x~Reset gold function ChrLst , C.Subs ,M.Mod ;~x~Substitute ChrLst , G1Lst+1 ,M.Nop ;~x~It's the gold key again ChrLst , C.Help ,M.Mod ;~x~The help key on VT100 ChrLst , C.Find ,M.Mod ;~x~Search enter arg ChrLst , C.UnDL ,M.Mod ;~x~Undelete line ChrLst , C.UnDC ,M.Mod ;~x~Undelete char ChrLst , C.UnDW ,M.Mod ;~x~Undelete word GldAro: ;~x~here to catch application ; arrow keys ChrLst , C.Top ,M.Cur ;~x~ ChrLst , C.Bot ,M.Cur ;~x~ ChrLst , C.UEOL ,M.Cur ;~x~ ChrLst , C.UBOL ,M.Cur ;~x~ .EndC; NE VT10$0 ChrLst , BadEsc ,M.Mod ;~x~ ; ; Terminal control escape sequences ; PSect .TXT. .NLIST BEX .If EQ,VT10$0 ;VT52 Terminal IniTrm: .Byte ;~d~Required for RSX SetTrm: ;~d~ .Byte ,,,, ;~d~Set VT52 mode if VT100 .Byte ,, ;~d~Erase line .Byte , ;~d~If 52 out of hold screen mode .Byte ;~d~ BotScr:: ;~d~ .Byte ,,<37+30>,<37+1> ;~d~ .Byte ,, ;~d~Bot of screen AltOn:: .Byte ,, ;~d~Alt keypad on AltOff::.Byte ,, ;~d~ALT KEYPAD OFF ZapScr: .Byte ,,,, ;~d~Clear whole screen Ers2Ln:: ;~d~Erase two lines at top .Byte ,,, ;~d~ .Byte ,, ;~d~ .Byte ,, ;~d~ Ers3Bt: ;~d~ .Byte ,,<37+22.>,<37+1>,,,, ;~d~ ;Erase three lines at bottom and ; leave cursor on next to last .IfF; EQ,VT10$0 ;VT100 Terminal Set80:: .Byte ,,,, ;~d~Set VT100 to 80 column mode .Byte ;~d~ IniTrm: ;~d~ SetTrm: .Byte , ;~d~Set ANSI if VT52 mode .Byte ,, ;~d~Set G1 as graphics (leave g0 alone) .Byte ;~d~Select G0 character set .Byte , ;~d~Save cursor pos .Byte ,, ;~d~Set scrolling region to whole screen .Byte ,,,, ;~d~Abs origin mode .Byte , ;~d~Restore cursor pos .Byte ,, ;~d~Attrib off .Byte ,,, ;~d~Replace mode ;;; .Byte ,,,, ;~d~Cursor functions .Byte ;~d~ AltOn:: .Byte ,, ;~d~Application mode AltOff::.Byte ,, ;~d~Engraving mode ZapScr: .Byte ,, ;~d~ .Byte ,,, ;~d~Zap the screen ; ; Note the next esc seq does not use direct cursor addressing ; so that it will work on any size screen up to 24 lines ; BotScr:: ;~d~ .Byte ,,'2,'4, ;~d~To bot of screen .Byte ,,,, ;~d~and erase to end of line Ers2Ln:: ;~d~ .Byte ,,,,, ;~d~ .Byte ,,, ;~d~ .Byte ,,, ;~d~Erase two lines at top Ers3Bt:: ;~d~ .Byte ,,'2,'4, ;~d~Erase three lines at bottom and .Byte ,,,'2, ;~d~ .Byte ,, ;~d~ leave cursor on next to last .Byte ;~d~ ; ; We will use shift in and out to switch to graphics mode ; to preserve the setting of the G0 char set for those in ; the United Kingdom who are using the UK set ; GrfOn:: ;~d~ .Byte , ;~d~Shift out for graphics GrfOff:: ;~d~ .Byte , ;~d~Shift in for normal chars EscCsi::.Byte ,, ;~d~Control sequence introducer .EndC; NE,VT10$0 ;VT100 Terminal ;>>>why even? .Even .List BEX PSect KEDCMD .SbTtl CHDSP - Char dispatch routine ;++ ;CHDSP ; ;FUNCTIONAL DESCRIPTION: ; ; Character dispatch ; ; Dispatch to routine or list from a character in R0 and ; a character address pair list ; ; LIST FORMAT: ; ; Adr: .Word Chr,Adr,Mod ; .Word <<400*Chr>+Chr>,Adr,Mod ;if 2 chars go the same place ; .Word ... ; .Word -1,ErrAdr,Mod ; ; Chr = character ; Adr = routine address or ; Adr = list address + 1 ; Mod = -1 if routine moves cursor & takes no other action ; = 0 if routine is not yet determined ; = +1 if routine causes any action besides cursor movement ; ; ;INPUT: ; R0 = char to match ; R1 = char list adr ; ;OUTPUT: ; Routine address called via PC or ; next list used and char read via TTYIN ;-- .Enable LSB ChDsp: Mov R1,-(SP) ;~x~Save R1 across us Mov R2,-(SP) ; and R2 too! 10$: Cmp #-1,@R1 ;~x~End of list Beq 20$ ;~x~Yes- use next address CmpB R0,@R1 ;Check for match Beq 20$ ;~x~Yes - use matching address CmpB R0,1(R1) ;test second char Beq 20$ ;~x~it matched Add #CLSize,R1 ;Skip to next entry Br 10$ ;~x~And keep looking .......... 20$: Mov 4(R1),R2 ;~x~R2=modification info Mov 2(R1),R1 ;Get matching adr Bit #1,R1 ;List?? Bne 70$ ;~x~Yes - use it again Tst R2 ;Is this a modifying command? Beq 60$ ;~x~ No Bgt 30$ ;~x~ Yup, modifys text Call @R1 ;~x~ Yup, but only modifies cursor positn ;Call routine via R1 Ror -(SP) ;Save carry Call $JoExcl ;~x~Don't include in journal Br 40$ ;~x~ ............ 30$: Call @R1 ;~x~Call routine via R1 Bit #100000,CtrlC ;*C* Ctrl/C typed? ;**TRICK** Do not change carry ;with previous instr or this will ;not work Bmi 50$ ;~x~*C* Nope Ror -(SP) ;Save carry Call RecPos ;~x~Record position include the command ; in journal 40$: Rol (SP)+ ;~x~Restore carry 50$: Mov (SP)+,R2 ;~x~*C* R2 original will be restored Mov (SP)+,R1 ;*C* R1 original will be restored Return ;~x~ ...... 60$: Mov (SP)+,R2 ;~x~R2 original will be restored Rts R1 ;~x~Call routine via R1 .......... ;R1 original will be restored 70$: Dec R1 ;~x~Get rid of extra bit TtInR ;~x~See if a character is waiting Bcc 90$ ;~x~Yes - we have it ;;;WARNING BUSYF is used for 2 purposes in following code ;;;be careful if you modify this code (or the SET/CLRBSY macros) ClrBsy ;~x~Editor is not busy now TTyIn ;~x~Read next character 80$: SetBsy ;~x~We are now busy Br 10$ ;~x~Go to look in next list .......... 90$: Tst BusyF ;~x~Are we set busy?? Bne 10$ ;~x~Yes, we have the char, dispatch Br 80$ ;~x~Set busy and dispatch .......... .Dsabl LSB .SbTtl BELERR - Signal error message ;++ ;BELERR ; ;FUNCTIONAL DESCRIPTION: ; ; Signal bell if carry set ;-- ;+ ;ERROR ;Of interest to writers: on any bell error, the input character buffer ;is flushed to prevent further actions which may be typed ahead. ;- .Enable LSB BelErr: Bcc 30$ ;~x~No bell BelRng:: ;~x~ Push ;Save R0 RCtrlO ;~x~Reset CtrlO .If NE,VT10$0 Tst QuietQ ;Quiet mode? Beq 10$ ;~x~Nope $Print @QutPtr ;~x~ Mov SP,QutFlg ;Say it is on Br 20$ ;~x~ ........... .EndC; NE,VT10$0 10$: TtyOut # ;~x~ 20$: ;~x~ Pop ;Restore R0 30$: Return ;~x~ ...... .Dsabl LSB .If NE,VT10$0 .SbTtl RSTQUT - Restore screen for quiet mode ;++ ;RSTQUT ; ;FUNCTIONAL DESCRIPTION: ; ; This routine restores the screen to the proper video ; if quiet mode is active and an error has been signalled. ; ;OUTPUT: ; ; All registers preserved. ;-- .Enable LSB RstQut:: ;~x~ Tst QutFlg ;Are we quiet? Beq 10$ ;~x~Nope Push ;Save char for dispatch Mov QutPtr,R0 ;Pointer to esc seq list Tst (R0)+ ;Advance to turn it off $Print @R0 ;~x~ Clr QutFlg ;Not again Pop ;Restore 10$: Return ;~x~ ...... .Dsabl LSB .EndC; NE,VT10$0 ;VT100 Terminal .SbTtl Data for quiet mode processing .If NE,VT10$0 PSect IMPURE QuietQ:: ;~d~ .BlkW 1 ;~d~Nonzero for quiet mode QutFlg: ;~d~ .BlkW 1 ;~d~Nonzero for screen quiet QutPtr:: ;~d~ .BlkW 1 ;~d~Pointer to list table PSect KEDCMD QutDrk:: ;~d~ .Word SetLit ;~d~Turn it on for dark screen QutLit:: ;~d~ .Word SetDrk ;~d~Turn it on for light screen .Word SetLit ;~d~Off for light screen .EndC; NE,VT10$0 ;VT100 Terminal .SbTtl C.REP - Setup a repeat count ;++ ;C.REP ; ;FUNCTIONAL DESCRIPTION: ; ; Setup a repeat count ; ; A repeat count for a command is gold followed by a string of ; digits. These digits are the number of times to repeat the ; command (decimal of course). ; ;INPUT: ; R0 = first digit ; ;OUTPUT: ; RepCtr = repeat count ;-- .Enable LSB C.Rep: Mov LnPtr,RepPtr ;~x~Save TtPtr for learn info Call DgtQ ;~x~A digit?? Bne 30$ ;~x~No error ClrBsy ;~x~We are not busy now Mov SP,PrNum ;Set for numeric only Mov #RepStr,R1 ;Setup repeat string Jsr R4,Prmpt ;~x~Prompt routine .Word RepPrm ;Prompt string Bcs 30$ ;~x~No good Push ;Save term character Mov -2(R1),R4 ;Get end of string Clr R3 ;Zap repeat count 10$: Cmp R1,R4 ;~x~Check end Bhis 20$ ;~x~Done MovB (R1)+,R0 ;Get a char Mov R3,R2 ;X 10 Asl R3 ;X 2 Asl R3 ;X 4 Add R2,R3 ;+ 1 = 5 Asl R3 ;X 2 = 10 Bic #^C17,R0 ;Clean up Add R0,R3 Br 10$ ;~x~Again .......... 20$: Pop ;~x~Restore term char Mov R3,RepCtr ;Save the count SetBsy ;~x~We are likely to be busy now CallR CmdGo1 ;~x~Dispatch to command .............. ;Avoid making stack deeper in case ;idiot user types digits so ;many times that the stack blows 30$: Jmp BadEsc ;~x~Go signal a bad esc sequence .............. .Dsabl LSB ; ; Data for repeat of commands ; PSect IMPURE RepPtr: .BlkW 1 ;~d~Pointer into macro buffer so ; that C.LSto can know enough not ; to include the repeat ; keystrokes in the macro buffer RepCtr:: ;~d~ .BlkW 1 ;~d~Repeat counter ; ; Prompt string for repeat prompt ; RepStr: .BlkW 1 ;~d~End address .BlkB PrmSiz ;~d~Size of the prompt string PSect .TXT. RepPrm: .Ascii "Repeat: " ;~d~ .Byte ;~d~ PSect KEDCMD .SbTtl CMDREP - Repeat macro routine ;++ ;CMDREP -- Macro repeat with keyboard lock ;QUKREP -- Macro repeat and no keyboard lock ; ;FUNCTIONAL DESCRIPTION: ; ; CMDREP is called by the macro 'REPEAT' ; This macro is used at the beginning of every command ; that can use the repeat function. No other interface is ; necessary. ; The macro calls the CMDREP routine which calls the ; command routine following the repeat the required ; number of times. ; ;INPUT: ; RepCtr = repeat count ; ;OUTPUT: ; ;-- .Enable LSB CmdRep:: ;~x~ KbLock ;Lock the keyboard QukRep: ;~x~ Tst RepCtr ;Repeat this command?? Ble 30$ ;~x~Nope 10$: Push <@SP> ;~x~Manufacture address Call @(SP)+ ;~x~Call and return here Bcs 20$ ;~x~Error - done Dec RepCtr Ble 20$ ;~x~All done Mov CurCmd,LstCmd ;Swap around command flags Clr CurCmD ;No bits for current command Br 10$ ;~x~Do it again .......... 20$: Pop <>,SAVE=*C* ;~x~*C* dump return- retain C for error 30$: Mov #0,RepCtr ;~x~*C* No more- retain C for error Return ;~x~ ...... .Dsabl LSB .SbTtl DGTQ - Compare R0 for digit ;++ ;DGTQ ; ;FUNCTIONAL DESCRIPTION: ; ; Compare character for 0 - 9 ; ;INPUT: ; R0 = character ; ;OUTPUT: ; Z set if so ; C always clear ;-- .Enable LSB DgtQ:: ;~x~ Cmp R0,#C.Zero Blo 10$ ;~x~Nope Cmp #C.Nine,R0 Blo 10$ ;~x~Nope Sez Return ;~x~ ...... 10$: .Word Clz!Clc ;~x~Nope Return ;~x~ ...... .Dsabl LSB .SbTtl CRTERM - Compare R0 for CR or line term .SbTtl LTERM - Compare R0 for line term ;++ ;CRTERM ; ;FUNCTIONAL DESCRIPTION: ; ; Compare character for CR or line term ; ;INPUT: ; R0 = character ; ;OUTPUT: ; Z set if CR or LF,VT,FF ;-- ;++ ;LTERM ; ;FUNCTIONAL DESCRIPTION: ; ; Compare character for line terminator ; ;INPUT: ; R0 = character ; ;OUTPUT: ; Z set if LF,VT,FF ; C always clear ;-- .Enable LSB CrTerm: ;~x~ Cmp R0,# ;Check for CR special Beq 20$ ;~x~Ok - return so LTerm:: ;~x~ Cmp #-1,R0 ;Check for in range Bhis 10$ ;~x~Outside below Cmp R0,#+1 ;Check high side Bhis 10$ ;~x~Nope Clc ;Return no error Sez ;A line term is here Return ;~x~ ...... 10$: Clz ;~x~Not a l term 20$: Return ;~x~ ...... .Dsabl LSB .SbTtl .SbTtl Editor function routines .SbTtl ; ; FUNCTION ROUTINES ; ; Routine names are of the form: ; C.XXX ; Where XXX is related to the function ; .SbTtl C.ADVN - Set advance mode ; ; Set advance mode ; .Enable LSB C.Advn: Clr Advanc ;~x~Forward Return ;~x~ ...... .SbTtl C.BACK - Set backup mode ; ; Set backup mode ; C.Back: Mov #1,Advanc ;~x~Backward Clc ;No error Return ;~x~ ...... ; ; Advance or backup mode flag word ; PSect IMPURE Advanc:: ;~d~ .BlkW 1 ;~d~Zero for forward PSect KEDCMD .SbTtl C.REST - Reset gold key and select mode ; ; C.REST -- to reset gold we need only return since ; we need to do nothing, CANSLC cancels select mode ; C.Rest: Call CanSlc ;~x~Cancel select mode Return ;~x~ ...... .Dsabl LSB .SbTtl C.ENTR,C.NCMD - Nop commands ; ; C.ENTR,C.NCMD -- NOP COMMANDS ; ; A NOP command is desirable to return from help gracefully ; since the next command struck after help is executed normally ; there should be a way to do nothing. ; ; Also, to allow command lines that are only comments (in the init file ; for instance) we won't call no command an invalid command. It's just ; a NOP .Enabl LSB C.NCmd::NoEChk ;~x~Don't let ENDCHK check for end of TstB @R1 ; command because if it fails, it will Beq C.Entr ;~x~ give "to many arguments" instead of CmpB (R1)+,#'@ ;Is this an @file request? Bne C.Err1 ;~x~Nope, "Invalid command" Jmp C.At ;~x~Yup, go do it ............ C.Entr: ;~x~ Clc.4: Clc ;~x~ Return ;~x~ ...... .Dsabl LSB ; ; Command error entry ; .Enable LSB C.Err:: NoEChk ;~x~Do not check for end of command C.Err1:: ;~x~Entry for further decode errors ;+ ;HELPER HELPER ;~x~ ;signal illegal command syntax ;- .Dsabl LSB .SbTtl C.INST - Insert a character ; ; Insert a character ; .Enable LSB C.Inst: Tst Inspct ;~x~Are we only inspecting the file? Bne 60$ ;~x~Yes- don't allow inserts give ;a helpful message ClrBsy ;~x~We are not really busy now QukRep ;~x~Repeat quickly 10$: ;~x~ Call WWrap ;~x~Do word wrap Bcs 50$ ;~x~Error Tst WrapQ ;Wrap on?? Beq 20$ ;~x~Nope Bit #WrpBit,CurCmd ;Wrapped?? Beq Clc.4 ;~x~We did something 20$: ;~x~ ; ; Optimise screen output for most common case ; CmpB R0,# ;Printable character Blo Clc.4 ;~x~Nope Bit #InsBit,LstCmd ;Still a run of inserts?? Beq Clc.4 ;~x~Nope Tst SlctQ ;In select range?? Bne Clc.4 ;~x~Yes - forget it Cmp InsFCP,FCP ;Text moved?? Bne Clc.4 ;~x~Yes - forget it Cmp FCP,PlyEnd ;End of playground? Bhis 30$ ;~x~If yes, try to optimize CmpB @FCP,# ;End of a line?? Bne Clc.4 ;~x~NOPE - FORGET IT 30$: Cmp CurChr,H.SzM2 ;~x~Still on the line Bhis Clc.4 ;~x~Nope may wrap now MovB R0,@CurAbs ;Save the char in the map Inc CurAbs ;Index into map Inc CurChr ;Next column Inc PreCol ;Next column rememberence TtyOut ;~x~Print the character Bis #InsBit,CurCmd ;Set the insert bit for a run Br Clc.4 ;~x~no error ............. PSect .TXT. EOF: ;~d~ .If NE,VT10$0 ;If VT100 .Byte ;~d~Graphics on .Byte ;~d~EOF indicator .Byte ;~d~Graphics off .Byte , ;~d~Move cursor back .IfF ;If VT52 .Byte , ;~d~Graphics on .Byte ;~d~EOF indicator .Byte , ;~d~Graphics off .Byte , ;~d~Move cursor back .EndC ;NE,VT10$0 PSect KEDCMD .SbTtl C.SPCL - Insert a special character ; ; Insert a special character ; ; Character code is the repeat count ; C.Spcl: Tst Inspct ;~x~Inspect mode? Bne 60$ ;~x~Yep Mov RepCtr,R0 ;Get the char code ;>>> change for 8bit support Bic #^C177,R0 ;Clear the crap Bne 10$ ;~x~Go insert it 40$: ;~x~ ;+ ;HELPER HELPER ;~x~ ; ;The user attempted to insert a null in the file using the special ;insert feature. Nulls are illegal input. ;- 50$: ;~x~ ;+ ;HELPER HELPER ;~x~ ;No room is available in the file for the character to ;be inserted. ;- .SbTtl C.CR - Insert CR and following LF ; ; Insert a carriage return and the following line feed ; C.CR: ;~x~ Tst Inspct ;Inspect mode? Bne 60$ ;~x~Illegal ClrBsy ;~x~We are not busy now QukRep ;~x~Repeat quickly Call InsNL ;~x~Insert a newline into file Bcs 50$ ;~x~Error report Return ;~x~ ...... NoInsp:: ;~x~ 60$: ;~x~ ;+ ;HELPER HELPER ;~x~ ; ; Modifying the file during /Inspect is not allowed ;- .Dsabl LSB .SbTtl WWRAP - Do word wrap ;++ ;WWRAP ; ;FUNCTIONAL DESCRIPTION: ; ; Do word wrap during entry ; ;INPUT: ; R0 = char ; ;OUTPUT: ; C set on error ;-- .Enable LSB WWrap: ;~x~ Call Insrt ;~x~Insert character Bcs 40$ ;~x~Return error Tst WrapQ ;Wrapping? Beq 40$ ;~x~Nope - carry on Push ;Save the char from harm Cmp #,R0 ;Special char? Bhi 30$ ;~x~Yes- just insert it Inc WrpCol ;We assume one more column Bit #WrpBit,LstCmd ;Have we just been here Bne 10$ ;~x~Yes- count ok Call Count ;~x~Where are we Mov R2,WrpCoL ;Save it 10$: Cmp WrapC,WrpCol ;~x~Too long a line yet?? Bhis 20$ ;~x~Nope Call WrapIt ;~x~Wrap the line Clc ;No error Br 30$ ;~x~ ........... 20$: Bis #WrpBit,CurCmd ;~x~Say we have just been here 30$: Pop ;~x~Restore char 40$: Return ;~x~Exit in case of error too ...... .Dsabl LSB .SbTtl WRAPIT - Wrap a line of text ;++ ;WRAPIT ; ;FUNCTIONAL DESCRIPTION: ; ; Wrap a line of text ; ;INPUT: NONE ; ;OUTPUT: ; Current line wrapped ; C set if error ; R1 not zero if word was wrapped ; R2 used and not restored ;-- .Enable LSB WrapIt:: ;~x~ Clr Un$Blk ;Turn off undeletes Mov BCP,R2 ;Look back for a space Mov R2,R1 ;Set for a word wrapped Inc R2 ;Look at last char too 10$: CmpB #,-(R2) ;~x~Til we find it Blo 10$ ;~x~Or a special char Bne 70$ ;~x~If not a space no wrap Neg R2 ;Make number of chars Add BCP,R2 ;To move back Beq 30$ ;~x~ Cmp R2,WrapC ;Too long a word? Bhi 70$ ;~x~Yes - do not wrap it Mov R2,R1 ;Save the count 20$: Call MvBkW ;~x~Back over word Bcs 70$ ;~x~Error Sob R1,20$ ;~x~Til at space 30$: Call RbChr ;~x~Delete spaces at end of new line Bcs 70$ ;~x~Error CmpB R0,# ;To get all trailing spaces Beq 30$ ;~x~ Call InsNL ;~x~Insert a new line Bcs 70$ ;~x~Error Mov R2,R1 ;Chars to walk past Beq 70$ ;~x~Done 40$: CmpB @FCP,# ;~x~Delete leading spaces Bne 50$ ;~x~Done Call DlChr ;~x~Delete one Sob R2,40$ ;~x~Til 50$: Tst R2 ;~x~Done? Beq 70$ ;~x~Done 60$: Call MvFwd ;~x~Forward to end Bcs 70$ ;~x~Error Sob R2,60$ ;~x~Of line 70$: Return ;~x~ ...... .Dsabl LSB ; ; Wrap data ; PSect IMPURE WrapQ:: ;~d~ .BlkW 1 ;~d~Nonzero for wrap mode WrapC:: ;~d~ .BlkW 1 ;~d~The right column for wrap + 1 WrpCol: .BlkW 1 ;~d~Column for wrap PSect KEDCMD .SbTtl INSNL - Insert a newline into the file ;++ ;INSNL ; ;FUNCTIONAL DESCRIPTION: ; ; Insert a newline ; ;INPUT: NONE ; ;OUTPUT: ; CRLF in file ; C set if error ;-- .Enable LSB InsNL:: ;~x~ Mov #,R0 ;Insert new line Call Insrt ;~x~ Bcs 10$ ;~x~Error Mov #,R0 Call Insrt ;~x~ 10$: Return ;~x~ ...... .Dsabl LSB .SbTtl Undelete data structures ;++ ; Undelete data structures ; ;There are three facets to the undelete process: ; ; Setting up to capture the deleted characters ; Capture of the deleted characters ; Insertion of the captured characters back into the file ; ;To overlap code as much as possible all undelete buffers are ;of identical format. They are in the impure area. ;-- ; ; Offsets into an undelete block ; Un$Act =: 0 ;Active if nonzero, 1 forward, ;-1 backward Un$Siz =: 2 ;Bytes in buffer Un$End =: 4 ;Adr of end of buffer Un$Str =: 6 ;Adr of start of buffer Un$Ptr =: 10 ;Pointer to next good char of buffer Un$Buf =: 12 ;Offset to start of buffer ; ; NOTE: These sizes have to be one byte short since we will save ;one byte more later ; U$CSiz =: 2 ;Size of char buffer ;(2 to allow for NL) U$WSiz =: 79. ;Allow a long word (ridiculous) U$LSiz =: 131. ;Allow a long line (very long) PSect IMPURE Un$Blk:: ;~d~ .BlkW 1 ;~d~Last block in use U$CBlk: .BlkB Un$Buf ;~d~Control info -- char block .BlkB U$CSiz ;~d~Character block .BlkB 1 ;~d~Overflow char .Even U$WBlk: .BlkB Un$Buf ;~d~Control info -- word block .BlkB U$WSiz ;~d~Word block .BlkB 1 ;~d~Overflow char .Even U$LBlk: .BlkB Un$Buf ;~d~Control info -- line block .BlkB U$LSiz ;~d~Line block .BlkB 1 ;~d~Overflow char .Even PSect KEDCMD .SbTtl UNSET - Setup undelete buffer ;++ ;UNSET ; ;FUNCTIONAL DESCRIPTION: ; ; Setup undelete buffer ; ;Initialize undelete buffer control areas. Must be called ;each time impure area is reallocated. ; ;INPUT: NONE ; ;OUTPUT: ; Undelete blocks setup ; R1-R3 used ;-- .Enable LSB UnSet: Clr Un$Blk ;~x~No buffer defined Mov #U$CBlk,R2 ;Offset to block Mov #U$CSiz,R1 ;Size of data area Call 10$ ;~x~Set up the block Mov #U$WBlk,R2 ;Offset to word block Mov #U$WSiz,R1 ;Size of block Call 10$ ;~x~Setup the block Mov #U$LBlk,R2 ;Offset to line block Mov #U$LSiz,R1 ;Size of block 10$: Mov R2,R3 ;~x~Save start of block for later Add #Un$Buf,R3 ;Offset to buffer to make ;abs adr of buffer Clr (R2)+ ;Active word Mov R1,(R2)+ ;Size word Mov R1,@R2 ;End address Add R3,(R2)+ ;Address of end of buffer Mov R3,(R2)+ ;Address of start Mov -2(R2),(R2)+ ;Pointer setup Return ;~x~ ...... .Dsabl LSB .SbTtl UNDOIT - Setup for undelete ;++ ;UNDOIT ; ;FUNCTIONAL DESCRIPTION: ; ; Great with burgers and fries ; ;Setup to capture deleted data ; ; Coke Typ,Dir ; ; Typ = C,W,L Dir = F,B ; ;Translates to ; ;INPUT: ; R1 = Offset to undelete block ; R2 = Direction of delete -1 or 1 ; ;OUTPUT: ; Block setup to capture data ;-- .Enable LSB UnDoWF: Mov #U$WBlk,R1 ;~x~Word forward Br 20$ ;~x~ ........... UnDoWB: Mov #U$WBlk,R1 ;~x~Word backward Br 10$ ;~x~ ........... UnDoLF: Mov #U$LBlk,R1 ;~x~Line forward Br 20$ ;~x~ ........... UnDoLB: Mov #U$LBlk,R1 ;~x~Line backward Br 10$ ;~x~ ........... UnDoCF: Mov #U$CBlk,R1 ;~x~Char forward Br 20$ ;~x~ ........... UnDoCB: Mov #U$CBlk,R1 ;~x~Char backward 10$: Mov #-1,R2 ;~x~Backward Br 30$ ;~x~ ........... 20$: Mov #1,R2 ;~x~ 30$: Tst Inspct ;~x~Not allowed in inspect mode Bne 40$ ;~x~Nope Mov R2,@R1 ;Save active word Mov Un$Str(R1),Un$Ptr(R1) ;Init start address Mov R1,Un$Blk ;Active block Return ;~x~ ...... 40$: Pop <> ;~x~So we go to caller's caller's caller Jmp NoInsp ;~x~then tell operation is invalid .............. .Dsabl LSB .SbTtl UNSTUF - Capture deleted data ;++ ;UNSTUF ; ;FUNCTIONAL DESCRIPTION: ; ; Capture deleted data ; ;Called from the two lowest level routines of the scroller ;to delete characters. The deleted character is added to ;the undelete buffer. ; ;INPUT: ; Deleted char in RBCR ; ;OUTPUT: ; Char saved in current undel buffer ;-- .Enable LSB UnStuf:: ;~x~ Push ;Save working reg Clc ;Return no error Mov Un$Blk,R1 ;Current buffer Beq 40$ ;~x~No buffer defined for capture, ;ok none needed Tst Un$Act(R1) ;Which way Beq 50$ ;~x~NO SUCH THING Cmp Un$Ptr(R1),Un$End(R1) ;Buffer full Blo 20$ ;~x~Ok Bhi 40$ ;~x~In case called too many times- ;ignore Cmp RepCtr,#1 ;Last rep? Ble 10$ ;~x~Yes, so we should signal a message Clc ;Report no errors if not last rep Br 40$ ;~x~Leave quietly ........... 10$: Call 70$ ;~x~Issue a message Br 30$ ;~x~And save char so not lost ........... 20$: Clc ;~x~Return no error normally 30$: MovB RbCr,@Un$Ptr(R1) ;~x~*C* save char Inc Un$Ptr(R1) ;*C* next byte 40$: Pop ,SAVE=*C* ;~x~*C* restore R1 Return ;~x~ ...... ; ; Signal errors in delete process ; 50$: Call 60$ ;~x~ Br 40$ ;~x~Return and restore ........... 60$: ;~x~ ;+ ;HELPER HELPER ;~x~ ;a logic error prevented the undelete buffer from being setup ;should not occur ;- 70$: ;~x~ ;+ ;HELPER HELPER ;~x~ ;Undelete buffer filled on last rep or on only rep ;- .Dsabl LSB .SbTtl C.UNDC - Undelete command routines .SbTtl C.UNDW - .SbTtl C.UNDL - ;++ ;C.UNDW C.UNDC C.UNDL ; ;FUNCTIONAL DESCRIPTION: ; ; Undelete command routines ; ;Insert the undelete buffer into the file if there is room ; ;INPUT: NONE ; ;OUTPUT: ; Appropriate undelete buffer inserted into file ;-- .Enable LSB C.UndC: Mov #U$CBlk,R1 ;~x~Char block Br UnCola ;~x~ .............. C.UndW: Mov #U$WBlk,R1 ;~x~Word block Br UnCola ;~x~ .............. C.UndL: Mov #U$LBlk,R1 ;~x~Line block UnCola: ;~x~ $7Up: ;~x~ Tst Inspct ;Trap inspect mode Bne 90$ ;~x~Not allowed here Tst @R1 ;Active?? Beq 60$ ;~x~Nope Repeat ;~x~Allow multiple times ;note that R1 must not be changed Tst ChrCtr+2 ;Enough room Bne 10$ ;~x~Plenty Mov Un$Ptr(R1),R2 ;Make space needed Sub Un$Str(R1),R2 ;As difference Cmp ChrCtr,R2 ;Enough? Blo 80$ ;~x~Nope 10$: Mov Un$Str(R1),R2 ;~x~Start Mov Un$Ptr(R1),R3 ;End Cmp R2,R3 ;Anything deleted? Beq 60$ ;~x~Nope- stop here Tst @R1 ;Which way? Bmi 40$ ;~x~Backward Mov R3,R4 ;Make count to put us straight Sub R2,R4 ;As length of insert 20$: MovB (R2)+,R0 ;~x~Get char Call Insrt ;~x~Insert the chars Bcs 70$ ;~x~Woops?? Cmp R2,R3 ;End? Blo 20$ ;~x~Nope 30$: Call MvBkw ;~x~Move backward ; Bcs - ;do not catch error since it ;doesn't matter Sob R4,30$ ;~x~Til all chars inserted Br 50$ ;~x~All done ........... 40$: MovB -(R3),R0 ;~x~Get a char Call Insrt ;~x~Stick it Bcs 70$ ;~x~Woops?? Cmp R3,R2 ;End? Bhi 40$ ;~x~Nope 50$: Clc ;~x~End with no error Return ;~x~ ...... ; ; Errors in undelete ; 60$: ;~x~ ;+ ;HELPER HELPER ;~x~ ;undelete buffer is empty. Nothing has been deleted since KED was started ;or the last delete failed. ;- 70$: ;~x~ ;+ ;HELPER HELPER ;~x~ ;A logic error occurred ;- 80$: ;~x~ ;+ ;HELPER HELPER ;~x~ ;insufficient space remains in file for undelete to occur ;- 90$: ;~x~ Jmp NoInsp ;~x~then tell operation is invalid .............. .Dsabl LSB .SbTtl C.WORD - Word moves ;++ ; What is a word ;Words are of the following forms: ; ; /CS/C ; /CS/T ; /C/T ; /T/T ; /T/C ; /T/S ; T/S/C ; T/S/T ; ;Where: ; // are used to illustrate where a word is ; S is a string of spaces ; T is a line terminator or tab (NL,CR,LF,FF,VT,TB) ; C is a string of any other characters ;-- .Enabl LSB C.Word: Tst Advanc ;~x~Which way Bne C.BWrd ;~x~Backword .Br C.FWrd ;Forword .SbTtl C.FWRD - Forward by a word ; ; Move forward by one word ; C.FWrd: Repeat ;~x~How many times Call WrdFwd ;~x~Forward setup 10$: Call MovFwd ;~x~Advance char ; Bcs - ;Pass error back Call @(SP)+ ;~x~Coroutine entry Br 10$ ;~x~Loop back .......... .Dsabl LSB .SbTtl C.BWRD - Backward a word ; ; Move backward by one word ; .Enabl LSB C.BWrd: Repeat ;~x~How many times Call WrdBkw ;~x~Setup backward coroutine 10$: Call MovBkw ;~x~Backup char ; Bcs - ;Pass error back Call @(SP)+ ;~x~Coroutine reentry Br 10$ ;~x~Loop back for rest of word .......... .Dsabl LSB .SbTtl C.DELW - Delete a word ; ; C.DELW -- Delete to beginning of next word ; .Enabl LSB C.DelW: Repeat ;~x~How many times UnDoIt W,F ;~x~Word forward Call WrdFwd ;~x~Setup coroutine 10$: Call DelChR ;~x~Delete a char Bcs 20$ ;~x~Error- no more MovB @FCP,R0 ;Get the char for word to look at 20$: Call @(SP)+ ;~x~Reenter coroutine Br 10$ ;~x~And back for more .......... .Dsabl LSB .SbTtl C.RUBW - Rub a word ; ; C.RUBW -- delete to beginning of this word ; .Enabl LSB C.RubW: Repeat ;~x~How many times UnDoIt W,B ;~x~Word backward Call WrdBkw ;~x~Setup coroutine 10$: Call RubChr ;~x~Delete a char ; Bcs - ;Pass error on Call @(SP)+ ;~x~Recall coroutine Br 10$ ;~x~And back for more .......... .Dsabl LSB .SbTtl WRDFWD - Word forward coroutine ;++ ;WRDFWD ; ;FUNCTIONAL DESCRIPTION: ; ; Word forward coroutine ; ;This coroutine contains the smarts to find the end of a word ;in the forward direction. It is used by moves and deletes. ; ; CALL: Call WrdFwd ; 10$: Move or delete char ; C=1 if end of file ; R0=@FCP char ; Call @(SP)+ to reenter routine ; Br 10$ ; ;Return is made from wrdfwd if error is encountered or end of word ;is reached. The cursor will be on the first char of the next word. ;-- .Enable LSB WrdFwd: MovB @FCP,R0 ;~x~Set up char Call WrdChr ;~x~What is the class? Bcs 30$ ;~x~Term Beq 20$ ;~x~Separator 10$: Call @(SP)+ ;~x~Recall to dump normal char Bcs 40$ ;~x~Error in dump Call WrdChr ;~x~Type of char Bcs PopC.3 ;~x~Term Bne 10$ ;~x~Normal ;Separator 20$: Call @(SP)+ ;~x~Recall for sep Bcs 40$ ;~x~Error Call WrdChr ;~x~Type? Beq 20$ ;~x~Separator Br PopC.3 ;~x~no error ............. 30$: Call @(SP)+ ;~x~Call to skip terminator Bcc Pop.1 ;~x~Ok no error 40$: Pop <> ;~x~Dump return ;+ ;HELPER HELPER ;~x~ ;End of file was struck when moving forward a word or ;deleting forward a word. ;- .Dsabl LSB .SbTtl WRDBKW - Word backward coroutine ;++ ;WRDBKW ; ;FUNCTIONAL DESCRIPTION: ; ; Word backward coroutine ; ;This coroutine contains the smarts to find the end of a word ;in the backward direction. It is used by moves and deletes. ; ; CALL: Call WrdBkw ; 1$: move or delete char ; C=1 if end of file ; R0=@BCP char ; Call @(SP)+ to reenter routine ; Br 1$ ; ;Return is made from wrdbkw if error is encountered or end of word ;is reached. The cursor will be on the first char of the next word. ;-- .Enable LSB WrdBkw: MovB @BCP,R0 ;~x~Char behind us Call WrdChr ;~x~What kind is it? Bcs 30$ ;~x~Term Beq 20$ ;~x~Sep 10$: Call @(SP)+ ;~x~Recall mover Bcs 40$ ;~x~Error Call WrdChr ;~x~Type? Bcs PopC.3 ;~x~Term Beq PopC.3 ;~x~Sep Br 10$ ;~x~Step past normal char .......... 20$: Call @(SP)+ ;~x~Recall mover Bcs 40$ ;~x~End of file Call WrdChr ;~x~What is the type of ye? Bcs PopC.3 ;~x~Term- fine we are done Beq 20$ ;~x~Sep keep going Br 10$ ;~x~Normal- skip them .......... 30$: Call @(SP)+ ;~x~Recall mover Bcs 40$ ;~x~Error PopC.3: Clc ;~x~No error return Pop.1: Pop <>,SAVE=*C* ;~x~Dump return- save carry Return ;~x~ ...... 40$: Pop <> ;~x~Dump return ;+ ;HELPER HELPER ;~x~ ;move or delete backward by word strikes EOF ;- .Dsabl LSB .SbTtl WRDCHR - Determine type of char for word ;++ ;WRDCHR ; ;FUNCTIONAL DESCRIPTION: ; ; Determine type of char for word check ; ;INPUT: ; R0 = char ;OUTPUT: ; C set if terminator TB-CR (11-15) ; Z set if space ; C,Z clear else ;-- .Enable LSB WrdChr: Cmp #-1,R0 ;~x~Low of TB to CR range Bhis 10$ ;~x~Too low Cmp R0,#+1 ;~x~Too high? Bhis 20$ ;~x~Yes 10$: Clz ;~x~No good Return ;~x~ ...... 20$: CmpB R0,# ;~x~Check for space too Clc ;Not term Ret.1: Return ;~x~ ...... .Dsabl LSB .SbTtl C.LINE - Line moves ; ; C.LINE - line moves ; .Enable LSB C.Line: Tst Advanc ;~x~Which way to go Bne C.BLn ;~x~Backward .Br C.FLn ;Forward .SbTtl C.FLN - Forward line ; ; C.FLN - forward one line ; C.FLn: Repeat ;~x~ Call MovFL ;~x~Scroller routine Bcc Ret.1 ;~x~No error ;+ ;HELPER HELPER ;~x~ ;Move forward line strikes EOF (end of file) ;- .Dsabl LSB .SbTtl C.BLN - Backward one line ; ; C.BLN - backward one line ; .Enable LSB C.UBOL: ;~x~move to beginning of line <<-> C.BLn: Repeat ;~x~ Call MovBL ;~x~Back to beginning ; ;Or to previous line Bcc Ret.1 ;~x~No error ;+ ;HELPER HELPER ;~x~ ;Backward one line strikes BOF ;(beginning of file) ;- .Dsabl LSB .SbTtl C.EOL - Go to end of line before term ; ; C.EOL - goto end of line before line terminator ; .Enable LSB C.EOL: Tst Advanc ;~x~Which way to go Bne 30$ ;~x~Backward C.UEOL: ;~x~move to end of line <->> 10$: Repeat ;~x~How many 20$: Call MovFwd ;~x~Move forward one logical char Bcs 50$ ;~x~End of file Call CRTerm ;~x~End of a line?? Bne 20$ ;~x~Nope Return ;~x~Yes ...... 30$: Repeat ;~x~ 40$: Call MovBkw ;~x~Backward move on logical char Bcs 60$ ;~x~Beginning of file MovB @FCP,R0 ;Forward char to check Call CRTerm ;~x~End of a line? Bne 40$ ;~x~Nope Return ;~x~ ...... 50$: ;~x~ ;+ ;HELPER HELPER ;~x~ ;end of line finds end of file when moving forward ;- 60$: ;~x~ ;+ ;HELPER HELPER ;~x~ ;end of line finds beginning of file when moving backward ;- .Dsabl LSB .SbTtl C.OPNL - Open line for entry ; ; C.OPNL - open line for entry ; .Enable LSB C.OpnL: Tst Inspct ;~x~Inspect mode? Bne 20$ ;~x~Yep Repeat ;~x~ Call InsNL ;~x~insert a CR LF pair Bcs 10$ ;~x~Error Call MovBkw ;~x~Backup of the chars ;only one move needed since CR,LF is ;a single logical newline char Return ;~x~ ...... 10$: ;~x~ ;+ ;HELPER HELPER ;~x~ ;Open line finds file full ;- 20$: ;~x~ Jmp NoInsp ;~x~then tell operation is invalid .............. .Dsabl LSB .If NE VT10$0 .SbTtl C.CHAR - Character moves ; ; C.CHAR - character moves ; .IfTF; NE VT10$0 .Enable LSB .IfT; NE VT10$0 C.Char: Tst Advanc ;~x~ Beq 40$ ;~x~Forward .Br 10$ ;Backward .EndC; NE VT10$0 .SbTtl C.LFT - Cursor backward ; ; C.LFT - move backward ; C.Lft: ;~x~ 10$: Repeat ;~x~Repeat and lock keyboard CC.Lft:: ;~x~Entry point for no repeat 20$: Call MovBkw ;~x~Scroller routine Bcc 30$ ;~x~No error ;+ ;HELPER HELPER ;~x~ ;Cursor backward strikes BOF ;- 30$: TstB @FCP ;~x~Is current char a null? Beq 20$ ;~x~If so skip it Return ;~x~ ...... .SbTtl C.RHT - Cursor forward ; ; C.RHT - move forward ; C.Rht: ;~x~ 40$: Repeat ;~x~Repeat and lock keyboard CC.Rht:: ;~x~Entry for no repeat 50$: Call MovFwd ;~x~Scroller routine Bcc 60$ ;~x~Ok ;+ ;HELPER HELPER ;~x~ ;- 60$: TstB @FCP ;~x~Is current char a null? Beq 50$ ;~x~If so skip it Return ;~x~ ...... .Dsabl LSB .SbTtl .SbTtl Paste buffer data .SbTtl ; ; Paste buffer data ; ; ; ; PasSiz = Size in bytes of paste buffer ; PasBuf = Abs address of paste buffer start ; PasSpc = Number of bytes left in paste buffer ; init to PASSIZ ; PasPtr -> Next free byte in paste buffer ; CutQ = Nonzero for CUTRNG to delete range ; SavQ = Nonzero for CUTRNG to save range in paste buffer ; PSect IMPURE PasSiz:: ;~d~ .BlkW 1 ;~d~Size of paste buffer PasBuf:: ;~d~ .BlkW 1 ;~d~Address of paste buffer PasSpc:: ;~d~ .BlkW 1 ;~d~Space in paste buffer PasPtr:: ;~d~ .BlkW 1 ;~d~First free byte in buffer CutQ:: ;~d~ .BlkW 1 ;~d~Nonzero for cut range SavQ:: ;~d~ .BlkW 1 ;~d~Nonzero for save range PSect KEDCMD .SbTtl Search string data ; ; Search string data ; PSect .TXT. SrModl: .Ascii "Model: " ;~d~Prompt for search string .Byte ;~d~ .If NE,VT10$0 ;If VT100 CurHom: .Byte ,,, ;~d~Move cursor to home position .IfF ;If VT52 CurHom: .Byte ,, ;~d~Move cursor to home position .EndC ;NE,VT10$0 PSect IMPURE SrPlC:: ;~d~ .BlkW 1 ;~d~Place of cursor after search ;0 for beginning, non zero for end ExctQ:: ;~d~ .BlkW 1 ;~d~Nonzero for exact search (case only) SrEnd:: .BlkW 1 ;~d~Abs pointer to end of string SrStr:: .BlkB PrmSiz ;~d~The string itself SBound:: ;~d~ .BlkW 1 ;~d~Zero for unbounded, non zero for ;bounded SrLins:: ;~d~ .BlkW 1 ;~d~Line count for line bounded search OldAdv: .Word -1+.-. ;~d~old state of the Advance flag SavCar: .BlkW 1 ;~d~place to save the state of the ;carry bit. PSect KEDCMD .SbTtl C.FIND - Find and find next .SbTtl C.FNXT - ;++ ;C.FIND, C.FNXT ; ;FUNCTIONAL DESCRIPTION: ; ; Find and find next ; ;Select search based on direction of ADVANC mode ; FNDNXT -- entry for substitute command ;-- .Enable LSB C.Find: Clr PrNum ;~x~Not numeric only Mov #SrStr,R1 ;Offset to string Jsr R4,Prmpt ;~x~Get the string .Word SrModl ;The prompt string Bcs 60$ ;~x~No good cancel command SetBsy ;~x~We are now busy Mov #FndLst,R1 ;Find list CallR ChDsp ;~x~ ............. C.FFNA: ;~x~ Mov Advanc,OldAdv ;save advance flag Call C.Advn ;~x~set it Br 20$ ;~x~join common code ........... C.FBNA: ;~x~ Mov Advanc,OldAdv ;save advance flag Call C.Back ;~x~set it Br 20$ ;~x~join common code ........... C.FFNX: ;~x~ Call C.Advn ;~x~set advance mode Br 10$ ;~x~carry on ........... C.FBNX: ;~x~ Call C.Back ;~x~set backup mode 10$: ;~x~ Mov #-1,OldAdv ;~x~ 20$: ;~x~ C.FNxt: ;~x~ Mov Df$Pag,SrLins ;Lines for bounded search Repeat ;~x~ ; ; This is a special non-repeat entry for subs to use ; FndNxt:: ;~x~ Mov PosCtr,SavCtr ;Save position in case Ctrl/C Mov PosCtr+2,SavCtr+2 ; Call StrSet ;~x~Setup string registers Beq 80$ ;~x~Nope no string defined Tst Advanc ;Which way oh master Beq 30$ ;~x~ Call C.BkSr ;~x~else backward Br 40$ ;~x~ ........... 30$: ;~x~ Call C.FSr ;~x~Forward 40$: ;~x~ Ror SavCar ;save the carry bit Tst OldAdv ;was a temp change made? Bmi 50$ ;~x~no Mov OldAdv,Advanc ;yes Mov #-1,OldAdv ;indicate no saved value now 50$: ;~x~ Rol SavCar ;restore the carry bit Return ;~x~ ...... ; ; Search errors ; 60$: ;~x~ ;+ ;HELPER HELPER ;~x~ ;CTRL/C or CTRL/Z were typed to find prompt ;- 70$: ;~x~ ;+ ;HELPER HELPER ;~x~ ;Illegal terminating escape sequence was entered to find prompt ;- 80$: ;~x~ ;+ ;HELPER HELPER ;~x~ ;search forward ;no string defined ;- .SbTtl Find character dispatch lists ; ; Find character dispatch lists ; PSect KEDCMD .Even FndLst: ;~x~ ChrLst , FndLs1+1,0 ;~x~eat ESC ChrLst , 70$ ,1 ;~x~error FndLs1: ;~x~ .If NE,VT10$0 ChrLst , FndLs2+1,0 ;~x~PFn keys (or applcatn cursor) ChrLst , FndLs3+1,0 ;~x~Cursor keys .IfF; NE,VT10$0 ChrLst , FndLs2+1,0 ;~x~Colored keys ChrLst , C.FBNA ,1 ;~x~advance ChrLst , C.FFNA ,1 ;~x~backup .EndC; NE,VT10$0 ChrLst , 70$ ,1 ;~x~Error FNDLS2: ;~x~ ChrLst , C.FFNX ,1 ;~x~Advance ChrLst , C.FBNX ,1 ;~x~Backup ChrLst , C.FNxt ,1 ;~x~current direction ChrLst , C.Entr ,1 ;~x~just define, don't move .If Ne VT10$0 FndLs3: ;~x~ ChrLst , C.FBNA ,1 ;~x~search forward ChrLst , C.FFNA ,1 ;~x~search backwards .EndC; NE VT10$0 ChrLst , 70$ ,1 ;~x~Error .Dsabl LSB PSect KEDCMD .SbTtl C.FSR - Search for next occurrence ; ;C.FSR ; ;Search for next occurrence ; .Enable LSB C.FSr: ;~x~ 10$: Call MvFwd ;~x~One char forward Bcs 50$ ;~x~End of file Call SLook ;~x~See if string is here?? Bcs 30$ ;~x~Search bound reached, help text ready Bne 10$ ;~x~Nope Return ;~x~No error ...... .SbTtl C.BKSR - Search backward for next occurrence ; ; C.BKSR - search backward for next occurrence ; C.BkSr: ;~x~ 20$: Call MvBkw ;~x~Move backward Bcs 50$ ;~x~End of file Call SLook ;~x~Look for string Bcs 30$ ;~x~Search bound reached, help text ready Bne 20$ ;~x~Keep looking ; Clc ;No error Return ;~x~ ...... 30$: Tst RetTNF ;~x~Did user SET SEARCH NORETURN? Beq 40$ ;~x~Yup, old fuddy duddy Mov SavCtr,R1 ;Original position to regain Mov SavCtr+2,R2 ; Call RgnPos ;~x~Get back to original position 40$: Sec ;~x~ Return ;~x~ ...... 50$: Call 30$ ;~x~Take care of SEARCH RETURN ;+ ;HELPER HELPER ;~x~ ;Search forward or backward fails to find model ;- .Dsabl LSB .SbTtl STRSET - Setup for string compare ;++ ;STRSET ; ;FUNCTIONAL DESCRIPTION: ; ; Setup for string compare ; ;INPUT: NONE ; ;OUTPUT: ; R3 -> beginning of string ; R4 -> end of string ; Z set on return if R3=R4 ;-- .Enable LSB StrSet:: ;~x~ Mov #SrStr,R3 ;Make beginning of string Mov SrEnd,R4 ;End of string Cmp R3,R4 ;Set Z on R3=R4 Return ;~x~ ...... .Dsabl LSB .SbTtl SLOOK - Look at current position for string ;++ ;SLOOK ; ;FUNCTIONAL DESCRIPTION: ; ; Look for string at current position ; ;INPUT: ; R3 -> beginning of compare model ; R4 -> end of compare model ; SRPLC nonzero for leave cursor at end ; ;OUTPUT: ; Z set if string found ; Z clr if string not found ; C set on error (bound reached) ; R0-R2 used ;-- .Enable LSB SLook: ;~x~ Tst SBound ;Bounded search Beq SLook1 ;~x~No Push ;Save start and end of string Mov #Df$Pag,R3 ;Define block Mov -2(R3),R4 ;End of string Beq 20$ ;~x~It's a line definition Call SELook ;~x~Look for the string Bne 30$ ;~x~Not here 10$: Pop ;~x~Restore regs ;+ ;HELPER HELPER ;~x~ ;bounded search reached the bound, page definition ;- 20$: MovB @BCP,R0 ;~x~Get previous character Call LTerm ;~x~Line terminator? rtn C clear Bne 30$ ;~x~Nope Dec SrLins ;One less lines to look Beq 10$ ;~x~All done 30$: Pop ;~x~Restore all regs .Br SLook1 ;Ok to continue .Dsabl LSB ; ; SLOOK1 - special entry without bound check ; .Enabl LSB Slook1:: ;~x~ Tst SrPlc ;Beginning or end Bne SELook ;~x~End- so be it Mov R3,R1 ;Beginning of string Mov FCP,R2 ;Forward from here 10$: ;~x~ Cmp R1,R4 ;End of target? Beq 30$ ;~x~Found it return Z set Cmp R2,PlyEnd ;End of buffer check Bhis 20$ ;~x~Yep- end MovB (R1)+,R0 ;Get target char Call CLook ;~x~Look at the char Bne 30$ ;~x~No good Inc R2 ;Next char Br 10$ ;~x~Keep looking .......... 20$: Clz ;~x~Not found 30$: Return ;~x~ ...... .Dsabl LSB ; ; SLOOK routine for cursor at end of target ; .Enable LSB SELook: Mov R4,R1 ;~x~End address Mov R3,R2 ;Start address Sub R4,R2 ; Minus end address = - length Inc R2 ;Adjust the length Add BCP,R2 ;Add address we're starting at Cmp PlyGnd,R2 ;Looking beyond PLYGND limits? Bhi 30$ ;~x~Error if so Mov BCP,R2 ;else start looking backwards SpLook:: ;~x~Entry for use by skip and ;include page 10$: Cmp R3,R1 ;~x~Beginning Bhis 20$ ;~x~Yes- found C clr MovB -(R1),R0 ;Backup Call CLook ;~x~Look at a char Bne 30$ ;~x~No good Dec R2 ;Backup address Br 10$ ;~x~ .......... 20$: Sez ;~x~Return we found it 30$: Return ;~x~ ...... .Dsabl LSB .SbTtl CLOOK - Compare a single char with model ;++ ;CLOOK ; ;FUNCTIONAL DESCRIPTION: ; ; Look at a char ; ;INPUT: ; R2 -> text char ; R0 = target char ; ;OUTPUT: ; Z set if chars match ; C clear ;-- .Enable LSB CLooK: CmpB R0,@R2 ;~x~Match? Beq 10$ ;~x~Yes Tst ExctQ ;Exact searches? Bne 10$ ;~x~Yes Call SwCase ;~x~Switch the case of R0 char CmpB R0,@R2 ;Match? ; Beq - ;Return Z set or not Clc ;Assure c clear 10$: Return ;~x~ ...... .Dsabl LSB .SbTtl SWCASE - Switch case of char ;++ ;SWCASE ; ;FUNCTIONAL DESCRIPTION: ; ; Switch case of character ; ;>>>Change for 8bit support ; ;INPUT: ; R0 = character ; ;OUTPUT: ; Char in R0 of opposite case ; Only A-Z affected ; C clr ;-- .Enable LSB SwCase:: ;~x~ Cmp #C.UC.A,R0 ;Check alpha range Bhi 30$ ;~x~Too low Cmp R0,#C.UC.Z ;Check high of range Blos 20$ ;~x~make lowercase UpCase:: ;~x~ 10$: Cmp #C.LC.a,R0 ;~x~Check low case range Bhi 30$ ;~x~Out side Cmp #C.LC.z,R0 ;Check high end of range Blo 30$ ;~x~Outside range Bic #40,R0 ;Clear to make upper case Br 30$ ;~x~ ........... DnCase:: ;~x~ Cmp #C.UC.A,R0 ;Check alpha range Bhi 30$ ;~x~Too low Cmp R0,#C.UC.Z ;Check high of range Bhi 30$ ;~x~Outside range 20$: ;~x~ Bis #40,R0 ;Make lowcase 30$: Clc ;~x~Return carry clear Return ;~x~ ...... .Dsabl LSB .SbTtl C.DARG - Delete last search target ; ; C.DARG - delete last search target ; .Enable LSB C.Darg:: ;~x~ KbLock ;~x~Lock the keyboard Call StrSet ;~x~Setup for string look Beq 50$ ;~x~No such string Call SLook1 ;~x~Are we on the target? Bne 70$ ;~x~No- do not delete it Tst SrPlc ;Which way for string? Bne 10$ ;~x~Backward UnDoIt W,F ;~x~Use word forward buffer Br 20$ ;~x~Ok ........... 10$: UnDoIt W,B ;~x~Word backward 20$: Cmp R3,R4 ;~x~End of string Beq Ret.2 ;~x~Yes Tst SrPlc ;Which direction Bne 30$ ;~x~Backward Call DlChr ;~x~Delete string char Br 40$ ;~x~Continue below .......... 30$: Call RbChr ;~x~Delete backward 40$: Bcs 60$ ;~x~End of file Inc R3 ;Advance toward end to count chars Br 20$ ;~x~Back for more .......... Ret.2: Return ;~x~No error ...... 50$: ;~x~ ;+ ;HELPER HELPER ;~x~ ;delete search argument found no string defined ;called from REPLACE and SUBSTITUTE ;- 60$: ;~x~ ;+ ;HELPER HELPER ;~x~ ;delete search argument found file extremity ;- 70$: ;~x~ ;+ ;HELPER HELPER ;~x~ ;Cursor is not on the search target and we do not allow ;chars to be deleted if it is not. ;- .Dsabl LSB .SbTtl C.RBCH - Delete a character to the left ; ; C.RBCH - delete a character to the left ; .Enable LSB C.RbCh: QukRep ;~x~Repeat with no keyboard lock UnDoIt C,B ;~x~Char backward Call RubChr ;~x~Delete a char (logical) Bcc Ret.2 ;~x~Ok ;+ ;HELPER HELPER ;~x~ ;Rub char left encounters beginning of file ;- .Dsabl LSB .SbTtl C.DLCH - Delete a character to the right ; ; C.DLCH - delete a character to the right ; .Enabl LSB C.DlCh: QukReP ;~x~Repeat with no keyboard lock UnDoIt C,F ;~x~Char forward Call DelChr ;~x~Delete a logical char right Bcc Ret.2 ;~x~Ok ;+ ;HELPER HELPER ;~x~ ;delete char right find end of file ;- .Dsabl LSB .SbTtl C.RUBL - Rub left one line ; ; C.RUBL - rub left one line ; .Enable LSB C.RubL: UnDoIt L,B ;~x~Line backward Call RubLn ;~x~Delete line left Bcc Ret.2 ;~x~No error ;+ ;HELPER HELPER ;~x~ ;rub left one line strikes bof ;- .Dsabl LSB .SbTtl C.DELL - Delete right one line ; ; C.DELL - delete right one line ; .Enable LSB C.DelL: Repeat ;~x~ UnDoIt L,F ;~x~Line forward 10$: Call DelChr ;~x~Delete a char Bcs 20$ ;~x~End of file Call LTerm ;~x~Line terminator Bne 10$ ;~x~Nope Return ;~x~C clr ...... 20$: ;~x~ ;+ ;HELPER HELPER ;~x~ ;rub right one line strikes eof ;- .Dsabl LSB .SbTtl C.DELN - Delete rest of line to terminator ; ; C.DELN - delete rest of line to terminator ; .Enable LSB C.DeLn: Repeat ;~x~ UnDoIt L,F ;~x~Line forward 10$: Call DeLChr ;~x~Delete a logical char Bcs 20$ ;~x~End of file MovB @FCP,R0 ;Next char?? Call CRTerm ;~x~Check for line term or CR Bne 10$ ;~x~Check for CR etc now Return ;~x~ ...... 20$: ;~x~ ;+ ;HELPER HELPER ;~x~ ;Delete right line to term strikes eof ;- .Dsabl LSB .SbTtl C.UP - Up one line on same column ; ; C.UP - move up one line at the same column ; .Enable LSB C.Up: ;~x~ Repeat ;~x~Repeat and lock keyboard Clr R4 ;Error counter for none Bit #AroCmd,LstCmd ;Last command an arrow command? Bne 10$ ;~x~Yes- don't count columns Call Count ;~x~No- count columns on this line Mov R2,Cols ;Save columns 10$: MovB @BCP,R0 ;~x~Are we at line start?? Call LTerm ;~x~?? Beq 20$ ;~x~Yes Call MovBL ;~x~Back one line 20$: Call MovBL ;~x~Back one more Bcc 30$ ;~x~No error Inc R4 ;Count the error 30$: Tst Cols ;~x~Column no Beq 60$ ;~x~Zero- thats all folks GoCol: ;~x~ Clr R2 ;The column we are on MovB @FCP,R0 ;Get char to check 40$: Call CtChr ;~x~Count columns for the char Beq 60$ ;~x~Line term so stop Cmp R2,Cols ;Too far?? Bhi 60$ ;~x~Yes - stop here Call MovFwd ;~x~One more Bcc 40$ ;~x~And look again- if not EOF 50$: Call 70$ ;~x~Set things up ;+ ;HELPER HELPER ;~x~ ;either up or down arrow strike eof or bof ;uparrow is not expected to strike eof ;- 60$: Tst R4 ;~x~Any errors? Bne 50$ ;~x~Yep 70$: Bis #AroCmd,CurCmd ;~x~Signal arrow command Return ;~x~ ...... .SbTtl C.DWN - Down one line to same column ; ; C.DWN - move down one line at the same column ; C.Dwn: ;~x~ Repeat ;~x~Repeat and lock keyboard Clr R4 ;No errors yet Bit #AroCmd,LstCmd ;Arrow command last Bne 80$ ;~x~Column already counted Call Count ;~x~Where are we on the line Mov R2,Cols ;Save columns 80$: Call MovFl ;~x~Forward one line Bcc 30$ ;~x~No error Cmp FCP,PlyEnd ;Is it EOF? Bhis 50$ ;~x~Yes, then immediate error Inc R4 ;Count an error Tst Cols ;Any columns?? Beq 60$ ;~x~Fine stay where we are Call MovBL ;~x~Backup to previous line Br GoCol ;~x~Go check for column zero ............. .Dsabl LSB ; ; Data for the arrow commands ; PSect IMPURE Cols: .BlkW 1 ;~d~Column 0-N PSect KEDCMD .SbTtl COUNT - Count columns for arrow commands ;++ ;COUNT ; ;FUNCTIONAL DESCRIPTION: ; ; Count columns ; ;INPUT: NONE ; ;OUTPUT: ; R2 = count ; Regs destroyed ;-- .Enable LSB Count:: ;~x~ Clr R2 ;No count yet Mov BCP,R1 ;Look back Cmp R1,PlyGnd ;Beginning yet Blo Ret.3 ;~x~Nothing to lookat 10$: Cmp R1,PlyGnd ;~x~Beginning?? Blos 20$ ;~x~Yes MovB @R1,R0 ;Char Call LTerm ;~x~Line term Beq 20$ ;~x~Ok- done moving back Dec R1 ;Move back Br 10$ ;~x~ .......... 20$: Cmp R1,BCP ;~x~Look for end Bhi Ret.3 ;~x~Ok end MovB (R1)+,R0 ;Get char to look at Call CtChr ;~x~Count for this char Br 20$ ;~x~ .......... .Dsabl LSB ; ; CTCHR -- count columns for a character ; Return Z set on line term ; R2 = column in line ; .Enable LSB CtChr: Call CRTerm ;~x~Is it a term? Beq Ret.3 ;~x~Don't count it Inc R2 ;Count one CmpB R0,# ;Tabs are special Bne Ret.3 ;~x~Nope- ok 10$: Bit #7,R2 ;~x~End of tab Beq 20$ ;~x~Yes Inc R2 ;Count one more Br 10$ ;~x~Back for more .......... 20$: Clz ;~x~Not equal Ret.3: Return ;~x~ ...... .Dsabl LSB .SbTtl C.COMN - Command processor ; ; C.COMN -- command processor ; .Enable LSB C.Comn:: ;~x~ Call $JoIncl ;~x~Clean out journal temp buffer Clr PrNum ;Not numbers only Mov #CmdStr,R1 ;Command string CROn ;Accept as a terminator Clr Commnt ;Clear comment indicator Jsr R4,Prmpt ;~x~Get a string .Word CmdPrm ;The command prompt Bcs 60$ ;~x~Canceled CROff ClrB @-2(R1) ;Zap end of string Tst R0 ;Did we hit the end of a recover file? Beq 40$ ;~x~Yup, return quietly CmpB R0,# ;Do we have one? Bne 10$ ;~x~No, continue CmdOn ;Yes, set command mode on Br 20$ ;~x~ ........... 10$: TtyIn ;~x~Next character .If NE,VT10$0 CmpB #,R0 ;VT100 .IfF; NE,VT10$0 CmpB #,R0 ;VT52 .EndC; NE,VT10$0 Bne 70$ ;~x~No good TtyIn ;~x~Next char CmpB #,R0 ;Last char Bne 70$ ;~x~No good CmdOff ;Assume we left command mode 20$: Mov #K.Lst,R3 ;~x~Master command list Call KySrch ;~x~Get the transfer address SetBsy ;~x~Say we are busy for all commands IsExe ON 50$ ;~x~Are we executing? YES Call ToRtn ;~x~Do routine and come back Bcs 40$ ;~x~If error leave command routine IsCmd ON C.Comn ;~x~Are we still in command mode? YES 30$: Return ;~x~No, must have processed "CHANGE" ...... 40$: Bit #100000,CtrlC ;~x~Is this an aborted command? Beq 30$ ;~x~No, just a plain old error CallR AbtCmd ;~x~Write the special abort record if .............. ; we're journaling 50$: CallR ToRtn ;~x~Don't do anything fancy in execute ............. ; mode 60$: CROff ;~x~ CmdOff ;+ ;HELPER HELPER ;~x~ ;The command prompt was canceled with control/c or /z ;- 70$: ;~x~ ;+ ;HELPER HELPER ;~x~ ;Another key besides ENTER was used to terminate the command prompt ;- .Dsabl LSB .SbTtl TORTN - Routine dispatch ;+ ; TORTN -- Routine dispatch ;- .Enabl LSB ToRtn: ;~x~ Call @R3 ;~x~Call the routine to allow return ; ; The macro ENDCHK calls us back here via CALL @(SP)+ ; The macro NOECHK does not call us back by doing TST (SP)+ ; .Br C2EndQ ;Perform the end check .Dsabl LSB .SbTtl C1ENDQ - Command line end checks .SbTtl C2ENDQ - ; ; C2ENDQ -- command line end check (2 levels down) ; C1ENDQ -- command line end check (1 level down) ; .Enabl LSB C2EndQ:: ;~x~ TstB @R1 ;Command line ended properly Beq 10$ ;~x~Yes ok Cmp (SP)+,(SP)+ ;Dump from stack to return ;two levels up ;+ ;HELPER HELPER ;~x~ ;There were extra characters on the command line beyond the last command ;word. This is illegal. ;- C1EndQ:: ;~x~ Call C2EndQ ;~x~Put us one more level down 10$: Return ;~x~ ...... .Dsabl LSB ; ; Command line data space ; PSect IMPURE .BlkW 1 ;~d~End of string CmdStr:: ;~d~ .BlkB PrmSiz+2 ;Command s~d~tring Commnt: .BlkW 1 ;~d~Comment indicator <>0 if "!" has been ; found in searching for a keyword PSect .TXT. CmdPrm: .Ascii "Command: " ;~d~ .Byte ;~d~ PSect KEDCMD .SbTtl KYCALL - Call routine based on a keyword ;++ ;KYCALL ; ;FUNCTIONAL DESCRIPTION: ; ; Call routine via keyword list ; ;INPUT: ; R1 -> target string ; R3 -> keyword list pair ; ;OUTPUT: ; Call routine matched via PC ; R0-R3 used ;-- .Enabl LSB KyCall:: ;~x~ Call KySrch ;~x~Search keyword list Jmp @R3 ;~x~Transfer to routine ........... ; .SbTtl KYDATA - Return data from keyword list ;++ ;KYDATA ; ;FUNCTIONAL DESCRIPTION: ; ; Return data from keyword list ; ;INPUT: ; R1 -> target string ; R3 -> keyword list pair ; ;OUTPUT: ; R0 = returned data ; R0-R3 used ;-- ;KyData: Call KySrch ; Mov R3,R0 ;Return data in R0 ; Return ; ...... .Dsabl LSB .SbTtl KNUMQ - Accumulate number for command ;++ ;KNUMQ ; ;FUNCTIONAL DESCRIPTION: ; ; Accumulate number for command ; Accept signed or unsigned input ; ;INPUT: ; R1 -> string ; ;OUTPUT: ; R1 -> after number ; R2 = number ; KNUMBR = number ; C clr if number converted ; C set if not ;-- .Enable LSB KNumQ:: ;~x~ Clr R2 ;Accumulate number here Push #0 ;Sign indicator positive MovB @R1,R0 ;Start with a number? CmpB R0,#'+ ;Positive? Beq 10$ ;~x~Sure, ignore sign CmpB R0,#'- ;Minus Bne 20$ ;~x~Nope - maybe a digit Inc (SP) ;Set for minus 10$: Inc R1 ;~x~Next character MovB (R1),R0 ;Next character 20$: Call DgtQ ;~x~Digit? Bne 70$ ;~x~Nope 30$: MovB (R1)+,R0 ;~x~Next char Call DgtQ ;~x~Digit? Bne 40$ ;~x~Nope Sub #,R0 ;Make digit Asl R2 ;10X = 2X + 8X Add R2,R0 ;+ 2X Asl R2 ;= 4X Asl R2 ;= 8X Add R0,R2 ;= 10X + Digit Br 30$ ;~x~Keep going .......... 40$: Dec R1 ;~x~Backup address Clc ;We had a number 50$: Rol -(SP) ;~x~*C* save carry Call SpNor ;~x~Ignore spaces Tst 2(SP) ;Sign indicator Beq 60$ ;~x~Positive Neg R2 ;Make minus 60$: Ror (SP)+ ;~x~*C* restore carry Pop <>,SAVE=*C* ;*C* dump sign indicator Mov R2,KNumbr ;*C* save safe away Return ;~x~ ...... 70$: Sec ;~x~Return no number Br 50$ ;~x~Ok return ........... .Dsabl LSB ; ; Data for accumulating numeric value ; PSect IMPURE KNumbr:: ;~d~ .BlkW 1 ;~d~Safe place for number PSect KEDCMD .SbTtl KEYTRM - Check for keyword terminator ;++ ;KEYTRM ; ;FUNCTIONAL DESCRIPTION: ; ; Check for keyword terminator ; ;INPUT: ; R0 = char ;OUTPUT: ; Z set if space or null (end of line) or beginning comment ; case is upper alpha ;-- .Enable LSB KeyTrm:: ;~x~ TstB R0 ;End of line Beq 20$ ;~x~Yep CmpB R0,# ;Space? Beq 20$ ;~x~Yep CmpB R0,# ;Tab? Beq 20$ ;~x~Yep CmpB R0,#'! ;Beginning of comment? Bne 10$ ;~x~Nope Mov SP,Commnt ;Yup, remember it Sez ;Set Z bit to indicate terminator Br 20$ ;~x~ ........... 10$: CmpB R0,# ;~x~lower case Blo 20$ ;~x~Nope CmpB R0,# ;lower case Bhi 20$ ;~x~Nope Bic #<40>,R0 ;Make upper 20$: Return ;~x~ ...... .Dsabl LSB .SbTtl SPNOR - Ignore spaces ;++ ;SPNOR ; ;FUNCTIONAL DESCRIPTION: ; ; Ignore spaces and comments ; ;INPUT: ; R1 -> character string ; ;OUTPUT: ; R1 -> beyond spaces in string ;-- .Enable LSB SpNor:: Tst Commnt ;~x~Have we found a "!" yet? Bne 20$ ;~x~Yup 10$: CmpB (R1)+,# ;~x~Space? Beq 10$ ;~x~Yes - keep going CmpB -1(R1),# ;Tab? Beq 10$ ;~x~Yes - keep going CmpB -(R1),#'! ;Was it the beginning of a comment? Bne 30$ ;~x~Nope 20$: TstB (R1)+ ;~x~Is this the end of line & comment? Bne 20$ ;~x~Nope Dec R1 ;Backup the address to last character 30$: Return ;~x~ ...... .Dsabl LSB .REM % ; ;WHITE ; ;Return z=1 if R0 is a white space character ;Return z=0 if R0 is not white space character ; ;Commnt <>0 is ! (comment) was found ; .Enabl LSB White:: CmpB R0,# ;~x~Space? Beq 10$ ;~x~Yep CmpB R0,# ;Tab? Beq 10$ ;~x~Yep CmpB R0,#'! ;Beginning of comment? Beq 10$ ;~x~Nope Mov SP,Commnt ;Yep, remember it 10$: Return ;~x~ % .Dsabl LSB .SbTtl .SbTtl Data structure for page and paragraph ; ; Data for page and paragraph ; PSect IMPURE ; ; Page definition block ; ; .BlkW ;~d~End address or zero for lines ; Df$Pax: .BlkB PrmSiz ;~d~String or first word is line count ; .BlkW 1 ;~d~End address Df$Pag:: ;~d~ .BlkB PrmSiz ;~d~String .BlkW 1 ;~d~End address Df$Par:: ;~d~ .BlkB PrmSiz ;~d~String PSect KEDCMD .SbTtl C.PAGE - Page and paragraph .SbTtl C.PARA - ; ; C.PAGE -- page moves ; C.PARA -- paragraph moves ; .Enable LSB C.Page: Mov #Df$Pag,R2 ;~x~Get defined structure Br 10$ ;~x~ ........... C.Para: Mov #Df$Par,R2 ;~x~ 10$: Mov -2(R2),R4 ;~x~End of string, lines or pages? Beq 50$ ;~x~Lines Mov R2,R3 ;Start of string Repeat ;~x~Repeat a page or section move 20$: Tst Advanc ;~x~Which way Beq 30$ ;~x~Forward Call MvBkw ;~x~Backward Br 40$ ;~x~Ok .......... 30$: Call MvFwd ;~x~ 40$: Bcs 60$ ;~x~No good Call SELook ;~x~Look for a page here Bne 20$ ;~x~Keep going Ret.4: Return ;~x~No error ...... 50$: Repeat ;~x~Repeat a page or section ;move by lines Push ;Save REPCTR Mov @R2,RepCtr ;Load line counter Call C.Line ;~x~Do line moves Pop ;Restore REPCTR Bcc Ret.4 ;~x~no Error 60$: Clr HlpDne ;~x~So we use this help ;+ ;HELPER HELPER ;~x~ ;move forward or backward by page or section finds beginning or end of file ;- .Dsabl LSB .SbTtl .SbTtl Data for tab functions ; ; Data for tab function ; PSect IMPURE TbLvl:: ;~d~ .BlkW 1 ;~d~Level of tab 1-n TbCnt:: ;~d~ .BlkW 1 ;~d~Indent level PSect KEDCMD .SbTtl TLUP - Increase tab level ; ; TLUP -- increase tab level ; .Enabl LSB TLUp: QukRep ;~x~Allow repeats Inc TbLvl ;Increment level Br Clc.2 ;~x~No error ............. .Dsabl LSB .SbTtl TLDWN - Decrease tab level ; ; TLDWN -- decrease tab level ; .Enabl LSB TLDwn: QukRep ;~x~Allow repeats Dec TbLvl ;Tab level down one Bge Clc.2 ;~x~Ok Clr TbLvl ;Clamp at zero Br Clc.2 ;~x~No error ............. .Dsabl LSB .SbTtl TALGN - Tab align ; ; TALGN -- tab align ; ; The level is set for the current column ; .Enabl LSB TAlgn: Tst TbCnt ;~x~Are we doing tabs? Ble Clc.2 ;~x~Nope Call Count ;~x~Count current column Clr R1 ;Here is level 10$: Sub TbCnt,R2 ;~x~Divide column by count Blt 20$ ;~x~Demand no remainder Inc R1 ;Keep level count Tst R2 ;Check remainder Bne 10$ ;~x~Til done Mov R1,TbLvl ;Save level Clc.2: Clc ;~x~ Return ;~x~ ...... 20$: ;~x~ ;+ ;HELPER HELPER ;~x~ ;remainder was not zero for divide of column by indent ;- .Dsabl LSB .SbTtl C.Chng - Gracefully leave command: mode ;+ ; C.Chng -- leave command: mode ; ;used by learn macros and such to control Command: execution mode ;- .Enabl LSB C.Chng:: ;~x~ EndChk ;~x~Make sure JFW hasn't typed in any ; extra words on the command line CmdOff ;Turn off Command: mode flag Return ;~x~ ...... .Dsabl LSB .SbTtl C.TAB - Do a structured tab function ; ; C.TAB -- do a structured tab function ; ;Insert appropriate number of tabs and spaces if no spaces or tabs ;on line ; .Enable LSB C.Tab: QukRep ;~x~Repeat quickly Tst TbCnt ;Tabs enabled? Ble 80$ ;~x~Nope Mov BCP,R1 ;Get BCP pointer 10$: Cmp R1,PlyGnd ;~x~End check Blo 20$ ;~x~End of scan MovB @R1,R0 ;Check for line term Call LTerm ;~x~Line term? Beq 20$ ;~x~Done scan Call SpcTbQ ;~x~Space or a tab? Beq 80$ ;~x~Yep Dec R1 ;Backup address Br 10$ ;~x~And keep checking .......... PlcTab:: ;~x~Entry used by tab adjust routine ;to realign tabs on a line. 20$: Clr R3 ;~x~Count spaces here Mov TbLvl,R2 ;Get level for tab Ble Clc.2 ;~x~Ok - all done 30$: Add TbCnt,R3 ;~x~Count it here with a simple multiply Sob R2,30$ ;~x~Til its done Call Count ;~x~Count columns on line Cmp R2,R3 ;Are we there Blt 40$ ;~x~Nope not yet Mov R2,R3 ;We need to add one space only Inc R3 ;So make desired column = .+1 40$: Mov R2,R4 ;~x~Save where we are Add #10,R2 ;Advance to next stop Bic #7,R2 ;And make the real column Cmp R2,R3 ;Are we there? Bgt 60$ ;~x~Tab is too much Call 80$ ;~x~Give them a tab Bcc 40$ ;~x~And back for more 50$: ;~x~ ;+ ;HELPER HELPER ;~x~ ;something failed with structured tab insertion ;- 60$: Sub R4,R3 ;~x~Make column residual Ble Clc.2 ;~x~We are there Mov #,R0 ;Get a space 70$: Call Insrt ;~x~Insert required spaces Bcs 50$ ;~x~Return error Sob R3,70$ ;~x~Til done Br Clc.2 ;~x~No error ............. 80$: Mov #,R0 ;~x~Insert a tab Call Insrt ;~x~Into the file Bcs 50$ ;~x~Error Return ;~x~ ...... .Dsabl LSB .SbTtl SPCTBQ - Is R0 a space or tab? ;++ ;SPCTBQ ; ;FUNCTIONAL DESCRIPTION: ; ; Set condition codes for R0 = space or tab character ; ;INPUT: ; R0 = character ; ;OUTPUT: ; CC's set appropriately ;-- .Enable LSB SpcTbQ:: ;~x~ Cmp R0,# ;Check for a space Beq 10$ ;~x~Yes, ok return Cmp R0,# ;Check for a tab 10$: Return ;~x~Return cc's to caller ...... .Dsabl LSB .SbTtl .SbTtl Macros and executable files facilities ;++ ; ;FUNCTIONAL DESCRIPTION: ; ;The macro facility allows functions and commands to KED to be 'learned' ;and later executed. In learn mode, all characters typed to ked are ;both executed and saved in the learn buffer for later execution. All ;commands and functions of KED may be learned except stop-learn and ;exec. These two commands are saved in the learn buffer but do nothing ;in exec mode. ; ;The functions and commands are: ; ;LEARN Enter learn mode ;S Stop learn mode ;X Stop learn and exec, possibly with repeat ;-- .SbTtl .SbTtl Macro facility data PSect IMPURE LrnLim::.BlkW 1 ;~d~Limit number of learn buffers TtBfr:: .BlkW 1 ;~d~Address of composite learn buffer TtBufE::.BlkW 1 ;~d~Address of end of composite learn ; buffer TtPtr:: .BlkW 1 ;~d~Current pointer into learn buffer fo ; executing LnPtr:: .BlkW 1 ;~d~Current pointer into learn buffer for ; learning LrnNxt::.BlkW 1 ;~d~Address of next available space in ; composite learn buffer ;LBfTab::.BlkW 1 ;~d~Address of Table of learn buffer ; descriptors L.Id == 0 ;~d~ Buffer identifier L.Buf == 2 ;~d~ Beginning of macro buffer L.BEnd == 4 ;~d~ End of macro buffer L.Cur:: .BlkW 1 ;~d~Pointer to current macro buffer ; descriptor for learning E.Cur:: .BlkW 1 ;~d~Pointer to descriptor of the macro ; currently being executed X.Cur:: .BlkW 1 ;~d~Pointer to "current" macro descriptor ; (to be executed on X ) TtSlid::.BlkW 1 ;~d~Size of gap for learn buffers to ; slide over (for clearing a buffer) LrnFlg::.BlkW 1 ;~d~Indicator that there is a macro being ; learned (to guard against nesting) TtInp:: .BlkW 1 ;~d~Input mode: T.Lrn == 1 ;~d~ Learning T.Exe == 2 ;~d~ Executing T.Rec == 4 ;~d~ Recovering T.Jou == 10 ;~d~ Journaling T.ExI == 20 ;~d~ Input from macro (to prevent ; recursive executes) T.JRe == 40 ;~d~ Journal all input T.SEr == 100 ;~d~ Suppress errors ;Command Processing information: T.SLF == 400 ;~d~ During recover, flag to ; prevent from ; being read in instead of ; T.Cmd == 1000 ;~d~ Command mode T.CR == 2000 ;~d~ is command terminator T.Abt == 4000 ;~d~ Processing an aborted command KedDef::.Rad50 /KED/ ;~d~Default macro/command file extension DefBuf::.Ascii /\/ ;~d~Default Buffer's name .Even ; ;Text for insertion in journal file ; ; Insert J.Cmd (<7>) if need to make sure that journal file ; knows we're in command mode. ; ; Insert J.Ins () if need to make sure that journal file or macro knows ; we're in insert mode. ; PSECT .TXT. J.Ins:: ;~d~ J.Cmd:: ;~d~ .Byte ;~d~Text to begin KED generated-learn .If NE ; buffers & journals in insert mode .Byte ;~d~ .IfF .Byte ;~d~ .EndC .Byte ;~d~ J.InL== .-J.Ins ;~d~ ;Text to switch to command mode in .If NE ; journal .Byte ,, ;~d~ .Byte ,, ;~d~<7> .IfF .Byte , ;~d~ .Byte ,, ;~d~ .EndC J.CmL == .-J.Cmd ;~d~ .Even PSect KEDCMD .SbTtl COMMND - Initialization Command File Processing ;+ ;COMMND - Process Initialization Command File ; ;FUNCTIONAL DESCRIPTION: ; ; Use $OpIni to open the user-specified initialization file, if ; any. If there was none, it will use DK:KEDINI.KED or SY:KEDINI.KED ; The initialization file can be an edited command ; file or a saved learn macro. It is executed the same way as ; the /RECOVER file and by the same routines. ;- .Enable LSB Commnd: Tst ComSsn ;~x~Is there an initialization file? Beq Ret.5 ;~x~no Call $OpIni ;~x~Reopen the init file after recover ; JReOn ;Turn on journal everything flag ; RecOn ;Set recover mode (nothing to nest) Bis #,TtInp ; Call ExLoop ;~x~And execute the file Call BelErr ;~x~Ring bell if we need to Bic #,TtInp ; ; RecOff ;Turn off recover mode ; JReOff ;Turn off journal everything Mov #Jo$Inp,R4 ; Call $ClsFl ;~x~Close the input channel .Br RecPos ;Position zero .Dsabl LSB .SbTtl RECPOS - Record current position in journal ;+ ;RECPOS - Record position ; ;FUNCTIONAL DESCRIPTION: ; ; Record position and include input in journal file (if journaling) ; ;INPUT ;- .Enabl LSB RecPos:: ;~x~ Clr PosCtr ;Initialize position counter Clr PosCtr+2 ; (double precision) CallR $JoIncl ;~x~Include previous input in journal ............... .Dsabl LSB .SbTtl RECOVR - Recover File Processing ;+ ;RECOVR ; ;FUNCTIONAL DESCRIPTION: ; ;Execute the commands in the recover file. Continue past errors, and ;recognize the special records. ;- .Enable LSB Recovr: Tst RecSsn ;~x~Is there a recover file? Beq Ret.5 ;~x~No, return SLFOff ;Control input from file ClrB PmtDef ;Initialize the prompt default Bis #,TtInp ; ; JReOn ;Recovering journal-journal everything ; RecOn ;Set recover mode ; SErOn ;Suppress errors Call ExLoop ;~x~And execute the file Bic #,TtInp ; ; SErOff ;Don't suppress errors ; RecOff ;Turn off recover mode ; JReOff ;Done recovering journal file Clr RecSsn ; ditto Call SetScr ;~x~Clean up the display .Br FixJou ;Make sure journal file is command ; mode, and write out what we have .DSABL LSB .SbTtl FIXJOU - Put command in journal to enter command mode ;+ ;FIXJOU - Insert change back to command mode in journal file ; ;FUNCTIONAL DESCRIPTION: ; ; If we have just completed execution of a file and journaled it, it was ;either the /RECOVER file or the initialization file. In either case, if ;we didn't end the execution in command mode, we have to set ourselves back to ;command mode in the journal file. This because a journal file may contain ;input from an orginal recover file, an initialization file, and an edit ;session, each of which assume they begin execution in command mode. ; ;INPUT: ; ;OUTPUT: ; Registers preserved ;- .Enable LSB FixJou: IsJou ON 10$ ;~x~Are we journaling? YES Ret.5: Return ;~x~Nope, nothing to do ...... 10$: SavReg ;~x~ Mov #Jo$Out,R4 ;Journal file Mov #J.Cmd,R1 ;Want to tell the journal file to go ; back to command mode for the ; processing of the next input Mov #J.CmL,R3 ;Move this many characters 20$: MovB (R1)+,R0 ;~x~ into the journal temp buffer Call Journl ;~x~ Sob R3,20$ ;~x~Til there's none left CallR $JoIncl ;~x~Make sure they go in the file ............... .Dsabl LSB .SbTtl C.AT - @file processing ;+ ;C.AT ; ;Functional Description: ; ;Execute commands directly from the file specified as though we were ;executing a macro. ;- .Enabl LSB C.At: ;~x~ ; NoEChk ;Already done at C.NCmd Push TtInp ;Save input mode JouOff ;And make sure journaling is off Call Nest ;~x~Nest before we change file info Bcs 20$ ;~x~No error Push R5 ;Save the Nest register across call Mov #Jo$Inp,R4 ;Use the journal input channel Mov KedDef,AuxDef ;Default the extension to .KED Call $OpFil ;~x~Open the file Mov #0,AuxDef ;*C* set back to no default Bcs 10$ ;~x~Error return RecOn ;Set recover mode Call ExLoop ;~x~And execute the file RecOff ;*C* Turn off recover mode 10$: Pop R5 ;~x~*C* Restore the Nest register ; Call BelErr ;~x~Ring bell if carry is set Rol -(SP) ;*C* save carry Mov #Jo$Inp,R4 ;Use the journal input channel Call $ClsFl ;~x~Close the @ channel Call UnNest ;~x~Unnest Ror (SP)+ ;*C* restore carry 20$: Pop TtInp ;~x~*C* Restore input mode ; Clc ;Errors have been taken care of Return ;~x~ ...... .Dsabl LSB .SbTtl C.LSTO - Stop learning ;+ ;C.LSTO ; ;FUNCTIONAL DESCRIPTION: ; ;Stop learning and save end of learned text ;- ;>>>are there any journal block boundary problems here? .Enable LSB C.LSto:: ;~x~ IsLrn OFF 20$ ;~x~Ignore unless learn mode LrnOff ;Set normal mode Clr LrnFlg ;No learning going on anywhere Mov L.Cur,R2 ;Point to current buffer descriptor Mov R2,X.Cur ;Change the "current" macro Tst RepCtr ;Did the user specify a repeat of ; Gld-s or Gld-x? Beq 10$ ;~x~No, okay Mov RepPtr,LnPtr ;Replace pointer with one before the ; repeat "nnnn" keystrokes ;Drop through to delete and ; first digit 10$: Sub #4,LnPtr ;~x~Backup and don't record Gld-s,Gld-x Mov LnPtr,L.BEnd(R2) ;Save end of commands Mov LnPtr,LrnNxt ;Keep track of where to start for ; next buffer 20$: Return ;~x~ ...... .Dsabl LSB .SbTtl C.EXEC - Stop learning and execute the "current" macro ;+ ;C.EXEC ; ;FUNCTIONAL DESCRIPTION: ; ;Execute the learned commands ;- .Enable LSB C.Exec:: ;~x~ Call C.LSto ;~x~Stop learning (if active) Call Nest ;~x~Nest current input modes Bcs 30$ ;~x~Couldn't nest, forget it Mov X.Cur,E.Cur ;Execute the "current" Br NstExe ;~x~Go nest and execute .............. .SbTtl C.EXS - Execute a specified macro ;+ ;C.EXS ; ;FUNCTIONAL DESCRIPTION: ; ;Execute a macro specified by the user ;- C.ExS:: Push BusyF ;~x~Save BusyF Clr BusyF ;Don't want "working" message now TtyIn ;~x~ Pop BusyF ;Restore BusyF CmpB R0,DefBuf ;Is it the default buffer? Beq 10$ ;~x~Yup, ok Call IsAlph ;~x~Is it alphabetic? Bcs 40$ ;~x~No, error 10$: Call FndLBf ;~x~Find correct buffer Bcs 40$ ;~x~Branch if it doesn't exist Repeat ;~x~ Call Nest ;~x~Try to nest the current input mode Bcs 30$ ;~x~Couldn't nest, forget it 20$: Mov R2,X.Cur ;~x~Found it, make it "current" Mov R2,E.Cur ;Execute it NstExe: Push R5 ;~x~Save the Nest register across spcexe Push TtInp ;Save journal status JouOff ;Don't journal executing keystrokes Call SpcExe ;~x~And go execute it Pop TtInp ;*C* Restore journal status Pop R5 ;*C* Restore the Nest register Ror -(SP) ;*C* Save carry Call UnNest ;~x~ Restore original input mode Rol (SP)+ ;*C* Restore carry 30$: Return ;~x~ ...... 40$: ;~x~ ;+ ;HELPER HELPER ;~x~ ;no macro by that name has been learned to execute ;- .Dsabl LSB .SbTtl ISALPH - Check to see if R0 is an alpha character ;+ ;ISALPH ; ;Functional description: ; ;Check to see if R0 contains an alphabetic character ; ;Output: ; R0 with #40 clear ; Carry clear - yes it's alphabetic ; Carry set - no, it isn't alphabetic ;- .Enable LSB IsAlph:: ;~x~ ;>>>Change for 8bit Bic #40,R0 ;Uppercase it CmpB R0,#'A ;Check bounds Blo 10$ ;~x~ CmpB #'Z,R0 ; 10$: Return ;~x~ .Dsabl LSB .SbTtl SPCEXE - Execute the "current" macro .SbTtl EXLOOP - Execute loop for macros and executable files ; ;SPCEXE ; ;FUNCTIONAL DESCRIPTION: ; ; Execute the buffer described at E.Cur ; .Enable LSB SpcExe: Mov E.Cur,R2 ;~x~Execute the current exec buffer Cmp L.Buf(R2),L.BEnd(R2) ;Are there any commands to execute?? Beq 60$ ;~x~Macro buffer is empty Repeat ;~x~Allow repeat counts Mov E.Cur,R2 ;Reset R2 for repeats Mov L.Buf(R2),TtPtr ;Setup command buffer ExLoop:: ;~x~ Push ;Save for recursion Bis #,TtInp ; CmdOn ;Start in command mode ; ExeOn ;Set exec mode ; ExIOn ;Set exec mode input 10$: IsExI OFF 50$ ;~x~Are we at the end of the buffer/file? ;Yes, do not execute the last function ; since it must be stop-learn or exec IsSer OFF 20$ ;~x~Are we doing the /RECOVER file? NO ;>>>JMP VWATCH ClrBsy ;~x~Stop "Working..." for a sec Mov #V.Updt,R0 ;Call to update screen Call VWatch ;~x~To show any changes SetBsy ;~x~Start "Working..." again 20$: Clr RepCtr ;~x~Zap the rep counter for next command IsCmd OFF 30$ ;~x~Are we in command mode? NO Call C.Comn ;~x~Go straight to Command routine Ror -(SP) ;*C* Save the carry bit Call RecPos ;~x~Include it in the journal Rol (SP)+ ;*C* Restore carry Br 40$ ;~x~*C* And around 'til done .......... 30$: TtyIn ;~x~Get a char from the commands Call CmdGo ;~x~Go exec a command 40$: Bcc 10$ ;~x~Keep going until there is an error Clr CtrlC ;Forgive and forget the abort CmdOff ;Note that this will get us out of ; command mode on any error IsSEr ON 10$ ;~x~Suppress the error? (/REC) yes Sec ;Keep carry set to stop REPEAT loop 50$: Pop ;~x~*C* Restore stack and repctr ExeOff ;*C* Clear exec mode Return ;~x~ ...... 60$: ;~x~ ;+ ;HELPER HELPER ;~x~ ;no macro has been learned to execute or it was already cleared ;- .Dsabl LSB .SbTtl RGNPOS - Regain previous cursor position ;+ ;RGNPOS - Regain position ; ;FUNCTIONAL DESCRIPTION: ; ; Go back to relative position given. Ignore abort info since the ;position counter will reflect exactly how far we got. ; ;INPUT ; R1 = Value of PosCtr to regain ; R2 = Value of PosCtr+2 to regain ;- .Enabl LSB RgnPos:: ;~x~ Push CtrlC ;Store control C status AbtOff ;Turn off abort mode 10$: Clr CtrlC ;~x~Clear indicator so that move routines ; will work Cmp PosCtr+2,R2 ;Which direction are we moving? Blt 30$ ;~x~Been moving backward, move up now Bne 20$ ;~x~Been moving foreward, move back now Cmp PosCtr,R1 ;Any characters left to move? Blo 30$ ;~x~Yup, move up Beq 40$ ;~x~Nope 20$: Call MvBkw ;~x~Step back a character Bcc 10$ ;~x~Til we're where we want to be Br 40$ ;~x~ ........... 30$: Call MvFwd ;~x~Step foreward a character Bcc 10$ ;~x~Til we're where we want to be 40$: Pop CtrlC ;~x~Restore Control C indicator to ; original status Return ;~x~ ...... .Dsabl LSB .SbTtl JOURNL - Store R0 in journal buffer ;+ ;JOURNL ; ;Put the contents of the low byte of R0 into the journal buffer and ;check for overflow. If there was overflow, query the user to see ;if s/he wants to continue. If not, exit. ;- .Enabl LSB Journl:: ;~x~ MovB R0,@JTPtr ;Put the character in the temp buffer Inc JTPtr ;And increment the pointer Cmp JTPtr,#JTPtr ;Did we overflow the buffer? Blt Ret.9 ;~x~No JouOff ;Terminate journaling Push TtInp ;Save input mode Clr TtInp ;Get response from terminal Jsr R4,ErrPmt ;~x~Find out if user wants to exit .Word EriJBO ;"Journal buffer overflow -Exit(Y,N)?" Beq 10$ ;~x~Exit Pop TtInp ;Restore input mode Return ;~x~Continue without journaling ...... 10$: Pop TtInp ;~x~Restore input mode CallR SpcExt ;~x~Say Goodnight Gracie .............. .If NE 0 ;never assemble here ;+ ;ERROR ErIJBO:: ;~d~ .Ascii /Journal preliminary buffer overflow - Exit session (Y,N)? / ;~d~ .Byte ;~d~ ;there is no more room in the temporary journal file buffer. The user ;may want to end the session at this point because further editing ;in this session will not be journaled. If the user replies "Y", an ;EXIT is performed (the text file is saved), otherwise the session is ;continued without journaling. ;- .EndC; NE 0 ;never assemble here .Dsabl LSB .SbTtl .SbTtl Input routines .SbTtl .SbTtl TNOWT - Input with no wait ;+ ; TNOWT - input with no wait ;- .Enable LSB TNoWt: IsRec ON TtyIn ;~x~Which mode? recover IsExe ON 50$ ;~x~Which mode? execute Call $TNoWt ;~x~Get a char Bcc 70$ ;~x~Go save a char Ret.9: Return ;~x~Return C set to caller ...... .SbTtl TTyIn - Input with wait ; ; TTyIn - input with wait ; TtyIn:: ;~x~ ;Recover mode input IsRec OFF 50$ ;~x~Which input mode? not recover Push R4 ;Save R4 Mov #Jo$Inp,R4 ;Look at recover file 10$: Call $GetCh ;~x~Get the next character from it Bcs 40$ ;~x~Done with this file CmpB R0,# ;This is the last character Beq 40$ ;~x~Done with this file ;>>>+*JMP* RT specific? CmpB R0,# ;Was that a carriage return? Bne 20$ ;~x~Nope, carry on SLFOn ;Flag that we should skip the next ; character if it's a Br 30$ ;~x~And move on ........... 20$: IsSLF OFF 30$ ;~x~Did we just get a last time? no SLFOff ;Clear it for next time CmpB R0,# ;Was this one a linefeed? Beq 10$ ;~x~Yup, skip it ;-*JMP* 30$: Pop R4 ;~x~*C* Restore R4 Br 70$ ;~x~And continue ........... 40$: Pop R4 ;~x~*C* Restore R4 Bic #,TtInp ;Get out of recover and execute ; RecOff ;Get out of recover mode ; ExIOff ;No characters left (or input error) ; clear to normal state and look Clr R0 ;Say null input to stop loop and Clr RecSsn ; get out of recover mode Return ;~x~ ...... ;Execute mode input 50$: IsExe OFF 60$ ;~x~Which input mode? normal MovB @TtPtr,R0 ;Execute mode- get a char Inc TtPtr ;Next byte Push R2 Mov E.Cur,R2 ;Look at the executing buffer's ; descriptor Cmp TtPtr,L.BEnd(R2) ;Done? Pop R2 ;*C* Blo 70$ ;~x~Nope ExIOff ;Yup, clear to normal state Br 70$ ;~x~ ........... ;Normal mode input (from keyboard) 60$: Call $TtyIn ;~x~Input a real char CmpB R0,# ;Was that a ^Z? Bne 70$ ;~x~No, carry on MovB #,R0 ;Yes, and it was keyboard input so ;call it ^C to prevent it being ;mistaken as EOF if it's stored in ;a macro or journal file ; STORING THE INPUT ;Learn mode storage 70$: IsLrn OFF 80$ ;~x~Learn mode? no MovB R0,@LnPtr ;Save it in learn mode Inc LnPtr ;Next byte Cmp LnPtr,TtBufE ;End of buffer Blo 80$ ;~x~Ok return ;Error- too much to learn Mov LrnNxt,LnPtr ;Back where we started Call 100$ ;~x~Signal the error from here Call BelErr ;~x~And bell the cat too Call C.LSto ;~x~Done learning (knowing too much can ; be dangerous) ;Journal mode storage 80$: IsJou OFF clc.1 ;~x~Journal the input? no Call Journl ;~x~Put the character in the temp buffer CmpB R0,# ;Was it a carriage return? Bne 90$ ;~x~Nope Push R0 ;Save CR MovB #,R0 ;Store the LF after the CR Call Journl ;~x~Put it in the temp journal buffer Pop R0 ;Restore CR 90$: IsExe OFF Clc.1 ;~x~Are we executing? no IsExI ON Clc.1 ;~x~Did we just reach the end of buffer? no CallR FixJou ;~x~Make sure journal file knows we're .............. ; going back to command mode ;Successful Return Clc.1: Clc ;~x~ Ret.6: Return ;~x~ ...... 100$: ;~x~ ;+ ;HELPER HELPER ;~x~ ;Too many bytes were entered; the capacity of the macro buffer was ;exceeded. ;- .Dsabl LSB .SbTtl NEST - Nest multiple input modes .SbTtl UNNEST - Unnest multiple input modes ;+ ;Nest, UnNest ; ;Functional description: ; ;First test to see if we're currently recovering a file or executing a macro, ;if so nest that information. Then do the same if we're currently learning. ;"Nest" stores the level of nesting used in R5 and "UnNest" uses that info, ;so don't destroy R5 between the calls. If "Nest" was called, "UnNest" must ;also be called. ; ;Output from Nest: ; ; R5 = level of nesting used plus 1. ; Carry clear if successful nest ; Carry set if couldn't do it - don't call UnNest in this case ; ;Input to UnNest: ; ; R5 = level of nesting used plus 1. (from successful NEST call) ;- .ENABL LSB Nest:: Mov #1,R5 ;~x~Assume there's no nesting IsExe OFF 10$ ;~x~Are we executing or recovering? no Call $Nest ;~x~Yes, save current mode info Bcs Ret.6 ;~x~Leave without nesting Inc R5 ;Remember to unnest when done 10$: IsLrn OFF Clc.1 ;~x~Are we learning? no Call $Nest ;~x~Yes, save current mode info Bcs UnNest ;~x~Unnest if necessary and leave Inc R5 ;Remember to unnest when done Br Clc.1 ;~x~Successful nesting ............. UnNest::Dec R5 ;~x~*C*Do we need to unnest? Beq Ret.6 ;~x~*C*No Call $Unnst ;~x~Yes, restore previous input mode Sec ;Always return carry set incase this was Br UnNest ;~x~*C* an unsuccessful attempt to nest .............. .DSABL LSB .END