.TITLE FULL_DUPLEX TERMINAL PROGRAMMING EXAMPLE .IDENT /05/ ; ******************************************************************** ; ; TERMINAL PROGRAM ; ; ******************************************************************** .SBTTL DECLARATIONS .DISABLE GLOBAL ; ; Declare the external symbols and MACRO libraries. ; .EXTERNAL LIB$GET_EF .LIBRARY 'SYS$LIBRARY:LIB.MLB' .LIBRARY 'SYS$LIBRARY:STARLET.MLB' ; ; Define symbols ; $IODEF ; Define I/O function codes $QIODEF ; Define QIO definition codes $SSDEF ; Define the system service status codes $TRMDEF ; Define itemlist read codes $TTDEF ; Terminal characteristic definitions ; ; Define macros ; .SHOW .MACRO ITEM LEN=0,CODE,VALUE .WORD LEN .WORD TRM$_'CODE' .LONG VALUE .LONG 0 .ENDM ITEM .NOSHOW ; ; Declare exit handler control block ; EXIT_HANDLER_BLOCK: .LONG 0 ; System uses this for pointer .LONG EXIT_HANDLER ; Address of exit handler .LONG 1 ; Argument count for handler .LONG STATUS ; Destination of status code STATUS: .BLKL 1 ; Status code from $EXIT ; ; Allocate terminal descriptor and channel number storage ; TT_DESC: .ASCID /SYS$INPUT/ ; Logical name of terminal TT_CHAN: .BLKW 1 ; TT channel number storage ; ; Define acknowledgment message. This is done right above input buffer ; so that we can concatenate the two together when the acknowledgment ; message is issued. ; ACK_MSG: .ASCII /Following input acknowledged: / ACK_MSGLEN=.-ACK_MSG ; Calculate length of message ; ; Allocate input buffer ; IN_BUFLEN = 20 ; Set length of buffer IN_BUF: .BLKB IN_BUFLEN ; Allocate character buffer IN_IOSB: .BLKQ 1 ; Input I/O status block ; ; Define out-of-band ast character mask ; CNTRLA_MASK: .LONG 0 .LONG ^B0010 ; Control A mask ; ; Define old terminal characteristics buffer ; OLDCHAR_BUF_LEN = 12 OLDCHAR_BUF: .BLKB OLDCHAR_BUF_LEN ; ; Define new terminal characteristics buffer ; NEWCHAR_BUF_LEN = 12 NEWCHAR_BUF: .BLKB NEWCHAR_BUF_LEN ; ; Define carriage control symbols ; CR=^X0D ; Carriage return LF=^X0A ; Line feed ; ; Define output messages ; ; Output messages are accessed by indexing into a table of ; longwords with each message described by a message address and ; message length ; ARRAY: ; Table of message addresses and ; lengths .LONG 10$ ; First message address .LONG 15$ ; First message length .LONG 20$ .LONG 25$ .LONG 30$ .LONG 35$ .LONG 40$ .LONG 45$ ; ; Define messages ; 10$: .ASCII /RED ALERT!!! RED ALERT!!!/ 15$=.-10$ ; 20$: .ASCII /ALL SYSTEMS GO/ 25$=.-20$ ; 30$: .ASCII /WARNING.....INTRUDER ALARM/ 35$=.-30$ ; 40$: .ASCII /***** SYSTEM OVERLOAD *****/ 45$=.-40$ ; ; Static QIO packet for message output using QIO$_G form ; WRITE_QIO: $QIO EFN=SYNC_EFN, - ; QIO packet FUNC=IO$_WRITEVBLK!IO$M_BREAKTHRU!IO$M_REFRESH, - IOSB=SYNC_IOSB ; ; Declare the required I/O status blocks. ; SYNC_IOSB:: .BLKQ 1 ; I/O status block for synchronous terminal processing. ; ; Declare the required event flags. ; ASYNC_EFN:: .BLKL 1 ; Event flag for asynchronous terminal processing. SYNC_EFN == WRITE_QIO + 4 ; Event flag for sync terminal processing. TIMER_EFN:: .BLKL 1 ; Event flag for timer processing. ; ; Timer storage ; WAITIME: .LONG -10*1000*1000*3,-1 ; 3 second delta time TIME: .BLKQ 1 ; Current storage time used for ; random number .PAGE .SBTTL START - MAIN ROUTINE .ENABLE LOCAL_BLOCK ;++ ; ; Functional description: ; ; ******************************************************************** ; ; Start program ; ; ******************************************************************** ; ; The following code performs initialization functions. ; It is assumed that the terminal is already in ; FULL-DUPLEX mode. ; ; NOTE: When doing QIO_S calls, parameters P1 and P3-P6 should be ; passed by value, while P2 should be passed by reference. ; ; Input parameters: ; None ; ; Output parameters: ; None ; ;-- .ENTRY START ^M < > ; Get the required event flags. PUSHAL ASYNC_EFN CALLS # 1, G^ LIB$GET_EF ; Get EFN for async terminal operations. BLBC R0, 10$ ; Error - branch. PUSHAL SYNC_EFN CALLS # 1, G^ LIB$GET_EF ; Get EFN for sync terminal operations. BLBC R0, 10$ ; Error - branch. PUSHAL TIMER_EFN CALLS # 1, G^ LIB$GET_EF ; Get EFN for timer operations. BLBC R0, 10$ ; Error - branch. ; Initialize the terminal characteristics. $ASSIGN_S DEVNAM=TT_DESC,-; Assign terminal channel using CHAN=TT_CHAN ; logical name and channel number BLBC R0, 10$ ; Error - branch. BSBW CHANGE_CHARACTERISTICS ; Change the characteristics of ; terminal BSBW ENABLE_CTRLCAST ; Allow Ctrl/C traps BSBW ENABLE_OUTBANDAST ; Enable Ctrl/A out-of-band AST BSBW ENABLE_READ ; Queue read MOVZWL TT_CHAN, WRITE_QIO+8 ; Insert channel into BRB LOOP ; static QIO packet 10$: BRW ERROR ; ; This loop outputs a message based on a random number and then ; delays for 3 seconds ; LOOP: $GETTIM_S TIMADR=TIME ; Get random time BLBC R0, 10$ ; Error - branch. EXTZV #6, #2, TIME, R0 ; Load random bits into switch MOVQ ARRAY[R0], - ; Load message address WRITE_QIO+QIO$_P1 ; and size into QIO ; packet ; ; Issue QIO write using packet defined in data area ; $QIOW_G WRITE_QIO BLBC R0, 10$ ; QIO error - branch. MOVZWL SYNC_IOSB, R0 ; Get the terminal driver status. BLBC R0, 10$ ; Terminal driver error - branch. ; ; Delay for 3 seconds before issuing next message ; $SETIMR_S EFN=TIMER_EFN,- ; Timer service DAYTIM=WAITIME ; will set event flag ; in 3 seconds BLBC R0, 10$ ; Error - branch. $WAITFR_S EFN=TIMER_EFN ; Wait for event flag BLBS R0, LOOP ; No error if set BRB 10$ ; Error - branch. .DISABLE LOCAL_BLOCK .PAGE .SBTTL CHANGE_CHARACTERISTICS - CHANGE CHARACTERISTICS OF TERMINAL ;++ ; ; Functional description: ; ; Routine to change the characteristics of the terminal. ; ; Input parameters: ; None ; ; Output parameters: ; R0 - status from $QIO call. ; R1 - R5 destroyed ; ;-- ; CHANGE_CHARACTERISTICS: $QIOW_S EFN=SYNC_EFN, - ; Get current terminal characteristics CHAN=TT_CHAN, - FUNC=#IO$_SENSEMODE, - IOSB=SYNC_IOSB, - P1=OLDCHAR_BUF, - P2=#OLDCHAR_BUF_LEN BLBC R0, 10$ ; Error if clear MOVZWL SYNC_IOSB, R0 ; Get the terminal driver status. BLBC R0, 10$ ; Error - branch $DCLEXH_S EXIT_HANDLER_BLOCK ; Declare exit handler to reset ; characteristics BLBC R0, 10$ ; Error - branch. MOVC3 #OLDCHAR_BUF_LEN, - ; Move old characteristics into OLDCHAR_BUF, - ; new characteristics buffer NEWCHAR_BUF BISL2 #TT$M_NOBRDCST, - ; Set nobroadcast bit NEWCHAR_BUF+4 ; ... $QIOW_S EFN=SYNC_EFN, - ; Set current terminal characteristics CHAN=TT_CHAN, - FUNC=#IO$_SETMODE, - IOSB=SYNC_IOSB, - P1=NEWCHAR_BUF, - P2=#NEWCHAR_BUF_LEN BLBC R0, 10$ ; QIO error - branch. MOVZWL SYNC_IOSB, R0 ; Get the terminal driver status. BLBC R0, 10$ ; Terminal driver error - branch. RSB 10$: BRW ERROR .PAGE .SBTTL ENABLE_CTRLCAST - ENABLE Ctrl/C AST ;++ ; ; Functional description: ; ; Routine to allow Ctrl/C recognition. ; ; Input parameters: ; None ; ; Output parameters: ; None ; ;-- ; ENABLE_CTRLCAST: $QIOW_S EFN=SYNC_EFN, - CHAN=TT_CHAN, - FUNC=#IO$_SETMODE!IO$M_CTRLCAST, - IOSB=SYNC_IOSB, - P1=CTRLCAST, - ; AST routine address P3=#3 ; User mode BLBC R0, 10$ ; Error - branch. MOVZWL SYNC_IOSB, R0 ; Get the terminal driver status. BLBC R0, 10$ ; Terminal driver error - branch. RSB 10$: BRW ERROR .PAGE .SBTTL ENABLE_OUTBANDAST - ENABLE Ctrl/A AST ;++ ; ; Functional description: ; ; Routine to allow CNTRL/A recognition. ; ; Input parameters: ; None ; ; Output parameters: ; None ; ENABLE_OUTBANDAST: $QIOW_S EFN=SYNC_EFN, - CHAN=TT_CHAN, - FUNC=#IO$_SETMODE!IO$M_OUTBAND, - IOSB=SYNC_IOSB, - P1=CTRLAAST, - ; AST routine address P2=#CNTRLA_MASK, - ; Character mask P3=#3 ; User mode BLBC R0, 10$ ; QIO error - branch. MOVZWL SYNC_IOSB, R0 ; Get the terminal driver status. BLBC R0, 10$ ; Terminal driver error - branch. RSB 10$: BRW ERROR .PAGE .SBTTL ENABLE_READ - QUEUE A READ TO THE TERMINAL. ;++ ; ; Functional description: ; ; Routine to queue a read operation to the terminal. ; ; Input parameters: ; None ; ; Output parameters: ; None ; ; Define item list for itemlist read ; ITEM_LST: ITEM 0, MODIFIERS, - ; Convert lowercase to TRM$M_TM_CVTLOW!TRM$M_TM_NOEDIT ; upper and inhibit line ITEM 6, TERM,MASK_ADDR ; editing ; Set up terminator mask ITEM_LEN = . - ITEM_LST MASK_ADDR: .LONG 1@^XD ; Terminator mask is .WORD 1@4 ; and "$" ENABLE_READ: $QIO_S EFN=ASYNC_EFN, - ; Must not be QIOW form or read will block CHAN=TT_CHAN, - ; process FUNC=#IO$_READVBLK!IO$M_EXTEND, - IOSB=IN_IOSB, - ASTADR=READAST, - ; AST routine to execute P1=IN_BUF, - ; on P2=#IN_BUFLEN, - P5=#ITEM_LST, - ; Itemlist read address P6=#ITEM_LEN ; Itemlist read size BLBC R0, 10$ ; QIO error - branch. ; The queued read operation will not affect write operations due ; to the fact that breakthru has been set for the write operations. RSB 10$: BRW ERROR .PAGE .SBTTL READAST - AST ROUTINE FOR READ COMPLETION .ENABLE LOCAL_BLOCK ;++ ; ; Functional description: ; ; AST routine to execute on read completion. ; ; Input parameters: ; None ; ; Output parameters: ; None ; ;-- ; 10$: MOVZWL IN_IOSB, R0 ; Get the terminal driver status 20$: BRW ERROR ; Exit with error status. .ENTRY READAST ^M < R2, R3, R4, R5 > ; Procedure entry mask BLBC IN_IOSB, 10$ ; Terminal driver error - branch MOVZWL IN_IOSB+2, R0 ; Get number of characters read into R0 ADDL2 #ACK_MSGLEN, R0 ; Add size of fixed acknowledge message $QIO_S EFN=ASYNC_EFN, - ; Issue acknowledge message CHAN=TT_CHAN, - ; Note, ACK must be asynchronous (QIO) FUNC=#IO$_WRITEVBLK, - ; and the terminal driver write status P1=ACK_MSG, - ; is ignored (no IOSB and AST routine). P2=R0 ; Specify IOSB and AST routine if output ; must be displayed on the terminal. BLBC R0, 20$ ; QIO error - branch ; ; Process read message ; ; . ; . ; . ;(user-provided code to decode command inserted here) ; . ; . ; . BSBW ENABLE_READ ; Queue next read RET ; Return to mainline loop .DISABLE LOCAL_BLOCK .PAGE .SBTTL CTRLAAST - AST ROUTINE FOR Ctrl/A .SBTTL CTRLCAST - AST ROUTINE FOR Ctrl/C .SBTTL ERROR - EXIT ROUTINE ;++ ; ; Functional description: ; ; AST routine to execute when Ctrl/C or Ctrl/A is entered. ; ; Input parameters: ; None ; ; Output parameters: ; None ; CTRLCAST:: CTRLAAST:: .WORD ^M < > ; Procedure entry mask MOVL #SS$_NORMAL, R0 ; Put success in R0 ERROR:: $EXIT_S R0 ; Exit RSB .PAGE .SBTTL EXIT_HANDLER - EXIT HANDLER ROUTINE ;++ ; ; Functional description: ; ; Exit handler routine to execute when image exits. It cancels ; any outstanding I/O on this channel and resets the terminal ; characteristics to their original state. ; ; Input parameters: ; None ; ; Output parameters: ; None ; ;-- ; .ENTRY EXIT_HANDLER ^M< > $CANCEL_S CHAN=TT_CHAN ; Flush any I/O on queue $QIOW_S EFN=SYNC_EFN, - ; Reset terminal characteristics CHAN=TT_CHAN, - FUNC=#IO$_SETMODE, - IOSB=SYNC_IOSB, - P1=OLDCHAR_BUF, - P2=#OLDCHAR_BUF_LEN BLBC R0, 10$ ; QIO error - branch. MOVZWL SYNC_IOSB, R0 ; Get the terminal driver status. 10$: RET .END START