Trailing-Edge
-
PDP-10 Archives
-
steco_19840320_1er_E35
-
10,5676/teco/newsrc/tectrm.mac
There are 3 other files named tectrm.mac in the archive. Click here to see a list.
SUBTTL Introduction
; Copyright (c) 1979, 1980 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(TRM,<TECO Terminal processing>) ; Generate the TITLE and other stuff
SUBTTL Table of Contents
;+
;.pag.lit
; Table of Contents for TECTRM - Terminal processing
;
;
; Section Page
; 1. Introduction . . . . . . . . . . . . . . . . . . . . . 1
; 2. Table of Contents. . . . . . . . . . . . . . . . . . . 2
; 3. Revision History . . . . . . . . . . . . . . . . . . . 3
; 4. T$INIT - Terminal initialization . . . . . . . . . . . 4
; 5. T$CINI - Per command initialization. . . . . . . . . . 5
; 6. T$SRTN - Set terminal routines up. . . . . . . . . . . 6
; 7. T$SECH - Set terminal to echo characters . . . . . . . 7
; 8. T$CECH - Clear terminal echo . . . . . . . . . . . . . 8
; 9. T$IBUF - Input a character buffered moe. . . . . . . . 9
; 10. T$TCHR - Type a character dependant upon ET value. . . 10
; 11. T$ACHR - Type a character for ^A command . . . . . . . 11
; 12. TYPCHR - Type out for ET = 0 . . . . . . . . . . . . . 12
; 13. TYPLIT - Type out for ET = 1 . . . . . . . . . . . . . 13
; 14. TYPIMG - Type out for ET = 3 . . . . . . . . . . . . . 14
; 15. T$OCHR - Type out routine for messages . . . . . . . . 15
; 16. T$OBUF - Output a character in buffered mode . . . . . 16
; 17. TTYOUT - Output the TTY buffer . . . . . . . . . . . . 17
; 18. Output routines
; 18.1. .TSTRG. . . . . . . . . . . . . . . . . . . . 18
; 18.2. .TCRLF - Output a CRLF. . . . . . . . . . . . 19
; 19. $STRING routines
; 19.1. T$TYPE. . . . . . . . . . . . . . . . . . . . 20
; 19.2. T$TGCH - Get a character from the string. . . 22
; 19.3. STRFNC - Function table . . . . . . . . . . . 23
; 19.4. T$T.T - Type an ASCIZ string. . . . . . . . . 24
; 19.5. T$T.C - Type an ASCIZ string with special characters 25
; 19.6. T$T.O - Type an unsigned octal number . . . . 26
; 19.7. T$T.D - Type a decimal number . . . . . . . . 27
; 19.8. T$T.F - Type a file spec from an FDB. . . . . 28
; 19.9. T$T.G - Type a Q-register name. . . . . . . . 29
; 19.10. T$T.7 - Type an ascii character . . . . . . . 30
; 19.11. T$T.6 - Type a SIXBIT character . . . . . . . 31
; 19.12. T$T.P - Type a PPN or path. . . . . . . . . . 32
; 19.13. T$T.W - Type a SIXBIT word. . . . . . . . . . 33
; 19.14. T$T.5 - Type an ASCII word. . . . . . . . . . 33
; 19.15. T$T.M - Type a carriage return. . . . . . . . 34
; 19.16. T$T.J - Type a line feed. . . . . . . . . . . 34
; 19.17. T$T.K - Type a vertical tab . . . . . . . . . 34
; 19.18. T$T.L - type a form feed. . . . . . . . . . . 34
; 19.19. T$T.V - Type a version number . . . . . . . . 35
; 19.20. T$T.0 - Insert a null . . . . . . . . . . . . 36
; 19.21. T$T.I - Set left margin . . . . . . . . . . . 36
; 19.22. T$T.S - Type another $STRING. . . . . . . . . 37
; 19.23. T$T.Z - type a switch table . . . . . . . . . 38
; 19.24. T$T.X - Set output routine. . . . . . . . . . 39
; 19.25. T$T.INS - Type the following string . . . . . 40
; 19.26. T$T.EOS - End the current string. . . . . . . 41
; 19.27. T$T.BEG - Illegal . . . . . . . . . . . . . . 41
; 19.28. T$T.N - Set no-carriage return. . . . . . . . 41
; 19.29. T$COLN - Type a colon . . . . . . . . . . . . 42
; 19.30. T$COMA - Type a comma . . . . . . . . . . . . 42
; 19.31. T$DOT - Type a period . . . . . . . . . . . . 42
; 19.32. T$T.A - Type a left angle braket. . . . . . . 43
; 19.33. T$T.R - Type a right angle bracket. . . . . . 43
; 19.34. T$T.Q - Type a double quote . . . . . . . . . 43
; 19.35. T$SPAC - Type a space . . . . . . . . . . . . 44
; 19.36. T$CHAR - Type the character in CH . . . . . . 45
; 20. Low segment for TECTRM . . . . . . . . . . . . . . . . 46
; 21. End of TECTRM. . . . . . . . . . . . . . . . . . . . . 47
;.end lit.pag
;-
SUBTTL Revision History
COMMENT |
1000 Start of this version
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
1017 By: Robert McQueen On: 12-August-1980
- The ENQ'd path was wrong sometimes, test backwards.
- ^Z command caused files to be renamed for EB'd files.
Modules: TECTRM,TECECM
Start of Version 200A(1126)
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
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 T$INIT - Terminal initialization
;+
;.HL1 T$INIT
;This routine will do the terminal initialization for TECO. It will
;find the terminal type from the monitor if possible and set the
;default TECO terminal type from that.
;.literal
;
; Usage:
; PUSHJ P,T$INIT ; Do terminal initialization
; (Return)
;.end literal
;-
$CODE ; Code
T$INIT: STORE T1,TTYFDB,TTYFDB+.FDLEN-1,0 ; Clear the FDB
STORI. $FMTRM,T2,FDBMOD,+TTYFDB ; Store the mode
STORI. <SIXBIT /TTY/>,T2,FDBDEV,+TTYFDB ; Store the device name
MOVX T1,$IOWRI ; To write on this
MOVEI T2,TTYFDB ; Get the address
PUSHJ P,F$OPEN ; Open the terminal
PJRST F$ERR ; Couldn't?
MOVE T3,MYJOB ; Get the job number
TRMNO. T3, ; Get the universal index
JRST DEFCRT ; Use the default
MOVX T2,.TOTRM ; Get the terminal type
MOVE T1,[XWD 2,T2] ; Get the argument pointer
TRMOP. T1, ; Get the type
JRST DEFCRT ; Use the default
JUMPE T1,DEFCRT ; Use the default
TXNE T1,LH.ALF ; Is it really a name?
JRST T$IN.1 ; Yes, just go look for it
HRL T1,T1 ; Move the offset into the correct half
HRRI T1,.GTTNM ; Get the terminal name
GETTAB T1, ; from the monitor
JRST DEFCRT ; Use the default
T$IN.1: MOVEM T1,TRMTYP ; Store the terminal type
MOVE T2,[-NUMCRT,,CRTTAB] ; Get the table pointer
PUSHJ P,LOKNAM ; Find it
JRST DEFCRT ; Use the default
MOVEI T1,-CRTTAB(T2) ; Compute the offset
SKIPA ; Enter into the common code
DEFCRT: MOVEI T1,CRTGEN-CRTDSP ; Get the offset of the "General CRT"
MOVE CRT,CRTDSP(T1) ; Get the flags
MOVEM CRT,CRTTYP ; Store the flags
FALL T$CINI ; And fall into per command initialization
SUBTTL T$CINI - Per command initialization
;+
;.HL1 T$CINI
;This routine will do the per command terminal initialization
;.literal
;
; Usage:
; PUSHJ P,T$CINI
; (Return)
;.end literal
;-
T$CINI: MOVE T1,[PUSHJ P,T$ICHW] ; Get the instruction to get a character
MOVEM T1,ICHINS ; Store it
TXZ S,S.LCTT ; Clear the terminal lower case bit
SETO T1, ; Get the line characteristics
GETLCH T1 ; for this line
TXNE T1,GL.LCM ; Is this a lower case terminal
TXO S,S.LCTT ; Yes - Set the terminal lower case bit
TXO S,S.SLOG ; Suppress the * in the log file
SKPCLS TTYFDB ; Terminal open?
JRST T$CI.0 ; Yes, don't need to open it again
; Here if the terminal was closed (An error after EX command)
MOVX T1,$IOWRI ; Get the function
MOVEI T2,TTYFDB ; Get the FDB address
PUSHJ P,F$OPEN ; Open the terminal again
PJRST F$ERR ; Failed, process the error
T$CI.0: LOAD. T1,FDBCHN,+TTYFDB ; Get the channel number
IONDX. T1, ; And get the UDX
STOPCD CUX,<Can't get terminal UDX>
HRRZM T1,TRMUDX ; Save the terminal UDX
MOVEM T1,TRMSOP+1 ; Save for the SKPINC TRMOP
MOVEM T1,TRMOCH+1 ; Also here for doing image output
MOVEM T1,TRMTOC+1 ; Also for getting number of chars in output buffer
HRRZ T3,T1 ; Get the universal I/O index
MOVX T1,.TOSOP ; Get the function for skip if output present
MOVEM T1,TRMSOP ; Save it
MOVX T1,.TOOIC ; Get the image output function
MOVEM T1,TRMOCH ; Save it
MOVX T1,.TOTOC ; Get the other function
MOVEM T1,TRMTOC ; Save it
MOVEI T2,.TOALT ; Check the state of altmode conversion
MOVE T1,[XWD 2,T2] ; Get the argument pointer for the TRMOP
TRMOP. T1, ; Get the altmode information from TOPS-10
LDB T1,[POINTR (S,S.LCTT)] ; Failed - Use the LC bit
SKIPE T1 ; Conversion of altmodes wanted ?
TXOA S,S.NALT ; No - Don't convert them
TXZ S,S.NALT ; Yes - Do the conversion
MOVX T2,.TOTSP ; Get the terminal transmit speed
MOVX T1,<XWD 2,T2> ; Get the arg pointer
TRMOP. T1, ; Get the speed from the monitor
MOVX T1,.TS120 ; Assume 1200 baud
MOVEM T1,TRMSPD ; Save the terminal speed
MOVX T2,.TOWID ; Get the width
MOVE T1,[XWD 2,T2] ; And set up for the TRMOP.
TRMOP. T1, ; Get the width
SKIPA T1,$CRWID(CRT) ; Get the default width
SOJ T1, ; Internal width is one less
MOVEM T1,TRMWID ; Store the value
MOVX T2,.TOPAG ; Determine if terminal has TTY PAGE set
MOVE T1,[XWD 2,T2] ; Get the pointer
TRMOP. T1, ; Get the bit
SETZ T1, ; Assume not TTY PAGE
STOR T1,S,S.XNXF ; Flag whether we get XON's/XOFF's
MOVX T2,.TOPSZ ; Get the terminal page size
MOVE T1,[XWD 2,T2] ; Get the TRMOP pointer
TRMOP. T1, ; Get the length of the terminal page
MOVE T1,$CRLIN(CRT) ; Don't know it, get the default
JUMPN T1,.+2 ; Have a length
MOVE T1,$CRLIN(CRT) ; No, get the default
MOVEM T1,TRMLEN ; Save the length
FALL T$SRTN ; Fall into routine to set up routines
SUBTTL T$SRTN - Set terminal routines up
;+
;.HL1 T$SRTN
;This routine will set up the terminal input and output routines.
;It will store the routine addresses in the TY.??? areas in the low
;segment. All calls to the routines to input and output characters
;will be by the $CALL macro.
;.literal
;
; Usage:
; PUSHJ P,T$SRTN
; (Return)
;.end literal
;-
T$SRTN: MOVEI T1,T$IBUF ; Routine to input a byte buffered
SKPNS ; Skip if not screen mode
MOVEI T1,V$ICHR ; Routine to input a byte video mode
MOVEM T1,TY.IBY ; Store in the place to input a byte
MOVEI T1,T$OBUF ; Routine to output a byte buffered
SKPNS ; Skip if not screen mode
MOVEI T1,V$OCHR ; Routine to output a byte video mode
MOVEM T1,TY.OBY ; Store in the low segment
MOVX T3,IO.FCS!.IOASC ; Get the status
SKIPE IMGFLG ; Image mode?
MOVX T3,IO.FCS!.IOPIM ; Yes, get the correct mode
SKIPN ECHOFF ; Want echo turned off for some reason?
SKPNS ; Screen mode?
TXO T3,IO.SUP ; Yes, suppress echoing
LOADS. T2,FDBCHN,+TTYFDB ; Get the channel number
HRRI T2,.FOSET ; Get the function
MOVE T1,[XWD 2,T2] ; Get the pointer
FILOP. T1, ; And set the status
STOPCD FSF,<FILOP. .FOSET function failed>
POPJ P, ; Return to the caller
SUBTTL T$SECH - Set terminal to echo characters
;+
;.HL1 T$SECH
; This routine will set up to have the terminal echo characters.
;-
T$SECH: SKIPN ECHOFF ; Echo off?
POPJ P, ; No, just return
JMPS T$SE.1 ; If screen mode just set the flag
$SAVE <T1,T2,T3> ; Yes, save some room
SETZ T2, ; clear room for the FILOP. arg
MOVX T3,IO.FCS!.IOASC ; Get the status
LOADS. T2,FDBCHN,+TTYFDB ; Get the channel number
HRRI T2,.FOSET ; Get the function
MOVE T1,[XWD 2,T2] ; Get the pointer
FILOP. T1, ; And set the status
STOPCD CSE,<Couldn't set terminal echo on>
T$SE.1: SETZM ECHOFF ; Flag echo is on
POPJ P, ; Return
SUBTTL T$CECH - Clear terminal echo
;+
;.HL1 T$CECH
; This routine will turn the terminal echo off.
;-
T$CECH: SKIPE ECHOFF ; Is it already off?
POPJ P, ; Yes, just return
JMPS T$CE.1 ; If screen mode just set the flag
$SAVE <T1,T2,T3> ; Yes, save some room
MOVX T3,IO.SUP!IO.FCS!.IOASC ; Get the status
LOADS. T2,FDBCHN,+TTYFDB ; Get the channel number
HRRI T2,.FOSET ; Get the function
MOVE T1,[XWD 2,T2] ; Get the pointer
FILOP. T1, ; And set the status
STOPCD CCE,<Couldn't set terminal echo off>
T$CE.1: SETOM ECHOFF ; Flag echo is off
POPJ P, ; Return
SUBTTL T$IBUF - Input a character buffered moe
;+
;.HL1 T$IBUF
;This routine will input a character from the terminal.
;.literal
;
; Usage:
; PUSHJ P,T$IBUF
; (Return)
;
;
; Returns:
; CH - Containing the characters
;.end literal
;-
T$IBUF: TXZE F,F.TYOF ; Need to output the buffer
PUSHJ P,TTYOUT ; Output the buffer
TIBF.2: PUSHJ P,T$READ ; Get a character
TXNE S,S.LIIN ; Want image of input?
PUSHJ P,LOGC.0 ; Yes, log the character
; Here on having gotten a character in CH. Check the character for
; a Control G. If it is and we are not in screen mode then we have
; to echo an "^G".
TIBF.3: CAXE CH,.CHBEL ; Is this a bell (Control G) ?
JRST ALTCNV ; No - Go check for old altmodes
MOVEI CH,"^" ; Echo the bell as ^G
PUSHJ P,TYPCHR ; Output the "^"
MOVEI CH,"G" ; Get the "G"
PUSHJ P,TYPCHR ; Output it too
MOVX CH,.CHBEL ; Get the bell back
POPJ P, ; Return to the caller
; Here to see if we must do altmode conversions. First see if the
; flag is set to do the conversion then check to see if the character
; is one that must be converted.
ALTCNV: TXNE S,S.NALT ; Old altmode conversions ?
POPJ P, ; No - Just return
CAXL CH,.CHALT ; Is this an old altmode ?
CAILE CH,.CHAL2 ; . . .
POPJ P, ; No - Go return properly
ALTC.1: MOVEI CH,.CHESC ; Return an new altmode
POPJ P, ; Return
; Here to convert the 175 and 176 to escape (33) if EO = 1
ALTEO: CAXE CH,.CHALT ; Old style altmode ?
CAIN CH,.CHAL2 ; . . .
CHKEO EO21,ALTC.1 ; Check for before version 21
POPJ P, ; EO > 1 or not 175 or 176
SUBTTL T$RBUF - Read any characters already typed into buffer
;+
;.HL1 T$RBUF
; This routine will read any characters which have been typed by the user
;into the peek-ahead buffer. In video mode, the characters will not have
;been echoed, therefore when the characters are read from the buffer, the
;reader is responsible for echoing.
;.b.lit
;
; Usage:
; PUSHJ P,T$RBUF
; (return here always)
;
;.end lit
;-
T$RBUF: $SAVE <T1,T2> ; Save T1
XCT ICHINS ; Get first character
POPJ P, ; Nothing there, just return
TRBU.1: XMOVEI T1,TTIBUF+$QRTPT ; Get the address of the buffer
PUSHJ P,M$ACHR ; Append the character
PUSHJ P,T$ICHS ; Get a character
JRST TRBU.2 ; Go clear the pointer
JRST TRBU.1 ; Store it
TRBU.2: LOAD. T1,TPTADR,+$QRTPT+TTIBUF ; Get the address of the buffer
ZERO. ,BLKPT,(T1) ; Clear the pointer
POPJ P, ; ANd return
SUBTTL T$ICHW - Input a character and wait if none available
;+
;.hl1 T$ICHW
; This routine will read a character from the terminal, waiting until one
;is available, if necessary.
;.b.lit
;
; Usage:
; PUSHJ P,T$ICHW
; (non-skip return never)
; (skip return always)
;
;.end lit
;-
T$ICHW:
TOPS10, INCHRW CH ; Get a character, wait forever
TOPS20,<
PBIN ; Get a character
MOVE CH,T1 ; Into correct ac
> ; End of TOPS20
PJRST .POPJ1 ; Give skip return always
SUBTTL T$ICHS - Input a character if available
;+
;.HL1 T$ICHS
; This routine will input a character if there are any available. If no
;characters are available, it will get the error return.
;.b.lit
;
; Usage:
; PUSHJ P,T$ICHS
; (No characters available)
; (Character input into CH)
;
;.end lit
;-
T$ICHS:
TOPS10,<
INCHRS CH ; Get a character (if any)
POPJ P, ; Nothing there
PJRST .POPJ1 ; Got one, return
> ; End of TOPS10
TOPS20,<
;**** Do something
> ; End of TOPS20
SUBTTL T$PEKW - Peek ahead a given number of character
;+
;.hl1 T$PEKW
; This routine will peek ahead n characters and wait for the characters to
;be typed.
;.b.lit
;
; Usage:
; T1/ Character number to peek at (1=first)
; PUSHJ P,T$PEKW
; (return, CH=character)
;
;.end lit
;-
T$PEKW: PUSHJ P,T$CHKI ; Check if the character is there
JRST .-1 ; Not there, try reading some
PUSHJ P,T$PEEK ; Get the character
STOPCD PCD,<Peek-ahead character disappeared>
POPJ P, ; And return
SUBTTL T$PEEK - Peek at a character
;+
;.hl1 T$PEEK
; This routine will peek at a character in the type-in buffer.
;.b.lit
;
; Usage:
; T1/ Character number to peek at (1=first,...)
; PUSHJ P,T$PEEK
; (return, not enough chars in buffer)
; (return, character in CH)
;
;.end lit
;-
T$PEEK: PUSHJ P,T$CHKI ; Check if we have enough input
POPJ P, ; No, forget it
LOAD. T3,TPTADR,+$QRTPT+TTIBUF ; Get the address of the buffer
SOJ T1, ; Get the character position
IDIVI T1,^D5 ; Convert character index to word address
TDO T1,BTAB(T2) ; Make into a byte pointer
ADD T1,T3 ; . . .
ADDX T1,.BKTLN ; . . .
LDB CH,T1 ; Get the character
PJRST .POPJ1 ; And return
SUBTTL T$REDN - Read some characters
;+
;.hl1 T$REDN
; This routine will skip some characters in the input buffer.
;Note that in video mode the characters will not be echoed.
;.b.lit
;
; Usage:
; T1/ number of characters to skip
; PUSHJ P,T$REDN
; (return here always)
;
;.end lit
;-
T$REDN: $SAVE <P1> ; Save P1
MOVE P1,T1 ; Copy the amount to skip
LOAD. T1,TPTADR,+$QRTPT+TTIBUF ; Get the address of the buffer
MOVE T2,P1 ; Get the amount to delete
SETZ T3, ; Delete from the top
LOAD. P1,BLKEND,(T1) ; Get the amount there currently
ZERO. ,BLKPT,(T1) ; Make sure PT is clear
SUB P1,T2 ; Get the amount there will be left
JUMPGE P1,.+2 ; Something left?
ADD T2,P1 ; No, delete the whole thing
PUSHJ P,M$SRNK ; Delete the characters
JUMPGE P1,.POPJ ; Need to delete more?
MOVM P1,P1 ; Yes, make it positive
TRDN.1: PUSHJ P,T$READ ; Get a character
SOJG P1,TRDN.1 ; And loop for all we need to get
POPJ P, ; And return
SUBTTL T$READ - Read a character
;+
;.hl1 T$READ
; This routine will read a character from the type-in buffer (or terminal).
;Note that in video mode, the character will not have been echoed. The
;caller is repsonsible for echoing the character.
;.b.lit
;
; Usage:
; PUSHJ P,T$READ
; (return, character in CH)
;
;.end lit
;-
T$READ: LOAD. T1,TPTADR,+TTIBUF+$QRTPT ; Get the address of the type-ahead
CFXN. ,BLKEND,(T1),0 ; Anything in the buffer?
JRST TREA.0 ; No, get one from the terminal
ZERO. ,BLKPT,(T1) ; Clear the pointer
ADDX T1,<POINT 7,.BKTLN,6> ; Point to the first character
LDB CH,T1 ; Get it
LOAD. T1,TPTADR,+TTIBUF+$QRTPT ; Get the address of the buffer back
MOVEI T2,1 ; Delete one character
SETZ T3, ; At the start of the buffer
PJRST M$SRNK ; Go delete it
TREA.0: PUSHJ P,T$ICHW ; No, get a character from the terminal
JFCL ; Always has one
POPJ P, ; And return
SUBTTL T$WAIT - Wait for a character, or until timer expires
;+
;.HL1 T$WAIT
; This routine will wait until a given time arrives, or a character is typed,
;depending upon its arguments.
;.b.lit
; T1/ Time to wait in milli-seconds (if negative, always wait full time)
; T2/ Number of characters to wait for
; PUSHJ P,T$WAIT
; (return, no character available)
; (return, character(s) avaiable)
;
;.end lit
;-
T$WAIT: $SAVE <P1,P2,P3,P4> ; Save some ac's
DMOVE P1,T1 ; Get a copy of the time
JUMPL T1,TWAI.1 ; If we don't care if character is here
SKIPE T1,P2 ; Get the number of characters to check for
PUSHJ P,T$CHKI ; Check if any characters here
JRST TWAI.1 ; Go wait if not enough here yet
PJRST .POPJ1 ; Otherwise, give skip return
TWAI.1:
TOPS10,<
; Get the current system uptime, and determine what the uptime should
;be when the timer is to expire
MOVX T1,%CNSUP ; Get the system uptime
GETTAB T1, ; . . .
SETZ T1, ; Assume system isn't up
MOVM T2,P1 ; Get the time to wait in milli-seconds
MUL T2,JIFSEC ; Convert to jiffies
DIVX T2,^D1000 ; . . .
ADD T1,T2 ; Get the uptime when we wish to continue
MOVE P3,T1 ; Get the final time
MOVE P4,T3 ; And the extra milli-seconds after that
; Now enter the loop to check for correct time
TWAI.2: MOVX T1,%CNSUP ; Get the current uptime
GETTAB T1, ; . . .
MOVX T1,.INFIN ; Assume we have been up forever
SUBM P3,T1 ; No, get the amount left to wait
JUMPLE T1,TWAI.3 ; If we hit end time, go check remaining milli-seconds
MULX T1,^D1000 ; Convert to milli-seconds
DIV T1,JIFSEC ; . . .
CAXLE T1,^D<68*1000> ; More than the max wait time?
MOVX T1,^D<68*1000> ; Yes, use the max
JUMPL P1,.+2 ; Wait to wake on TTY input?
TXO T1,HB.RTC ; Yes, flag that
TXO T1,HB.RWJ ; Don't allow anyone else to wake us
HIBER T1, ; Wait for a while
JRST [IDIVI T1,^D1000 ; Make number of seconds to wait
SLEEP T1, ; Do it
JRST .+1] ; And continue
JUMPL P1,TWAI.2 ; If we don't want to wake for input, check time
SKIPE T1,P2 ; Get the number of characters to check for
PUSHJ P,T$CHKI ; Check if that much input
JRST TWAI.2 ; No, wait some more
PJRST .POPJ1 ; Else, all done
; Here when jiffy portion of timing runs out. Check for input (maybe), and
;wait the rest of the fractional jiffies (milli-seconds)
TWAI.3: JUMPN T1,TWAI.6 ; If we are already a jiffy past, skip this
JUMPL P1,TWAI.4 ; If want to wait without checking input, skip this
SKIPE T1,P2 ; Otherwise, get the character count
PUSHJ P,T$CHKI ; And check if available
JRST TWAI.4 ; Not there yet
PJRST .POPJ1 ; Got them, return now
; Here to wait the final milli-seconds.
TWAI.4: MSTIME P3, ; Get the current time
ADD P3,P4 ; Plus the amount we want to wait
TWAI.5: MSTIME T1, ; Get the current time
SUBM P3,T1 ; Get the amount left to wait
JUMPLE T1,TWAI.6 ; All done waiting
JUMPL P1,.+2 ; Abort on input?
TXO T1,HB.RTC ; Yes, get the flag
TXO T1,HB.RWJ ; Otherwise only allow our job
HIBER T1, ; Wait a little
JFCL ; Old monitor can run us this far?
JUMPL P1,TWAI.5 ; See if timer expired
SKIPE T1,P2 ; Get the number of chars we are waiting for
PUSHJ P,T$CHKI ; Check if they are here yet
JRST TWAI.5 ; No, check timer
PJRST .POPJ1 ; Yes, all done
; Here when timer has expired completely. Just check if the desired
;characters are available
TWAI.6: JUMPE P2,.POPJ1 ; 0 characters are always available now
MOVE T1,P2 ; Otherwise get the count
PJRST T$CHKI ; And check what we have
> ; End of TOPS10
TOPS20,<
;****** Do something
> ; End of TOPS20
SUBTTL T$CHKI - Check for input availability
;+
;.HL1 T$CHKI
; This routine will check if there are a given number of characters of
;terminal input available.
;.b.lit
;
; Usage:
; T1/ Number of characters to check for
; PUSHJ P,T$CHKI
; (return, characters not available)
; (return, characters available)
;
;.end lit
;-
T$CHKI: LOAD. T2,TPTADR,+$QRTPT+TTIBUF ; Get the address of the buffer
CFML. ,BLKEND,(T2),T1 ; Have as many chars as we are looking for?
PJRST .POPJ1 ; Yes, all done
TCHK.0: PUSHJ P,T$RBUF ; No, read into the buffer some more (if anything there)
LOAD. T2,TPTADR,+$QRTPT+TTIBUF ; Get the address of the buffer
CFML. ,BLKEND,(T2),T1 ; Have as many chars as we are looking for?
AOS (P) ; Yes, give skip return
POPJ P, ; All done
SUBTTL T$CTYI - Check for type-ahead
;+
;.hl1 T$CTYI
; This routine will check if there has been any type-ahead at all.
;It is mainly used by the screen update processing to determine is an update
;should be aborted.
;.b.lit
;
; Usage:
; PUSHJ P,T$CTYI
; (return, no type ahead)
; (return, characters have been typed)
;
;.end lit
;-
T$CTYI: SKPINC ; Check if monitor has some characters
JRST TCTY.1 ; No, check if any in buffer
PJRST .POPJ1 ; Yes, return
TCTY.1: PUSH P,T1 ; Save T1
LOAD. T1,TPTADR,+$QRTPT+TTIBUF ; Get the address of the buffer
CFXE. ,BLKEND,(T1),0 ; Anything in the buffer?
AOS -1(P) ; Yes, bump return address
POP P,T1 ; Restore T1
POPJ P, ; And return
SUBTTL T$TCHR - Type a character dependant upon ET value
;+
;.hl1 T$TCHR
; This routine will type a character from CH. How the character
;is typed depends upon the ET value. If ET=0 then the character
;will be typed literally if it is between a space and an underscore
;(back arrow), or if it is a control-character between a tab
;and a carriage return. Otherwise, it with either be typed as ^char
;(if is a control-char) or $ (for altmode) or possible as a case flagged character
;(depending on the EU value and the terminals LC bit.)
;-
T$TCHR: MOVE T1,ETVAL ; Get the ET value
JRST @ETDSP(T1) ; Dispatch to the correct routine
; Dispatch routine depending on the ET value
ETDSP: EXP TYPCHR ; ET = 0
EXP TYPLIT ; ET = 1
EXP TYPIMG ; ET = 2
SUBTTL T$ACHR - Type a character for ^A command
;+
;.hl1 T$ACHR
; This routine will type a character respecting the ET value
;but not the EU value.
;-
T$ACHR: MOVE T1,ETVAL ; Get the ET value
JRST @T$ATBL(T1) ; And do the right thing
T$ATBL: EXP T$OCHR ; Type the character without flagging
EXP TYPLIT ; Literal typeout
EXP TYPIMG ; Image typeout
SUBTTL TYPCHR - Type out for ET = 0
;+
;.hl1 TYPCHR
; This routine will type out a character if the ET value is 0.
;It will respect the EU value for case flagging.
;-
TYPCHR: PUSHJ P,ALTEO ; Convert altmodes as needed
TXNE S,S.LCTT ; Lower case terminal?
PJRST T$OCHR ; Yes, no case flagging needed
SKIPGE T1,TYCASF ; No, get the EU value
PJRST T$OCHR ; EU = -1 means no case flagging
CAXGE CH,"`" ; Lower case range character?
JRST TYPC.1 ; No, check if upper case range
JUMPN T1,T$OCHR ; If EU = 1 no lower case flagging
TYPC.0: PUSH P,CH ; Must flag character, save it
MOVX CH,"'" ; Get the flag character
PUSHJ P,@TY.OBY ; Output it
MOVE CH,(P) ; Get the character back
TXZ CH,"A"^!"a" ; Convert to upper case
PUSHJ P,@TY.OBY ; Type it
POP P,CH ; Restore the character
POPJ P, ; And return
TYPC.1: CAXGE CH,"@" ; Upper case range character?
PJRST T$OCHR ; No, go type it
JUMPE T1,T$OCHR ; Yes, just type if EU = 0
JRST TYPC.0 ; Must flag the character
SUBTTL TYPLIT - Type out for ET = 1
;+
;.hl1 TYPLIT
; This routine will type out a character if the ET value is 1.
;It will simply put the character into the output buffer.
;-
TYPLIT: PJRST @TY.OBY ; Output a byte
SUBTTL TYPIMG - Type out for ET = 3
;+
;.hl1 TYPIMG
; This routine will type out a character in image mode.
;The character will be typed with odd parity and also put into the
;log file if the user requested.
;-
TYPIMG: TXNE S,S.SLOG ; Want this?
TXNN S,S.LOUT ; Logging output?
JRST .+2 ; No, skip this
PUSHJ P,LOGCHR ; Yes, put it in the log file
TXZE F,F.TYOF ; Need to output the buffer first?
PUSHJ P,TTYOUT ; Yes, force it so things are in the correct order
SKIPL CHRFLG(CH) ; Need a parity bit on?
TRO CH,200 ; Yes, turn it on
IONEOU CH ; Output the character
TRZ CH,200 ; Make sure character is back correctly
POPJ P, ; And return
SUBTTL T$OCHR - Type out routine for messages
;+
;.hl1 T$TOCHR
; This routine will type out a character with control-character
;conversion, but no case flagging. It is used for error message
;type out and for re-printing the commands for ^G<space> or ^G., or
;when backspacing makes it necessary to retype the command.
;-
T$OCHR: CAXE CH,.CHTAB ; Tab's go literally
CAIL CH," " ; If greater than a space all is okay
PJRST @TY.OBY ; Just go type the character
CAXL CH,.CHCNH ; Is this between a backspace
CAXLE CH,.CHCRT ; And a carriage return?
JRST T$OC.1 ; No, check for altmode
CAXE CH,.CHLFD ; Line feeds
CAXN CH,.CHCRT ; And carriage returns
PJRST @TY.OBY ; Always go literally
JMPS T$OC.2 ; If screen mode, these all go as ^char
CAXE CH,.CHCNH ; Control-H?
JRST @TY.OBY ; Or literally for non-screen
TXNE CRT,CR$TTY ; TTY type terminal
JRST T$OC.2 ; Yes, go type the ^H
PJRST @TY.OBY ; No, type literally
T$OC.1: CAXE CH,.CHESC ; Is this an escape?
JRST T$OC.2 ; No, must use ^char form
MOVX CH,"$" ; Yes, use a dollar sign
PUSHJ P,@TY.OBY ; Output it
MOVX CH,.CHESC ; And restore the escape
POPJ P, ; And return
T$OC.2: PUSH P,CH ; Here to type as ^char
MOVX CH,"^" ; Get the up-arrow
PUSHJ P,@TY.OBY ; Type it
MOVE CH,(P) ; Get the character back
ADDX CH,"A"-.CHCNA ; Convert to correct character
PUSHJ P,@TY.OBY ; Output it
POP P,CH ; Get the character back
CAXE CH,.CHBEL ; Was it a bell?
POPJ P, ; No, just return
TXON S,S.SLOG ; Already suppressing log file?
PUSH P,[[TXZ S,S.SLOG ; No, remember to clear the flag
POPJ P,]] ; And return
PJRST @TY.OBY ; And output the character
SUBTTL T$OBUF - Output a character in buffered mode
;+
;.hl1 T$OBUF
; This routine will output a character into the terminal output
;buffer. It will also send the character to the log file if
;the user has request type out be logged.
;If the character should not go to the log file either S.SLOG should
;be on or T$OB.0 should be called.
;-
T$OBUF: TXNN S,S.SLOG ; Log stuff suppressed?
TXNN S,S.LOUT ; Write in log file also?
JRST .+2 ; No log wanted
PUSHJ P,LOGCHR ; Yes, do it
T$OB.0: SKPOPN TTYFDB ; Terminal open?
JRST [OUTCHR CH ; No, just output the character
POPJ P,] ; And return
T$OB.2: TXO F,F.TYOF ; Flag we have to output the buffer
SOSL .FDBRH+.BFCTR+TTYFDB ; Count the byte
JRST T$OB.1 ; Have room, go write it
PUSHJ P,TTYOUT ; No room, write the buffer
JRST T$OB.2 ; And try again
T$OB.1: SKIPL CHRFLG(CH) ; Need parity bit on?
TRO CH,200 ; Yes, do so
IDPB CH,.FDBRH+.BFPTR+TTYFDB ; Store the character
TRZ CH,200 ; Clear the parity bit
CAXLE CH,.CHLFD ; Is this less than a line feed
POPJ P, ; No, Return
FALL TTYOUT ; Yes, go output the buffer
SUBTTL TTYOUT - Output the TTY buffer
;+
;.hl1 TTYOUT
; This routine will force the monitor to type the terminal
;output buffer on the users terminal.
;-
TTYOUT: $SAVE <CH,T1> ; Save CH, T1 and T2
LOAD. T1,FDBCHN,+TTYFDB ; Get the channel number
SETZ CH, ; Clear this
STOR T1,CH,FO.CHN ; Store the channel number
HRRI CH,.FOOUT ; Get the function
MOVE T1,[XWD 1,CH] ; Get the argument pointer
FILOP. T1, ; Do it
JFCL ; Don't care
TXZ F,F.TYOF ; No longer need to output
POPJ P,
SUBTTL Output routines -- .TCRLF - Output a CRLF
;+
;.HL1 .TCRLF
;This routine will output a carriage return and a line feed.
;-
.TCRLF: MOVEI CH,.CHCRT ; Get the first character
PUSHJ P,T$OCHR ; Output it
MOVX CH,.CHLFD ; Get the second
PJRST T$OCHR ; Output it and return
SUBTTL $STRING routines -- T$TYPE
;+
;.hl1 $STRING routines
; These routines handle the output of the text string generated by
;the $STRING macro.
;.hl2 T$TYPE
; This is the main entry point for the $STRING routines. There is an alternate
;entry into this routine at T$ERTY if the ac's have already been saved.
;.b
;.literal
; Usage:
; MOVEI T1,Address.of.string
; PUSHJ P,T$TYPE
; (return)
;
;.end literal
;-
T$TYPE: $SAVE <TYPEAC,TYPEAC+T1,TYPEAC+T2,TYPEAC+T3,TYPEAC+T4,TYPEAC+P1,
TYPEAC+P2,TYPEACT+P3,TYPEAC+P4,TYPEAC+A1,TYPEAC+A2,TYPEAC+CH,
TGCRTN,EOSCRL,COLUMN,LFTMAR,STRTMP,TYPOUT,TLSTCH> ; Save necessary items
MOVEM T2,TYPEAC+T2 ; Save T2
MOVE T2,[XWD T3,TYPEAC+T3] ; Get the pointer to save the ac's
BLT T2,TYPEAC+CH ; And save through P4
PUSHJ P,T$ERTY ; Type the string
MOVE CH,[XWD TYPEAC+T2,T2] ; Get the BLT pointer
BLT CH,CH ; And restore the ac's
POPJ P, ; And return
T$ERTY: SETZM COLUMN ; Put at left margin
SETZM LFTMAR ; Clear the left margin
SETOM EOSCRL ; Flag we want a CRLF at the end of the string
SETZM TYPOUT ; Flag type on terminal
MOVEI T2,[OUTCHR CH ; Get desparation type out routine
POPJ P,] ; In case the terminal is open yet
SKPOPN TTYFDB ; If terminal is open, all is fine
MOVEM T2,TYPOUT ; No, use the OUTCHR
T$TY.S: SETZM TLSTCH ; No last character
HLRZM T1,TGCRTN ; Save the get-a-char routine
TXNE T1,LH.ALF ; Have a get a thing routine?
HRRZM T1,TYPOUT ; Yes, save the address
SKIPE TGCRTN ; Did we get a routine?
TDZA T1,T1 ; No, for T1 clear
HRLI T1,(POINT 7,) ; Set up the byte pointer
MOVE P1,T1 ; And copy into P1
T$TY.0: PUSHJ P,T$TGCH ; Get a character
CAXE CH,$TFBEG ; Is it the prefix character?
JRST T$TY.0 ; No, skip until we find it
PUSHJ P,T$TGCH ; Get a character
JUMPE CH,.-1 ; Skip nulls
CAXLE CH,$TFMAX ; Small enough?
STOPCD (BSF,<Bad $STRING function>)
MOVE T1,STRFNC-$TFBEG(CH) ; Get the table entry
TXNN T1,TF$ARG ; Need an arg?
JRST T$TY.5 ; No, skip this
SETZ P2, ; Clear the word to build the address
MOVE T3,[POINT 7,P2,7] ; And set up to build it
MOVEI T4,4 ; Get the count
T$TY.9: PUSHJ P,T$TGCH ; Get a character
IDPB CH,T3 ; And store it
SOJG T4,T$TY.9 ; Loop for all the chars
; Calculate the effective address, using the callers ac's if
;necessary.
T$TY.1: LOAD T2,P2,IW.IDX ; Get the index field
JUMPE T2,T$TY.2 ; Have one?
CAIG T2,CH ; Is is an ac we have saved?
SKIPA T2,TYPEAC(T2) ; Yes, get the value from the block
MOVE T2,(T2) ; No, just get the value from the AC
T$TY.2: LOAD T3,P2,IW.ADR ; Get the address field
ADD T2,T3 ; Get the total
TXNN P2,IW.IND ; Is the indirect bit on?
JRST T$TY.4 ; No, go store the address
TXZ T2,LH.ALF ; Clear the left half
CAIG T2,CH ; Saved ac?
MOVEI T2,TYPEAC(T2) ; Yes, point to the right thing
MOVE P2,(T2) ; Get the word
JRST T$TY.1 ; And go around again
T$TY.4: TXNE T1,TF$IMM ; Immediate address type function?
JRST T$TY.5 ; Yes, skip this
CAIG T2,CH ; Need to relocate to saved ac's?
MOVEI T2,TYPEAC(T2) ; Yes, get the correct address
T$TY.5: PUSHJ P,(T1) ; And call the right routine
JRST T$TY.0 ; Loop until we get the end of string
POPJ P, ; And return
SUBTTL $STRING routines -- T$TGCH - Get a character from the string
;+
;.hl2 T$TGCH
; This routine will get a character from the string.
;-
T$TGCH: SETZ CH, ; Clear the last character
EXCH CH,TLSTCH ; Get it
JUMPN CH,.POPJ ; And return it if we have one
SKIPE TGCRTN ; Have a routine to call?
PJRST @TGCRTN ; Yes, go do it
ILDB CH,P1 ; No, just get a character
POPJ P, ; And return
SUBTTL $STRING routines -- STRFNC - Function table
; This table contains the flags and dispatch addresses for the $STRING
;functions.
STRFNC:
DEFINE TT(CHAR,FLAGS,STRING),<EXP FLAGS+T$T.'CHAR>
TXTTYP ; Expand the macro
SUBTTL $STRING routines -- T$T.E - Type a DOSTR table
;+
;.hl2 T$T.E
;This routine will type a DOSTR table. It will call T$T.T to do all the
;hard work.
;-
T$T.E: $SAVE <P1> ; Save a register
MOVE P1,(T2) ; Copy the pointer to the table
JRST T$TE.1 ; Enter the loop
T$TE.0: MOVEI CH,"," ; Get the character to output
PUSHJ P,T$CHAR ; Output the character
MOVEI CH," " ; And a space
PUSHJ P,T$CHAR ; . . .
T$TE.1: MOVE T1,@(P1) ; Get the byte pointer to the first string
PUSHJ P,T$TA.1 ; Output the string
AOBJN P1,T$TE.0 ; Loop for all entries
POPJ P, ; Return to the caller
SUBTTL $STRING routines -- T$T.T - Type an ASCIZ string
;+
;.hl2 T$T.T
; This routine will cause the ASCIZ string pointed to by the address
;to be typed out.
;-
T$T.T: MOVE T1,T2 ; Get the address
HRLI T1,(POINT 7,) ; Get the byte pointer into it
JRST T$TA.1 ; And join common routine
T$T.B: MOVE T1,(T2) ; Get the address of the string
T$TA.1: $SAVE <P1> ; Save P1
MOVE P1,T1 ; And get the byte pointer
T$TA.2: ILDB CH,P1 ; Get the character
JUMPE CH,.POPJ ; Just return if it is a null
PUSHJ P,T$CHAR ; Otherwise type the character
JRST T$TA.2 ; And loop for entire string
SUBTTL $STRING routines -- T$T.C - Type an ASCIZ string with special characters
;+
;.HL2 T$T.C
; This routine will cause the ASCIZ string pointed to by the address to
;be typed out. Any special characters will be typed as <xxx> where xxx
;is the name of the special character.
;-
T$T.C: $SAVE <P1> ; Save P1
MOVE P1,T2 ; Get the address
HRLI P1,(POINT 7) ; Build the full byte pointer
T$TC.0: ILDB CH,P1 ; Get the character
JUMPE CH,.POPJ ; Give a normal return
PUSHJ P,T$FCHR ; Type a funny character
JRST T$TC.0 ; Loop for the next character
SUBTTL $STRING routines -- T$T.O - Type an unsigned octal number
;+
;.hl2 T$T.O
; This routine will type the value pointed to by the address to be typed
;out as an unsigned octal number.
;-
T$T.O: SKIPL T1,(T2) ; Get the value
JRST T$TO.0 ; Not negative, skip the sign
MOVEI CH,"-" ; Get the minus sign
PUSHJ P,T$CHAR ; Type the sign
MOVN T1,(T2) ; Get the positive value
T$TO.0: SETZB T2,T3 ; Clear T2 and T3
T$TO.1: IDIVI T1,^D8 ; Get the digit
PUSH P,T2 ; Save it
AOJ T3, ; And count it
JUMPN T1,T$TO.1 ; And loop for all the digits
T$TO.2: POP P,CH ; Get the digit back
ADDX CH,"0" ; Make it an ascii character
PUSHJ P,T$CHAR ; And type the character
SOJG T3,T$TO.2 ; Loop for all the chars
POPJ P, ; And return
SUBTTL $STRING routines -- T$T.D - Type a decimal number
;+
;.hl2 T$T.D
; This routine will type the value as a decimal number.
;-
T$T.D: SKIPL T1,(T2) ; Is the value negative?
JRST T$TD.0 ; No, skip this
MOVEI CH,"-" ; Get the minus sign
PUSHJ P,T$CHAR ; And type it
MOVN T1,(T2) ; And get the value as positive
T$TD.0: IDIVI T1,^D10 ; Get a digit
PUSH P,T2 ; Save it
JUMPE T1,.+2 ; Done?
PUSHJ P,T$TD.0 ; No, get the next
POP P,CH ; Get the digit back
ADDX CH,"0" ; Make it ASCII
PJRST T$CHAR ; And type the character
SUBTTL $STRING routines -- T$T.F - Type a file spec from an FDB
;+
;.hl2 T$T.F
; This routine will type out a complete file spec from an FDB.
;-
T$T.F: $SAVE <P1> ; Save some ac's
MOVE P1,(T2) ; Get the arg address
CFXN. ,FDBNOD,(P1),0 ; Have a node?
JRST T$TF.1 ; No, skip this
MOVEI T2,.FDNOD(P1) ; Yes, get the address
PUSHJ P,T$T.W ; Type it
PUSHJ P,T$COLN ; Type a colon
PUSHJ P,T$COLN ; And another
T$TF.1: CFXN. ,FDBDEV,(P1) ; Have a device
JRST T$TF.2 ; No, skip it
MOVEI T2,.FDDEV(P1) ; Yes, get the address
PUSHJ P,T$T.W ; And type it
PUSHJ P,T$COLN ; And type the colon
T$TF.2: MOVEI T2,.FDNAM(P1) ; Get the address of the name
PUSHJ P,T$T.W ; Type it
MOVX T1,FD.HEX ; Check if we have an extension
TDNN T1,.FDFLG(P1) ; No, skip it
JRST T$TF.3 ; . . .
PUSHJ P,T$DOT ; Yes, print a dot
CFXN. T1,FDBEXT,(P1),0 ; Have an extension?
JRST T$TF.3 ; No, skip this
LOADS. T1,FDBEXT,(P1) ; Get the extension
MOVEM T1,STRTMP ; Save it in the temp
MOVEI T2,STRTMP ; Get the address
PUSHJ P,T$T.W ; Type the string
T$TF.3: MOVX T1,FD.PTH ; Get the bit to check
TDNN T1,.FDFLG(P1) ; Check if we have a path
JRST T$TF.4 ; No, skip this
MOVEI T1,.FDPPN-.PTPPN(P1) ; Get the address of the path
MOVEM T1,STRTMP ; Save it
MOVEI T2,STRTMP ; Get the address
PUSHJ P,T$T.P ; And type the PPN and path
T$TF.4: CFXN. T1,FDBPRO,(P1),0 ; Have a protection to type?
JRST T$TF.5 ; No, skip it
MOVEI T2,[ASCIZ | /PROTECTION:|] ; Get the text
PUSHJ P,T$T.T ; List it
LOAD. T3,FDBPRO,(P1) ; Get the protection
MOVEI CH,"0" ; See if we need leading zeros
CAIGE T3,100 ; Will it print three digits?
PUSHJ P,T$CHAR ; No, print the first zero
MOVEI CH,"0" ; Get the zero back
CAIGE T3,10 ; Will it print two digits?
PUSHJ P,T$CHAR ; No, print the second zero
MOVEM T3,STRTMP ; Save the value
MOVEI T2,STRTMP ; Get the address
PUSHJ P,T$T.O ; And type the number
T$TF.5: CFXN. T1,FDBVER,(P1),0 ; Have a version number?
JRST T$TF.6 ; No, skip it
MOVEI T2,[ASCIZ | /VERSION:|] ; Get the text
PUSHJ P,T$T.T ; And tell him what this is
MOVEI T2,.FDVER(P1) ; Get the version address
PUSHJ P,T$T.V ; And list it
T$TF.6: CFXN. T1,FDBMOD,(P1),0 ; Have a non-default mode?
JRST T$TF.7 ; No, skip this
MOVEI T2,[ASCIZ | /MODE:|] ; Get the text
PUSHJ P,T$T.T ; And type it
LOAD. T1,FDBMOD,(P1) ; Get the mode
MOVEI T2,MODKEY(T1) ; Get the address of the sixbit
PUSHJ P,T$T.W ; Type the keyword
T$TF.7: POPJ P, ; And return
SUBTTL $STRING routines -- T$T.G - Type a Q-register name
;+
;.HL2 T$T.G
;This routine will type a Q-register name. It gets the name
;from the QRG block supplied as the argument.
;-
T$T.G: MOVE T2,(T2) ; Get the Q-reg address
MOVE T1,$QRFLG(T2) ; Get the flags
TXNE T1,QR$PRD!QR$LQR ; Predefined or user long name?
JRST T$T.G0 ; Yes, go check which
MOVE CH,$QRQRN(T2) ; No, get the name
JRST T$CHAR ; Enter the common routine
; Here if the name is not a single character
T$T.G0: TXNN T1,QR$LQR ; User defined long name?
JRST [MOVE T1,$QRQRN(T2) ; No, must be predefined
PJRST T$TA.1] ; So go type it
$SAVE <P1,P2> ; Save P1
LOAD. P1,TPTADR,+$QRQRN(T2) ; Get the address of the STE
LOAD. P2,SYMCNT,(P1) ; Get the count of the number of characters
ADDX P1,<POINT 7,$SYNAM> ; Make a byte pointer
T$T.G1: ILDB CH,P1 ; Get the character
PUSHJ P,T$CHAR ; Output the character
SOJG P2,T$T.G1 ; Loop back
POPJ P, ; Return
SUBTTL $STRING routines -- T$T.7 - Type an ascii character
;+
;.hl2 T$T.7
; This routine will type a single ASCII character from the address given.
;-
T$T.8: MOVE CH,(T2) ; Get the character
PJRST T$CHAR ; And type it
T$T.7: MOVE CH,(T2) ; Get the character
T$FCHR: MOVSI T2,-FNYLEN ; Build the byte pointer
T$T7.0: CAMN CH,FNYTBL(T2) ; Is this the character
JRST T$T7.1 ; Yes - Continue
AOBJN T2,T$T7.0 ; Loop until we fail or find it
PJRST T$CHAR ; Output the character
T$T7.1: PUSHJ P,T$T.A ; Output the left angle bracket
HRRI T2,FNYTXT(T2) ; Get the address
PUSHJ P,T$T.T ; Output the string
PJRST T$T.R ; Output the closing bracket
DEFINE FNYCHR,<
FC .CHNUL,NULL
FC .CHBEL,BELL
FC .CHVTB,VT
FC .CHTAB,TAB
FC .CHCRT,CR
FC .CHFFD,FF
FC .CHESC,ESC
FC .CHLFD,LF
> ; End of FNYCHR macro definition
DEFINE FC(CHAR,TEXT),<EXP CHAR>
FNYTBL: FNYCHR ; Expand the characters
FNYLEN==.-FNYTBL ; Determine the lenght of the table
; Expand the text
DEFINE FC(CHAR,TEXT),<ASCII |'TEXT'|>
FNYTXT: FNYCHR ; Expand the text
SUBTTL $STRING routines -- T$T.6 - Type a SIXBIT character
;+
;.hl2 T$T.6
; This routine will type a single SIXBIT character from the address given.
;-
T$T.6: MOVE CH,(T2) ; Get the character
ADDX CH,"A"-'A' ; Convert to ascii
PJRST T$CHAR ; And type it
SUBTTL $STRING routines -- T$T.P - Type a PPN or path
;+
;.hl2 T$T.P
; This routine will type out a PPN from the address or a complete path
;if the address contains the address of a path block.
;-
T$T.P: $SAVE <P1,P2> ; Save P1
MOVE P1,(T2) ; Get the arg
JUMPE P1,.POPJ ; Just return if null
TXNN P1,LH.ALF ; Have an address?
SKIPE .PTPPN(P1) ; Yes, is the ppn in the block zero?
JRST .+2 ; Must type it
POPJ P, ; No, just return
MOVEI CH,"[" ; Get the open bracket
PUSHJ P,T$CHAR ; And type it
SETZ P2, ; Clear in case no path
TXNE P1,LH.ALF ; Have just a PPN
JRST T$TP.1 ; Yes, go handle it
HRLI P2,<.PTPPN-.PTMAX> ; Get the number of words
HRRI P2,.PTPPN(P1) ; And point to the first one
MOVE P1,(P2) ; Get the PPN
T$TP.1: JUMPGE P1,T$TP.2 ; SIXBIT PPN?
MOVEM P1,STRTMP ; Yes, save it
MOVEI T2,STRTMP ; And get the address
PUSHJ P,T$T.W ; And type it
JRST T$TP.3 ; Go handle the rest
T$TP.2: HLRZM P1,STRTMP ; Save the project number
MOVEI T2,STRTMP ; Get the address
PUSHJ P,T$T.O ; And type it
PUSHJ P,T$COMA ; Type a comma
HRRZM P1,STRTMP ; Save the programmer number
MOVEI T2,STRTMP ; Get the address
PUSHJ P,T$T.O ; Type the programmer number
T$TP.3: AOBJP P2,T$RBRK ; Type a right bracket if done
SKIPE (P2) ; Have an SFD?
JRST T$TP.4 ; Yes, go type it
T$RBRK: MOVEI CH,"]" ; No, get the character
PJRST T$CHAR ; And type the closing bracket
T$TP.4: PUSHJ P,T$COMA ; Type a comma
MOVEI T2,(P2) ; Get the address
PUSHJ P,T$T.W ; And type the word
JRST T$TP.3 ; Loop for all the SFD's
SUBTTL $STRING routines -- T$T.W - Type a SIXBIT word
;+
;.hl2 T$T.W
; This routine will type a single SIXBIT word.
;-
T$T.W: SKIPN T3,(T2) ; Get the word
POPJ P, ; Return if nothing to type
T$TW.1: SETZ T2, ; Clear T2
LSHC T2,6 ; Get a character
MOVEI CH,"A"-'A'(T2) ; Get the character
PUSHJ P,T$CHAR ; Type it
JUMPN T3,T$TW.1 ; Loop for all of the charas
POPJ P, ; And return
SUBTTL $STRING routines -- T$T.5 - Type an ASCII word
;+
;.hl2 T$T.5
; This routine will type a single ASCII word.
;-
T$T.5: MOVE T3,(T2) ; Get the word
TXZ T3,1B35 ; Clear the LSN bit
JUMPE T3,.POPJ ; Return if nothing to type
T$T5.1: SETZ T2, ; Clear T2
LSHC T2,7 ; Get a character
MOVE CH,T2 ; Get the character
PUSHJ P,T$CHAR ; Type it
JUMPN T3,T$T5.1 ; Loop for all the chars
POPJ P, ; And return
SUBTTL $STRING routines -- T$T.M - Type a carriage return
;+
;.hl2 T$T.M
; This routine will type a carriage return (no line feed).
;-
T$T.M: MOVX CH,.CHCRT ; Get the character
PJRST T$CHAR ; And type it
SUBTTL $STRING routines -- T$T.J - Type a line feed
;+
;.hl2 T$T.J
; This routine will type a line feed.
;-
T$T.J: MOVX CH,.CHLFD ; Get the character
PJRST T$CHAR ; And type it
SUBTTL $STRING routines -- T$T.K - Type a vertical tab
;+
;.hl2 T$T.K
; This routine will type a vertical tab.
;-
T$T.K: MOVX CH,.CHVTB ; Get the character
PJRST T$CHAR ; And type it
SUBTTL $STRING routines -- T$T.L - type a form feed
;+
;.hl2 T$T.L
; This routine will type a form feed.
;-
T$T.L: MOVX CH,.CHFFD ; et the character
PJRST T$CHAR ; And type it
SUBTTL $STRING routines -- T$T.V - Type a version number
;+
;.hl2 T$T.V
; This routine will type out a version number in standard form.
;-
T$T.V: $SAVE <P1> ; Save this value
MOVE P1,(T2) ; Get the word
LOAD T1,P1,VR.VER ; Get the major version
JUMPE T1,T$TV.1 ; Have it?
MOVEM T1,STRTMP ; Save it
MOVEI T2,STRTMP ; Get the address
PUSHJ P,T$T.O ; And type it
T$TV.1: LOAD T1,P1,VR.MIN ; Get the minor version
JUMPE T1,T$TV.3 ; Have it?
IDIVX T1,^D26 ; Split into two digits
JUMPE T1,T$TV.2 ; First digit there?
MOVEI CH,"A"-1(T1) ; Yes, convert to a letter
PUSH P,T2 ; Save T2
PUSHJ P,T$CHAR ; And type the character
POP P,T2 ; Get back the second digit
T$TV.2: MOVEI CH,"A"-1(T2) ; Get the seond digit
PUSHJ P,T$CHAR ; And list it
T$TV.3: TXNN P1,VR.EDT ; Have an edit level?
JRST T$TV.4 ; No, go handle who field
MOVEI CH,"(" ; et a left paren
PUSHJ P,T$CHAR ; And type it
LOAD T1,P1,VR.EDT ; Get the edit
MOVEM T1,STRTMP ; Save the number
MOVEI T2,STRTMP ; Get the address
PUSHJ P,T$T.O ; Type it
MOVEI CH,")" ; Get the close paren
PUSHJ P,T$CHAR ; Type the lcose paren
T$TV.4: TXNN P1,VR.WHO ; Have a who field?
POPJ P, ; No, return
LOAD T1,P1,VR.WHO ; Get the field
MOVNM T1,STRTMP ; Save in the temp
MOVEI T2,STRTMP ; Get the address
PJRST T$T.O ; And go type the value
SUBTTL $STRING routines -- T$T.0 - Insert a null
;+
;.hl2 T$T.0
; This routine will terminate a string with a null. No descriptors
;after it will be looked at.
;-
T$T.0: SETZB CH,EOSCRL ; Clear the character and the crlf flag
PJRST T$CHAR ; And go store the null
SUBTTL $STRING routines -- T$T.I - Set left margin
;+
;.hl2 T$T.I
; This routine will set the left margin to the given immediate
;value.
;-
T$T.I: MOVE T1,TRMWID ; Not a real CRT, get the width
CAIL T2,-20(T1) ; Is this too far left?
MOVEI T2,-20(T1) ; Yes, use the max
MOVEM T2,LFTMAR ; Save the new left margin
POPJ P, ; And return
SUBTTL $STRING routines -- T$T.S - Type another $STRING
;+
;.hl2 T$T.S
; This routine will type another $STRING string.
;-
T$T.S: $SAVE <P1,LFTMAR,TGCRTN,TLSTCH> ; Save P1 for upper level
MOVE T1,T2 ; Get the address of the string
PJRST T$TY.S ; And call ourself to process the string
SUBTTL $STRING routines -- T$T.Z - type a switch table
;+
;.hl2 T$T.Z
; This routine will type out a switch table given an AOBJx pointing to the
;names.
;-
T$T.Z: $SAVE <P1,P2> ; Save some working room
MOVE P1,(T2) ; Get the AOBJx
JUMPGE P1,.POPJ ; Just return if none
SETO P2, ; Flag no comma yet
T$TZ.1: LDB T2,[POINT 6,(P1),5] ; Get the first character
CAXN T2,'.' ; Is it a dot?
JRST T$TZ.3 ; Yes, skip it (internal place holder)
AOJE P2,T$TZ.2 ; Need a comma?
PUSHJ P,T$COMA ; Yes, type it
PUSHJ P,T$SPAC ; Type a space
T$TZ.2: MOVEI T2,(P1) ; Get the address
PUSHJ P,T$T.W ; And type the word
T$TZ.3: AOBJN P1,T$TZ.1 ; And loop for all the entries
POPJ P, ; Return
SUBTTL $STRING routines -- T$T.X - Set output routine
;+
;.hl2 T$T.X
; This routine will set the output a character routine to the address given.
;The routine will be called with the character to type in CH. It may smash
;only CH.
;-
T$T.X: MOVEM T2,TYPOUT ; Store the routine address
POPJ P, ; And return
SUBTTL $STRING routines -- T$T.INS - Type the following string
;+
;.hl2 T$T.INS
; This routine will type the string which follow after the function code.
;Call with the byte pointer in P1, returns updated P1.
;-
T$T.INS:PUSHJ P,T$TGCH ; Get the next character
CAXN CH,$TFBEG ; Next byte a function
JRST [MOVEM CH,TLSTCH ; Save the character
POPJ P,] ; And return
JUMPE CH,T$T.INS ; Ignore nulls
PUSHJ P,T$CHAR ; No, type the character
JRST T$T.INS ; And loop until end
SUBTTL $STRING routines -- T$T.EOS - End the current string
;+
;.hl2 T$T.EOS
; This routine is called on the end of a string.
;-
T$T.EOS:SKIPN EOSCRL ; Want a CRLF?
JRST .POPJ1 ; No, return
PUSHJ P,T$T.M ; Yes, type the carriage return
AOS (P) ; Force te skip return
PJRST T$T.J ; And type the line feed
SUBTTL $STRING routines -- T$T.BEG - Illegal
T$T.BEG:STOPCD (T2I,<Type 2 function is illegal>)
SUBTTL $STRING routines -- T$T.N - Set no-carriage return
;+
;.hl2 T$T.N
; This routine will set so no carriage return is given at the end of the
;current string.
;-
T$T.N: SETZM EOSCRL ; Clear the flag for the crlf
POPJ P, ; And return
SUBTTL $STRING routines -- T$COLN - Type a colon
;+
;.hl2 T$COLN
; This routine will type a colon.
;-
T$COLN: MOVEI CH,":" ; Get the character
PJRST T$CHAR ; And go type the character
SUBTTL $STRING routines -- T$COMA - Type a comma
;+
;.hl2 T$COMA
; THis routine will type a comma.
;-
T$COMA: MOVEI CH,"," ; Get the comma
PJRST T$CHAR ; And go type it
SUBTTL $STRING routines -- T$DOT - Type a period
;+
;.hl2 T$DOT
; This routine will type a period (dot).
;-
T$DOT: MOVEI CH,"." ; Get the character
PJRST T$CHAR ; And go type it
SUBTTL $STRING routines -- T$T.A - Type a left angle braket
SUBTTL $STRING routines -- T$T.R - Type a right angle bracket
;+
;.HL2 T$T.R and T$T.A
; These routines will type a right and left angle bracket.
;-
T$T.R: SKIPA CH,[EXP .CHRAB] ; Get a right angle bracket
T$T.A: MOVX CH,.CHLAB ; Get a left angle bracket
PJRST T$CHAR ; Type the character
SUBTTL $STRING routines -- T$T.Q - Type a double quote
;+
;.hl2 T$T.Q
; This routine will type a double quote.
;-
T$T.Q: MOVX CH,"""" ; Get the character
PJRST T$CHAR ; And type it
SUBTTL $STRING routines -- T$SPAC - Type a space
;+
;.hl2 T$SPAC
; This routine will type a space.
;-
T$SPAC: MOVEI CH," " ; Get the character
FALL T$CHAR ; And fall into the routine
SUBTTL $STRING routines -- T$CHAR - Type the character in CH
;+
;.HL2 T$CHAR
; This routine will type a character. It will insert CRLF's as necessary
;to avoid wraparound if possible.
;-
T$CHAR: SKIPE TYPOUT ; Have a typeout?
JRST @TYPOUT ; Yes, go use it
$SAVE <P1,P2> ; Save P1 and P2
SETZ P1, ; Clear the character width
PUSHJ P,ALTEO ; Convert altmodes
CAXE CH,.CHESC ; Is this an escape?
CAIL CH," " ; This a normal character?
AOJA P1,T$CH.9 ; Yes, only one wide
CAXN CH,.CHTAB ; Is this a tab?
JRST [MOVX P1,7 ; Yes, put at tab stop
EXCH P1,COLUMN ; Switch around
IORM P1,COLUMN ; . . .
SUB P1,COLUMN ; Get the amount to move
MOVN P1,P1 ; Make it positive
JRST T$CH.9] ; And go handle it
CAXE CH,.CHCNH ; Is this a backspace?
JRST T$CH.7 ; No, check other control chars
TXNE CRT,CR$TTY ; Is this a TTY?
JRST T$CH.6 ; Yes, make it two wide
SOJA P1,T$CH.9 ; Otherwise it is minus one
T$CH.7: CAXL CH,.CHLFD ; Is this a line feed?
CAXLE CH,.CHFFD ; Or other vertical positioning?
JRST .+2 ; No, try carriage return
JRST T$CH.9 ; Yes, zero wide
CAXE CH,.CHCRT ; Is this a carriage return?
T$CH.6: SKIPA P1,[EXP 2] ; No, use two wide
MOVN P1,COLUMN ; Yes, this puts the column to zero
T$CH.9: PUSH P,P1 ; Save the width
EXCH P1,COLUMN ; Switch the column and width
CAMG P1,LFTMAR ; At the left margin?
CAIE CH," " ; Yes, is this a space?
JRST T$CH.8 ; Must write the character
MOVEM P1,COLUMN ; Yes, reset the column
POP P,P1 ; Get the value back
POPJ P, ; And return, ignoring the leading space
T$CH.8: MOVE P2,TRMWID ; Get the width from the monitor
CAIL P1,-20(P2) ; Getting near the right margin?
CAIE CH," " ; A space?
JRST T$CH.1 ; No, go type the character
POP P,(P) ; Yes, get rid of the stacked value
PUSHJ P,.TCRLF ; Yes, type a crlf
SETZM COLUMN ; Clear the column
T$CH.0: MOVEI CH," " ; Get a space
MOVE P1,COLUMN ; Get the column number
T$CH.A: CAML P1,LFTMAR ; Hit the right place yet?
POPJ P, ; Yes, return
PUSHJ P,T$OCHR ; No, type a space
AOS P1,COLUMN ; Bump the column
JRST T$CH.A ; And loop
T$CH.1: MOVEM P1,COLUMN ; Reset the column
SKIPLE (P) ; Don't indent for characters zero or negative wide
CAML P1,LFTMAR ; Need to indent?
JRST T$CH.4 ; No, just type the character
PUSH P,CH ; Save the character
PUSHJ P,T$CH.0 ; Indent the proper amount
POP P,CH ; Get the character back
T$CH.4: POP P,P1 ; Get rid of the character width
ADDM P1,COLUMN ; Reset the column
PJRST T$OCHR ; And type it
SUBTTL Low segment for TECTRM
$IMPURE ; Do the impure storage
LOWVER(TRM,3) ; Low segment version number for this module
; Terminal I/O buffers and blocks
TTYFDB: BLOCK .FDLEN ; FDB for the terminal
TRMUDX: BLOCK 1 ; UDX for the terminal
TRMSPD: BLOCK 1 ; Terminal speed from monitor
TRMSOP: BLOCK 2 ; TRMOP. block for skip if output present
TRMOCH: BLOCK 3 ; TRMOP. to use for image output
TRMTOC: BLOCK 2 ; TRMOP. block for getting number of chars in output buffer
; Flags
TYCASF: BLOCK 1 ; Type out case flag
; 0 = Type ' before LC, + = Type ' before UC
; - = Don't type '
; Terminal processing data
TY.OBY: BLOCK 1 ; Address of the routine to output a byte
TY.IBY: BLOCK 1 ; Address of the routine to input a byte
TY.OST: BLOCK 1 ; Address of the routine to output a string
TY.IST: BLOCK 1 ; Address of the routine to input a string
; Storage for $STRING routines
COLUMN: BLOCK 1 ; Current column for output
EOSCRL: BLOCK 1 ; Flag for CRLF at end of string
LFTMAR: BLOCK 1 ; Column for left margin
TYPEAC: BLOCK 20 ; Block for saving AC's during T$TYPE
; routine
STRTMP: BLOCK 1 ; Temp for storing things we need the address of
TYPOUT: BLOCK 1 ; Address of routine to call for output
TGCRTN: BLOCK 1 ; Routine to fetch a character
TLSTCH: BLOCK 1 ; Character to be read again
ECHOFF: BLOCK 1 ; Flag whether echo is on or off
TRMWID: BLOCK 1 ; Terminal width from monitor
TRMLEN: BLOCK 1 ; Length of the terminal page
TRMTYP: BLOCK 1 ; Terminal type
; Peek ahead buffer
TTIBUF: BLOCK $QRLEN ; TERMINAL-INPUT-BUFFER Q-register
ICHINS: BLOCK 1 ; Instruction to get character from terminal
SUBTTL End of TECTRM
END ; End of TECTRM