Trailing-Edge
-
PDP-10 Archives
-
steco_19840320_1er_E35
-
10,5676/teco/newsrc/teccin.mac
There are 3 other files named teccin.mac in the archive. Click here to see a list.
SUBTTL Introduction
; Copyright (c) 1982 Stevens Institute of Technology, Hoboken, New Jersey
; 07030.
; This software may be used and copied provided that this copyright notice
;is included, and provided that copies of all modifications are sent to:
;
; TECO Project
; Computer Center
; Stevens Institute of Technology
; Castle Point Station
; Hoboken, New Jersey 07030
;
;
; The information in this software is subject to change without notice
; and should not be construed as a commitment by Stevens Institute of
; Technology.
; Search needed universals
SEARCH TECUNV ; TECO universal file
; Generate the prologue
TECVER==200 ; Major version number
TECMIN==1 ; Minor version number
TECEDT==1157 ; Edit level
TECWHO==0 ; Last editor
PROLOGUE(CIN,<TECO Command input routines>) ; Generate the TITLE and other stuff
$CODE ; Put things into code PSECT
SUBTTL Table of Contents
SUBTTL Revision History
COMMENT |
1145 By: Nick Bush On: 8-Febuary-1982
Re-write command input routines to implement FI command. As part of this
allow user to set prompt by storing the prompt text for normal commands in
the Q-register 'COMMAND-PROMPT'.
Modules: TECUNV,TECPRS,TECCIN,TECFCM,TECVID,TECUPD
1157 By: Nick Bush On: 28-April-1982
Fix command input to work correctly with a ^U after an escape on the
first line of a command.
Put in yet another check in an attempt to avoid PTD stopcodes for the command
buffer.
Modules: TECCIN,TECUPD
|
SUBTTL Special flags
; The following are special flags are stored in the saved character
;to indicate special processing that needs to be done when the
;character is read.
INTFLG C,LH.ALF,$$
FLAG ECH ; Character needs to be echoed if video mode
SUBTTL C$CINI - Initialize command input
;+
;.hl1 C$CINI
; This routine is used to initialize the command input routines.
;It will set the QRG where text is to be stored, and where the prompt
;is to come from.
;.lit
;
; Usage:
; T1/ Address of QRG
; T2/ Length of prompt
; PUSHJ P,C$CINI
; (return here always)
;
;.end lit
;-
C$CINI: MOVEM T1,CINQRG ; Save the QRG address
MOVEM T2,PMTLEN ; And the length of the prompt
POPJ P, ; And return
SUBTTL C$INPT - Command input processing.
;+
;.HL1 C$INPT
;This routine will input a command into a text buffer associated with
;a QRG block.
;It will not do any immdediate command processing.
;.literal
;
; Usage:
; T1/ Address of the QRG to use for inputting the command into
; T2/ Length of prompt (text already in QRG)
; CH/ 0 or first character of command (not yet echoed)
; PUSHJ P,C$INPT
; (Return)
;
; On return:
; - Text of the command stored.
;
;.end literal
;-
C$INPT: JUMPE CH,CINP.0 ; Any first character?
TXO CH,C$$ECH ; Flag it will need echoing in video mode
PUSHJ P,C$RCHR ; Yes, set up to fetch it
JRST CINP.4 ; And go get a character
; Here if we need to prompt
CINP.0: PUSHJ P,C$PRMT ; Prompt (or update screen)
; Here to get the input
CINP.4: PUSHJ P,C$ICHS ; Input a character with all processing
; Check if anything left of input. If not, then we should return so
;special first character things can be done.
MOVE T1,CINQRG ; Get the QRG address
LOAD. T1,TPTADR,+$QRTPT(T1) ; And get the address of the buffer
CFMG. T2,BLKPT,(T1),PMTLEN ; Anything left?
POPJ P, ; No, let caller figure it out
JUMPL CH,CINP.4 ; If we just edited something forget this
PUSHJ P,C$CEND ; Check if done
JRST CINP.5 ; All done
JRST CINP.4 ; Need more, keep going
; Here when done with the command
CINP.5: JMPS .POPJ1 ; Done if screen mode
AOS (P) ; Give skip return
PJRST .TCRLF ; Otherwise type a CRLF
SUBTTL C$PRMT - Prompt the user
;+
;.hl1 C$PRMT
; This routine will output the prompt (or update the screen) for the
;current QRG.
;-
C$PRMT: JMPS CPRM.V ; Skip this if video mode
SKIPN T2,PMTLEN ; Any prompt to type?
JRST CPRM.3 ; No, just force out the buffer
CPRM.1: MOVE T1,CINQRG ; Get the QRG address
LOAD. T1,TPTADR,+$QRTPT(T1) ; Get the address of the buffer
ADDX T1,<POINT 7,.BKTLN> ; Set up the byte pointer
CPRM.2: SOJL T2,CPRM.3 ; Done yet?
ILDB CH,T1 ; Get a character
PUSHJ P,T$OCHR ; Type it
JRST CPRM.2 ; And loop
CPRM.3: TXNE F,F.TYOF ; Any typeout left to force out?
PUSHJ P,TTYOUT ; Yes, force it
POPJ P, ; And return
; Here in video mode to update the screen
CPRM.V: SKIPL OUTFLG ; Check if any output was done
JRST CPRM.W ; No, just set up the input routine
SETZM OUTFLG ; Flag no output now
MOVEI T1,[ASCIZ |--Cont--|] ; Yes, get the prompt
PUSHJ P,V$ASK ; And ask him if he is done
CPRM.W: MOVE T1,CINQRG ; Get the QRG address
ZERO. ,QRGVAL,(T1) ; Clear out the fixed position value
BITOFF T2,QR$FIX!QR$SHF,$QRFLG(P1) ; Flag section should be updated to show current position
XMOVEI T1,$QRPDB(T1) ; Point to the old buffer pointer
SKIPE $TPADR(T1) ; Is there one?
PUSHJ P,M$RELB ; Yes, release it so that things are updated ok
MOVX T1,.TRUE ; Get the flag
PUSHJ P,SC$UPD ; And update the screen
PJRST V$CINI ; Initialize the input routines
SUBTTL C$CEND - Check for end of command.
;+
;.hl1 C$CEND
;This routine will check for the end of the current command processing.
;It will give a non-skip return if the end of the command is encountered and
;a skip return if it is not.
;.literal
;
; Usage:
; CH/ Current character
; PUSHJ P,C$CEND
; (Non-skip return)
; (Skip Return)
;
; On a non-skip return:
; - End of command
;
; On a skip return:
; - Not end of the command
;
;.end literal
;-
C$CEND: CAXE CH,.CHESC ; Yes, second escape?
PJRST .POPJ1 ; And give skip return
TXZ F,F.ECHO ; Clear echoing for one char
PUSHJ P,C$ICHR ; Get a character with editing
CAXE CH,.CHESC ; Second consecutive escape?
JRST CEND.1 ; No, echo the character
JMPNS CEND.E ; No echo needed for EVOFF
MOVX CH,"$" ; Yes, get a dollar sign
PUSHJ P,V$ECHO ; Echo it
MOVX CH,.CHESC ; And get the escape back
CEND.E: MOVE T1,CINQRG ; Get the QRG to append to
PJRST M$ACHR ; And append the character
; Here if it is not the end of the command. Echo the character and
;give skip return
CEND.1: AOS (P) ; Give skip return when done
TXO CH,C$$ECH ; Flag character needs to be echoed
PUSHJ P,C$RCHR ; Remember the character
POPJ P, ; Or just return if EVOFF$
SUBTTL C$ICHS - Input a character with special character processing.
;+
;.HL1 C$ICHS
;This routine will input a character. It will do any special character
;processing that is required. That is it will handle the control G and
;control R processing.
;.literal
;
; Usage:
; PUSHJ P,C$ICHS
; (Return)
;
; On return:
; CH/ Next non-special character
;
;.end literal
;-
BITMSK(SPCMSK,.CH,<CNG,CNR>) ; Define mask of interesting chars
C$ICHS: PUSHJ P,C$ICHE ; Get a character (with editing)
JUMPL CH,.POPJ ; If editing character, try again
MOVX T1,SPCMSK ; Get the mask of special characters
LSH T1,(CH) ; Shift it over
JUMPGE T1,.POPJ ; If not a special character, just return
XMOVEI T1,SPCTBL ; Get the table
PUSHJ P,DISP1 ; Do the function
POPJ P, ; Wasn't one, just return
POPJ P, ; Otherwise just return
SPCTBL: XWD C$CCNG,.CHBEL ; Control-G (bell)
XWD C$CCNR,$CHQOT ; Quoting character (^R)
XWD 0,0 ; End of table
SUBTTL C$CCNG - Process the control G special character
;+
;.HL1 C$CCNG
;This routine will handle the control G processing. It will cause the
;next character to be read. If the next character is a control G, space
;or period it will do some special processing.
;.literal
;
; Usage:
; PUSHJ P,C$CCNG
; (Return)
;
; On return:
; - Finished the processing.
;
;.end literal
;-
C$CCNG: PUSHJ P,C$ICHE ; Get the next character (with editing)
JUMPL CH,.POPJ ; Just return if it was edited away
$SAVE <P1> ; Save P1
MOVE P1,CH ; Copy the char
MOVEI T1,BELDSP ; Get the dispatch table address
SKPNS ; Screen mode?
MOVEI T1,VBELDS ; Yes, get correct table pointer
PUSHJ P,NDISPT ; Dispatch
MOVE CH,P1 ; Get the character back again
POPJ P, ; And return
; Dispatch table for ^G in non-video mode
BELDSP: XWD CNG.SP," " ; ^G<space>
XWD CNG.PR,"." ; ^G.
XWD CNG.BL,.CHBEL ; ^G^G
XWD 0,0
; Routines for ^G commands in non-video mode
CNG.SP: PUSHJ P,C$DLCH ; Delete a character
JFCL ; Never happens
PUSHJ P,C$DLCH ; Delete the second
JFCL ; Forget the error
MOVE T1,CINQRG ; Get the QRG address
LOAD. T1,TPTADR,+$QRTPT(T1) ; Get the buffer address
CFMG. T2,BLKPT,(T1),PMTLEN ; Anything other than the prompt?
JRST CCNU.F ; No, go delete that
PUSHJ P,C$RPRT ; Reprint the line
SETO CH, ; Flag no character left
POPJ P, ; And return
CNG.PR: PUSHJ P,C$DLCH ; Delete a character
JFCL ; Never happens
PUSHJ P,C$DLCH ; Delete the second
JFCL ; Ignore this
MOVE T1,CINQRG ; Get the QRG address
LOAD. T1,TPTADR,+$QRTPT(T1) ; Get the buffer address
CFMG. T2,BLKPT,(T1),PMTLEN ; Anything other than the prompt?
JRST CCNU.F ; No, go delete that
PUSHJ P,CRPR.A ; ^G. reprints entire command
SETO CH, ; Flag nothing left
POPJ P, ; And return
CNG.BL: MOVE T1,PMTLEN ; Delete back to the prompt
PUSHJ P,C$DLTX ; . . .
PUSHJ P,.TCRLF ; Type a CRLF
SETO CH, ; Flag nothing left
POPJ P, ; And return
; Table for ^G in video mode
VBELDS: XWD CNG.VS," " ; ^G<space>
XWD CNG.VS,"." ; ^G. (same as ^G<space>)
XWD CNG.VB,.CHBEL ; ^G^G
XWD 0,0
; Here on ^G<space> or ^G.
CNG.VS: PUSHJ P,C$DLCH ; Delete the character
JFCL ; Ignore it
PUSHJ P,C$DLCH ; And the second
JFCL ; Shouldn't happen
MOVE T1,CINQRG ; Get the Q-reg we are using
LOAD. T2,TPTADR,+$QRTPT(T1) ; Get the text buffer address
CFMG. T3,BLKPT,(T2),PMTLEN ; More than just the prompt?
JRST CCNU.E ; No, just refresh things
PJRST V$CTRG ; Yes, fix things up
; Here one ^G^G
CNG.VB: PUSHJ P,CCNU.E ; Just delete the world and refresh things
SETO CH, ; Flag nothing left
POPJ P, ; And return
SUBTTL C$CCNR - Process the control R special character
;+
;.HL1 C$CCNR
;This routine will hanlde the control R quoting character processing.
;It will quote any character except a delete, control U or a control W.
;.literal
;
; Usage:
; PUSHJ P,C$CCNR
; (Return)
;
; On return:
; CH/ Quoted character.
; or -1 if ^R was edited away
;
;.end literal
;-
C$CCNR: PUSHJ P,C$ICHE ; Get the next character
JUMPL CH,.POPJ ; Just return if edited away
PJRST C$ICHE ; Otherwise, try again
SUBTTL C$ICHE - Input a character with editing
;+
;.HL1 C$ICHE
;.literal
;
; Usage:
; CINQRG/ QRG to append the character to
; PMTLEN/ Length of text that is the prompt (already in QRG)
; PUSHJ P,C$ICHE
; (Return)
;
; On return:
; CH/ Character that was input (=-1 if editing character)
; Character appended to buffer (or characters deleted)
;
;.end literal
;-
BITMSK(EDCMSK,.CH,<CNH,CNW,CNU>) ; Define mask for interesting chars
C$ICHE: PUSHJ P,C$ICHR ; Get a character
MOVX T1,EDCMSK ; Get the mask of editing characters
LSH T1,(CH) ; Check if special character
CAXE CH,.CHDEL ; Delete?
JUMPGE T1,ICHE.1 ; No, other special character?
; Here if the character is an editing character.
;Call the correct routine for handling it
XMOVEI T1,EDCTBL ; Get the table address
TXNE CRT,CR$TTY ; Want backspace editing?
XMOVEI T1,EDCTB1 ; No, leave that out
PUSHJ P,DISP1 ; Dispatch on the character
JRST ICHE.1 ; Not in table, just append it in
SETO CH, ; Flag some editing was done
POPJ P, ; And return
; Here if the character should be appended to the buffer.
ICHE.1: MOVE T1,CINQRG ; Get the QRG address
PUSHJ P,M$ACHR ; Append the character
MOVE T1,CINQRG ; Get the QRG address
LOAD. T1,TPTADR,+$QRTPT(T1) ; Get the address of the buffer
LOAD. T3,BLKEND,(T1) ; Get the final address
MOVE T2,T3 ; And get a copy
SOJ T2, ; Plus one
PJRST UPDBND ; Update the bounds
; Dispatch table for editing characters
EDCTBL: XWD C$CCNH,.CHCNH ; Backspace (control-H)
EDCTB1: XWD C$DELE,.CHDEL ; Delete
XWD C$CCNW,.CHCNW ; Control-W
XWD C$CCNU,.CHCNU ; Control-U
XWD 0,0 ; End of table
SUBTTL C$CCNW - Process a control W editing character
;+
;.HL1 C$CCNW
; This routine will handle control-W editing characters. This will
;delete the previous word, or the previous delimeter if the previous item
;is not a word.
;.literal
;
; Usage:
; PUSHJ P,C$CCNW
; (Return)
;
; On return:
;
;.end literal
;-
C$CCNW: MOVE T1,CINQRG ; Get the QRG we are using
LOAD. T1,TPTADR,+$QRTPT(T1) ; Get the address of the buffer
PUSHJ P,C$DWRD ; Find the start of the word
CAMGE T1,PMTLEN ; Hit the prompt?
JRST CCNU.0 ; Yes, act like control-U
JMPNS CCNW.1 ; Video mode works different
CAMG T1,PMTLEN ; Deleting back to the prompt?
JRST CCNU.E ; Yes, just update or reprompt
PUSHJ P,C$DLTX ; Delete the text
MOVX T1,.TRUE ; Put cursor and end of command
PJRST V$UPCM ; Update the command display
; Check how many characters being deleted. Just ignore 0 characters,
;and handle 1 character like a delete.
CCNW.1: TXNN CRT,CR$RUB ; Old style rubouts?
CAMLE T1,PMTLEN ; No, anything left other than the prompt?
JRST .+2 ; Keep going
JRST CCNU.F ; Get rid of everything
$SAVE <P1,P2,P3,P4> ; Save some ac's
MOVE P4,CINQRG ; Get the QRG address
LOAD. P4,TPTADR,+$QRTPT(P4) ; Get the address of the buffer
MOVE P1,T1 ; Put into safer place
LOAD. T1,BLKEND,(P4) ; Get the final address
SUB T1,P1 ; See how many are being deleted
TXNE CRT,CR$RUB ; Old rubout treatment?
JRST CCNW.R ; Yes, go handle it
CAMGE P1,PMTLEN ; Only the prompt?
JRST [PUSHJ P,CCNW.B ; Delete the ^W
JRST CDEL.0] ; And delete the character
CAMG P1,PMTLEN ; Anything left past the prompt?
JRST CCNW.B ; Back up over two characters (^W)
JRST CCNW.2 ; Fancy rubout, go handle it
; Here for old rubout style treatment of ^W. We will just type out the
;characters backwards.
CCNW.R: MOVE P1,T1 ; Get the number of characters to delete
CCNW.O: PUSHJ P,C$DLCH ; Kill the character
STOPCD PWD,<Part of word disappeared>
PUSHJ P,T$OCHR ; Type the character out
SOJG P1,CCNW.O ; And keep deleting
POPJ P, ; And return
; To properly handle words which wrap around line boundaries, we
;will determine the position of the final character which will be left,
;and then determine how many (if any) line boundaries the word being
;deleted crosses.
CCNW.2: PUSHJ P,C$BLIN ; Find the start of this line
CAMN T1,P1 ; If start of line and start of word are
JRST CCNU.0 ; the same, just act line an ^U
MOVE P2,T1 ; Otherwise, get the current position
SUBM P1,P2 ; Get the number of characters to skip
BLDBPT (T1,(P4)) ; Set up the byte pointer
MOVE P3,T1 ; Get the byte pointer
SETZ T2, ; Clear the line position
CCNW.3: ILDB CH,P3 ; Get a character
PUSHJ P,C$CLEN ; And get the position
CAMLE T2,TRMWID ; Need to wrap yet?
JRST [SUB T2,TRMWID ; Correct for wrap-around
SOJA T2,.+1] ; . . .
SOJG P2,CCNW.3 ; Keep getting the width until we hit the spot
; Save the horizontal position, and see whether the word wraps
PUSH P,T2 ; Save the current position
LOAD. P2,BLKEND,(P4) ; Get the end address of the buffer
SUB P2,P1 ; And determine how many characters are being deleted
SETZ P4, ; Initialize a counter for times the word wraps
CCNW.4: ILDB CH,P3 ; Get a character
PUSHJ P,C$CLEN ; Get the character length
CAMG T2,TRMWID ; Need to wrap now?
JRST CCNW.5 ; No, skip this
SUB T2,TRMWID ; Correct for the wrap-around
SOJ T2, ; . . .
AOJ P4, ; Count the line
CCNW.5: SOJG P2,CCNW.4 ; And loop for all characters
ADDI T2,2 ; Account for the echo of the ^W
CAMLE T2,TRMWID ; Need to wrap because of that?
JRST [SUB T2,TRMWID ; Yes, do it
AOJ P4, ; Count the line
SOJA T2,.+1] ; . . .
POP P,T1 ; Get the old width back
JUMPN P4,CCNW.6 ; If the word is on more than one line, go handle
SUB T2,T1 ; No, get the number of characters to delete
MOVE P2,T2 ; Get into safe place
TXNE CRT,CR$CTU ; Terminal have a delete to EOL?
JRST CCNW.7 ; Yes, do it that way
CCNW.C: MOVE T1,$CRBCK(CRT) ; Get the backspace sequence
PUSHJ P,SC$MES ; Output it
PUSHJ P,C$ERS1 ; Kill the character
SOJG P2,CCNW.C ; . . .
MOVE T1,P1 ; Get the number to delete
PJRST C$DLTX ; Delete the characters
; Here if the word is on one line and the terminal has a DEL function.
CCNW.7: MOVE T1,$CRBCK(CRT) ; Get the back cursor sequence
PUSHJ P,SC$MES ; Output the sequence
SOJG P2,CCNW.7 ; Back up enough
XCT $CRDEL(CRT) ; Delete the end of the line
MOVE T1,P1 ; Get the number to delete
PJRST C$DLTX ; Delete the characters
; Here if the word spans lines. This is a real problem on terminals
;without a delete to end of line since it can be very expensive to delete
;all those characters.
; On terminals which have a DEL and DLF functions, we will use them
;to go up the page to the line with the word. On terminals without,
;we will leave the ^W there and reprint the start of the line that
;is left.
CCNW.6: TXNN CRT,CR$NCR ; Allowed to have free CR's?
TXNN CRT,CR$CTU ; And have a DEL function?
JRST CCNW.8 ; No, must do strange way
XCT $CRCTU(CRT) ; Delete this line
CCNW.9: XCT $CRDLF(CRT) ; No, go up one line
XCT $CRDEL(CRT) ; And delete it
SOJG P4,CCNW.9 ; Keep trying
MOVE T1,P1 ; Get the deletion point
PUSHJ P,C$DLTX ; Delete the text
MOVEI CH,.CHCRT ; Keep the monitor informed of where we are
PUSHJ P,T$OCHR ; Type it
PUSHJ P,T$OCHR ; (second one to make sure everyone is happy)
JRST CRPR.0 ; And go type the line back out
; Here if the terminal is stupid.
CCNW.8: MOVE T1,P1 ; Get the amount to delete
PUSHJ P,C$DLTX ; Do it
PJRST C$RPRT ; And type the start of the line out
; Here to delete the ^W from the screen and back up over the previous
;character
CCNW.B: MOVE T1,$CRBCK(CRT) ; Get the backspace seequnce
PUSHJ P,SC$MES ; Back up one
PUSHJ P,C$ERS2 ; Eat two chars
MOVE T1,$CRBCK(CRT) ; And back up one more
PJRST SC$MES ; and return
SUBTTL C$CCNU - Process a control U editing character
;+
;.HL1 C$CCNU
; This routine will handle the control-U editing character. This
;will delete back to the beginning of the current line, or, if the
;last character was an end-of-line, and we are in video mode, it will
;delete the previous line.
;.literal
;
; Usage:
; PUSHJ P,C$CCNU
; (Return)
;
; On return:
;
;.end literal
;-
C$CCNU: JMPS CCNU.1 ; Process the video one
CAXN CH,.CHCNU ; Was this on a ^U character?
PUSHJ P,T$OCHR ; Yes, we must echo it
CCNU.0: SKPS ; Skip this in screen mode
XCT $CRCTU(CRT) ; Do the function
CCNU.1: PUSHJ P,C$BLIN ; Find the start of this line
CAMG T1,PMTLEN ; Are we hitting the prompt?
JRST CCNU.E ; Yes, delete everything back to it
MOVE T2,CINQRG ; Get the QRG address
LOAD. T2,TPTADR,+$QRTPT(T2) ; Get the address of the buffer
CFMN. ,BLKEND,(T2),T1 ; Were we already at the start of a line?
JMPNS CCNU.2 ; Yes, need to check for previous line in screen mode
PUSHJ P,C$DLCH ; Delete the previous character (EOL)
JRST CCNU.E ; If nothing left, all done
CAXE CH,.CHLFD ; Need to check for CRLF?
JRST CCNU.3 ; No, skip the check
MOVE T1,CINQRG ; Get the QRG we are reading into
LOAD. T1,TPTADR,+$QRTPT(T1) ; Yes, get the address of the buffer
LOAD. T2,BLKEND,(T1) ; And the last character address
SOJ T2, ; Minus one to fetch last character
IDIVI T2,5 ; Convert to byte pointer
TDO T2,BTAB(T3) ; . . .
ADD T2,T1 ; . . .
ADDX T2,.BKTLN ; . . .
LDB CH,T2 ; Get the character before what we just deleted
CAXN CH,.CHCRT ; Carriage return?
PUSHJ P,C$DLCH ; Yes, delete it
JRST CCNU.E ; If nothing left, all done
CCNU.3: PUSHJ P,C$BLIN ; Find the start of the line
CAMG T1,PMTLEN ; Deleting into the prompt?
JRST CCNU.E ; Yes, just go try again
CCNU.2: PUSHJ P,C$DLTX ; Delete the text
JMPNS .POPJ ; If not screen more, we are all done
MOVX T1,.TRUE ; Put cursor at end of command
PJRST V$UPCM ; Otherwise, do the screen update
; Here if the entire buffer is being deleted. Delete the text from
;the buffer and either re-prompt (non-video), or update the whole screen.
CCNU.F: XCT $CRCTU(CRT) ; Kill whatever is there
CCNU.E: MOVE T1,PMTLEN ; Get where to delete to
PUSHJ P,C$DLTX ; Delete the text
JMPS [SETO CH, ; Flag editing was done
POPJ P,] ; And return
TXNN CRT,CR$NCR ; Allowed to have free CR's?
TXNN CRT,CR$CTU ; Have a control-U string?
JRST [PUSHJ P,.TCRLF ; No, print a CRLF
SETO CH, ; Flag editing character
POPJ P,] ; And return
MOVX T1,<BYTE(7).CHCRT,.CHCRT> ; Send a couple CR's first
PUSHJ P,SC$MES ; Output the CR's
SETO CH, ; Flag editing character
POPJ P, ; And return
SUBTTL C$CCNH - Process a control H editing character
;+
;.HL1 C$CCNH
;.literal
;
; Usage:
; PUSHJ P,C$CCNH
; (Return)
;
; On return:
;
;.end literal
;-
C$CCNH: JMPS CDEL.V ; If video mode, go handle it
MOVE T1,$CRCBS(CRT) ; Get the string to cancel the backspace
PUSHJ P,SC$MES ; Do it
JRST CDEL.0 ; And delete the character
SUBTTL C$DELE - Process a delete editing character
;+
;.HL1 C$DELE
;This rutine will handle deleting a character with the rubout
;character (177). It will cause the screen to update, or the text to be
;typed on the terminal, etc.
;.literal
;
; Usage:
; T1/ QRG text is being deleted from
; PUSHJ P,C$DELE
; (Return)
;
; On return:
; - Proper handling finished.
;
;.end literal
;-
C$DELE: TXNN CRT,CR$RUB ; Check if old type of rubout processing wanted?
JRST CDEL.1 ; No, do fancy stuff
C$RUBO: PUSHJ P,C$DLCH ; Kill the character
JRST CCNU.F ; Empty?
TXO S,S.OLOG ; Suppress one character to the log file
PUSHJ P,T$OCHR ; Type the character out
POPJ P, ; Return
; Here if we want special processing of rubouts.
CDEL.1: JMPS CDEL.V ; Video mode?
MOVE T1,CINQRG ; Get the QRG address
LOAD. T1,TPTADR,+$QRTPT(T1) ; And determine the address of the buffer
CFMG. T2,BLKPT,(T1),PMTLEN ; Just the prompt left?
JRST CCNU.F ; And exit through common routine
MOVE T1,$CRCRB(CRT) ; Get the string to cancel the rubout
PUSHJ P,SC$MES ; Type the string
; Here to delete the previous character because of either a delete or
;backspace being typed.
CDEL.0: PUSHJ P,C$HPOS ; Get the position
$SAVE <P1,P2,P3,P4> ; Save some ac's
DMOVE P3,T1 ; Copy the informaion
PUSHJ P,C$DLCH ; Delete the character from the buffer
POPJ P, ; Nothing left, all done
PUSH P,CH ; Save the character
PUSHJ P,C$HPOS ; Go gigure out the horizontal position
DMOVE P1,T1 ; Get the position information
POP P,T1 ; Get the character back
PUSHJ P,CDEL.2 ; Delete the character from the screen
MOVE T1,CINQRG ; Get the address of the QRG
LOAD. T1,TPTADR,+$QRTPT(T1) ; Get the address of the buffer
CFMG. T2,BLKPT,(T1),PMTLEN ; Anything more than the prompt?
JRST CCNU.F ; Yes, wipe it out
POPJ P, ; No, just return
; Check for special characters
CDEL.2: CAXG T1,.CHBEL ; Control G or less ?
JRST C$DCH2 ; Delete the two char wide character
CAXN T1,.CHCNH ; Is this a backspace ?
JRST C$DCM1 ; Delete a backspace
CAXN T1,.CHTAB ; Is this a tab ?
JRST C$DCTB ; Delete an end of line
CAXN T1,.CHLFD ; Line feed?
JRST C$DCEL ; Yes, delete it
CAXG T1,.CHFFD ; EOL? (LF, VT1, FF)
JMPNS C$DCEL ; Delete an end of line
CAXN T1,.CHCRT ; Carriage return ?
JRST C$DCCR ; Yes - Delete it
CAXE T1,.CHESC ; Is this an altmode ?
CAXL T1," " ; or .GE. a blank ?
JRST C$DCH1 ; Yes - Delete a single character
PJRST C$DCH2 ; No, it is two characters wide
; Here in video mode to delete one character
CDEL.V: PUSHJ P,V$DELC ; Delete one character
POPJ P, ; Return
JRST CCNU.E ; Nothing left
SUBTTL C$DLCH - Routine to delete one character from the buffer
;+
;.HL1 C$DLCH
; This routine will delete the last character in the text buffer.
;.lit
;
; Usage:
; PUSHJ P,C$DLCH
; (Return, buffer empty)
; (Return, character deleted)
; On skip return:
; CH/ Character which was deleted
;
;.end lit
;-
BACKUP::
C$DLCH: MOVE T3,CINQRG ; Get the Q-reg we are using
LOAD. T3,TPTADR,+$QRTPT(T3) ; Get the text buffer address
LOAD. T1,BLKPT,(T3) ; Get the address of PT
SOJ T1, ; Decrement the position
CAMGE T1,PMTLEN ; Anything left past the prompt?
POPJ P, ; No, can't delete the prompt
STOR. T1,BLKPT,(T3) ; Decrement the pointer
MOVE T1,T3 ; Get the address of the buffer
LOAD. T2,BLKEND,(T1) ; And the final character
MOVE T3,T2 ; Get a copy
SOJ T2, ; Fix up to indicate last character being killed
PUSHJ P,UPDBND ; And update the bounds
MOVE T3,T1 ; Get the buffer address back
LOAD. T1,BLKPT,(T3) ; Get the pointer back
DECR. T4,BLKEND,(T3) ; Adjust Z
INCR. T4,BLKFRE,(T3) ; Adjust the number free
IDIVI T1,5 ; Build a byte pointer
ADDI T1,.BKTLN(T3) ; Point to the correct word
HLL T1,BTAB(T2) ; Fill in the rest of the byte pointer
LDB CH,T1 ; Get the character
JRST .POPJ1 ; Give a skip return
SUBTTL C$DLTX - Routine to delete some text from the buffer
;+
;.hl1 C$DLTX
; This routine will delete back to a given point in the buffer.
;.lit
;
; Usage:
; T1/ Desired final address
; PUSHJ P,C$DLTX
; (Return, text deleted)
;
;.end lit
;-
C$DLTX: MOVE T3,T1 ; Get the offset
MOVE T1,CINQRG ; Get the Q-reg
LOAD. T1,TPTADR,+$QRTPT(T1) ; Get the text buffer address
LOAD. T2,BLKEND,(T1) ; Get the end pointer
SUB T2,T3 ; And get the number of characters we are deleting
JUMPE T2,.POPJ ; If none being deleted, skip this
LOAD. T4,BLKPT,(T1) ; Get the pointer address
SUB T4,T2 ; Decrement the pointer
JUMPGE T4,.+2 ; Don't let it get negative
SETZ T4, ; . . .
STOR. T4,BLKPT,(T1) ; Update the pointer
MOVE T2,T3 ; Get the first character killed
LOAD. T3,BLKEND,(T1) ; And the last
PUSH P,T2 ; Save T2
PUSH P,T3 ; And T3
PUSHJ P,UPDBND ; Update the bounds
POP P,T3 ; And restore the info
POP P,T2 ; To actually delete the characters
EXCH T2,T3 ; Fix up for shrinking buffer
SUB T2,T3 ; And get the amount being killed
PUSHJ P,M$SRNK ; Shrink the buffer
POPJ P, ; And return
SUBTTL C$DCxx - Routines to delete characters from the screen
;+
;.HL1 C$DCxx
; These routines are used to rubout characters on the screen of a CRT when
;we are not in video mode (EVOFF).
;.lit
;
; Usage:
; CH/ Character being deleted
; P1/ Length of last character before being deleted
; P2/ Column that current text runs to
; P3/ Length of character being deleted
; P4/ Column after character being deleted
; PUSHJ P,C$DCxx
; (return)
;
;.end lit
;.hl2 C$DCH1
; This routine will delete a one character wide character field.
;-
C$DCH1: PUSHJ P,C$ERS1 ; Delete one character
PJRST C$DCFN ; And finish up
;+
;.hl2 C$DCH2
; This routine will rubout a two character wide character from the
;terminal.
;-
C$DCH2: PUSHJ P,C$ERS2 ; Rubout the characters
FALL C$DCFN ; And finish up
;+
;.hl2 C$DCFN
; This routine will finish up from deleting a character.
;-
C$DCFN: CAMG P2,P4 ; Finished ?
POPJ P, ; All done
FALL C$DCRW ; Line was wrapped and now is not, retype things
;+
;.HL2 C$DCRW
; This routine will reprint the current command. It is used when
;a character is deleted which terminated the line on the screen.
;-
C$DCRW: XCT $CRDLF(CRT) ; Delete a line
TXNN CRT,CR$NWP ; Terminal wrap around backwards?
XCT $CRDLF(CRT) ; No, delete another line feed
TXNE CRT,CR$NCR ; Allowed the free CR's?
JRST C$RPRT ; Reprint the line
MOVEI CH,.CHCRT ; Get a carriage return
PUSHJ P,T$OCHR ; And output it
PUSHJ P,T$OCHR ; Make sure it really gets out
; (problem in DM1520A loses the first one)
JRST CRPR.0 ; Reprint the line (minus the CRLF)
;+
;.HL2 C$DCM1
; Here to delete a character which is minus one columns wide (backspace).
;Just send the string to blank a character.
;-
C$DCM1: MOVE T1,$CRSPC(CRT) ; Get the text to blank out the character
PJRST SC$MES ; Send it to the terminal
;+
;.HL2 C$DCTB
; Here to delete a tab. To do this we must figure out what column the tab
;started in and then delete back to that pointer
;-
C$DCTB: JUMPE P4,C$DCFN ; If at the beginning of the line go retype if needed
SUB P4,P2 ; Determine how much to back up
SOJLE P4,.POPJ ; If nothing to type, don't bother
CDCT.0: MOVE T1,$CRBCK(CRT) ; Get the string address
PUSHJ P,SC$MES ; Back up
SOJG P4,CDCT.0 ; Loop
POPJ P, ; And return
;+
;.HL2 C$DCCR
; This routine will delete a carriage return.
;-
C$DCCR: MOVE T1,$CRSPC(CRT) ; Get the forward cursor
TXNE CRT,CR$WAP ; Wrap around forward work?
TXNN CRT,CR$NWP ; Yes, also wrap around backwards?
JRST .+2 ; One or the other doesn't work
PUSHJ P,SC$STR ; Both work, put back at column 0
SKIPE T1,$CRDCR(CRT) ; Get the address of the text to output
PUSHJ P,SC$STR ; Output it
PJRST CRPR.0 ; Act like a ^G<space>
;+
;.HL2 C$DCEL
; This routine will delete a end of line character
;-
C$DCEL: ADDI T1,(CRT) ; Get the block address plus the character
MOVE T3,$CRDLF-.CHLFD(T1) ; Get the proper string
MOVE T1,$CRSPC(CRT) ; Undo the backspace
TXNE CRT,CR$NWP ; Does this terminal wrap around backwards?
SKIPE P2 ; Yes, are we at column 0?
JRST .+2 ; Don't need to kill the backspace
DCEL.1: PUSHJ P,SC$MES ; kill the effect of a backspace
JUMPE T3,C$DCFN ; Have something to do?
XCT T3 ; Yes, do it
JRST C$DCFN ; And continue on
SUBTTL C$ERS1 and C$ERS2 - Routines to erase characters from screen
;+
;.HL2 C$ERS1 and C$ERS2
; These routines will erase characters from the CRT. C$ERS1 will handle
;a single character position, and C$ERS2 will do two character positions.
;-
C$ERS2::PUSHJ P,C$ERS1 ; Get the first character
MOVE T1,$CRBCK(CRT) ; Get the back cursor sequence
PUSHJ P,SC$MES ; Do it
FALL C$ERS1 ; And fall into routine to erase second character
C$ERS1::MOVE T1,$CRDBS(CRT) ; Get the string
PJRST SC$MES ; And output it
SUBTTL C$RPRT - Reprint the last line
;+
;.HL1 C$RPRT
; This routine will reprint some text from the current command buffer.
;.lit
;
; Usage:
; PUSHJ P,C$RPRT ; Type a CRLF and current line
;
; PUSHJ P,CRPR.0 ; Just type current line
;
; PUSHJ P,CRPR.A ; Print CRLF and entire command
;
;.end lit
;-
C$RPRT: PUSHJ P,.TCRLF ; Output a CRLF
CRPR.0: MOVE T1,CINQRG ; Get the address of the QRG we are inputting
PUSHJ P,C$BLIN ; Find the start of the line
$SAVE <P1,P2,P3> ; Save some ac's
MOVE P1,CINQRG ; Get the QRG address
LOAD. P1,TPTADR,+$QRTPT(P1) ; Get the address of the buffer
LOAD. P2,BLKPT,(P1) ; Get the current position
SUB P2,T1 ; And get the amount to type
JRST CRPR.1 ; Join common routine
; Here to print entire buffer
CRPR.A: PUSHJ P,.TCRLF ; Type a CRLF
CRPR.B: $SAVE <P1,P2,P3> ; Save P1 and P2
MOVE P1,CINQRG ; Get the QRG address
LOAD. P1,TPTADR,+$QRTPT(P1) ; Get the address of the text
LOAD. P2,BLKPT,(P1) ; And the amount to type
SETZ T1, ; Type from start of buffer
; Common code for printing from given position
CRPR.1: IDIVI T1,5 ; Make the byte pointer
TDO T1,BTAB-1(T2) ; . . .
ADDX T1,.BKTLN ; And point to the text
ADD T1,P1 ; . . .
MOVE P3,T1 ; Get the pointer into a safe place
; Here to loop typing characters
CRPR.2: SOJL P2,.POPJ ; Done?
ILDB CH,P3 ; Get a character
PUSHJ P,T$OCHR ; Type it
JRST CRPR.2 ; Get the next character
SUBTTL C$HPOS - Determine horizontal position
;+
;.HL2 C$HPOS
;This routine will determine the horizonntal position of the current character
;in the command string.
;.literal
;
; Usage:
; PUSHJ P,C$HPOS
; (Return)
;
; Returns:
; T1 - The length of the last character
; T2 - The character position
;.end literal
;-
C$HPOS: PUSHJ P,C$BLIN ; Back to the beginning of the line
$SAVE <P1,P2> ; Save P1/P2
MOVE P1,CINQRG ; Get the QRG address
LOAD. P1,TPTADR,+$QRTPT(P1) ; Get the command buffer address
MOVE P2,T1 ; Copy the character address
IDIVI T1,5 ; Make a byte pointer
HLL T1,BTAB-1(T2) ; . . .
ADDI T1,.BKTLN(P1) ; Get the address of the text in the block
LOAD. T2,BLKPT,(P1) ; Get the character address of point
SUB T2,P2 ; Compute the length
MOVE P1,T1 ; Copy both items over
EXCH T2,P2 ; And switch the others
SETZ T1, ; Assume we start counting from zero
MOVE T2,T1 ; Copy the address of the first character
CHPO.0: SOJL P2,.POPJ ; Return if at it
ILDB CH,P1 ; Get the first character
PUSHJ P,C$CLEN ; Determine the length of the character
CAMLE T2,TRMWID ; Wider then allowed ?
SETZ T2, ; Yes - Set the width to zero
JRST CHPO.0 ; Loop until done
SUBTTL C$CLEN - Determine length of character
;+
;.HL2 C$CLEN
;This routine will return the length of the character that is given it.
;It will also update the character position on the line of the character,
;this is mainly for tabs.
;.literal
;
; Usage:
; MOVE CH,Character
; MOVE T2,Line.position
; PUSHJ P,C$CLEN
; (Return)
;
; Returns:
; T1 - Length of the character
; T2 - Updated line position.
;.end literal
;-
C$CLEN: SETZ T1, ; Clear the lenght
CAXE CH,.CHESC ; Is this an altmode ?
CAXL CH," " ; Or anything " " or over ?
AOJA T1,CLEN.1 ; Yes - It has a width of one
CAXN CH,.CHCRT ; Is this a carriage return?
JRST [SETZB T1,T2 ; Yes, that puts us at column 0
POPJ P,] ; Return the zeros
CAXN CH,.CHCNH ; Is this a backspace ?
SOJA T1,.POPJ ; Yes - Width of minus one
CAXN CH,.CHLFD ; A linefeed is zero
JRST CLEN.1 ; Return to the caller
CAXN CH,.CHVTB ; A vertical tab may be special
JRST [JMPS CLEN.3 ; If screen processing then 2
ADD T1,$CRWVT(CRT) ; Else use the value in theblock
JRST CLEN.1]
CAXN CH,.CHFFD ; A form feed might also
JRST [JMPS CLEN.3 ; If screen processing then 2
ADD T1,$CRWFF(CRT) ; Else use the value in the block
JRST CLEN.1]
CAXE CH,.CHTAB ; A tab ?
JRST CLEN.3 ; No - Use the width of 2
TXO T2,7 ; Make it at the tab stop
AOJ T2, ; Bump so we go to the next
MOVEI T1,^D8 ; Get the length
POPJ P, ; Return
; Here for control characters. The width is two
CLEN.3: MOVEI T1,2 ; Add in the width
CLEN.1: ADD T2,T1 ; This is the new length
POPJ P, ; Return
SUBTTL C$BLIN - Determine start of line
;+
;.HL2 C$BLIN
;This routine will determine the beginning of the line of the command.
;It will set up the registers for calling NLINE and then call it.
;.literal
;
; Usage:
; PUSHJ P,C$BLIN
; (Return -- T1 contains the character address)
;.end literal
;-
C$BLIN: MOVE T1,CINQRG ; Get the address of the QRG
LOAD. T1,TPTADR,+$QRTPT(T1) ; Get the text buffer address
JMPS C$BL.Z ; If video mode, different break set
LOAD. T1,BLKPT,(T1) ; And save PT
PUSH P,T1 ; . . .
C$BL.0: SETZ A1, ; Back to the beginning of the line
PUSHJ P,GETCMD ; Do the argument processing
MOVE T1,A2 ; Return it in T1
SOJL T1,C$BL.2 ; If we hit the beginning of the buffer return this value
SOJL T1,C$BL.2 ; If only one character from start of buffer return zero
IDIVI T1,5 ; Make the word offset
HLL T1,BTAB(T2) ; And make the byte pointer
MOVE T2,CINQRG ; Get the QRG to use
LOAD. T2,TPTADR,+$QRTPT(T2) ; Get the command buffer address again
ADDI T1,.BKTLN(T2) ; And make the byte pointer absolute
LDB T3,T1 ; Get the character before the pointer
CAXE T3,.CHFFD ; Is this a form feed ?
CAXN T3,.CHVTB ; Or a vertical tab ?
JRST C$BL.3 ; Yes, end of the line
CAXE T3,.CHCRT ; Is it a carriage return?
JRST C$BL.1 ; No, back up some more
ILDB T3,T1 ; Yes, get the next character
CAXE T3,.CHLFD ; Is it a line feed?
JRST C$BL.1 ; No, need to go back some more
C$BL.3: SKIPA T1,A2 ; Found the place, return the character address
C$BL.2: SETZ T1, ; Hit beginning of buffer first
MOVE T2,CINQRG ; Get the QRG address
LOAD. T2,TPTADR,+$QRTPT(T2) ; Make sure PT is still correct
POP P,T3 ; . . .
STOR. T3,BLKPT,(T2) ; Store the old pointer back
POPJ P, ; Return to the caller
C$BL.1: SUBI A2,1 ; Back up one character
STOR. A2,BLKPT,(T2) ; To find the previous end of line
JRST C$BL.0 ; And try again
; Here if screen mode
C$BL.Z: PUSHJ P,GETVID ; Get the address of the beginning of the line
MOVE T1,A2 ; Copy the results
POPJ P, ; Return to the caller
SUBTTL C$DWRD - Find previous word boundary
;+
;.HL2 C$DWRD
; This routine will determine how much should be deleted on a ^W.
;It will determine the amount to delete the same way as the monitor
;does, with the exception that in video mode, it will also delete EOL's.
;.literal
;
; Usage:
; T1/ Address of text buffer
; PUSHJ P,C$DWRD
; (return, T1= new END address)
;
;.end lit
;-
C$DWRD: $SAVE <P1,P2> ; Save some ac's
MOVE P1,T1 ; Get the buffer address
LOAD. T1,BLKEND,(P1) ; Get the final character address
SETZ P2, ; Nothing deleted so far
CDWR.1: SOJL T1,.RET0 ; If nothing left, just return
MOVE T2,T1 ; Get the address
IDIVX T2,5 ; Convert to a byte pointer
ADD T2,P1 ; . . .
ADDX T2,.BKTLN ; . . .
TDO T2,BTAB(T3) ; . . .
LDB T2,T2 ; Get the character
MOVE T3,CHRFLG(T2) ; Get the flags
JUMPN P2,CDWR.2 ; If we have already deleted something, check this char
TXNN T3,CF.NUM!CF.ALP ; Alphanumeric character?
JRST CDWR.3 ; No, check spacing
MOVE P2,T2 ; Yes, save the character
JRST CDWR.1 ; And keep going
CDWR.3: CAXE T2,.CHTAB ; Is it a tab?
CAXN T2," " ; Or space?
JRST [SETO P2, ; Yes, flag that
JRST CDWR.1] ; And keep going
JMPS CDWR.4 ; Screen mode?
CAXE T2,.CHCRT ; Carriage return?
CAXN T2,.CHLFD ; Or line feed?
AOJA T1,.POPJ ; Yes, don't delete them
CAXE T2,.CHVTB ; Or vertical tabs
CAXN T2,.CHFFD ; Or form feeds
AOJA T1,.POPJ ; . . .
POPJ P, ; Anything else we just delete the one character
; Here in screen mode when we have a delimeter. If it is anything
;but a LF, just delete the one character. If it is a LF, check if it is
;part of a CRLF, and if so, also delete the CR.
CDWR.4: CAXE T2,.CHLFD ; Line feed?
POPJ P, ; No, all done
SOS T2,T1 ; Yes, get the previous character
IDIVI T2,5 ; Make the byte pointer
TDO T2,BTAB(T3) ; . . .
ADD T2,P1 ; . . .
ADDX T2,.BKTLN ; . . .
LDB T2,T2 ; Get the character
CAXE T2,.CHCRT ; Carriage return?
AOJ T1, ; No, this is a lonely LF
POPJ P, ; Return
; Here for subsequent characters
CDWR.2: CAXE T2,.CHTAB ; Spacing character?
CAXN T2," " ; . . .
JRST [JUMPL P2,CDWR.1 ; Yes, if no alpha yet, keep deleting
AOJA T1,.POPJ] ; Otherwise this is the end
TXNN T3,CF.NUM!CF.ALP ; Alphanumeric?
AOJA T1,.POPJ ; No, don't delete it
MOVE P2,T2 ; Yes, save the character
JRST CDWR.1 ; And keep going
SUBTTL C$ICHR - Input a character
;+
;.HL1 C$ICHR
;This routine will input the next character from the user terminal. It will
;get any saved characters if there is one.
;.literal
;
; Usage:
; PUSHJ P,C$ICHR
; (Return)
;
; On return:
; CH/ Next character
;
;.end literal
;-
C$ICHR: SETZ CH, ; Clear this incase of a saved character
EXCH CH,CINSVD ; Get the saved character
JUMPE CH,CICH.1 ; Return if we have a character
TXZE CH,C$$ECH ; Need to be echoed?
SKPS ; Maybe, video mode?
JRST .+2 ; No echo needed
PUSHJ P,V$ECHO ; Yes, echo it
POPJ P, ; Return to the caller
; Here if we need to get another character
CICH.1: $SAVE <XCTING> ; Save the execution flag
SETZM XCTING ; Flag we are in input wait
PJRST @TY.IBY ; Get a character and return
SUBTTL C$RCHR - Repeat the current character.
;+
;.HL1 C$RCHR
;This routine is used to repeat the current character that was input from the
;user. The next call to C$ICHR will input this character again.
;.literal
;
; Usage:
; PUSHJ P,C$RCHR
; (Return)
;
; On return:
; - Character saved.
;
;.end literal
;-
C$RCHR: MOVEM CH,CINSVD ; Save the command charater
POPJ P, ; Return to the caller
SUBTTL Low segment
$IMPURE
LOWVER(CIN,1)
CINQRG: BLOCK 1 ; Address of QRG we are using
PMTLEN: BLOCK 1 ; Length of prompt string within QRG
CINSVD: BLOCK 1 ; Saved character to be parsed again (for C$RCHR/C$ICHR)
SUBTTL End of TECCIN
END ; End of TECCIN