.TITLE RSTACT -- RSX TO RSTS REMOTE TERMINAL ACTION ROUTINES .IDENT /X01.04/ ;* ;* LAST EDIT: WOLERY 11 JULY 80 ; ; COPYRIGHT (C) 1979, 1980 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION X01.00 ; M.L. SPENCE ; MODIFIED FROM RVT PROGRAM, BY R. E. CALDWELL 15-DEC-79/11-JAN-80 ; ; ; REMOTE VIRTUAL TERMINAL ; ; THIS PROGRAM RUNS ON A LOCAL NODE (M/M-PLUS ONLY) TO ALLOW A TERMINAL ; TO APPEAR TO BE LOCALLY ATTACHED TO A REMOTE RSTS/E NODE. ; THE USER INTERFACE AND THE PROTOCOL OF THE DECNET/E "NET" TASK ARE USED. ; ; ALL I/O IS INITIATED WITHIN AST'S; ALL I/O HAS COMPLETION AST'S DECLARED. ; ; ; MACRO LIBRARY CALLS .MCALL DIR$ .MCALL QIOW$S .MCALL WSIG$S,QIO$S .MCALL REC$S,SND$S .MCALL GNDW$S .MCALL NETDF$,CRBDF$,TTSYM$ NETDF$ ; DEFINE NET SYMBOLICS CRBDF$ ; DEFINE CON BLOCK SYMBOLICS TTSYM$ ; DEFINE TT SYMBOLICS .PSECT $$CODE,RO,I ;* ;* IF THE FOLLOWING PARAMETER IS DEFINED, CALLS TO A NETWORK ;* MESSAGE-TRACING PACKAGE WILL BE INSERTED IN THE INITIALIZATION, ;* LINK RECEIVE, AND LINK TRANSMIT SECTIONS. ;* MTRACE=1 ;TRACE MESSAGES SENT AND RECEIVED .SBTTL LNKRCV - HANG A RECEIVE ON NETWORK ;+ ; ; ; SUBROUTINE TO DO LINK RECEIVE ; ; ALLOCATES A BUFFER TO RECEIVE NETWORK DATA ; ;- LNKRCV:: MOV R0,-(SP) ; SAVE R0 MOV R1,-(SP) ; AND R1 MOV #$MXMSG,R1 ; MAXIMUM LENGTH MESSAGE RSTS SENDS US CALL GETBUF ; ALLOCATE A BUFFER BCS 90$ ; EXIT IF ERROR 15$: REC$S #LINK,#1,R1,#LRAST, BCC 90$ ; IF CC, OK WSIG$S ; WAIT FOR SIGNIFICANT EVENT BR 15$ ; RETRY ON ERROR 90$: MOV (SP)+,R1 ; RESTORE R1 MOV (SP)+,R0 ; AND R0 RETURN ; RETURN TO CALLER .SBTTL LNKWRT - NETWORK TRANSMIT ;+ ; ; ; SUBROUTINE TO ISSUE LINK WRITE (XMIT) ; ; THIS ROUTINE IS CALLED WHEN THERE IS TERMINAL INPUT OR ; A CONTROL MESSAGE TO SEND TO THE REMOTE HOST. ; ;* THIS ROUTINE WAS MODIFIED TO INSERT CALLS TO THE ;* MESSAGE-TRACE DEBUG ROUTINES. THESE CALLS ARE ASSEMBLED ;* ONLY IF THE 'MTRACE' PARAMETER IS DEFINED -- SEE THE ;* ".MCALL" SECTION OF THIS PROGRAM. ; ; INPUT: R0 = ADDRESS OF BUFFER WITH DATA ; R1 = ADDRESS OF IOSB ; R2 = BYTE COUNT FOR TRANSFER ;- LNKWRT:: .IF DF MTRACE ;MESSAGE-TRACE DEBUGGING PACKAGE CALL TRCXMT ; TRACE MESSAGE SENT .ENDC 10$: SND$S #LINK,#1,R1,#LWAST, ; TRANSMIT MESSAGE BCC 20$ ; SKIP IF IT WORKED WSIG$S ; WAIT FOR EVENT BR 10$ ; RETRY ON ERROR 20$: RETURN ; RETURN TO CALLER .SBTTL TRMRD - INPUT FROM TERMINAL ;+ ; ; ; SUBROUTINE TO DO TERMINAL READ AND READ AFTER PROMPT. ; CALLED BY UNSAST ROUTINE FOR HOST READS, ; AND BY RDAST AND RPRAST ROUTINES FOR LOCAL CONTROL READS ; (AFTER PROMPT). ; ; INPUT ; R0 = ADDRESS OF BUFFER ;- TRMRD:: MOV R0,R1 ; COPY BUFFER ADDRESS TSTB LOCFLG ;* IN LOCAL CONTROL DIALOGUE WITH USER? BNE 50$ ;* YES -- DO READ-AFTER-PROMPT CMPB #1,TTREAD ;* IS A READ CURRENTLY OUTSTANDING? BLT 90$ ;* YES -- DON'T HAVE MORE THAN ONE HUNG MOV #IO.RLB,R3 ;* SET FUNCTION = READ LOGICAL BLOCK MOV #TERCHR,R4 ;* POINT TO NORMAL TERMINATOR TABLE TSTB MODE ;* IN ODT (SINGLE-CHARACTER) MODE? BEQ 20$ ;* IF EQ, NO -- READ WITH NORMAL TERMINATORS MOV #IO.RTT!TC.BIN,R3 ; SET FUNCTION = READ WITH TERMINATORS MOV #ODTCHR,R4 ;* TABLE MAKES ALL CHARACTERS TERMINATORS 20$: CMPB #RE.OFF,ECHO ;* SET BY CONTROL-MESSAGE HANDLING BNE 25$ ;* IF EQ, REMOTE SYSTEM SHOULD ECHO BIS #TF.RNE,R3 ; OR IN SUBFUNCTION FOR NO ECHO 25$: MOV R1,R0 ; COPY ADDRESS SUB #4,R0 ; POINT TO IOSB ADD #RM.HLEN,R1 ; R1 = READ BUFFER ADDRESS INC R1 ; ADD ONE FOR DATA LENGTH BYTE MOVB TRPWID,R2 ;* SET BYTE COUNT TO WIDTH OF TERMINAL LINE 30$: QIO$S R3,#TERM,,,R0,#RDAST, ; ATTEMPT FUNC BCC 40$ ; IF CLEAR, OK WSIG$S ; WAIT FOR EVENT BR 30$ ; RETRY ON ERROR 40$: INCB TTREAD ; SET FLAG -- READ HAS BEEN HUNG BR 90$ ; GO RETURN ; ; ISSUE READ-AFTER-PROMPT TO RECEIVE LOCAL CONTROL COMMANDS FROM USER ; 50$: MOV #" ,LOCINP ; BLANK OUT BEGINNING OF BUFFER 60$: QIO$S #IO.RPR,#TERM,,,#LOCSB,#RPRAST,<#LOCINP,#80.,,#RSTN,#RSTNLN,#'$> BCC 90$ ; EXIT IF OK WSIG$S ; WAIT FOR EVENT BR 60$ ; RETRY ON ERROR 90$: RETURN ; RETURN TO CALLER .SBTTL TRMWRT - OUTPUT TO TERMINAL ;+ ; ; ; SUBROUTINE TO ISSUE TERMINAL WRITE ; ; THIS ROUTINE IS CALLED BY THE LINK-RECEIVE AST DISPATCHER ; FOR DATA MESSAGES FROM THE REMOTE HOST. ; ; INPUT: ; R0 = BUFFER ADDRESS (IOSB+4) ; = DATA JUST RECEIVED FROM REMOTE HOST ;- TRMWRT:: MOV R5,-(SP) ; SAVE R5 MOV R0,R1 ; COPY BUFFER ADDRESS SUB #4,R0 ; POINT TO IOSB MOVB R.DLN(R1),R2 ;* GET LENGTH OF DATA TO BE WRITTEN BIC #177400,R2 ;* CLEAR HIGH-ORDER BYTE ADD #R.DAT,R1 ;* POINTER TO WRITE DATA AREA MOV #IO.WLB,R5 ; DEFAULT TO WRITE LOGICAL BLOCK TSTB MODE ;* IS THIS ODT (SINGLE-CHARACTER) MODE? BEQ 10$ ; IF EQ, NO BIS #TF.WAL,R5 ; OR IN SUBFUNCTION -- WRITE PASS ALL BR 30$ ; WRITE IT 10$: 30$: QIO$S R5,#TERM,,,R0,#WTAST, ; ISSUE TERMINAL I/O BCC 90$ ; EXIT IF OK WSIG$S ; WAIT FOR EVENT BR 30$ ; RETRY ON ERROR 90$: MOV (SP)+,R5 ; RESTORE R5 RETURN ; RETURN TO CALLER .SBTTL TRMODE - CONTROL MESSAGE FROM HOST ;+ ; ; ; THIS ROUTINE IS CALLED BY THE LINK-RECEIVE AST DISPATCHER ; FOR CONTROL MESSAGES FROM THE REMOTE HOST. ; SET UP THE PROCESSING CONTROLS ACCORDING TO THE FIELDS ; IN THE CONTROL MESSAGE FROM THE HOST. ; ; INPUT: ; R0 = BUFFER ADDRESS (IOSB+4) ; = MESSAGE JUST RECEIVED FROM REMOTE HOST ;- TRMODE:: MOV R0,R1 ; COPY POINTER TO MESSAGE BUFFER ADD #R.CMN,R1 ; POINT TO MENU FIELD MOVB R.MNL(R0),R2 ; GET LENGTH OF MENU FIELD ADD R2,R1 ; POINT TO FIRST CONTROL FIELD BITB #RC.ECH,R.CMN(R0) ; IS ECHO FIELD PRESENT? BEQ 20$ ; IF EQ, NO MOVB (R1)+,ECHO ; SET ECHO CONTROL AS HOST WANTS TSTB HTRFLG ; IF THIS IS NOT AN RSX NETWORK TERMINAL, BEQ 20$ ; THEN PROCEED WITH MESSAGE CMPB #RE.OFF,ECHO ; DID HOST JUST TELL US TO ECHO? BEQ 20$ ; NO -- OK IF HOST IS WILLING TO ECHO. MOV R0,-(SP) ; SAVE MENU FIELD MOV R1,-(SP) ; SAVE POINTER TO CONTROL PARAMETERS MOV #ODTLEN,R2 ; GET LENGTH OF ODT MESSAGE MOV #ODTMSG,R3 ; POINT TO START OF "ENTER ODT MODE" MESSAGE CALL MSGSND ; TELL HOST WE INSIST WE WON'T ECHO ; BCS ? ; DON'T KNOW WHAT TO DO IF THIS FAILS INCB MODE ; SET ODT MODE FLAG MOV (SP)+,R1 ; RESTORE R1 MOV (SP)+,R0 ; AND R0 20$: BITB #RC.DLM,R.CMN(R0) ; IS DELIMITER FIELD PRESENT? BEQ 40$ ; IF EQ, NO MOV #32.,R2 ; COUNT OF BYTES IN DELIMITER FIELD MOV #TERCHR,R3 ; POINT TO TABLE OF TERMINATING CHARACTERS 30$: MOVB (R1)+,(R3)+ ; COPY TABLE FOR USE WITH READ TO TERMINAL SOB R2,30$ ; LOOP 40$: BITB #RC.WID,R.CMN(R0) ; IS TERMINAL WIDTH FIELD PRESENT? BEQ 50$ ; IF EQ, NO TSTB (R1)+ ; IF PRESENT, IGNORE -- HOST CAN'T SET THIS TSTB (R1)+ ; ONLY TERMINAL SIDE CAN SET 50$: BITB #RC.TYP,R.CMN(R0) ; IS TERMINAL TYPE FIELD PRESENT? BEQ 60$ ; IF EQ, NO TSTB (R1)+ ; IF PRESENT, IGNORE -- HOST CAN'T SET THIS TSTB (R1)+ ; ONLY TERMINAL SIDE CAN SET 60$: BITB #RC.FIL,R.CMN(R0) ; IS TERMINAL FILL COUNT PRESENT? BEQ 90$ ; IF EQ, NO TSTB (R1)+ ; IF PRESENT, IGNORE -- HOST CAN'T SET THIS TSTB (R1)+ ; ONLY TERMINAL SIDE CAN SET 90$: SUB #4,R0 ; POINT TO IOSB BEFORE DATA AREA IN BUFFER MOV #$MXMSG,R1 ; MAXIMUM LENGTH MESSAGE RSTS SENDS US CALL RELBUF ; RELEASE BUFFER WITH CONTROL MESSAGE RETURN .SBTTL TRBOMB - UNSUPPORTED MESSAGE FROM HOST ;+ ; ; ; EXIT TASK IF HOST WON'T SUPPORT WHAT WE WANT, OR VICE VERSA. ; ;- TRBOMB:: MOV #$MXMSG,R1 ;MAXIMUM SIZE OF LINK MESSAGE CALL RELBUF ;RELEASE BUFFER WITH HOST MESSAGE DIR$ #ABONET ;ABORT LOGICAL LINK DIR$ #QIOKIL ;ABORT TERMINAL I/O CALL ERR17 ;PROTOCOL NOT SUPPORTED BY HOST DIR$ #SETEXI ;WAKE UP MAIN TASK AND EXIT SEC ; SET BAD STATUS RETURN .SBTTL TREDIT - PROVIDE LOCAL EDITING ;+ ; ; ; THIS ROUTINE PROVIDES THE LOCAL EDITING FUNCTIONS ; WHICH ARE NOT PERFORMED BY THE TERMINAL DRIVER. ; THIS ROUTINE IS NEVER ENTERED IN ODT MODE; THE ; HOST DOES EDITING IN THAT CASE. ; ; INPUT: R0 = POINTER TO DATA BUFFER ; R1 = POINTER TO IOSB ; SECOND ON STACK = CHARACTER WHICH TERMINATED READ. ; ; OUTPUT: R0, R1 = PRESERVED ; CARRY = CLEAR IF DATA BUFFER TO BE SENT TO HOST, ; SET IF NOT ; TERMINAL WRITE ISSUED TO ECHO APPROPRIATELY. ;- TREDIT:: CMPB #CRET,2(SP) ;WAS LAST CHARACTER READ A ? BNE 30$ ; IF NE, NO CMPB #1,R.DLN(R0) ;WAS THE ONLY CHARACTER TYPED? BEQ 30$ ; IF SO, DON'T DO EXTRA ECHO. DIR$ #QIOCRL ; ECHO WITH A PAIR BR 90$ ; DONE 30$: CMPB #IE.EOF,(R1) ;END OF FILE STATUS ON READ? BNE 40$ ; IF NE, NO MOVB #CTLZ,R.DAT(R0) ; STORE EOF INDICATOR FOR HOST ; BR 90$ ; DONE 40$: 90$: CLC ; WRITE BUFFER TO HOST 99$: RETURN ; RETURN TO CALLING PROGRAM .SBTTL CMDERR - ERROR IN LOCAL COMMAND FROM USER ;+ ; ; ; THIS ROUTINE INFORMS THE USER THAT THE COMMAND WAS UNRECOGNIZED. ; ;- CMDERR:: 10$: DIR$ #QIOEMS ; ISSUE ERROR MESSAGE BCC 90$ ; EXIT IF OK WSIG$S ; WAIT FOR EVENT BR 10$ ; TRY AGAIN 90$: CLC ; RE-ISSUE PROMPT RETURN .SBTTL CMDHLP - OUTPUT LOCAL HELP TEXT TO USER ;+ ; ; ; THIS ROUTINE PRINTS THE HELP MESSAGE TEXT. ; ;- CMDHLP:: 10$: DIR$ #QIOHLP ; ISSUE HELP MESSAGE BCC 90$ ; EXIT IF OK WSIG$S ; WAIT FOR EVENT BR 10$ ; TRY AGAIN 90$: CLC ; RE-ISSUE PROMPT RETURN .SBTTL CMDCNT - RETURN TO NORMAL TERMINAL-HOST MODE ;+ ; ; ; THIS ROUTINE STOPS LOCAL COMMAND-PROCESSING MODE. ; ;- CMDCNT:: DIR$ #QIOCRL ; SEND CLRB LOCFLG ; CLEAR LOCAL-PROCESSING FLAG SEC ; SET CARRY TO RETURN TO NORMAL RETURN .SBTTL CMDEXI - EXIT FROM PROGRAM, DISCONNECT HOST ;+ ; ; ; THIS ROUTINE SETS UP TO STOP THIS PROGRAM. ; ;- CMDEXI:: DIR$ #DISCON ; SEND DISCONNECT MESSAGE TO REMOTE HOST DIR$ #QIOKIL ; CANCEL ALL OUTSTANDING TERMINAL I/O DIR$ #SETEXI ; SET EVENT FLAG TO BREAK LINK CLRB LOCFLG ; CLEAR LOCAL-PROCESSING FLAG MOV #EX$SUC,XSTAT ; SET PROGRAM EXIT STATUS SEC ; SET CARRY TO RETURN TO NORMAL (NON-AST) RETURN .SBTTL CMDODT - ENTER ODT MODE ;+ ; ; ; THIS ROUTINE PUTS THE TERMINAL-HOST LINK INTO ODT MODE, ; AND RETURNS FROM LOCAL COMMAND MODE TO NORMAL OPERATION. ; ;- CMDODT:: 10$: DIR$ #QIOCRL ; SEND BCC 15$ ; SKIP IF OK WSIG$S ; WAIT FOR EVENT BR 10$ ; RETRY ON ERROR 15$: MOV #ODTLEN,R2 ; GET LENGTH OF ODT MESSAGE MOV #ODTMSG,R3 ; POINT TO START OF "ENTER ODT MODE" MESSAGE CALL MSGSND ; SEND MESSAGE TO HOST BCC 20$ ; CONTINUE IF SEND BUFFER WAS AVAILABLE CLC ; RE-ISSUE PROMPT SO USER WILL RETRY COMMAND BR 90$ ; GO RETURN 20$: INCB MODE ; SET ODT MODE FLAG CLRB LOCFLG ; CLEAR LOCAL-PROCESSING FLAG SEC ; SET CARRY TO RETURN TO NORMAL OPERATION 90$: RETURN ; RETURN TO CALLING PROGRAM .SBTTL CMDNOR - LEAVE ODT MODE, RE-ENTER NORMAL MODE ;+ ; ; ; THIS ROUTINE PUTS THE TERMINAL-HOST LINK INTO NORMAL MODE, ; AND RETURNS FROM LOCAL COMMAND MODE TO NORMAL OPERATION. ; ;- CMDNOR:: 10$: DIR$ #QIOCRL ; SEND BCC 15$ ; SKIP IF OK WSIG$S ; WAIT FOR EVENT BR 10$ ; RETRY ON ERROR 15$: MOV #NORLEN,R2 ; GET LENGTH OF NORMAL-MODE MESSAGE MOV #NORMSG,R3 ; POINT TO "EXIT ODT MODE" MESSAGE CALL MSGSND ; SEND MESSAGE TO HOST BCC 20$ ; CONTINUE IF SEND BUFFER WAS AVAILABLE CLC ; RE-ISSUE PROMPT SO USER WILL RETRY COMMAND BR 90$ ; GO RETURN 20$: CLRB MODE ; CLEAR ODT MODE FLAG CLRB LOCFLG ; CLEAR LOCAL-PROCESSING FLAG SEC ; SET CARRY TO RETURN TO NORMAL OPERATION 90$: RETURN ; RETURN TO CALLING PROGRAM .SBTTL CMDCTP - SEND CONTROL/P TO HOST ;+ ; ; ; THIS ROUTINE SENDS A CONTROL/P CHARACTER TO THE HOST ; IN A NORMAL DATA MESSAGE, AND RETURNS FROM LOCAL ; COMMAND MODE TO NORMAL OPERATION. ; ;- CMDCTP:: 10$: DIR$ #QIOCRL ; SEND BCC 15$ ; SKIP IF OK WSIG$S ; WAIT FOR EVENT BR 10$ ; RETRY ON ERROR 15$: MOV #CTPLEN,R2 ; LENGTH OF CONTROL-P MESSAGE MOV #CTPMSG,R3 ; POINT TO CONTROL-P MESSAGE CALL MSGSND ; SEND MESSAGE TO HOST BCC 20$ ; CONTINUE IF SEND BUFFER WAS AVAILABLE CLC ; RE-ISSUE PROMPT SO USER WILL RETRY COMMAND BR 90$ ; GO RETURN 20$: CLRB LOCFLG ; CLEAR LOCAL-PROCESSING FLAG SEC ; SET CARRY TO RETURN TO NORMAL OPERATION 90$: RETURN ; RETURN TO CALLING PROGRAM .PAGE .END