Trailing-Edge
-
PDP-10 Archives
-
steco_19840320_1er_E35
-
10,5676/teco/newsrc/tecvid.mac
There are 3 other files named tecvid.mac in the archive. Click here to see a list.
SUBTTL Introduction
; Copyright (c) 1980, 1981 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==1174 ; Edit level
TECWHO==0 ; Last editor
PROLOGUE(VID,<TECO Video processing>) ; Generate the TITLE and other stuff
SUBTTL Table of Contents
SUBTTL Revision History
COMMENT |
1000 Start of this version
1005 By: Nick Bush On: 21-July-1980
Add capability for scrolling the screen downwards on terminals with
the function. This currently works only for VT-52's, but provides
the necessary support for any terminal with a scrolling region.
Modules: TECDEC,TECVID
1007 By: Nick Bush On: 30-July-1980
1) Make CHKTYI work a little better on slow speed (<=600 baud)
terminals. It will now wait until the output buffer is empty before
returning the no input return.
2) Put the cursor in a better position to indicate the location of PT
when PT = Z. The only time the cursor will now be over the prompt
is when PT = Z and the last line of the buffer is terminated by an
end of line character, and is on the last line of the window.
Modules: TECUNV,TECVID,TECTRM
1013 By: Nick Bush On: 6-August-1980
Make UPDLIN use SC$WLN to write out a line if the line on the screen is
blank, and we didn't have a function block for the replacement.
Make FS and FN searches only move the text in the text buffer once, not
do a delete and an insert. It will now only delete characters if the
new string is shorter, and only insert space if the new string is longer.
Modules: TECVID,TECSRH
1015 By: Nick Bush On: 11-August-1980
Don't give the NSM message until after we have parsed the Q-register name.
Otherwise, we a end up executing the Q-register name.
Modules: TECVID
1024 By: Robert McQueen On: 19-August-1980
Clear the executing flag in V$ASK and turn in back on after the character
input has been done.
Modules: TECVID
1026 By: Nick Bush On: 21-August-1980
When the command buffer is not the last thing on the screen on a terminal
without insert/delete line or scrolling, if type in extends past the
end of the section, various errors can result (ill mem ref's, looping,
...).
Modules: TECVID
1047 By: Robert McQueen On: 24-October-1980
79 Character lines would cause the 79th charcter to print twice, the
second time on the wrapped around line if there was no CRLF ending the
line.
Modules: TECVID
1061 By: Nick Bush On: 18-December-1980
1) Finish and debug Tektronix 4025 support.
2) Add FW command.
3) Add capability of logging screen update info in log file.
Modules: TECUNV,TECTEK,TECSRH,TECTBL,TECECM,TECVID,TECERR
1064 By: Robert McQueen On: 23-December-1980
VT100s are strange in that after clearing the screen the cursor is left on
the bottom of the screen. Add a new word to the $CRxxx blocks $CRERY to
be the Y position after the screen is erased.
Modules: TECUNV,TECDEC,TECVID
1065 By: Robert McQueen On: 29-December-1980
Remove the previous edit since it is easier to just add a home sequence
after the erase function. The erase sequence is now: <esc>[2J<esc>[H
Modules: TECUNV,TECDEC,TECVID
1066 By: Robert McQueen On: 6-January-1981
Fix various problems with TECVID processing of VT100s. FFD stopcodes
and illegal memory references.
Modules: TECVID
1102 By: Nick Bush On: 23-Febuary-1981
Fix VIDPOS to handle wrapped around lines correctly. It was using the
wrong value to check if it had found the correct line.
Modules: TECVID
1106 By: Nick Bush On: 13-May-1981
Improve screen updating for times when the new screen has portions which
are identical with the old. This will also fix most cases of wrapped
around lines on the top of the section of the screen.
Also fix some random /MODE:DUMP bugs.
Modules: TECUNV,TECVID,TECCMD,TECECM,TECUUO,TECMEM
1107 By: Nick Bush On: 15-May-1981
PTD stopcodes if screen update is aborted during a scroll down operation.
Modules: TECVID
1110 By: Nick Bush On: 30-June-1981
Fix a couple bugs in updating. Make sure that all lines which
get destroyed as a result of scroll operations actually get marked
that way. Also do not just assume that if the first and last
lines are valid that all lines in between are. Check that all
lines are valid before using the current screen.
Modules: TECVID
1112 By: Robert McQueen On: 10-July-1981
Half the screen would disappear on ADM3As and other types of messed up
screen updates. This would only happen if it was cheaper to clear the
screen and then write the data. Clear LD$SME in the new LDBs in this case.
Modules: TECVID
1113 By: Nick Bush On: 12-July-1981
Fix a backwards compare in SC$WRS. The update will now correctly
fix the bottom line when that should be more efficient.
Modules: TECVID
1116 By: Nick Bush On: 10-August-1981
More work on VT-100's. Get size of scrolling region right, and also make
sure the region is properly set when we do a LF in the command echoing
section.
Modules: TECVID,TECDEC
1117 By: Robert McQueen On: 14-August-1981
- Scroll up didn't work correctly at all times.
- Correct the cursor position after you scroll the screen up.
Modules: TECVID
1120 By: Robert McQueen On: 14-August-1981
NRC stopcodes from control U processing on VT100s if you have a two line
COMMAND-BUFFER.
Modules: TECVID
1121 By: Nick Bush On: 17-August-1981
Control-U's in three line command buffers did not work. More
checks were needed in DISPLY.
Fix defaulting of file spec paths to work correctly. A previous edit
had broken it.
Modules: TECVID,TECFIL
1122 By: nb On: 21-August-1981
Fix DISPLY to not ill mem ref with extremely long lines. (>15000 characters).
DISP.4 was referencing the previously found BEG (or thought it was) without
first checking if there were any lines left on the top of the screen.
Modules: TECVID
Start of Version 200A(1126)
1130 By: Nick Bush@SIT On: 5-November-1981
Split TECVID into two files: TECVID and TECUPD.
Redo how command editing is do in video mode to make the ^W editing
character easier to implement.
Add a new format for the V command when in video mode to allow the
user more control over the position of text on the screen.
Modules: TECVID,TECUPD,TECMVM
1131 By: Nick Bush On: 6-November-1981
Fix V$OCHR and V$ASK to work when the screen buffer has not been set up.
This is mainly for errors which occur during the initial command processing.
Modules: TECVID
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
1153 By: Nick Bush On: 2-April-1982
Fix problem with update not choosing most efficient end of screen to fix.
V$CINI was smashing info that it shouldn't have been.
Modules: TECVID
1161 By: Nick Bush On: 13-May-1982
Add new code to support peek-ahead for immediate (FC table) commands and
for a new form of the control-T command.
Add the new form of the control-T command to allow macros to peek at
input, and to make use of timed input. Also add the Q-register
TERMINAL-INPUT-BUFFER to hold the text being peeked at, with the side
effect of allowing macros to store text into the Q-register, and have
it be treated as input typed on the terminal.
Also change the space command to just pass through the arguments unless
EO is set to 4 or less.
Modules: TECUNV,TECVID,TECUPD,TECMVM,TECPRS,TECTRM,TECCMD,TECTBL
1165 By: Nick Bush On: 6-June-1982
Try yet again to get rid of the PTD stopcodes that occur with the command
buffer updates associated with type-ahead. Hopefully this will be the
last fix required for this problem.
Modules: TECVID
1174 By: Nick Bush On: 11-August-1982
When running terminal in image mode, tack the parity bit on correctly.
Don't smash the Q-reg in the LDB to terminate the command buffer section
unless absolutely necessary.
Modules: TECTRM,TECVID
|
SUBTTL Macro definitions
; The following macros are for use in checking for type-ahead
DEFINE $CHTYI(FLAG),<
IFB <FLAG>,<PUSHJ P,CHKTYI>
IFIDN <FLAG>,<SEEN>,<SKIPN TYIFLG>
IFIDN <FLAG>,<NOWAIT>,<PUSHJ P,CHTYI0>
> ; End of $CHTYI definition
SUBTTL V$CINI - Per command initialization
;+
;.HL1 V$CINI
; This routine is called before command input for each command
;-
$CODE ; Put into code PSECT
V$CINI: JMPNS T$SRTN ; If turned off, go reset routines
$SAVE <P1> ; Save P1
MOVE P1,CINQRG ; Get the QRG address
XMOVEI T1,$QRPDB(P1) ; Get the previous buffer word
SKIPE $TPADR(T1) ; Anything there?
PUSHJ P,M$RELB ; Yes, release it
; Set up the update screen buffer for the command buffer location.
LOAD. T1,QRGOFS,(P1) ; Get the offset to the first line
LOAD. T2,QRGNLN,(P1) ; And the number of lines
DMOVE T3,T1 ; Get a copy of the display info
IMULX T1,$LDLEN ; Convert to LDB address
ADD T1,SCRNAD ; . . .
JUMPE T3,VCIN.2 ; If QRG starts on first line, skip this
CFMN. T4,LDBQRG,-$LDLEN(T1),P1 ; Previous line marked as part of this?
ZERO. ,LDBQRG,-$LDLEN(T1) ; Yes, make sure it doesn't count
MOVE T4,T2 ; Get the number of lines back
VCIN.2: STOR. P1,LDBQRG,(T1) ; Store the QRG address of the line
ADDX T1,$LDLEN ; Advance to the next line
SOJG T2,VCIN.2 ; If any
ADD T3,T4 ; Get the last line number+1
CAMGE T3,SCRNLN ; End of screen?
JRST [CFMN. T2,LDBQRG,(T1),P1 ; Same Q-reg?
ZERO. ,LDBQRG,(T1) ; No, make sure this QRG stops here
JRST .+1] ; And continue
MOVE T1,CINQRG ; Get the address of the QRG we are using
ZERO. ,QRGVAL,(T1) ; Clear out the value (fixed pos)
BITOFF T2,QR$FIX!QR$SHF,$QRFLG(T1) ; And clear the fixed flags
TXNE F,F.INFI ; Doing an FI command?
SKIPA T1,[EXP .TRUE] ; Yes, put cursor where it needs to be
MOVX T1,.FALSE ; No, leave things where they are
PUSHJ P,UPDCMD ; Update the command section with not type-ahead
TXZ F,F.DUJ!F.CREC ; Clear the echoing flags
MOVEI T1,V$OCHR ; Get the output routine
MOVEM T1,TY.OBY ; Store the output routine
MOVEI T1,VCIN.0 ; Get the routine to call for the first char
MOVEM T1,TY.IBY ; Save the address
POPJ P, ; And return
; Here when first character is wanted
VCIN.0: $SAVE <P1,P2> ; Save P1
MOVEI P1,V$ICHR ; Get the routine to get chars from now on
MOVEM P1,TY.IBY ; Save for top level
MOVE P2,CINQRG ; Get the address of the QRG
LOAD. P1,QRGOFS,(P2) ; Get the first line of the command buffer
IMULX P1,$LDLEN ; And get the first LDB address
ADD P1,SCRNAD ; . . .
STOR. P2,LDBQRG,(P1) ; Store the Q-reg address
BITON P2,LD$FSC!LD$CMD,$LDFLG(P1) ; Flag this is the first command line
FALL V$ICHR ; And go get first character
SUBTTL V$ICHR - Input a character video mode
;+
;.HL1 V$ICHR
;This routine will input a character in video mode.
;.literal
;
; Usage:
; PUSHJ P,@TY.IBY ; Input a byte
; (Return)
;
; Returns:
; CH - Character input from the terminal
;.end literal
;-
V$ICHR: TXZE F,F.TYOF ; Have buffered chars to type?
PUSHJ P,TTYOUT ; Yes, output them first
PUSHJ P,T$READ ; Get a character
TXNE S,S.LIIN ; Want image of input?
PUSHJ P,LOGC.0 ; Yes, log this character
SETZM TYIFLG ; Flag that we got the type ahead (now must check with montior)
PUSHJ P,ALTCNV ; Do any necessary altmode conversion
SKIPN ECHOFF ; User turn echo off?
TXON F,F.ECHO ; Or caller requesting no echo?
POPJ P, ; Don't need to echo the character
FALL V$ECHO ; Echo the character
SUBTTL V$ECHO - Echo an input character
;+
;.hl1 V$ECHO
; This routine will echo a character which was input from the terminal.
;The character is echoed on the screen in the current position of the
;command string. If the character causes vertical motion (either because
;it is a line feed, or because the character caused wrap around), the
;terminal dependent scroll routine will be called to cause a new line
;to be used.
;.b.lit
;
; Usage:
; MOVE CH,Character
; PUSHJ P,V$ECHO
; (return, character still in CH)
;
;.end literal
;-
V$ECHO: SKIPGE ASKPOS ; CMDBUF displayed?
POPJ P, ; No, forget it
CAIE CH,.CHCNH ; Backspace?
CAIN CH,.CHDEL ; Is this a delete?
POPJ P, ; Yes, just return
$SAVE <X,Y> ; Save some room
$SAVE <CH> ; And the character
$SAVE <T1,T2,T3,T4> ; Save some working room
DMOVE X,CMDPOS ; Get the position for the command
VECH.4: MOVE T4,Y ; Get the line number
IMULX T4,$LDLEN ; Make the offset to the LDB
ADD T4,SCRNAD ; And get the address
CAXE CH,.CHLFD ; Is this a line feed
JRST VECH.2 ; No, then skip this mess
TXC F,F.DUJ!F.CREC ; Complement the flags
TXCN F,F.DUJ!F.CREC ; Check if ^M is on the screen before this
JRST [TXZ F,F.DUJ!F.CREC ; No, but last char was CR so just return
POPJ P,] ; . . .
TXZN F,F.CREC ; Was the last a CR ?
JRST VECCRL ; No, check if we need ^J
JRST VECH.3 ; Continue processing
VECH.2: TXZE F,F.CREC ; Was the last character a CR ?
PUSHJ P,VECECR ; Yes, then echo the CR
VECH.3: TXZ F,F.CREC!F.DUJ ; Clear the flags
CAXL CH," " ; Character being echoed a control character ?
JRST VECH.0 ; Yes, single position
; Here for control characters. First character for special chars that
;should be printed as something other than ^char.
MOVEI T1,ECHDSP ; Get the dispatch table address
PUSHJ P,NDISPT ; And dispatch to the correct routine
VECH.1: PUSH P,CH ; No a special character
MOVEI CH,"^" ; Print as ^char
PUSHJ P,VECH.0 ; Print the up-arrow
POP P,CH ; Restore the character
ADDX CH,"A"-.CHCNA ; Make the printing equivalent
JRST VECH.A ; And echo it
; Here for printing characters. Make sure we don't need to do a free
;crlf first.
VECH.0: CAML X,SCRWID ; Room for this character yet?
PUSHJ P,VECFCR ; No, do a CRLF
VECH.A: LOAD. T1,LDBNUM,(T4) ; Any characters on the line?
LOAD T2,$LDFLG(T4),LD$FSC ; Get the first command line flag
JMPF T2,VECH.8 ; Is this the first line?
JUMPN T1,.+2 ; Any characters on the line?
SETZ X, ; No, start from column 0
VECH.8: INCR. ,LDBNUM,(T4) ; Increment the number of characters on the line
SUB T1,X ; Get the number of characters beyond the cursor
JUMPLE T1,VECH.9 ; Are there any?
PUSHJ P,SC$POS ; Position to the correct place
XCT $CRDEL(CRT) ; Yes, delete them
MOVE T1,CINQRG ; Get the QRG we are reading
STOR. T1,LDBQRG,(T4) ; Flag this is part of the command buffer
VECH.9: MOVE T2,CINQRG ; Get the QRG
LOAD. T2,TPTADR,+$QRTPT(T2) ; Get the command buffer addres
LOAD. T3,BLKPT,(T2) ; And get the pointer
STOR. T3,LDBEND,(T4) ; Store the end pointer
CFMGE. ,BLKOED,(T2),T3 ; New highest end?
STOR. T3,BLKOED,(T2) ; Yes, save it
MOVE T2,X ; Get the position on the line
IDIVX T2,D$CPW ; Get the index to make a byte pointer
LOAD. T1,LDBTXT,(T4) ; Get the text address
HLL T1,BTAB(T3) ; Get the byte pointer
ADD T1,T2 ; And point to the correct word
DPB CH,T1 ; Store the character
PUSHJ P,SC$CHR ; Type the character
DMOVEM X,CMDPOS ; Save the new position
POPJ P, ; And return
; Dispatch table for special control characters
ECHDSP: XWD VECESC,.CHESC ; Escapes echo as $ and put cursor at current pointer
XWD VECLFD,.CHLFD ; Line feed causes a scroll(maybe)
XWD VECCRT,.CHCRT ; Carriage returns put cursor in column 0
XWD VECTAB,.CHTAB ; Tabs cause positioning
XWD .POPJ,.CHCNU ; Control-U does nothing
XWD .POPJ,.CHCNW ; Control-W also does nothing
XWD VECVTB,.CHVTB ; Vertical tab
XWD VECFFD,.CHFFD ; Form feed
XWD 0,0 ; End of table
; Here to echo a tab
VECTAB: CAML X,SCRWID ; Past right margin yet?
PUSHJ P,VECFCR ; Yes, do the crlf
LOAD. T1,LDBNUM,(T4) ; Get the current character count
JUMPN T1,.+2 ; Anything here?
SETZ X, ; No, make sure we are at left margin
SUB T1,X ; Get the number of characters left past cursor
JUMPLE T1,VTAB.2 ; Are there any?
PUSHJ P,SC$POS ; Position to the correct place
XCT $CRDEL(CRT) ; Yes, delete them first
MOVE T1,CINQRG ; Get the QRG address
STOR. T1,LDBQRG,(T4) ; Flag this is part of the command buffer
VTAB.2: MOVE T1,X ; Get the old position
IORX X,7 ; And then move to next tab stop
AOJ X, ; Add one
DMOVEM X,CMDPOS ; Save the position
SUBM X,T1 ; Get the number of characters we are moving
MOVE T2,CINQRG ; Get the QRG address
LOAD. T2,TPTADR,+$QRTPT(T2) ; Get the buffer address
LOAD. T3,BLKPT,(T2) ; Get the current pointer
STOR. T3,LDBEND,(T4) ; Store it
CFMGE. ,BLKOED,(T2),T3 ; This the new highest end?
STOR. T3,BLKOED,(T2) ; Yes, save it
LOAD. T3,LDBNUM,(T4) ; Get the number already there
MOVE T2,T3 ; Get the number
ADD T3,T1 ; Plus the amount the tab is adding
STOR. T3,LDBNUM,(T4) ; Store the new number of characters
IDIVX T2,D$CPW ; Convert to word and byte offset
HLL T2,BTAB-1(T3) ; Get the byte pointer
LOAD. T3,LDBTXT,(T4) ; Get the text buffer address
ADDI T2,(T3) ; And make the absolute byte pointer
MOVX CH," " ; Get a space
IDPB CH,T2 ; Store the character
SOJG T1,.-1 ; Loop for all the spaces the tab creates
PJRST SC$POS ; And do the positioning
; Here to echo an escape
VECESC: MOVX CH,"$" ; Get the character to echo as
PUSHJ P,VECH.0 ; Echo it
TXNE F,F.INFI ; Doing an FI command?
POPJ P, ; Yes, just return
SKIPL PTPOS+$OFSY ; Real Y position?
SKIPGE PTPOS+$OFSX ; Should we really move it?
POPJ P, ; No, just return
$CHTYI ; Check for type-ahead
JRST .+2 ; None, continue on
POPJ P, ; Have some, just return now
MOVX T1,HB.RTC!HB.RWJ+^D500 ; Wait half a second for more type in
HIBER T1, ; . . .
JFCL ; Ignore the error
$CHTYI ; Check for more input
PJRST SC$PT ; Put cursor at correct point
POPJ P, ; More type in, don't bother moving the cursor
; Here to echo the carriage return. This may be part of a carriage
; return line feed.
VECCRT: TXO F,F.CREC ; Flag that a carriage return was 'echoed'
POPJ P, ; And return to the caller
; Here to echo the carriage return after the next character has been gotten
; from the input source.
VECECR: $SAVE <CH> ; Save the character
BITON T1,LD$CR,$LDFLG(T4) ; Flag that we have an ^M on this line
MOVX CH,.CHCRT ; Convert to a CR
PJRST VECFFD ; Join a common routine
; Here to echo a line feed
VECLFD: SETZ X, ; Clear the X position
MOVE T1,CINQRG ; Get the QRG address
BITON T2,LD$CRLF,$LDFLG(T4) ; Flag this line ended with a CRLF
PUSHJ P,SC$GSC ; And scroll the screen
VLFD.0: MOVE T4,Y ; Get the lne number
IMULX T4,$LDLEN ; Make the correct LDB address
ADD T4,SCRNAD ; . . .
DMOVEM X,CMDPOS ; Store the position
BITON T2,LD$CMD,$LDFLG(T4) ; Light the flags
MOVE T2,CINQRG ; Get the QRG address
STOR. T2,LDBQRG,(T4) ; Remember who this is
LOAD. T2,TPTADR,+$QRTPT(T2) ; Get the text buffer pointer
LOAD. T2,BLKPT,(T2) ; get the current pointer
AOJ T2, ; Make it the next character
STOR. T2,LDBBEG,(T4) ; Save it
POPJ P, ; And return
; Here to perform a free crlf when we are at the right margin of the screen
VECFCR: MOVX T2,LD$WAP ; Flag this line is wrapping around
VFCR.0: IORM T2,$LDFLG(T4) ; And flag that this line wraps around
SETZ X, ; Next character is in column 0
MOVE T1,CINQRG ; Get the QRG address
PUSHJ P,SC$GSC ; And scroll if needed
PUSHJ P,VLFD.0 ; Fix up the beg for the next line
DECR. ,LDBBEG,(T4) ; To be what we want
POPJ P, ; And return
; Here for a form feed or a vertical tab. We will print the character
;out as ^K or ^L but then do a CRLF. This makes type in look like the screen
;display.
VECVTB:
VECFFD: PUSHJ P,VECH.1 ; Echo the control character first
SETZ T2, ; No flags to add to the line
PUSHJ P,VFCR.0 ; And then give a free CRLF
PUSHJ P,VLFD.0 ; Fix up the beg pointer
INCR. ,LDBBEG,(T4) ; To be correct
POPJ P, ; And return
; Here for a line feed. Check if last char was a CR that is on the
;screen as ^M. If so, we must delete the ^M and position ourselves correctly.
VECCRL: TXZN F,F.DUJ ; Is there an ^M there?
JRST VECFFD ; No, echo as ^J
SUBX T4,$LDLEN ; Yes, back up a line (must be line before this one)
SOJ Y, ; Back this up also
LOAD. X,LDBNUM,(T4) ; Get the number of chars on the line
SUBI X,2 ; Get the correct position
STOR. X,LDBNUM,(T4) ; Update LDBNUM
PUSHJ P,SC$POS ; Put us there
MOVEI T1,2 ; Get the number of chars to use
XCT $CRDEL(CRT) ; And delete to the end of line
LOAD. X,LDBNUM,(T4) ; Get the number back again
SUBI X,2 ; Fix it
JUMPN X,VCRL.1 ; Hit column 0?
MOVE T1,CINQRG ; Get the address of the QRG
LOAD. T1,TPTADR,+$QRTPT(T2) ; Yes, must check if last line wrapped
LOAD. T2,BLKPT,(T1) ; Get the pointer
SUBI T2,2 ; Point the char before CR
IDIVI T2,5 ; Convert to word/byte
HLL T2,BTAB(T3) ; And get the byte pointer
ADDI T2,.BKTLN(T1) ; Get the address
LDB CH,T2 ; Get the character
PUSHJ P,CKTRM ; Check if terminator
VCRL.1: TDZA T2,T2 ; No, remember that
SETO T2, ; Flag this was a terminator
BITON T1,LD$CRLF,$LDFLG(T4) ; Flag line now ends with a CRLF
BITOFF T1,LD$CR,$LDFLG(T4) ; And not a CR
JUMPL T2,VECLFD ; Previous char terminator?
AOJ Y, ; No, bump the line number back
SETZ X, ; And set to first column
DMOVEM X,CMDPOS ; Make sure CMDPOS is ok
PJRST SC$POS ; And position in correct place
SUBTTL V$OCHR - Output a video mode character
;+
;.hl1 V$OCHR
; This routine is called from the output routines in TECTRM to output
;a single character to the screen.
;-
V$OCHR: TXNN S,S.SLOG ; Want this output?
TXNN S,S.LOUT ; Maybe, logging output?
JRST .+2 ; Don't log it
PUSHJ P,LOGCHR ; Yes, log the character
SKIPL ASKPOS ; If CMDBUF not displayed, just put it anywhere
SKIPN SCRNAD ; If no screen buffer, just type the character
JRST [OUTCHR CH ; If no screen buffer, just type it
SETOM OUTFLG ; Flag there is some output to wait for
SETOM MESFLG ; Screen messed up now
POPJ P,] ; Return
CAXN CH,.CHBEL ; Is this a bell?
PJRST SC$IMG ; Yes, just output it
; Here to check to see if the --more-- should be typed on the screen
$SAVE <X,Y> ; Save the X and Y position
$SAVE <CH> ; Save the character register
$SAVE <T1,T2,T3,T4> ; Save the Tx registers
DMOVE X,CMDPOS ; Get the command position
SKIPN OUTFLG ; Any chars output yet?
CAXE CH,.CHLFD ; Line feed
JRST VOCH.0 ; No, skip this
TXZE F,F.CREC ; Thing which caused the break a CR?
POPJ P, ; Yes, just return
VOCH.0: SETOM OUTFLG ; Flag we have output. Need continue before prompting
CAME Y,ASKPOS+$OFSY ; . . .
JRST VOCH.3 ; No, continue processing
PUSHJ P,CKTRM ; Terminating character ?
JRST [CAMG X,ASKPOS+$OFSX ; Or more than the offset
JRST VOCH.3 ; Not the right line, just continue
JRST VOCH.1] ; It is, type the --More--
VOCH.1: MOVEI T1,[ASCIZ |--More--|] ; Get the text to type
PUSH P,CH ; Save the character
PUSHJ P,V$ASKA ; Ask the user if they want more
DMOVE X,CMDPOS ; Get the command position
POP P,CH ; Restore the character
CAXN CH,.CHCRT ; This a carriage return?
TXO F,F.CREC ; Yes, flag that was last thing seen
PUSHJ P,CKTRM ; Terminating character?
JRST .+2 ; No, must print it
JRST VOCH.2 ; Go clear the flag and return
MOVE T1,TY.OBY ; Get the output routine
CAIE T1,.POPJ ; Did it change ?
PJRST VOCH.3 ; No, echo the character
VOCH.2: SETZM OUTFLG ; Flag no output left
POPJ P, ; And return
; Here if we can just output the character
VOCH.3: PUSHJ P,VECH.4 ; Output the character
TXNE F,F.TYOF ; Anything to output?
PUSHJ P,CKTRM ; And is it a line terminator?
POPJ P, ; No, just return
PJRST TTYOUT ; Output the buffers
SUBTTL Screen editing -- V$ASK - Ask a question and wait for response
;+
;.hl1 V$ASK
;This routine will type some text in the ASKPOS position and then wait
;for a response from the user. If the user gives an invalid response the
;routine will given the help message to the user.
;.literal
;
; Usage:
; MOVEI T1,[ASCIZ |String to type|]
; PUSHJ P,V$ASK
; (Return)
;
;.end literal
; If the user gives a no (N) response the routine will set the output
;routine to be just a .POPJ, else it will leave everything alone.
;-
V$ASK: $SAVE <X,Y> ; Save X and Y
$SAVE <T1,T2,T3,T4> ; Save T1 to T4
; Alternate entry point for V$OCHR
V$ASKA: SKIPGE ASKPOS ; Should we just return?
POPJ P, ; Yes, he doesn't have CMDBUF displayed
CLRBFI ; Clear any type ahead
SETZM TYIFLG ; And remember there is none
$SAVE <P1,P2,P3> ; Save P1
MOVE P1,T1 ; Copy the address
SKIPN SCRNAD ; Have the screen data yet?
JRST VASK.T ; No, do things different
DMOVE X,ASKPOS ; Get the position
MOVE P2,Y ; Get the address
IMULX P2,$LDLEN ; Compute the LDB address
ADD P2,SCRNAD ; . . .
PUSHJ P,SC$POS ; Position to there
HRLI P1,(POINT 7) ; Build the byte pointer
STOR. X,LDBNUM,(P2) ; Store the number of characters
MOVE T1,X ; Get the number of chars
IDIVX T1,D$CPW ; Convert to word/byte offset
LOAD. P3,LDBTXT,(P2) ; Get the text buffer address
HLL P3,BTAB-1(T2) ; Get the byte pointer
ADDI P3,(T1) ; And point to correct word
VASK.0: ILDB CH,P1 ; Get a character
JUMPE CH,VASK.1 ; If finished
IDPB CH,P3 ; Store the character
XCT $CRTCH(CRT) ; Type the character
INCR. T1,LDBNUM,(P2) ; Count the character that is being displayed
JRST VASK.0 ; Loop until done
VASK.T: OUTSTR [BYTE (7).CHCRT,.CHLFD,0] ; Do the CRLF
OUTSTR (P1) ; And type the prompt
VASK.1: TXZ F,F.ECHO ; Turn off echoing for a character
SETZM XCTING ; Flag not executing now
PUSHJ P,V$ICHR ; Get a character
CAXE CH,.CHCRT ; Carriage return?
JRST VASK.3 ; No, continue
TXZ F,F.ECHO ; Yes, clear echo for this one
PUSHJ P,V$ICHR ; And get te line feed
MOVX CH,.CHCRT ; Get the character back
VASK.3: SETOM XCTING ; Flag executing now
MOVEI T1,ASKDSP ; Get the dispatch table
PUSHJ P,NDISPT ; Call the non-returning dispatch
JRST ASKHLP ; Give the help message
; Dispatch table for the answer from the user
ASKDSP: XWD ASKHLP,"?" ; If the user typed a question mark
XWD ASKHLP,"H" ; If the user typed a "H"
XWD ASKYES,"Y" ; If the user typed a "Y"
XWD ASKNO, "N" ; If the user typed a "N"
XWD ASKYES," " ; Space is also a yes
XWD ASKYES,.CHCRT ; As is carriage return
XWD ASKNO,.CHDEL ; Delete is same as no
XWD 0, 0 ; End of the list
; Help message for the message processing
ASKTXT: ASCIZ |Type "Y" to continue, "N" to abort, "?" for this message --|
; Here for typing the help message
ASKHLP: SKIPN SCRNAD ; Have the buffer?
JRST ASKH.T ; No, just type it
MOVE Y,ASKPOS+$OFSY ; Get the Y position
SETZ X, ; Clear the X position
PUSHJ P,SC$POS ; Position to the beginning of the line
MOVE P1,[POINT 7,ASKTXT] ; Get the text pointer
LOAD. P3,LDBTXT,(P2) ; Get the text address
HRLI P3,(POINT 7,) ; And make the pointer
ASKH.0: ILDB CH,P1 ; Get a character
JUMPE CH,ASKH.1 ; Have one?
IDPB CH,P3 ; Store the character
XCT $CRTCH(CRT) ; Type the character
JRST ASKH.0 ; Loop for the next
ASKH.1: LOAD. T1,LDBNUM,(P2) ; Get the number of positions
SUB T1,X ; Get the number left
STOR. X,LDBNUM,(P2) ; Save the number of chars
XCT $CRDEL(CRT) ; Delete to the end of the line
PJRST VASK.1 ; And loop back
; Here if we don't have the screen buffer yet
ASKH.T: OUTSTR [BYTE(7).CHCRT,.CHLFD] ; Output a CRLF
OUTSTR ASKTXT ; And the text
PJRST VASK.1 ; Try again
; Here for aborting the type out
ASKNO: MOVEI T1,.POPJ ; Get the new output routine
MOVEM T1,TY.OBY ; Store as the new routine
POPJ P, ; Return to the caller
; Here to continue processing
ASKYES: MOVE T2,CINQRG ; Get the QRG address
LOAD. T1,QRGOFS,(T2) ; Get the offset to the first line
LOAD. T2,QRGNLN,(T2) ; Get the number of lines
PUSHJ P,SC$CLR ; Clear the section of the screen
MOVE Y,CINQRG ; Get the QRG address
LOAD. Y,QRGOFS,(Y) ; Get the line number again
SETZ X, ; Get the X position
DMOVEM X,CMDPOS ; Store the new command position
PJRST SC$POS ; And position to that place on the screen
SUBTTL V$CTRG - Handle ^G. input command
;+
;.hl1 V$CTRG
; This routine will handle a control-G "." command while the
;command is being input. This will clear the screen and cause all
;lines which were part of the command to be reprinted.
;-
V$CTRG: $SAVE <P1,P2> ; Save some ac's
MOVE P1,SCRNAD ; Get the address of the LDB's
MOVE P2,SCRNLN ; And the size
VCTG.1: LOAD. T1,LDBTXT,(P1) ; Get the address of the text
PUSHJ P,CLRL.0 ; Clear it out
LOAD. T1,LDBQRG,(P1) ; Get what is displayed here
CAMN T1,CINQRG ; Is it the command buffer?
JRST VCTG.2 ; Yes, skip clearing the positions
ONES. ,LDBBEG,(P1) ; Clear out the beg
ONES. ,LDBEND,(P1) ; And the end
VCTG.2: ZERO. ,LDBNUM,(P1) ; And say we have nothing here
ADDX P1,$LDLEN ; Advance to the next block
SOJG P2,VCTG.1 ; . . .
MOVE T1,$CRERS(CRT) ; Erase the screen
PUSHJ P,SC$STR ; . . .
SETZM CURPOS+$OFSX ; Flag we are home
SETZM CURPOS+$OFSY ; . . .
MOVX T1,.TRUE ; Flag we want cursor at end of QRG
PJRST UPDCMD ; And update the command portion
SUBTTL V$DELC - Handle a delete or backspace
;+
;.hl1 V$DELC
; This routine is called during command input if the user typed
;a backspace or a delete.
;-
V$DELC: PUSHJ P,BACKUP ; Delete the character from the command buffer
PJRST .POPJ1 ; If all done, give the skip return
MOVE T1,CINQRG ; Get the QRG address
LOAD. T1,TPTADR,+$QRTPT(T1) ; Get the command buffer address
CFMG. T2,BLKPT,(T1),PMTLEN ; Are we back to the prompt?
PJRST .POPJ1 ; Yes, all done
LOAD. T2,BLKPT,(T1) ; Get the current position
MOVE T3,T2 ; Get a copy
AOJ T3, ; Plus one
PUSHJ P,UPDBND ; Update the bounds
MOVX T1,.TRUE ; Flag we want cursor at end of command
FALL UPDCMD ; Fall into the routine to update the section
SUBTTL V$UPCM - Update the command buffer on the screen
;+
;.hl1 V$UPCM
; This routine will update the command buffers section of the screen.
;It will do so without changing what is currently where on the screen
;if desired.
;-
V$UPCM:
UPDCMD: $SAVE <NOTYIA,P1> ; Save the flag
MOVE P1,T1 ; Get the flag
SETOM NOTYIA ; Flag don't abort on type-ahead
SETZM TYIFLG ; Flag nothing seen so far
MOVX T2,QR$UPD ; If we have fancy stuff then do full update
TXNE CRT,CR$DIL!CR$SCR ; Have insert/delete line or scrolling?
TXNN S,S.SCRL ; If scrolling wanted
MOVX T2,QR$FIX ; Get the bit to turn on
MOVE T1,CINQRG ; Get the QRG address
IORM T2,$QRFLG(T1) ; must do silly things
PUSHJ P,SC$UPS ; Update it
DMOVEM T1,CMDPOS ; Store the position of the next character
MOVE T1,CINQRG ; Get the QRG address
BITOFF T2,QR$FIX,$QRFLG(T1) ; Turn off the fixed flag
TXZ F,F.DUJ!F.CREC ; Clear the flags
$SAVE <X,Y> ; Save X and Y
DMOVE X,CMDPOS ; Set up for correct place
JMPF P1,.+2 ; Want the cursor moved to end of command?
PUSHJ P,SC$POS ; Yes, do it
MOVE T1,CINQRG ; Get the QRG address
LOAD. T1,TPTADR,+$QRTPT(T1) ; Get the command buffer address
LOAD. T2,BLKPT,(T1) ; Get the pointer
SOJ T2, ; Back off to look at the previous character
IDIVI T2,5 ; Get the address and byte position
HLL T2,BTAB(T3) ; Set up the byte pointer
ADDI T2,.BKTLN(T1) ; Get the absolute address
LDB T1,T2 ; Get te character
CAXE T1,.CHCRT ; Is it a carriage return
POPJ P, ; No, return
MOVE T1,Y ; Get the current line number
IMULX T1,$LDLEN ; Make into LDB offset
ADD T1,SCRNAD ; And make it the LDB address
TXO F,F.DUJ!F.CREC ; Flag previous char was CR
JUMPE Y,.POPJ ; First line of screen?
LOAD. T2,LDBQRG,(T1) ; Get the Q-reg address
CAMN T2,CINQRG ; Is this the command buffer?
TXZ F,F.CREC ; Previous line was part of command, remember ^M is on screen
POPJ P, ; And return
SUBTTL Screen editing -- SC$GSC - General scroll routine
;+
;.hl1 SC$GSC
; This routine is the general routine called to scroll a region of the
;screen on terminals without insert/delete line functions. It will
;simply scroll the whole screen when necessary.
;-
SC$GSC: $SAVE <CH> ; Save CH
MOVE T2,SCRNLN ; Get the number of lines on the screen
CAIL Y,-1(T2) ; Will this line cause the whole screen to scroll?
JRST SGSC.1 ; Yes, go fix up the LDB's
LOAD. T2,QRGOFS,(T1) ; No, get the first line number
LOAD. T3,QRGNLN,(T1) ; And the number of lines
ADDI T2,-1(T3) ; Get the number of the last line
CAMGE Y,T2 ; Still within this region
JRST SGSC.0 ; Yes, just output the line feed
TXNE S,S.SCRL ; Scrolling allowed?
CAIE T3,1 ; Only one line?
JRST .+2 ; Don't scroll
JRST SGSC.4 ; Yes, just do a delete to end of line
TXNE CRT,CR$DIL!CR$SCR ; Have a scrolling region or can fake one?
TXNN S,S.SCRL ; Scrolling requested?
JRST .+2 ; Don't scroll
JRST SGSC.2 ; Yes, go do it
PUSH P,X ; Save X position
SETZ X, ; And put on first character of next line
AOS T2,Y ; Get the next line number
IMULX T2,$LDLEN ; Get the LDB address
ADD T2,SCRNAD ; . . .
STOR. T1,LDBQRG,(T2) ; Store the QRG that this line now belongs to
LOAD. T1,LDBNUM,(T2) ; Get the number of characters on this line
PUSHJ P,SC$POS ; Position the cursor
XCT $CRDEL(CRT) ; And delete the line
MOVE T1,T2 ; Get the LDB address
PUSHJ P,FLSLDB ; Clear it out
POP P,X ; Get the X position back
PJRST SC$POS ; Position to the currect place and return
; Here if we just need a line feed
SGSC.0: MOVX CH,.CHLFD ; Get a line feed
TXNN CRT,CR$SCR ; Have scroll thingys?
PJRST SC$CHR ; And output it
PUSH P,Y ; Save Y
LOAD. T2,QRGOFS,(T1) ; Get the top line number
LOAD. Y,QRGNLN,(T1) ; And the number of lines
ADDI Y,(T2) ; Get the bottom
SOJ Y, ; . . .
SETZ T1, ; Don't move anything
XCT $CRSUP(CRT) ; . . .
POP P,Y ; Restore Y
PJRST SC$CHR ; And output the character
; Here if we are falling off the bottom of the screen. Move the LDB's
;up to account for the scrolling
SGSC.1: TXNE CRT,CR$DIL!CR$SCR ; Have a scrolling region or can fake one?
TXNN S,S.SCRL ; Want scrolling?
JRST .+2 ; No scrolling, do whole screen
JRST SGSC.2 ; Yes, go do it
MOVE T1,SCRNAD ; Get the address of the first LDB
MOVE T2,SCRNLN ; And get the length
SOJ T2, ; Get the last line
IMULX T2,$LDLEN ; Get the offset to the last
ADD T2,T1 ; And make the last LDB
PUSHJ P,SC$SCR ; Move the LDB's around
PUSHJ P,SC$POS ; Put into correct place
SOS PTPOS+$OFSY ; Will move the line up one
MOVX CH,.CHLFD ; Get a line feed
TXNN CRT,CR$SCR ; Have scrolling region?
PJRST SC$IMG ; And output it, causing the screen to scroll
PUSH P,Y ; Save Y
SETZB T1,T2 ; Set up the correct region
MOVE Y,SCRNLN ; Get the screen length
SOJ Y, ; Minus one
XCT $CRSUP(CRT) ; Set up the region to be the whole screen
POP P,Y ; Restore Y
PJRST SC$IMG ; And output the LF
; Here if we must scroll a section of the screen, and the terminal is
;capable of doing it reasonably.
SGSC.2: $SAVE <P1> ; Save P1
MOVE P1,T1 ; And remember the address
LOAD. T1,QRGOFS,(P1) ; Get the offset to the first line
LOAD. T2,QRGNLN,(P1) ; And the number of lines
CAIN T2,1 ; Only one line in this section?
JRST SGSC.4 ; Yes, just do the delete to end of line
IMULX T1,$LDLEN ; Get the offset to the LDB
SOJ T2, ; Make it the offset from the first to the last
IMULX T2,$LDLEN ; Make this the LDB offset also
ADD T1,SCRNAD ; Get the address of the first LDB
ADD T2,T1 ; This also
PUSHJ P,SC$SCR ; Move the LDB info around
TXNN CRT,CR$SCR ; Have a scrolling region?
JRST SGSC.3 ; No, fake it
LOAD. T2,QRGNLN,(P1) ; Get the number of lines back
SOJ T2, ; Make it the offset backwards
SUBM Y,T2 ; Get the top line number
MOVEI T1,1 ; Get the number of lines to scroll up
PUSH P,X ; Save the current position
XCT $CRSUP(CRT) ; Scroll it up
POP P,X ; Restore the current X pos
PJRST SC$POS ; Position correctly
; Here to perform the functions of a scrolling region using insert/delete
;line functions
SGSC.3: PUSH P,X ; Save the current X pos
PUSH P,Y ; Save the line number
LOAD. Y,QRGOFS,(P1) ; Get the first line number of this section
PUSHJ P,SC$POS ; Position to correct place
MOVEI T1,1 ; One line
XCT $CRDLL(CRT) ; Delete the line
POP P,Y ; Get the line number back
MOVE T1,SCRNLN ; Get the number of lines this has
CAIN T1,1(Y) ; Is this the last line of the screen?
JRST SGSC.A ; Yes, just go position to the new line
PUSHJ P,SC$POS ; No, position to the right place
MOVEI T1,1 ; One line
XCT $CRINL(CRT) ; And insert the line
SGSC.A: POP P,X ; Restore the current X pos
PJRST SC$POS ; And reposition to correct place
; Here if the section is only one line long. Just do a delete to end
;of line function.
SGSC.4: SETZ X, ; Clear the X position
PUSHJ P,SC$POS ; Position us there
MOVE T1,Y ; Get the line number
IMULX T1,$LDLEN ; And get the LDB address
ADD T1,SCRNAD ; . . .
PUSH P,T1 ; Save it
LOAD. T1,LDBNUM,(T1) ; Get the number of chars on this line
XCT $CRDEL(CRT) ; And delete the line
POP P,T1 ; Get the LDB address back
SETZ X, ; Clear the X position again
PUSHJ P,SC$POS ; And reposition the cursor
PJRST FLSLDB ; And clear it
SUBTTL Screen editing -- SC$SCR - Scroll a region of the screen
;+
;.hl1 SC$SCR
; This routine is called to update the LDB's when a region of the screen
;is being scrolled.
;.b.lit
;
; Usage:
; MOVEI T1,First.LDB
; MOVEI T2,Last.LDB
; PUSHJ P,SC$SCR
; (return here, LDB's updated)
;
;.end literal
;-
SC$SCR: $SAVE <P1,P2,P3> ; Save some room
DMOVE P1,T1 ; Get the args
LOAD. P3,LDBTXT,(P1) ; Get the text address of the first LDB
CAIN P1,(P2) ; Only one line?
JRST SSCR.2 ; Yes, skip the loop
SSCR.0: LOAD. T1,LDBTXT,+$LDLEN(P1) ; Get the text from the next line
STOR. T1,LDBTXT,(P1) ; And move it up
LOAD. T1,LDBNUM,+$LDLEN(P1) ; Get the number of characters
STOR. T1,LDBNUM,(P1) ; Store it
LOAD. T1,LDBFLG,+$LDLEN(P1) ; Get the flags
STOR. T1,LDBFLG,(P1) ; Store it
LOAD. T1,LDBBEG,+$LDLEN(P1) ; Yes, get the start pointer
STOR. T1,LDBBEG,(P1) ; Store it
LOAD. T1,LDBEND,+$LDLEN(P1) ; Get the end pointer
STOR. T1,LDBEND,(P1) ; And store it
LOAD. T1,LDBQRG,+$LDLEN(P1) ; Get the Q-register address
STOR. T1,LDBQRG,(P1) ; Store the QRG address also
; Here to check if we are done with the loop
SSCR.2: ADDX P1,$LDLEN ; Bump to the next
CAIGE P1,(P2) ; Done yet?
JRST SSCR.0 ; No, loop
; Here after the text pointers have been moved. P3 contains the address
;of the text block we will use for the new line, P2 contains the new LDB
;address. Note that T1 is left with the address of the QRG of the previous line
SSCR.3: STOR. T1,LDBQRG,(P2) ; Store the QRG address
STOR. P3,LDBTXT,(P2) ; Store the text address
ZERO. ,LDBNUM,(P2) ; No characters on the line
ZERO. T1,LDBFLG,(P2) ; Clear the flags
ONES. ,LDBBEG,(P2) ; Clear the BEG
ONES. ,LDBEND,(P2) ; And end
MOVE T1,P3 ; Get the text address
PJRST CLRL.0 ; And go clear the LDB
REPEAT 0,<
SUBTTL Screen editing -- SC$SDN - Scroll a region of the screen
;+
;.hl1 SC$SDN
; This routine is called to update the LDB's when a region of the screen
;is being scrolled down.
;.b.lit
;
; Usage:
; MOVEI T1,Bottom line
; MOVEI T2,Top line
; PUSHJ P,SC$SDN
; (return here, LDB's updated)
;
;.end literal
;-
SC$SDN: $SAVE <P1,P2,P3> ; Save some room
DMOVE P1,T1 ; Get the args
LOAD. P3,LDBTXT,(P1) ; Get the text address of the bottom LDB
CAIN P1,(P2) ; Only one line?
JRST SSDN.2 ; Yes, skip the loop
SSDN.0: LOAD. T1,LDBTXT,-$LDLEN(P1) ; Get the text from the next line
STOR. T1,LDBTXT,(P1) ; And move it down
LOAD. T1,LDBNUM,-$LDLEN(P1) ; Get the number of characters
STOR. T1,LDBNUM,(P1) ; Store it
LOAD. T1,LDBFLG,-$LDLEN(P1) ; Get the flags
STOR. T1,LDBFLG,(P1) ; Store it
LOAD. T1,LDBQRG,-$LDLEN(P1) ; Get the Q-register address
STOR. T1,LDBQRG,-$LDLEN(P1) ; Store the address
LOAD. T1,LDBBEG,-$LDLEN(P1) ; Get the start pointer
STOR. T1,LDBBEG,(P1) ; Store it
LOAD. T1,LDBEND,-$LDLEN(P1) ; Get the end pointer
STOR. T1,LDBEND,(P1) ; And store it
; Here to check if we are done with the loop
SSDN.2: SUBX P1,$LDLEN ; Bump to the next
CAILE P1,(P2) ; Done yet?
JRST SSDN.0 ; No, loop
; Here after the text pointers have been moved. P3 contains the address
;of the text block we will use for the new line, P2 contains the new LDB
;address.
SSDN.3: STOR. P3,LDBTXT,(P2) ; Store the text address
ZERO. ,LDBNUM,(P2) ; No characters on the line
ONES. ,LDBBEG,(P2) ; Clear the BEG
ONES. ,LDBEND,(P2) ; And end
ZERO. T1,LDBFLG,(P2) ; Clear the flags
MOVE T1,P3 ; Get the text address
PJRST CLRL.0 ; And go clear the LDB
> ; End of REPEAT 0 for SC$SDN
SUBTTL Screen editing -- SC$VID - Allocate the screen buffer
;+
;.hl2 SC$VID
; This routine will set up to use the screen editing features. It will
;allocate the buffer for the screen and initialize it to spaces.
;-
SC$VID: MOVE T1,SCRNAD ; Get the screen address
JUMPN T1,SVID.0 ; Have one already - Skip the setup
TXZN S,S.SCRN ; Clear the flag
POPJ P, ; Not on yet anyway
SKIPN $CRXYP(CRT) ; Have an X-Y address string?
PJRST T$SRTN ; Set the terminal input routines
SKIPN T2,CRTLEN ; Have a length set?
SKIPE T2,TRMLEN ; No, have one from the TRMOP?
JRST .+2 ; Have a length
JRST T$SRTN ; No, just reset the terminal routines
SKIPN T1,CRTWID ; Have a width set?
SKIPE T1,TRMWID ; No, have one from the TRMOP?
JRST .+2 ; Yes, go set things up
JRST T$SRTN ; No, just set up the terminal routines
; Set up the screen buffer address here
TXO S,S.SCRN ; Flag we now have screen mode
$SAVE <P1,P2,P3,P4> ; Save P1 to P3
MOVEM T2,SCRNLN ; Store the number of lines
MOVEM T1,SCRWID ; Save the width
AOJ T1, ; Plus one
IDIVX T1,D$CPW ; Convert to number of words
SKIPE T2 ; Any extra needed?
AOJ T1, ; Yes, count it
MOVEM T1,LINWDS ; Save the number of words
PUSHJ P,SVID.A ; Allocate the first set
MOVEM T1,SCRNAD ; Save as normal address
PUSHJ P,SVID.A ; Allocate the update set
MOVEM T1,SUPDAD ; Store it
MOVE T1,SCRNLN ; Get the number of lines on the CRT
MOVX T2,.BTGEN ; Allocation from general storage
PUSHJ P,M$ZBLK ; Allocate a zero block
MOVEM T1,FNCLST ; Store as the function list block
MOVE T1,SCRNLN ; Get the number of lines on the CRT
MOVX T2,.BTGEN ; Allocation from general storage
PUSHJ P,M$ZBLK ; Allocate a zero block
MOVEM T1,CSTLST ; Save the list address
MOVE T1,SCRNLN ; Get the number of lines
ASH T1,1 ; Make the max function length
MOVX T2,.BTGEN ; Get the block type
PUSHJ P,M$GBLK ; Get the block
MOVEM T1,FNCBLK ; Save it
SVID.4: MOVE T1,$CRERS(CRT) ; Have an erase string?
PUSHJ P,SC$STR ; Yes, do it
SETZM CURPOS+$OFSX ; Flag we are at 0,0
SETZM CURPOS+$OFSY ; . . .
SKIPN T1,CRTWID ; Get the current width
MOVE T1,TRMWID ; . . .
CAMN T1,SCRWID ; Did it change?
POPJ P, ; No, all is fine
MOVEM T1,SCRWID ; Yes, save the current width
SETOM MESFLG ; And flag things need some help
POPJ P, ; And return
; Here to allocate the update buffers
SVID.A: MOVE T1,SCRNLN ; Get the length
IMULX T1,$LDLEN ; Compute the number of words
MOVEI P4,(T1) ; Get the offset to the first line of text
MOVE T2,LINWDS ; Get the number of words per line
IMUL T2,SCRNLN ; Get the total
ADD T1,T2 ; . . .
MOVX T2,.BTGEN ; Get the general thingy for the video
PUSHJ P,M$ZBLK ; Allocate a zero block
MOVE P1,T1 ; Get the address
ADD P4,T1 ; Fix the other pointer
MOVN P2,SCRNLN ; Get the number of lines
MOVSI P2,(P2) ; Move it into the other half
HRR P2,P1 ; Get the address
SETZ P3, ; Start labeling at line 0
SVID.1: MOVEI T1,(P4) ; Get the address
STOR. T1,LDBTXT,(P2) ; Store the block
STOR. P3,LDBLIN,(P2) ; Store the line number
PUSHJ P,CLRL.0 ; Clear the line
ADDI P3,1 ; Increment the line number
ADD P4,LINWDS ; Plus the length of the line
ADDX P2,$LDLEN-1 ; Point to the next entry
AOBJN P2,SVID.1 ; Loop for all entries
MOVE T1,P1 ; Get the address back
POPJ P, ; And return it
; Here if there was a screen buffer
SVID.0: SKIPN T1,CRTLEN ; Have a length set?
MOVE T1,TRMLEN ; Get the number of lines
CAME T1,SCRNLN ; Is it the same as what we have?
JRST SVID.2 ; No, must reallocate the buffer
SKIPN T1,CRTWID ; Get the width
MOVE T1,TRMWID ; Get the width of the lines
IDIVX T1,D$CPW ; And get the number of words required for each
JUMPE T2,.+2 ; Need an extra?
AOJ T1, ; Yes, count it
CAMN T1,LINWDS ; Same number of words needed?
JRST SVID.4 ; Yes, skip the whole bit
SVID.2: PUSHJ P,SC$RVD ; Return the video info
JRST SC$VID ; Try again from the top
SUBTTL SC$RVD - Return video information allocated by SC$VID
;+
;.HL1 SC$RVD
; This routine will return the information that was allocated by SC$VID.
;It will also clear the display info in the Q-registers.
;-
SC$RVD: SKIPN SCRNAD ; Have the screen data?
POPJ P, ; No, just return
$SAVE <P1> ; Save P1
MOVN P1,SCRNLN ; Get the number of lines
MOVSI P1,(P1) ; Build the AOBJx pointer
HRR P1,SCRNAD ; Get the screen address
SRVD.3: LOAD. T1,LDBQRG,(P1) ; Get the Q-register associated with this
JUMPE T1,SRVD.9 ; Have one?
BITOFF T2,QR$VID!QR$VLU!QR$FCT,$QRFLG(T1) ; Yes, flag it is no longer being displayed
ZERO. T2,QRGOFS,(T1) ; Clear the offset
ZERO. T2,QRGNLN,(T1) ; And the number of lines
SRVD.9: ADDX P1,$LDLEN-1 ; Compute the address of the next block
AOBJN P1,SRVD.3 ; Loop deleting the blocks
MOVE T1,SCRNAD ; Get the address
PUSHJ P,M$RBLK ; Return it
MOVE T1,SUPDAD ; Get the update block address
PUSHJ P,M$RBLK ; Return it
MOVE T1,FNCLST ; Get rid of the function list
PUSHJ P,M$RBLK ; Return it
MOVE T1,CSTLST ; Get the cost list address
PUSHJ P,M$RBLK ; And return it
MOVE T1,FNCBLK ; Get the function block address
PUSHJ P,M$RBLK ; Return it
SETZ T1, ; Clear SCRNAD
EXCH T1,SCRNAD ; Get the address of the old block
PUSHJ P,M$RBLK ; Return the old block
SETZM SCRNLN ; Nothing on the screen at the moment
SETZM SCRWID ; . . .
POPJ P, ; And return
SUBTTL Screen editing -- SC$FIN - Finish up
;+
;.hl2 SC$FIN
; This routine will output the string to put the cursor at the
;lower left hand corner of the screen. It will also perform
;any reseting of the terminal that is needed.
;-
SC$FIN: MOVE Y,SCRNLN ; Get the number of lines on the screen
SOJ Y, ; Make it the correct line number
SETZ X, ; Want cursor in column 0
PUSHJ P,SC$POS ; Position to the correct place
XCT $CRFIN(CRT) ; Cause the terminal to be put in reasonable state
POPJ P, ; And return
SUBTTL Screen editing -- SC$POS - Position the cursor
;+
;.HL2 SC$POS
;This routine will position the cursor to the position that is described
;by the X and Y positions in A1 and A2.
;.literal
;
; Usage:
; DMOVE X,X and Y positions
; PUSHJ P,SC$POS
; (Return)
;.end literal
;-
SC$POS: CAMN X,CURPOS+$OFSX ; Are we already there?
CAME Y,CURPOS+$OFSY ; . . .
JRST .+2 ; No, must position
POPJ P, ; Yes, just return
$SAVE <X,Y,T1,T2,T3> ; Save the positions
XCT $CRXYP(CRT) ; No, do the positioning
POPJ P, ; And return
SUBTTL Screen editing -- SC$DEL - Delete to end of line
;+
;.hl1 SC$DEL
; This routine is called to delete from the current position to the end
;of the line. This is used for terminals which do not have a delete to
;end of line function. It will use blanks to delete the characters that
;are actually on the screen.
;.b.lit
;
; Usage:
; MOVE T1,Number of characters left on screen line
; DMOVE X,Position
; PUSHJ P,SC$DEL (usually from XCT $CRDEL(CRT))
; (return here)
;
;.end literal
;-
SC$DEL: $SAVE <P1> ; Save room for the count
$SAVE <CH> ; Save the current character
MOVE CH,$CRDSP(CRT) ; Get the destructive space
MOVE P1,T1 ; Get the count
SDEL.0: SOJL P1,.POPJ ; Return if done
XCT $CRTCH(CRT) ; Else output the character
JRST SDEL.0 ; Loop
SUBTTL Screen editing -- SC$STR - Write a string
;+
;.HL2 SC$STR
; This routine will write out a string of up to 5 characters on the
;screen.
;.literal
;
; Usage:
; MOVE T1,$CRxxx(CRT) ; Get the string to output
; PUSHJ P,SC$STR ; Output the string
; (Return)
;
;.end literal
;-
SC$STR: JUMPE T1,.POPJ ; Just return if nothing to type
$SAVE <CH> ; Save the current character
TXNE F,F.TYOF ; Need to output first?
PUSHJ P,TTYOUT ; Yes, force the other out
TXNN T1,177B6 ; Have anything in the left half?
JRST SC$S.2 ; No, is this a TECO defined string?
PUSH P,T1 ; Save the string
MOVX T1,<POINT 7,(P)> ; Get the byte pointer
SC$S.1: ILDB CH,T1 ; Get a character
JUMPE CH,.T1PJ ; Return if null
PUSHJ P,SC$IMG ; Type the character
TXNE T1,<INSVL.(70,BP.PFL)> ; Only do one word
JRST SC$S.1 ; Loop for all chars
PJRST .T1PJ ; Return
SC$S.2: $SAVE <T1,T2> ; Save T1 and T2
HRRZ T2,T1 ; Get the string address
MOVEI T1,[$STRING(<^X/SC$IMG/^N^S/(T2)/>)] ; Set up to type the string
PJRST T$TYPE ; Do it
SUBTTL Screen editing -- SC$MES - Write a non-image string
;+
;.HL1 SC$MES
; This routine will write out a screen control string in non-image mode.
;.literal
;
; Usage:
; MOVE T1,$CRxxx(CRT)
; PUSHJ P,SC$MES
; (Return)
;.end literal
;-
SC$MES: JUMPE T1,.POPJ ; Just return if nothing
$SAVE <CH> ; Save the current character
TXNE F,F.TYOF ; Need to output first?
PUSHJ P,TTYOUT ; Yes, force the other out
TXNN T1,177B6 ; Have something in the left half?
JRST SC$M.2 ; No, if not user string go type it
PUSH P,T1 ; Save the string
MOVX T1,<POINT 7,(P)> ; Get the byte pointer
SC$M.0: ILDB CH,T1 ; Get a character
JUMPE CH,.T1PJ ; Return if null
OUTCHR CH ; Output the character
TXNE T1,<INSVL.(70,BP.PFL)> ; Check if done with the word
JRST SC$M.0 ; No, loop
JRST .T1PJ ; Yes, return
SC$M.2: $SAVE <T1,T2> ; Save P1 and P2
HRRZ T2,T1 ; Get the string address
MOVEI T1,[$STRING(<^X/SC$M.3/^N^S/(T2)/>)] ; Set up to type the string
PJRST T$TYPE ; Do it
SC$M.3: OUTCHR CH ; Output the character
POPJ P, ; And return
SUBTTL Screen editing -- SC$PT - Move cursor to PT
;+
;.HL2 SC$PT
; This routine will position he cursor to PT on the screen.
;.literal
;
; Usage:
; PUSHJ P,SC$PT
; (Return)
;
;.end literal
;-
SC$PT: DMOVE X,PTPOS ; get the position of PT
JUMPL X,.POPJ ; Just return if no place to go
PJRST SC$POS ; Go to that position
SUBTTL Screen editing -- SC$IMG - output a character to the screen
;+
;.hl 1 SC$IMG
; This routie will output a character to the terminal in image mode.
;This routine will output the character with the correct parity.
;.literal
;
; Usage:
; MOVE CH,Character to output
; PUSHJ P,SC$IMG
; (Return)
;
;.end literal
;-
SC$IMG: SKIPL CHRFLG(CH) ; Need the parity bit on for this one?
TRO CH,200 ; Yes, turn it on (even parity)
SC$IM0: MOVEM CH,TRMOCH+2 ; Save the character
MOVE CH,[XWD 3,TRMOCH] ; Get the pointer
TRMOP. CH, ; And output the character
IONEOU TRMOCH+2 ; Couldn't
MOVE CH,TRMOCH+2 ; Get the character back
TRZ CH,200 ; Clear the bit
TXNE S,S.LVID ; Want video logged?
PJRST LOGC.0 ; Yes, go do it
POPJ P, ; And return
SUBTTL Screen Editing -- SC$FIL - Output fill characters
;+
;.HL 1 SC$FIL
; This routine is called to output enough fill characters to give
;the terminal enough time to perform a function. It is called with
;the time the terminal requires to perform the function in milliseconds.
;It will output enough nulls as fill characters to account for that much
;time.
;.b.lit
;
; Usage:
; MOVE T1,Number of milli-seconds to fill
; PUSHJ P,SC$FIL
; (Return, terminal ready for next output)
;
;.end literal
;-
SC$FIL: MOVE T2,TRMSPD ; Get the terminal speed
MUL T1,CPSTBL(T2) ; Get the number of chars we need to send
DIVX T1,^D1000 ; . . .
JUMPE T1,.POPJ ; Just return if no fill necessary
$SAVE <CH> ; Else save the current character
MOVX CH,.CHNUL ; Get a null
PUSHJ P,SC$IMG ; And fill
SOJG T1,.-1 ; Keep filling long enough for the terminal to finish
POPJ P, ; And return
SUBTTL Screen Editing -- SC$CFL - Calculate fill cost
;+
;.HL 1 SC$CFL
; This routine is called to calculate the number of fill chars
;which are required by an operation. These characters are included
;in any cost calculation for a given terminal.
;.b.lit
;
; Usage:
; MOVE T1,Number of milli-seconds to fill
; PUSHJ P,SC$CFL
; (Return, T1= number of fill chars)
;
;.end literal
;-
SC$CFL: MOVE T2,TRMSPD ; Get the terminal speed
MUL T1,CPSTBL(T2) ; Get the number of chars we need to send
DIVX T1,^D1000 ; . . .
POPJ P, ; And return
SUBTTL Screen Editing -- CPSTBL - Character per second table
; This table contains the number of characters which can be output
;per second at the standard baud rates. It is indexed by the .TSxxx
;symbol.
DEFINE ENT(SPEED,CPS,INDEX)<TABENT(SPEED,^D<CPS>)>
TABDEF CPS,.TS
TSPEED ; Generate the table
TABEND
SUBTTL Screen editing -- SC$CHR - Output a character at a given posisiton
;+
;.HL1 SC$CHR
; This routine will output a character at a given place on the screen. It
;will keep track of where the current position is.
;.b.literal
; Usage:
; MOVEI CH,character
; DMOVE X,position
; PUSHJ P,SC$CHR
; (return with X, Y and CURPOS updated)
;
;.end literal
;-
SC$CHR: PUSHJ P,SC$POS ; Position us on the screen
PUSHJ P,SC$IMG ; Output the character in image mode
CAXGE CH," " ; Printing character?
JRST SC$C.1 ; No, check what type of control character it is
AOJ X, ; Bump the position
JRST SC$C.R ; Go return
SC$C.5: AOJ Y, ; And bump the Y position
CAML Y,SCRNLN ; Did this cause the screen to scroll?
STOPCD SCR,<Screen was scrolled by SC$CHR>
SC$C.R: DMOVEM X,CURPOS ; Update the current position
POPJ P, ; And return
; Here if the character was a control character.
SC$C.1: CAXE CH,.CHTAB ; Is this a tab?
JRST SC$C.2 ; No, check for other motion chars
AOJ X, ; Bump the position
TXO X,7 ; And round up to the next tab stop
TXNN CRT,CR$TAB ; Terminal have hardware tab stops?
PUSHJ P,SC$POS ; No, move the cursor
DMOVEM X,CURPOS ; And save the position
POPJ P, ; Return
SC$C.2: CAXE CH,.CHCNH ; Backspace?
JRST SC$C.3 ; No, try other chars
SOJGE X,SC$C.R ; Just return if still okay
TXNN CRT,CR$NWP ; Does this terminal go backwards?
AOJA X,SC$C.R ; No, we stayed at column 0
MOVE X,SCRWID ; Otherwise we are now at the end of a line
SOJGE Y,SC$C.R ; On the previous line
SETZ Y, ; Don't go above screen
JRST SC$C.R ; And return
SC$C.3: CAXE CH,.CHCRT ; Carriage return?
JRST SC$C.4 ; No, check line feed
SETZ X, ; Yes, just clears the X position
PJRST SC$C.R ; And return
SC$C.4: CAXE CH,.CHLFD ; Line feed?
JRST SC$C.R ; No, assume non-printing
JRST SC$C.5 ; Otherwise bump the line and check for scrolling
SUBTTL Screen editing -- SC$CLS - Clear a section
SUBTTL Screen editing -- SC$CLR - Clear a section
;+
;.HL1 SC$CLS and SC$CLR
;These routines will clear a section of the screen and clear the text
;block that the LDBs point to. If SC$CLS is called the QRG pointer
;in the LDB will be cleared.
;.literal
;
; Usage:
; MOVEI T1,QRG.block.address
; PUSHJ P,SC$CLS
; (Return)
;
; MOVEI T1,Offset.into.screen.buffer
; MOVEI T2,Number.of.lines
; PUSHJ P,SC$CLR
; (Return)
;
;.end literal
;-
SC$CLS: $SAVE <P1> ; Save P1
MOVE P1,T1 ; Get the arg
BITOFF T2,QR$VID!QR$VLU!QR$FCT,$QRFLG(P1) ; Flag not displaying this anymore
ZERO. T1,QRGOFS,(P1) ; Clear the offset and
ZERO. T1,QRGNLN,(P1) ; the number of lines
SKIPN VINADR ; If we have a screen address
JRST SCLS.1 ; Else just clear out previous pointer
LOAD. T1,TPTADR,+VINADR ; Get the address of the info
LOAD. T2,VINNLN,(T1) ; Get the number of lines
SCLS.0: CFMN. ,VINQRG,(T1),P1 ; Is this this Q-reg?
ZERO. ,VINQRG,(T1) ; Yes, clear it
AOJ T1, ; Advance to the next
SOJG T2,SCLS.0 ; And loop for all items
SCLS.1: MOVEI T1,$QRPDB(P1) ; Get the address of the previous pointer
SKIPE (T1) ; Is there any?
PUSHJ P,M$RELB ; Yes, release it
SETZM $QRPDB(P1) ; Make sure it is clear
POPJ P, ; Return to the caller
SC$CLR: SKIPN SCRNAD ; If we have a screen address
POPJ P, ; Else just return
$SAVE <P1,P2,P3,P4> ; Clear P1
$SAVE <X,Y> ; Save the X and Y addresses
$SAVE <CH> ; And save CH
MOVX P1,$LDLEN ; Get the length of the LDB
IMUL P1,T1 ; Compute the word offset
ADD P1,SCRNAD ; Compute the address
MOVNS T2 ; Compute the number of words
HRL P1,T2 ; For an AOBJN pointer
SCLR.0: SETZ X, ; Clear the X offset
LOAD. Y,LDBLIN,(P1) ; Get the line number from the Y offset
LOAD. T1,LDBNUM,(P1) ; Get the number of characters on the line
JUMPE T1,SCLR.1 ; Anything to delete?
TXNN CRT,CR$CTU ; Terminal know how to do real delete to end of lines?
JRST SCLR.2 ; No, go simualte it
PUSHJ P,SC$POS ; Go to that position on the screen
XCT $CRDEL(CRT) ; Delete the line
SCLR.1: MOVEI T1,(P1) ; Get the address of the LDB
PUSHJ P,FLSLDB ; Clear the counters and fill with spaces
ADDX P1,$LDLEN-1 ; Advance to the next LDB
AOBJN P1,SCLR.0 ; Loop for all the LDBs
POPJ P, ; Return to the caller
; Here to simulate a delete to end of line for terminals without it
SCLR.2: LOAD. P4,LDBTXT,(P1) ; Get the pointer to the text
HRLI P4,(POINT 7,) ; And make the byte pointer
SETZ P3, ; Clear the count of spaces
MOVE P2,T1 ; Get the number of chars on the line
SCLR.3: SOJL P2,SCLR.1 ; Done yet?
ILDB T1,P4 ; Get a character
JUMPE T1,.+2 ; Is it a null?
CAIN T1," " ; Is it a space?
AOJA P3,SCLR.3 ; Yes, just count it
JUMPE P3,SCLR.4 ; Any previous spaces ?
HRLI T1,(X) ; Yes, get the current X pos
HRRI T1,(Y) ; And the current Y
MOVSI T2,(P3) ; Get where we are going
ADD T2,T1 ; . . .
XCT $CRCPP(CRT) ; Get the cost of getting there with positioning
CAMLE T1,P3 ; Cheaper to do the position or write the spaces?
AOJA P3,SCLR.4 ; Cheaper to write the spaces out
ADD X,P3 ; Get where we want to be
MOVEI P3,1 ; Get the number of space to output
SCLR.4: MOVEI CH," " ; Get a space
XCT $CRTCH(CRT) ; Type it
SOJG P3,SCLR.4 ; And tyxe all that are necessary
SETZ P3, ; Clear the count of skipped chars
JRST SCLR.3 ; Go for the next line
SUBTTL Screen editing -- SC$ERS - Clear the whole screen
;+
;.hl1 SC$ERS
; This routine will clear the whole screen and the LDB's. It will leave
;the cursor at X=0 Y=0.
;.b.literal
;
; PUSHJ P,SC$ERS
; (return here)
;.end literal
;-
SC$ERS: JMPNS .POPJ ; Just return if not on
$SAVE <P1> ; Save P1
MOVE T1,$CRERS(CRT) ; Clear the screen
PUSHJ P,SC$STR ; Output the string
MOVN P1,SCRNLN ; Get the number of lines on the screen
MOVSI P1,(P1) ; Into the left half
HRR P1,SCRNAD ; Get the LDB addresses
; Loop clearing the displayed text for all the LDB's
SERS.0: MOVEI T1,(P1) ; Get the address of the LDB
PUSHJ P,FLSLDB ; Clear the counters and moves spaces into it
ADDX P1,$LDLEN-1 ; Bump to the next LDB
AOBJN P1,SERS.0 ; Loop for all the lines
SETZM CURPOS+$OFSX ; Clear the X position
SETZM CURPOS+$OFSY ; Clear the Y position
POPJ P, ; And return
SUBTTL SC$SSR - Set screen regions
;+
;.hl1 SC$SSR
; This routine is called to set up the update LDB with the current
;screen regions.
;-
SC$SSR: $SAVE <P1,P2,P3,P4> ; Save some ac's
SKIPN VINADR+$TPADR ; Have one allocated?
JRST [TXZ S,S.SCRN ; No, turn off screen mode
POPJ P,] ; And return
SKIPN T1,CRTWID ; Have a width set?
MOVE T1,TRMWID ; Get the current terminal width
SKIPN T2,CRTLEN ; Have a length set?
MOVE T2,TRMLEN ; Get the length of the screen
CAMN T2,SCRNLN ; Same as current?
CAME T1,SCRWID ; Same as what had last time?
PUSHJ P,SC$VID ; No, allocate new LDB's
LOAD. P1,TPTADR,+VINADR ; Get the address of the block
LOAD. P2,VINNLN,(P1) ; Get the number of lines
MOVE P3,SUPDAD ; Get the address of the update LDB's
MOVE P4,SCRNLN ; Get the length of the screen
SETZB T2,T3 ; Clear the QRG lines
LOAD. T4,VINQRG,(P1) ; Get the QRG address
SETZ P1, ; Start with first line
SSSR.1: LOAD. T1,TPTADR,+VINADR ; Get the address of the VIN
ADD T1,P1 ; Get the correct offset
LOAD. T1,VINQRG,(T1) ; Get the QRG address
SKIPE T4 ; Any QRG currently?
CAMN T1,T4 ; Still in same QRG?
AOJA T3,SSSR.2 ; Yes, keep looping
PUSHJ P,SSSR.S ; Set up the Q-reg info
LOAD. T2,LDBLIN,(P3) ; Get the current line number
MOVEI T3,1 ; One line already in current QRG
MOVE T4,T1 ; Get the address of the current QRG
SSSR.2: STOR. T1,LDBQRG,(P3) ; Store it
AOJ P1, ; Advance to next line
ADDX P3,$LDLEN ; . . .
SOJLE P4,SSSR.4 ; If this is the end of the screen, stop now
SOJG P2,SSSR.1 ; Loop for all lines
SSSR.3: ZERO. ,LDBQRG,(P3) ; Clear out the LDB since nothing is here
ADDX P3,$LDLEN ; Advance to next LDB
SOJG P4,SSSR.3 ; . . .
JUMPN T4,SSSR.S ; If we have a QRG left, go set it
POPJ P, ; Otherwise just return
; When we get here, if T4 is non-zero, we have a region to set.
;Then we must fix up the rest of the Q-regs (if any) in the display list
;to indicate that they aren't actually displayed at this point.
SSSR.4: JUMPE T4,SSSR.5 ; If nothing to set, skip it
PUSHJ P,SSSR.S ; Set up this Q-reg with the current lines
; Skip the rest of the lines which claim to be here.
SSSR.5: SOJLE P2,SSSR.8 ; Return if nothing left
LOAD. T1,TPTADR,+VINADR ; Get the address of the block
ADD T1,P1 ; Point to correct line
LOAD. T1,VINQRG,(T1) ; Get the QRG address
CAMN T1,T4 ; Same as current one?
AOJA P1,SSSR.5 ; Yes, loop through it
MOVE T4,T1 ; Get the address of the next QRG
; Here to clear out the display info for the reset of the QRG's
SSSR.6: JUMPE T4,SSSR.7 ; If no QRG here, try the next
BITOFF T2,QR$VID,$QRFLG(T4) ; Clear the displayed flag
ZERO. T2,QRGOFS,(T4) ; Clear the offset to the first
ZERO. T2,QRGNLN,(T4) ; And the number of lines
SSSR.7: AOJA P1,SSSR.5 ; Loop for all lines left
; Now determine if CMDBUF is displayed and set up the correct place for
;ASKPOS.
SSSR.8: MOVX T1,QR$VID ; Check if CMDBUF is displayed
SETOM ASKPOS ; Assume it isn't
TDNN T1,$QRFLG+CMDBUF ; Is it?
POPJ P, ; No, just return
LOAD. T1,QRGNLN,+CMDBUF ; Get the number of lines it has
LOAD. T2,QRGOFS,+CMDBUF ; Get the offset to the first line
ADDI T2,-1(T1) ; Get the last line number
MOVEM T2,ASKPOS+$OFSY ; Save as Y position
SKIPN T1,SCRWID ; Have a width set yet?
SKIPE T1,CRTWID ; User set one?
JRST .+2 ; Yes, use that
MOVE T1,$CRWID(CRT) ; Get the width of the terminal
SUBI T1,^D14 ; Find where the X position should be
JUMPGE T1,.+2 ; If positive, all is fine
SETZ T1, ; Not 14 characters wide, use whole line
MOVEM T1,ASKPOS+$OFSX ; Save the X position
POPJ P, ; And return
; Subroutine to set up the display info into the Q-reg
SSSR.S: $SAVE <T1,T2,T3,T4,P1> ; Save some ac's
MOVE P1,T4 ; Get the QRG address
STOR. T2,QRGOFS,(P1) ; Store the line number
STOR. T3,QRGNLN,(P1) ; And number of lines
LOAD. T1,QRGDTP,(P1) ; Get the data type
CAXN T1,$DTTXT ; Is there text here?
JRST SSSR.T ; Yes, skip this
MOVX T2,$DTTXT ; No, get the new data type
XCT RQRGTB(T1) ; Set the new datatype
SETZ T1, ; No, get a null buffer
PUSHJ P,M$GTXT ; . . .
XMOVEI T2,$QRTPT(P1) ; Get the address of the pointer
PUSHJ P,M$USEB ; And set it up
BITOFF T1,QR$FIX!QR$SHF,$QRFLG(P1) ; Flag no particular position wanted
SSSR.T: BITON T1,QR$VLU!QR$VID!QR$FCT,$QRFLG(P1) ; Flag this is displayed
POPJ P, ; And return
SUBTTL Low segment for TECVID
$IMPURE ; Do the impure storage
LOWVER(VID,4) ; Low segment version number of this module
; CRT data
VINADR: BLOCK $TPLEN ; Address of VIN block
SCRNAD: BLOCK 1 ; Address of the list of LDB entries
SUPDAD: BLOCK 1 ; Update LDB's
; for the screen
SCRNLN: BLOCK 1 ; Number of lines
SCRWID: BLOCK 1 ; Width of screen
CRTWID: BLOCK 1 ; Width of screen as set by user
CRTLEN: BLOCK 1 ; Length of screen as set by user
LINWDS: BLOCK 1 ; Number of words per line buffer
MESFLG: BLOCK 1 ; Screen messed up
OUTFLG: BLOCK 1 ; Flag that output has been done. This means
; that --Cont-- needs to be done before prompting
PTPOS: BLOCK 2 ; Position of PT
CMDPOS: BLOCK 2 ; Position to echo commands at
CURPOS: BLOCK 2 ; Current position
; The following two items must be in this order
CRTTYP: BLOCK 1 ; Type of CRT in use (index into CRT table)
CRTFNC: BLOCK $CRMAX+1 ; Max CRT block
; For V$OCHR
ASKPOS: BLOCK 2 ; Position at which the '--More--' should be
; typed to the user
SUBTTL End of TECVID
END ; End of TECVID