Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_SRC_3_19910112
-
utilities/chat.mac
There are no other files named chat.mac in the archive.
Title Chat
Search Monsym
Asuppress
; register definitions
t1=1
t2=2
t3=3
t4=4
p=17
;opdefs
opdef CALL [pushj p,] ; to call a subroutine
opdef RET [popj p,] ; to return from a subroutine
;constants
buflen==^d100 ; length of prompt string (words)
grblen==^d5000 ; garbage buffer length
stlen==^d20 ; stack length
Subttl Main
;; main program
; initialize everything
start: RESET ; set things up
GJINF ; get job information
movem t4,ttyno ; store object terminal number
move t2,t1 ; directory number into AC2
hrroi t1,prompt ; pointer to prompt string spcae
DIRST ; get directory string
erjmp error ; blow up detected
hrroi t2,tagon ; pointer to tag on string
setz t3, ; string terminator a null byte
SOUT ; tack on to end of name string
setz t2, ; null byte
idpb t2,t1 ; append it to end of string
jrst cont ; go on
contd: RESET ; general setup
cont: move P,[iowd stlen,stack] ; set up push down stack
setzm inrdty ; in RDTTY flag = false
CALL tmodes ; set up terminal mode words
CALL tnmode ; set terminal no echo
movei t1,.fhslf ; handle on current process
move t2,[levtab,,chntab] ; addresses of tables for interrupt
SIR ; store table addresses in monitor
EIR ; enable interrupt system
CALL inton ; activate interrupt channels
hrroi t1,[asciz\Mail gripes and comments to Haruka@SRI-KL
\] ; print introduction so that
PSOUT ; user knows program is ready
CALL clibuf ; clear input buffer
rstart: WAIT ; pause here indefinitely
jrst rstart ; just in case it unWAITs somehow...
Subttl Terminal Handlers
;; terminal handling routines
; clear input buffer for clean up purposes
clibuf: movei t1,.cttrm ; get handle on terminal
CFIBF ; clear input buffer
RET ; return to caller
; set up terminal mode words
tmodes: movei t1,.cttrm ; handle on terminal
RFMOD ; get terminal mode word
movem t2,omode ; save old mode word
trz t2,tt%eco+tt%dam ; no echo, no translation
movem t2,nmode ; save new mode word
RET ; return to caller
; set terminal to old mode
tomode: movei t1,.cttrm ; handle on terminal
move t2,omode ; get mode word
SFMOD ; set program-related modes
STPAR ; set device-related modes
RET ; return to caller
; set terminal to new mode
tnmode: movei t1,.cttrm ; handle on terminal
move t2,nmode ; get mode word
SFMOD ; set program-related modes
STPAR ; set device-related modes
RET ; return to caller
Subttl Interrupt Channels
;; routines to assign and deassign interrupt channels
; assign terminal codes with interrupt channels
assign: move t1,[.ticti,,0] ; activate on typein
ATI ; assign it to channel 0
move t1,[.ticcb,,1] ; CTRL B
ATI ; assign it to channel 1
move t1,[.ticcl,,2] ; CTRL L
ATI ; assign it to channel 2
move t1,[.ticcn,,3] ; CTRL N
ATI ; assign it to channel 3
move t1,[.ticcx,,4] ; CTRL X
ATI ; assign it to channel 4
move t1,[.ticcz,,5] ; CTRL Z
ATI ; assign it to channel 5
move t1,[.tices,,27] ; escape (^d23 = 27)
ATI ; assign it to channel 23
RET ; return to caller
; deassign terminal codes with interrupt channels
deasgn: movei t1,.ticti ; activate on typein
DTI ; deassign it from channel 0
movei t1,.ticcb ; CTRL B
DTI ; deassign it from channel 1
movei t1,.ticcl ; CTRL L
DTI ; deassign it from channel 2
movei t1,.ticcn ; CTRL N
DTI ; deassign it from channel 3
movei t1,.ticcx ; CTRL X
DTI ; deassign it from channel 4
movei t1,.ticcz ; CTRL Z
DTI ; deassign it from channel 5
movei t1,.tices ; escape
DTI ; deassign it from channel 23
RET ; return to caller
; activate and assign interrupt channels
inton: movei t1,.fhslf ; handle on process
move t2,[1b0+1b1+1b2+1b3+1b4+1b5+1b23] ; channels to activate
AIC ; activate interrupt channels being used
CALL assign ; assign terminal interrupts to channels
RET ; return to caller
; deactivate and deassign interrupt channels
intof: movei t1,.fhslf ; handle on process
move t2,[1b0+1b1+1b2+1b3+1b4+1b5+1b23] ; channels to deactivate
DIC ; deactivate interrupt channels being used
CALL deasgn ; deassign terminal interrupts to channels
RET ; return to caller
;; channel table for interrupts
chntab: 3,,typin ; channel 0
2,,ctrlb ; channel 1
2,,ctrll ; channel 2
2,,ctrln ; channel 3
2,,ctrlx ; channel 4
2,,ctrlz ; channel 5
0,,0 ; .icaov (6) - arithmetic overflow
0,,0 ; .icfov (7) - arithmetic floating overflow
0,,0 ; channel 8 - reserved for DEC
0,,0 ; .icpov (9) - pushdown list (PDL) overflow.
0,,0 ; .iceof (10) - end of file condition
0,,0 ; .icdae (11) - data error file condition
0,,0 ; channel 12 - reserved for DEC
0,,0 ; channel 13 - reserved for DEC
0,,0 ; channel 14 - reserved for DEC
0,,0 ; .icili (15) - illegal instruction
0,,0 ; .icird (16) - illegal memory read
0,,0 ; .iciwr (17) - illegal memory write
0,,0 ; channel 18 - reserved for DEC
0,,0 ; .icift (19) - inferior process termination
0,,0 ; .icmse (20) - system resources exhausted
0,,0 ; channel 21 - reserved for DEC
0,,0 ; .icnxp (22) - nonexistent page reference
2,,escape ; channel 23
0,,0 ; channel 24
0,,0 ; channel 25
0,,0 ; channel 26
0,,0 ; channel 27
0,,0 ; channel 28
0,,0 ; channel 29
0,,0 ; channel 30
0,,0 ; channel 31
0,,0 ; channel 32
0,,0 ; channel 33
0,,0 ; channel 34
0,,0 ; channel 35
; table of storage locations for PC and flag saving on interrupts
levtab: 0,,pclev1 ; level 1 (presently not in use)
0,,pclev2 ; level 2
0,,pclev3 ; level 3
Subttl Interrupt Handlers
;; interrupt handlers
; check if interrupt occurred during RDTTY input and STI and BOUT
; a CRLF if this is so
stilf: setz t1, ; t1 = 0
camn t1,inrdty ; in middle of RDTTY?
jrst nosti ; no, so no need to STI CRLF
movei t1,.cttrm ; get handle on terminal
movei t2,15 ; CR
BOUT ; print it on terminal to start new line
movei t2,12 ; and a LF to complete the CRLF
BOUT ; show it on the screen
STI ; send to terminal to terminate RDTTY input
setzm inrdty ; and the flag should match
nosti: RET ; return to caller
; TYPEIN handler...wakes up on non-CR, non-LF characters and heads line
; with prompt...also types help message if first character is a "?"
typin: PBIN ; read in a character
trz t1,200 ; mask out parity bit
move t3,t1 ; save character in AC3
CALL tomode ; set terminal echo
caie t3,15 ; CR?
cain t3,12 ; LF?
jrst ocrlf ; output CRLF sans prompt
cain t3,"?" ; help?
jrst help ; print help message
setom inrdty ; in RDTTY flag = true
hrroi t1,prompt ; pointer to prompt
PSOUT ; print it
movei t1,.cttrm ; handle on terminal
move t2,t3 ; get ready to return character
BOUT ; display the first character
BKJFN ; back up pointer for RDTTY
erjmp error ; oh, well...
hrroi t1,.nulio ; pointer to garbage collection area
move t2,[rd%bel+grblen*5] ; set up for RDTTY
hrroi t3,prompt ; for ^R buffer
RDTTY ; read in garbage
erjmp error ; whoops!
return: CALL tnmode ; set terminal no echo
CALL clibuf ; clear input buffer
setzm inrdty ; in RDTTY flag = false
DEBRK ; dismiss the interupt
; output a CRLF
ocrlf: hrroi t1,crlf ; pointer to CRLF
PSOUT ; print it
jrst return ; go back
; print a help message
help: hrroi t1,hmsg ; get help message
PSOUT ; print it out
jrst return ; go back
; the help message
hmsg: asciz \
[^B] => Blanks screen. (Note: this may not clear the other person's
screen if the other person has a different type of terminal)
[^L] => Allows user to create a talk link to an another terminal.
Chat will prompt the user for the terminal number.
[^N] => Allows user to change the prompt. A carriage return will
keep the prompt the same.
[^X] => Push down to inferior exec. Show off other programs, etc.,
and pop back to continue as before.
[^Z] => Break links and exit. If you wish to reenter the program,
type CONTINUE to keep the most current prompt and START to
revert to the default prompt.
[ESC] => Prints out "Go ahead."
[?] => If typed at beginning of line when there is yet no prompt,
this list is printed, otherwise it is interpreted as a
normal character.
[See also PS:<HELP>CHAT.HLP.]
\ ; help message
; ^B handler...blanks screen
ctrlb: movei t1,.cttrm ; handle on terminal
movei t2,15 ; CR
STI ; send to terminal
movei t2,12 ; LF
STI ; finish CRLF
setz t2, ; zero out AC
came t2,inrdty ; was it in RDTTY?
setzm inrdty ; yes, clear flag
CALL tnmode ; put terminal in binary mode
movei t1,.cttrm ; handle on terminal
GTTYP ; get terminal type
caig t2,blnkmx ; all we know about now
skipn t1,blnktb(t2) ; get string to dump
jrst bldone ; none - do nothing
tloe t1,-1 ; check for word or pointer
hrroi t1,blnktb(t2) ; word. make it a pointer
PSOUT ; dump it
bldone: DEBRK ; return to main program
; some useful macros
define STDASC <BYTE (7) 33,"H",33,"J",0>
define CTL(CHAR) <"CHAR"-100>
; lookup table for terminal types and their blank codes
blnktb: 0 ; (0) TTY 33
0 ; (1) TTY 35
0 ; (2) TTY 37
0 ; (3) TI / EXECUPORT
BYTE (7) CTL(Z),0 ; (4) ADM-3
BYTE (7) CTL(]),CTL(^),0 ; (5) DATAMEDIA-2500
STDASC ; (6) HP2645
BYTE (7) 176,34,0 ; (7) HAZELTINE-1500
0 ; (8) SYSTEM DEFAULT
0 ; (9) IDEAL (NO FILL)
[BYTE (7)35,177,177,177,177,177,177,37,0] ; (10) VT05
STDASC ; (11) VT50
0 ; (12) LA30
BYTE (7)35,37 ; (13) GT40 - NO FILL REQUIRED
0 ; (14) LA36
STDASC ; (15) VT52
[BYTE (7)33,"[","H",33,"[","J",0] ; (16) VT100
0 ; (17) LA38
0 ; (18) LA120
0 ; (19) TTY43
BYTE (7) 33,"+",0 ; (20) SOROC 120
BYTE (7) CTL(E),CTL(Y),0 ; (21) GILLOTINE
STDASC ; (22) TELERAY 1061
[BYTE (7) 34,"E","R","A",";",0] ; (23) TEK 4025
BYTE (7) CTL(L),0 ; (24) ANN ARBOR
STDASC ; (25) HEATH 19
BYTE (7) CTL(L),0 ; (26) CONCEPT 100
BYTE (7) 33,"K",0 ; (27) IBM 3101
BYTE (7) 33,"*",0 ; (28) TELEVIDEO 912
0 ; (29) TEKTRONIX 4023
BYTE (7) CTL(Y),CTL(K),0 ; (30) DATAMEDIA 1520
[BYTE (7) 33,"[","H",33,"[","J",0] ; (31) AMBASSADOR
BYTE (7) CTL(P),CTL(R),CTL(P),CTL(V),0 ; (32) DTC 382
blnkmx=.-blnktb
; ^L handler...allow user to create new link
ctrll: CALL tomode ; set terminal echo
setz t2, ; zero out AC
came t2,inrdty ; in RDTTY?
jrst nolnk ; yes, don't allow new link
hrroi t1,[asciz\TTY:\] ; ask for TTY number
move t3,t1 ; copy it for ^R buffer
PSOUT ; ask the user
hrroi t1,ttystr ; pointer to TTY string buffer
move t2,[rd%bel+buflen*5] ; set up for RDTTY
RDTTY ; read in TTY number
erjmp error ; c'est la vie
hrroi t1,ttystr ; pointer to the string we just input
movei t3,10 ; TTY numbers are octal
NIN ; translate string into number
erjmp nerror ; looks like an error in the input
caig t2,0 ; if less than or equal to zero
jrst nerror ; then it's an error
camn t2,ttyno ; compare with object terminal number
jrst rcover ; if equal, no need to make link
hrloi t1,(tl%eor+tl%ero) ; get ready to set up talk link
movei t2,400000(t2) ; terminal handle in AC2
TLINK ; set up link
erjmp lerror ; couldn't link
hrroi t1,lbannr ; pointer to link banner
PSOUT ; print it out
rcover: CALL tnmode ; set no echo
nolnk: DEBRK ; return to main program
nerror: hrroi t1,[asciz\?No such terminal number
\] ; the error message
PSOUT ; print it out
jrst rcover ; recover from error
lerror: cain t1,DESX1 ; invalid source/destination designator?
jrst nerror ; yep, use "no such terminal" message
caie t1,TLNKX2 ; link not received within 15 seconds?
jrst other ; nope, it was some other error
hrroi t1,[asciz\[Link refused]
\] ; link refused message
PSOUT ; print it
jrst rcover ; recover from error
other: ESOUT ; print out "?"
movei t1,.priou ; get handler on primary output device
hrloi t2,.fhslf ; get handle on current process
setz t3, ; clear register three
ERSTR ; print out translated error string
erjmp nrcovr ; can't recover from this one
erjmp nrcovr ; or this one
hrroi t1,crlf ; pointer to crlf
PSOUT ; output it
jrst rcover ; attempt to recover from error
nrcovr: HALTF ; stop right here!
jrst .-1 ; disallow continue
; ^N handler...allow user to change prompt
ctrln: CALL tomode ; set terminal echo
setz t2, ; zero out AC
camn t2,inrdty ; in RDTTY?
jrst nobout ; no, don't output CRLF
hrroi t1,crlf ; pointer to CRLF
PSOUT ; print it
nobout: hrroi t1,[asciz\New prompt:\] ; ask for new prompt
move t3,t1 ; copy it for ^R buffer
PSOUT ; query user
hrroi t1,nprmpt ; pointer to new prompt buffer
move t2,[rd%bel+buflen*5] ; set up for RDTTY
RDTTY ; read in new prompt
erjmp error ; oh, well
move t2,[point 7,prompt] ; byte pointer to prompt
move t3,[point 7,nprmpt] ; byte pointer to new prompt
ildb t1,t3 ; do it once
caie t1,15 ; CR?
cain t1,12 ; LF?
jrst goback ; no change
jrst build ; else start building new prompt
trunc: ildb t1,t3 ; get next byte
caie t1,15 ; CR?
cain t1,12 ; LF?
jrst eos ; then we're done
cain t1,0 ; null byte maybe?
jrst eos ; we're done in that case too
build: idpb t1,t2 ; otherwise, add it to the string
jrst trunc ; and go on
eos: movei t1," " ; a space
idpb t1,t2 ; tack it onto string
setz t1, ; null byte
idpb t1,t2 ; string terminator
goback: CALL tnmode ; set terminal no echo
setz t1, ; set AC to zero
camn t1,inrdty ; compare with in RDTTY flag
jrst stino ; was not in RDTTY, don't STI CRLF
movei t1,.cttrm ; handle on terminal
movei t2,15 ; carriage return
STI ; send it to input buffer
movei t2,12 ; line feed
STI ; simulate input to terminal
stino: DEBRK ; dismiss the interrupt
; ^X handler...push down to lower exec
ctrlx: CALL intof ; turn off interrupts
CALL tomode ; set terminal echo
movsi t1,(gj%sht+gj%old) ; short form, old file
hrroi t2,[asciz\SYSTEM:EXEC.EXE\] ; get a version of the EXEC
GTJFN ; get a JFN on the file
erjmp error ; no go
hrrzm t1,jfn ; save JFN with flags cleared
move t1,[cr%cap] ; give inferior process same capabilities
CFORK ; create an inferior process
erjmp error ; couldn't do it
movem t1,handle ; store process handle
hrlz t1,handle ; process handle in left half
hrr t1,jfn ; process handle,,JFN
GET ; map EXEC into lower process
hrroi t1,[asciz\
[Pushing down to inferior EXEC. Type POP to return.]
\] ; warning message
PSOUT ; notify user
move t1,handle ; process handle in AC1
setz t2, ; start at primary entry vector
SFRKV ; fire up lower process
WFORK ; wait for process to halt
KFORK ; kill the lower process
hrroi t1,[asciz\
[You're back in CHAT.]
\] ; notify user of return to top level
PSOUT ; print it
CALL inton ; turn on interrupts
CALL clibuf ; clear input buffer
CALL tnmode ; set terminal no echo
movei t1,.cttrm ; get handle on terminal
movei t2,12 ; LF
STI ; send to terminal to terminate RDTTY
DEBRK ; dismiss the interrupt
; ^Z handler...break links and exit
ctrlz: CALL tomode ; reset terminal mode
hrroi t1,[asciz\(breaking links)
\] ; message about breaking of links
PSOUT ; notify user
move t1,[tl%cro+tl%cor+tl%obj] ; get bits and object designator
seto t2, ; set remote designator to -1
TLINK ; clear all links
erjmp error ; oh, well...maybe next time
movei t1,.fhslf ; handle on self
DIR ; disable the interrupt system
CALL clibuf ; clear input buffer
HALTF ; here we die
jrst contd ; allow continue...restart program
; ESC handler...type go ahead message
escape: CALL tomode ; set terminal echo
CALL stilf ; STI LF if necessary
hrroi t1,prompt ; pointer to prompt
PSOUT ; print it
hrroi t1,[asciz\Go ahead.
\] ; "Go ahead."
PSOUT ; print it
CALL tnmode ; terminal no echo
DEBRK ; dismiss the interrupt
Subttl Error Routine
;; general error routine
error: hrroi t1,[asciz\JSYS error: \] ; pointer to error lead-in
ESOUT ; append lead-in to "?" and print
movei t1,.priou ; get handler on primary output device
hrloi t2,.fhslf ; get handle on current process
setz t3, ; clear register three
ERSTR ; print out translated error string
erjmp .+2 ; in case of any sort of
erjmp .+1 ; error at this point, we must
HALTF ; stop here
jrst .-1 ; continue disallowed
Subttl Storage Area
;; storage locations
tagon: asciz \> \ ; tack this on after name
crlf: byte (7)15,12,0,0,0 ; CRLF string
pclev1: block 1 ; PC & flags for priority 1 interrupts
pclev2: block 1 ; PC & flags for priority 2 interrupts
pclev3: block 1 ; PC & flags for priority 3 interrupts
handle: block 1 ; process handle
jfn: block 1 ; JFN goes here
omode: block 1 ; old terminal mode
nmode: block 1 ; new terminal mode
inrdty: block 1 ; in RDTTY flag
ttyno: block 1 ; TTY number
stack: block stlen ; push down stack
prompt: block buflen ; put prompt string here
nprmpt: block buflen ; put new prompt here
ttystr: block buflen ; put string of TTY number here
lbannr: block buflen ; put link banner here
end start