Google
 

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