.TITLE RSXNET - Commununications To Another CPU .IDENT /4.0/ .ENABL LC ;+ ; ; Free software BY ; Project Software & Development, Inc. ; ; This software is furnished for free and may be used and copied as ; desired. This software or any other copies thereof may be provided ; or otherwise made available to any other person. No title to and ; ownership of the software is hereby transferred or allowed. ; ; The information in this software is subject to change without notice ; and should not be construed as a commitment by PROJECT SOFTWARE ; AND DEVELOPMENT, INC. ; ; PROJECT SOFTWARE assumes no responsibility for the use or reliability ; of this software on any equipment whatsoever. ; ; Project Software & Development, Inc. ; 14 Story St. ; Cambridge, Ma. 02138 ; 617-661-1444 ; ; ; Title: RSXNET ; Author: Robin Miller & Gary Larsen ; Date: February 18, 1982 ; ;- .ENABL AMA .MCALL ALUN$S, ASTX$S, CLEF$S, CMKT$S, DIR$, DSAR$S, ENAR$S .MCALL EXIT$S, GMCR$, MRKT$S, QIOW$, QIOW$S, QIO$S, SETF$S .MCALL SREX$S, TTSYM$, WTSE$S, FINIT$ TTSYM$ ; DEFINE TERMINAL SYMBOLS ;+ ; ; Modification History: ; ; December 28, 1985 by Robin Miller. Version 4.0 ; o Decided not to buffer characters received during command ; mode. This causes problems with file transfer modes at ; the present time, and prevented the user from discarding ; unwanted input. ; o Only change TC.DLU=2 when the remote port is set remote. ; Although this doesn't seem to cause any problems on other ; ports, it should only be done to ports set /REMOTE. ; o Fix problem with constantly queuing up remote QIO's, even ; when there is nothing coming in on that port. Also, don't ; queue up remote reads when the error IE.DNR has occured so ; the mainline can properly reset the terminal characteristics. ; ; December 27, 1985 by Robin Miller. Version 4.0 ; o Change write functions to include the write break-through ; subfunction (TF.WBT). I'm not sure this is really needed, ; but I don't think it will hurt anything. ; o Only reset the remote terminal characteristics when the ; remote error is "Device Not Ready" (IE.DNR). ; o Add addition check in local AST routine for the interrupt ; character being typed a second time. This will hopefully ; close a window where the mainline was still in wait state. ; o Change the remote characteristic (TC.DLU) from 1 to 2 to ; allow us to talk to autodial modems without RTS being set. ; This is needed for RSX-11M V4.1 and RSX-11M+ V3.0 drivers. ; o Change remote modem flag name from SMODM to RMODEM. ; o Change references to XON/XOFF, the usage was reversed. ; ; December 23, 1985 by Robin Miller. Version 3.8 ; o Reduce the amount of buffer space being used for processing ; incoming characters from the remote terminal. We now operate ; more like the VMS terminal driver with alternate typehead and ; typeahead alarm. ; o Buffer incoming characters from the remote system when we are ; in command mode. These characters will be displayed upon ; returning to virtual terminal mode. ; o Change default interrupt character from CTRL/Y to CTRL \. ; o Move the user initialization file buffer to module INIFIL.MAC. ; o Modify the cancel marktime directive to only cancel marktimes ; destined for the timer AST routine. This will allow our normal ; delay routine to complete properly. ; o Major changes, so changed version number to 4.0. ; ; December 22, 1985 by Robin Miller. Version 3.7 ; o Reduce the size of the local write from 64 to 32 to create a ; smaller window for problems with XON/XOFF control. ; o Added an ABORT AST to kill I/O and exit gracefully. ; ; December 20, 1985 by Robin Miller. Version 3.6 ; Reset remote terminal characteristics and speed on errors. ; This is needed mainly for modem hangup since the terminal ; driver resets certain characteristics at that time. ; ; November 11, 1985 by Robin Miller. Version 3.5 ; Disable the auto-baud and broadcast characteristics on the ; remote port. ;- .SBTTL Local/Global Equates. ; ; Equates. ; LF == 10. ; LINE FEED CR == 13. ; CARRIAGE RETURN XON = 17. ; CONTROL/Q XOFF = 19. ; CONTROL/S CTRLC = 03. ; CONTROL/C DEFINT = 28. ; Default interrupt is "^\". ; Remote Equates. BUFSIZ = 512. ; Size of transmission buffers. COMCHR == 32. ; Size of each remote buffer. COMCTS = ; Nearness to EOB before XOFF. COMTIM = 10. ; Max time for buffer fill (ticks). COMNBF = 3. ; Number of remote buffers. COMSIZ = +COMCTS ; Size of main remote buffer. ; Local Equates. TTYMAX = 32. ; Maximum bytes per local QIO$. ; Logical Unit Number (LUN) and Event Flag Number (EFN) assignments. INLUN == 1 ; INPUT FILE LUN INEFN == 1 ; INPUT FILE EFN OUTLUN == 2 ; OUTPUT FILE LUN OUTEFN == 2 ; OUTPUT FILE EFN LOGLUN == 3 ; LOG FILE LUN LOGEFN == 3 ; LOG FILE EFN CMDLUN == 4 ; COMMAND FILE LUN CMDEFN == 4 ; COMMAND FILE EFN LOCAL == 5 ; LOCAL TTY LUN AND EFN REMOTE == 6 ; REMOTE TTY LUN AND EFN WAITEF == 10. ; MAINLINE WAIT EVENT FLAG SYNCEF == 11. ; OUTPUT SYNC FLAG MRKEFN == 12. ; Mark time event flag. ; File transmission modes: DUMP == 0 ; DUMP MODE GET == 1 ; GET A FILE SEND == 2 ; SEND A FILE .SBTTL DATA AREA ;+ ; ; Terminal characteristics: ; ; TC.ABD - Auto-baud detection. (/ABAUD) ; TC.ACR - Wrap-around. ; TC.BIN - Binary input. ; TC.DLU - Dialup line. ; TC.FDX - Full duplex. ; TC.HLD - Hold screen. ; TC.NEC - No echo. ; TC.NBR - No Broadcast. (/NOBRO) ; TC.RAT - Typeahead. ; TC.SCP - Scope ; TC.SMR - Upper-case conversion disabled. ; TC.SLV - Slave terminal. ; TC.TTP - Terminal type. ; ;- .NLIST BEX ; Terminal characteristics for the local port. TTYSV:: .BYTE TC.ACR,0,TC.BIN,0,TC.FDX,0,TC.HLD,0,TC.NEC,0,TC.RAT,0 .BYTE TC.SCP,0,TC.SMR,0,TC.SLV,0,TC.TTP TTYPE:: .BYTE T.V100 ; Default terminal type. TTYSVL= .-TTYSV FIXCH:: .BYTE TC.BIN,0,TC.NEC,0 ; Local fix after being aborted. FIXCHL=.-FIXCH TTYCH:: .BYTE TC.ACR,1,TC.BIN,1,TC.FDX,1,TC.HLD,0,TC.NEC,1,TC.RAT,1 .BYTE TC.SCP,1,TC.SMR,1 TTYCHL= .-TTYCH ; Terminal characteristics for the remote port. COMSV:: .BYTE TC.ACR,0,TC.BIN,0,TC.FDX,0,TC.HLD,0,TC.NEC,0,TC.NBR,0 .BYTE TC.RAT,0,TC.SCP,0,TC.SMR,0,TC.SLV,0,TC.WID,0 .BYTE TC.ABD,0,TC.DLU,0 RMODEM == .-1 ; The remote modem flag <> 0 = True. COMSVL= .-COMSV COMCH:: .BYTE TC.ACR,0,TC.BIN,1,TC.FDX,1,TC.HLD,0,TC.NEC,1,TC.NBR,1 .BYTE TC.RAT,1,TC.SCP,1,TC.SMR,1,TC.SLV,1,TC.WID,255. .BYTE TC.ABD,0,TC.DLU,0 SMODEM == .-1 ; The remote modem location to change. COMCHL= .-COMCH BUFADR::.WORD 0 ; ENDING BUFFER ADDRESS BUFLEN::.WORD 0 ; # OF BYTES TO WRITE BUFSRT::.WORD 0 ; START OF BUFFER BUFLUN::.WORD 0 ; LUN TO WRITE TO BUFEND::.WORD 0 ; END OF BUFFER AREA GMCFLG::.WORD 0 ; GET MCR COMMAND FLAG INTRPT::.WORD DEFINT ; The interrupt character. INCMD:: .BLKB 80. ; IN COMING COMMAND TTYBUF::.WORD 0 ; LOCAL INPUT BUFFER COMBUF::.BLKB COMSIZ ; The remote input buffer. COMEND:: RBUFF:: .BLKB BUFSIZ ; Allocate the receive buffer. LBUFF:: .BLKB BUFSIZ ; Allocate the local buffer. XBUFF:: .BLKB BUFSIZ ; Allocate the transmit buffer. ; -=user did CTRL/S, +=buffer ovrflw caused CTRL/S, 0=no CTRL/S COMCTL::.WORD 0 ; The remote flag word. LSTCOM::.WORD SRTCOM ; The remote buffer pointer. SRTCOM::.REPT COMNBF+1 ; Generate remote QIO buffers. .BLKW 2 ; The I/O status block. .BLKB COMCHR ; The remote buffer area. .ENDR ENDCOM:: ; End of remote QIO buffer area. COMFLG::.WORD COMNBF ; Set the number of remote buffers. COMPTR::.WORD COMBUF ; Pointer to remote input buffer. COMCNT::.WORD 0 ; Byte count in remote buffer. COMMKT::.WORD 0 ; # of MRKT$'s outstanding for remote. COMQIO::.WORD COMCHR ; Number of characters for remote QIO. FILTIM::.WORD COMTIM ; Time to wait for buffer to fill. RIOSB:: .BLKW 2 ; I/O STATUS BLOCK FOR REMOTE LIOSB:: .BLKW 2 ; I/O STATUS BLOCK FOR LOCAL TTY XIOSB:: .BLKW 2 ; I/O STATUS BLOCK FOR TRANSMISSION ABOFLG::.WORD 0 ; Abort flag (CTRL/C typed). <> 0 = TRUE BCKFLG::.WORD 0 ; BACKUP TO PREVIOUS QUESTION <> 0 = TRUE DEBFLG::.WORD 0 ; DEBUG OUTPUT FLAG <> 0 = TRUE ECHFLG::.WORD 0 ; PERFORM LOCAL ECHO FLAG <> 0 = TRUE ERRFLG::.WORD 0 ; Error on remote read QIO$. <> 0 = TRUE EXFLG:: .WORD 0 ; EXIT TO SYSTEM FLAG <> 0 = TRUE HLPFLG::.WORD 0 ; HELP WANTED FLAG <> 0 = TRUE INTFLG::.WORD 0 ; INTERRUPT CHARACTER TYPED <> 0 = TRUE LOCFLG::.WORD 0 ; LOCAL OUTPUT TO LOGFILE <> 0 = TRUE LOCCHA::.WORD 0 ; LOCAL CHARACTERISTICS CHANGED <> 0 = TRUE MAXBC:: .WORD 0 ; MAXIMUM BYTE COUNT RECEIVED MAXCOM::.WORD 0 ; Maximum count of remote buffer. REMCHA::.WORD 0 ; REMOTE CHARACTERISTICS CHANGED<> 0 = TRUE CODE:: .WORD 0 ; LAST CODE RECEIVED (I.E., ACK OR NAK) MODE:: .WORD 0 ; TRANSMISSION MODE (DUMP, GET, OR SEND) ; Directive Parameter Blocks (DPB's). ASTLOC::QIOW$ IO.ATA,LOCAL,LOCAL,,LIOSB,, ; LOCAL UNSOL/AST ASTREM::QIOW$ IO.ATA,REMOTE,REMOTE,,RIOSB,, ; REMOTE UNSOL/AST ATTLOC::QIOW$ IO.ATT,LOCAL,LOCAL,,LIOSB ; ATTACH THE LOCAL TERMINAL ATTREM::QIOW$ IO.ATT,REMOTE,REMOTE,,RIOSB ; ATTACH THE REMOTE TERMINAL DETLOC::QIOW$ IO.DET,LOCAL,LOCAL ; DETACH THE LOCAL TERMINAL DETREM::QIOW$ IO.DET,REMOTE,REMOTE, ; DETACH THE REMOTE TERMINAL GETLOC::QIOW$ SF.GMC,LOCAL,LOCAL,,LIOSB,, ; GET LOCAL GETREM::QIOW$ SF.GMC,REMOTE,REMOTE,,RIOSB,, ; GET REMOTE GMCR:: GMCR$ ; GET COMMAND LINE DPB HANGUP::QIOW$ IO.HNG,REMOTE,REMOTE,,RIOSB ; HANGUP THE MODEM KILLOC::QIOW$ IO.KIL,LOCAL ; Kill local terminal I/O. KILREM::QIOW$ IO.KIL,REMOTE ; Kill remote terminal I/O. RESLOC::QIOW$ SF.SMC,LOCAL,LOCAL,,LIOSB,, ; RESET LOCAL TTY RESREM::QIOW$ SF.SMC,REMOTE,REMOTE,,RIOSB,, ; AND THE REMOTE FIXLOC::QIOW$ SF.SMC,LOCAL,LOCAL,,LIOSB,, ; FIX LOCAL TERMINAL SETLOC::QIOW$ SF.SMC,LOCAL,LOCAL,,LIOSB,, ; SET CHARACTERISTICS SETREM::QIOW$ SF.SMC,REMOTE,REMOTE,,RIOSB,, ; AND THE REMOTE ; ; ASCII messages. ; .NLIST BEX CTRLQ: .ASCIZ CTRLS: .ASCIZ CRLF:: .ASCIZ .EVEN .SBTTL RSXNET - Mainline Code. ;+ ; ; RSXNET - Mainline code. ; ;- RSXNET::MOV @#.FSRPT,R0 ; GET POINTER TO FSR TST A.DFUI(R0) ; HAS .FINIT BEEN DONE (DDT) BNE 10$ ; IF NE, YES (DO ONLY ONCE) FINIT$ ; INIT FILE STORAGE REGION 10$: ALUN$S #LOCAL,#"TI,#0 ; ASSIGN LUN TO TI0: CALL CHKDIR ; CHECK FOR ERRORS DIR$ #ATTLOC ; ATTACH THE LOCAL TERMINAL DIR$ #FIXLOC ; TURN OFF RPA AND TURN ON ECHO CALL CHKLIO ; AND CHECK FOR ERRORS MOV #-1,INTFLG ; SHOW WE ARE ASKING QUESTIONS DIR$ #GMCR ; GET MCR COMMAND LINE BCS 20$ ; IF CC, GOT A COMMAND LINE MOV #GMCR+G.MCRB,R0 ; POINT TO INPUT BUFFER CALL SKIP ; POINT PAST TASKNAME TSTB (R0) ; WAS ANYTHING ON THE COMMAND LINE ? BEQ 20$ ; IF EQ, NO MOV #INIFLN,R1 ; ADDRESS OF BUFFER TO PUT MCR INPUT 15$: MOVB (R0)+,(R1)+ ; COPY COMMAND LINE TO INI FILE BUFFER BNE 15$ ; IF NE, NO CLRB -2(R1) ; Clear the line terminator. MOV #-1,GMCFLG ; SHOW WE GOT A COMMAND LINE 20$: CALL STARTUP ; GO ASK ALL THE QUESTIONS SREX$S #ABOAST ; Setup the exit AST routine. MOV #COMBUF,COMPTR ; SETUP THE BUFFER POINTER CLR COMCNT ; INITIALIZE REMOTE BYTE COUNT ; Get the current local terminal characteristics. DIR$ #GETLOC ; GET LOCAL CHARACTERISTICS CALL CHKLIO ; CHECK FOR ERRORS ; Detach the local terminal and re-attach with unsolicited AST input. DSAR$S ; DISABLE AST'S FOR A WHILE DIR$ #DETLOC ; DETACH THE LOCAL TERMINAL ; Set up the new local terminal characteristics. DIR$ #SETLOC ; SETUP LOCAL CHARACTERISTICS CALL CHKLIO ; DID WE GET AN ERROR MOV #-1,LOCCHA ; SHOW LOCAL TERMINAL CHANGED DIR$ #ASTLOC ; ATTACH LOCAL WITH UNSOL/AST CALL CHKLIO ; CHECK FOR ERRORS ENAR$S ; RE-ENABLE AST'S CLR INTFLG ; SHOW NOT IN A COMMAND ; BR LOOP ; BRANCH TO MAINLINE .SBTTL LOOP - LOOP READING FROM TERMINALS ;+ ; ; LOOP - Loop reading from local and remote terminals. ; ; Inputs: ; None ; ;- LOOP:: TST COMCTL ; DID USER TYPE CTRL/S ? BMI 50$ ; IF MI, YES (WAIT AWHILE) TST COMCNT ; ANY REMOTE BYTE COUNT ? BEQ 40$ ; IF EQ, NO DSAR$S ; YES, DISABLE AST'S CMP COMCNT,MAXCOM ; Need to update max count ? BLOS 5$ ; If LOS, no. MOV COMCNT,MAXCOM ; Yes, so set new maximum. 5$: MOV COMPTR,BUFADR ; SAVE THE BUFFER ADDRESS MOV #TTYMAX,BUFLEN ; SET # OF BYTES TO OUTPUT MOV COMCNT,R3 ; COPY THE REMOTE BYTE COUNT SUB #TTYMAX,R3 ; ADJUST THE BYTE COUNT BHIS 10$ ; IF HIS, NOT TOO MUCH. ADD R3,BUFLEN ; TTYMAX WAS TOO MANY. CLR R3 ; INITIALIZE THE COUNT 10$: MOV R3,COMCNT ; NEW REMOTE BYTE COUNT SUB R3,BUFADR ; POINT TO END OF THIS GROUP BCS 20$ ; CS- RE-WRAP CMP BUFADR,#COMBUF ; POINTED BEFORE BEGINNING? BHIS 30$ ; HIS- NO 20$: ADD #COMSIZ,BUFADR ; POINT TO THAT MUCH BEFORE END 30$: ENAR$S ; ENABLE AST'S MOV #COMBUF,BUFSRT ; SET BUFFER START MOV #COMEND,BUFEND ; SET BUFFER END MOV #LOCAL,BUFLUN ; SET BUFFER LUN CALL BUFOUT ; OUTPUT TO UNIT 40$: TST COMCTL ; DID WE SEND CTRL/S ? BLE 45$ ; IF LE, NO CMP COMCNT,# ; STILL NEAR BUFFER OVERFLOW ? BHIS 45$ ; IF HIS, YES BIC #77777,COMCTL ; CLEAR CTRL/S FLAG QIO$S #IO.WAL,#REMOTE,,,,,<#CTRLQ,#1,#0> ; SEND XON 45$: TST INTFLG ; Was interrupt key typed ? BNE 55$ ; If NE, yes. TST COMCNT ; Anything else to output ? BNE LOOP ; If NE, yes (write more). 50$: WTSE$S #WAITEF ; WAIT FOR SOMETHING TO DO CLEF$S #WAITEF ; CLEAR OUR EVENT FLAG TST INTFLG ; INTERRUPT KEY TYPED ? BEQ 60$ ; IF EQ, NO 55$: CALL GETCMD ; ELSE GET USER COMMAND MOV #COMNBF,COMFLG ; Set all remote buffers free. MOV #SRTCOM,LSTCOM ; SET TO USE 1ST BUFFER CLR COMCNT ; Clear the buffer count. MOV #COMBUF,COMPTR ; Reset the buffer pointer. CLR INTFLG ; Reset the interrupt flag. ; ; If the remote error was "Device Not Ready" (IE.DNR) then reset ; the remote terminal characteristics and speed since the terminal ; driver changes certain characteristics when a modem is hungup. ; 60$: TST ERRFLG ; Was there a remote error ? BEQ 70$ ; If EQ, no. CMPB #IE.DNR,RIOSB ; Was error "Device Not Ready" ? BNE 65$ ; If NE, no. CALL WABIT ; Wait for device to be ready. CALL RRESET ; Reset remote characteristics. 65$: CLR ERRFLG ; Reset the remote error flag. 70$: JMP LOOP ; Go check for local output. .SBTTL TTYAST - Local Character AST Routine. ;+ ; ; TTYAST - Local terminal character AST routine. ; ; Inputs: ; (SP) = The local input character. ; ;- TTYAST::MOVB (SP)+,TTYBUF ; COPY THE INPUT BYTE BICB #200,TTYBUF ; CLEAR THE PARITY BIT TST EXFLG ; EXIT FLAG SET ? BNE 10$ ; IF NE, YES (IGNORE BYTE) TST INTFLG ; PROCESSING A COMMAND ? BEQ 20$ ; IF EQ, NO (CONTINUE) CMPB INTRPT,TTYBUF ; Interrupt character again ? BNE 5$ ; If NE, no. QIO$S #IO.KIL,#REMOTE ; Yes, so kill remote I/O. BR 25$ ; And wakeup the mainline. 5$: CMPB #CTRLC,TTYBUF ; CONTROL/C TYPED ? BNE 10$ ; IF NE, NO (IGNORE BYTE) MOV #-1,ABOFLG ; SET THE ABORT FLAG CALL CANCEL ; CANCEL OUTSTANDING I/O 10$: BR 90$ ; And use common exit. ; Check for the local interrupt character. 20$: CMPB INTRPT,TTYBUF ; INTERRUPT BYTE TYPED ? BNE 30$ ; IF NE, NO MOV #-1,INTFLG ; SHOW INTERRUPT TYPED 25$: SETF$S #MRKEFN ; Set the delay event flag. SETF$S #WAITEF ; Wakeup the mainline. BR 90$ ; And use common exit. ; Check for special control characters. 30$: CMPB #XOFF,TTYBUF ; CONTROL/S TYPED ? BNE 40$ ; IF NE, NO BIS #100000,COMCTL ; YES, SHOW XOFF TYPED BR 70$ ; SEND IT TO REMOTE 40$: CMPB #XON,TTYBUF ; CONTROL/Q TYPED ? BNE 70$ ; IF NE, NO BIC #100000,COMCTL ; YES, CLEAR XOFF FLAG SETF$S #WAITEF ; Wakeup mainline to output. TST COMCTL ; Did we send an XOFF ? BNE 90$ ; If NE, yes (no XON yet). ; Write the character to the remote system. 70$: TSTB ECHFLG ; DO LOCAL ECHOING ? BEQ 80$ ; IF EQ, NO QIO$S #IO.WAL,#LOCAL,,,,,<#TTYBUF,#1,#0> 80$: QIO$S #IO.WAL,#REMOTE,,,,,<#TTYBUF,#1,#0> 90$: ASTX$S ; EXIT FROM AST .SBTTL COMAST - REMOTE CHARACTER AST ROUTINE ;+ ; ; COMAST - Remote character AST routine. ; ; This routine is entered whenever a read is not outstanding at the ; remote terminal. The character from the remote is added to the ; remote buffer, and a read is issued. ; ; Inputs: ; (SP) = the input character. ; ; Outputs: ; All registers are preserved. ; ;- COMAST::MOVB (SP)+,@COMPTR ; Copy the incoming character. TST EXFLG ; Does user want to exit ? BNE 100$ ; If NE, yes (discard). TST INTFLG ; Processing a commmand ? BNE 100$ ; If NE, yes (discard). INC COMPTR ; Adjust the output pointer. INC COMCNT ; Adjust the output count. CMP COMPTR,#COMEND ; Are we at end of buffer ? BNE 30$ ; If NE, no. MOV #COMBUF,COMPTR ; Yes, wrap to beginning. 30$: CMP COMCNT,# ; Getting near buffer overflow ? BLO 40$ ; If LO, no. QIO$S #IO.WAL,#REMOTE,,,,,<#CTRLS,#1,#0> ; Send XOFF. INC COMCTL ; Show we sent the XOFF. 40$: MOV R4,-(SP) ; Save R4 MOV R5,-(SP) ; and R5. BR QIOARM ; Queue up the remote reads. 100$: ASTX$S ; Exit the AST. .ENABL LSB QIOARM::TST ERRFLG ; Was there a remote error ? BNE 30$ ; If NE, yes (no QIO's). TST COMFLG ; Are all the buffers in use ? BEQ 30$ ; If EQ, yes. QIOCOM:: MOV LSTCOM,R4 ; Set address of next buffer. MOV R4,R5 ; Copy starting buffer address. ADD #4,R5 ; Point past I/O status block. QIO$S #IO.RAL,#REMOTE,,,R4,#REMAST, CALL CHKDIR ; Check for directive errors. MRKT$S ,FILTIM,#TICKS,#TIMCOM ; Set the timer for buffer fill. DEC COMFLG ; Adjust the free buffer count. INC COMMKT ; Count number of timers queued. MOV R4,LSTCOM ; Copy the current buffer address. ADD #COMCHR+4,LSTCOM ; Point to the next free buffer. CMP LSTCOM,#ENDCOM ; Are we at end of buffer area ? BNE 20$ ; If NE, no. MOV #SRTCOM,LSTCOM ; Yes, point to starting area. 20$: BR QIOARM ; Try to arm another read. 30$: MOV (SP)+,R5 ; Restore R4 MOV (SP)+,R4 ; and R5. SETF$S #WAITEF ; Wakeup the mainline. ASTX$S ; And exit the AST. .DSABL LSB .SBTTL TIMCOM - REMOTE MARKTIME AST ROUTINE ;+ ; ; TIMCOM - Remote Marktime AST routine. ; ; This routine is entered when the marktime issued after a read to the ; remote expires. After all marktimes have expired, the remote I/O is ; killed and REMAST is entered with the bytes received from the remote. ; ;- TIMCOM::TST EXFLG ; EXIT FLAG SET ? BNE 10$ ; IF NE, YES (KILL I/O) TST INTFLG ; PROCESSING A COMMMAND ? BEQ 20$ ; IF EQ, NO (CONTINUE) ; ; If exiting or processing a command, cancel marktimes, and kill remote ; I/O so RSXNET commands will not get screwed. ; 10$: CMKT$S ,#TIMCOM ; Cancel any remote marktimes. CLR COMMKT ; INITIALIZE MARKTIME COUNT BR 30$ ; AND CONTINUE ... 20$: DEC COMMKT ; ADJUST MARKTIME COUNT BNE 40$ ; IF NE, MORE TO GO 30$: QIO$S #IO.KIL,#REMOTE ; KILL TRANSFER,,,USE WHAT YOU GOT! 40$: TST (SP)+ ; CLEAN THE STACK ASTX$S ; AND RETURN .SBTTL REMAST - Remote Read AST Routine. REMAST:: INC COMFLG ; Adjust free buffer count. TST EXFLG ; EXIT FLAG SET ? BNE 10$ ; IF NE, YES (IGNORE) TST INTFLG ; PROCESSING A COMMMAND ? BEQ 20$ ; IF EQ, NO (CONTINUE) 10$: TST (SP)+ ; REMOVE RIOSB ADDRESS ASTX$S ; AND RETURN 20$: MOV R4,-(SP) ; SAVE R5 MOV R5,-(SP) ; AND R4 MOV R1,-(SP) ; SAVE R1 MOV R3,-(SP) ; SAVE R3 MOV COMPTR,R1 ; COPY THE BUFFER POINTER MOV COMCNT,R3 ; AND THE BYTE COUNT MOV 10(SP),R4 ; COPY ADDRESS OF RIOSB MOV R4,R5 ; CALC ADDR OF BUFFER ADD #4,R5 ; POINT TO DATA BUFFER TSTB (R4) ; Was there any errors ? BPL 50$ ; If PL, no. CMPB #IE.ABO,(R4) ; Was the read killed ? BNE 40$ ; If NE, no. ; ; When the reads get killed, only the current outstanding read ; has an AST delivered. All other reads which are queued, get ; killed, but the specified AST is not delevered. Therefore, ; we must set all buffers as free when abort is detected. ; MOV #COMNBF,COMFLG ; Yes, set all buffers free. ; ; Sometimes when our read is killed, there is a very large byte ; count in the I/O status block. Just another RSX-11M mystery. ; CMP #COMCHR,2(R4) ; Is byte count too large ? BLO 80$ ; If LO, yes (don't use). BR 50$ ; Don't report this error. 40$: MOV (R4),RIOSB ; Copy the I/O error code. CALL CRIOSB ; Write the error message. MOV #-1,ERRFLG ; Show there was an error. 50$: MOV 2(R4),R4 ; COPY THE BYTE COUNT BEQ 85$ ; If EQ, nothing was read. CMP R4,MAXBC ; IS THIS THE MAX SO FAR ? BLT 60$ ; IF LT, NO MOV R4,MAXBC ; YES, SAVE FOR STATUS 60$: MOVB (R5)+,(R1)+ ; COPY BYTES TO MAIN BUFFER INC R3 ; ADJUST THE BYTE COUNT CMP R1,#COMEND ; AT END OF BUFFER ? BNE 70$ ; IF NE, NO (LOOP) MOV #COMBUF,R1 ; YES, RESET TO BEGINNING 70$: SOB R4,60$ ; LOOP UNTIL DONE CMP R3,# ; Getting near buffer overflow ? BLO 80$ ; If LO, no. QIO$S #IO.WAL,#REMOTE,,,,,<#CTRLS,#1,#0> ; Yes, send XOFF. INC COMCTL ; Show we sent the XOFF. 80$: MOV 10(SP),R4 ; Copy the status block address. MOV R1,COMPTR ; SAVE THE BUFFER POINTER MOV R3,COMCNT ; AND THE BYTE COUNT TST ERRFLG ; Was there a remote error ? BEQ 90$ ; If EQ, no (continue ...) CMPB #IE.DNR,(R4) ; Was error "Device Not Ready" ? BNE 90$ ; If NE, no (queue next read). 85$: MOV (SP)+,R3 ; Restore MOV (SP)+,R1 ; all MOV (SP)+,R5 ; saved MOV (SP)+,R4 ; registers. TST (SP)+ ; Remove status block address. SETF$S #WAITEF ; Wakeup mainline for output. ASTX$S ; And exit the AST. 90$: MOV (SP)+,R3 ; Restore R3 MOV (SP)+,R1 ; and R1. MOV R4,R5 ; Copy the status block address. ADD #4,R5 ; Point to the data buffer. MOV 2(SP),4(SP) ; Move R4 down on the stack. MOV (SP)+,(SP) ; Move R5 down and clean stack. JMP QIOCOM ; Now go queue another read. .SBTTL BUFOUT - OUTPUT BUFFER ;+ ; ; BUFOUT - Output the buffer received from the remote system. ; ;- BUFOUT::CALL $SAVAL ; SAVE ALL REGISTERS TST EXFLG ; EXIT FLAG SET ? BNE 20$ ; IF NE, YES (RETURN) TST INTFLG ; INTERRUPT FLAG SET ? BNE 20$ ; IF NE, YES (RETURN) MOV BUFADR,R4 ; GET ENDING ADDR SUB BUFLEN,R4 ; CALC START ADDR CMP R4,BUFSRT ; BUFFER WRAP AROUND ? BLT 10$ ; IT LT, YES ; Write the buffer to the log file. MOV R4,R2 ; START OF BUFFER MOV BUFLEN,R3 ; COPY THE BYTE COUNT CALL WRTLOG ; WRITE IT TO THE LOGFILE QIOW$S #IO.WAL,BUFLUN,#SYNCEF,,#XIOSB,, CALL CHKXIO ; CHECK FOR ERRORS RETURN ; AND RETURN 10$: MOV BUFADR,R4 ; GET END ADDRESS SUB BUFSRT,R4 ; HOW FAR FROM BEGINNING? MOV R4,-(SP) ; SAVE R4 MOV BUFLEN,R4 ; TOTAL LENGTH SUB (SP),R4 ; MINUS CHARS AT BEGINNING MOV BUFEND,R5 ; END ADDR SUB R4,R5 ; FIND BEGINNING OF STRING ; Write the buffer to the log file. MOV R5,R2 ; SET THE BUFFER ADDRESS MOV R4,R3 ; COPY THE BYTE COUNT CALL WRTLOG ; WRITE IT TO THE LOGFILE QIOW$S #IO.WAL,BUFLUN,#SYNCEF,,#XIOSB,, CALL CHKXIO ; CHECK FOR ERRORS MOV (SP)+,R4 ; RESTORE R4 BEQ 20$ ; EQ- NO NEED FOR SECOND QIO CMPB XIOSB,#IE.ABO ; WAS THE FIRST QIO ABORTED ? BEQ 20$ ; IF EQ, YES (NO 2ND QIO) TST EXFLG ; EXIT FLAG SET? BNE 20$ ; NE- YES...GIVE-UP TST INTFLG ; INTERRUPT FLAG SET ? BNE 20$ ; IF NE, YES (RETURN) ; Write the buffer to the log file. MOV BUFSRT,R2 ; STARTING ADDRESS OF BUFFER MOV R4,R3 ; COPY THE BYTE COUNT CALL WRTLOG ; WRITE IT TO THE LOGFILE QIOW$S #IO.WAL,BUFLUN,#SYNCEF,,#XIOSB,, CALL CHKXIO ; CHECK FOR ERRORS 20$: RETURN .SBTTL CANCEL - Cancel local and remote I/O. ;+ ; ; CANCEL - Cancel the local and remote I/O. ; ; Be careful if calling this routine from AST level since outstanding ; I/O will cause us to hang since other I/O can't complete. ; ;- CANCEL::DIR$ #KILLOC ; KILL I/O ON LOCAL TTY DIR$ #KILREM ; KILL I/O ON REMOTE TTY RETURN .SBTTL WABIT - Wait for device to become ready. ;+ ; ; WABIT - Wait for device to become ready. ; ; This routine is called to wait for a little after a device has gone to ; not ready. This is done so resetting of the terminal characteristics ; will go into effect properly. ; ; Inputs: ; None. ; ; Outputs: ; All registers are preserved. ; ;- WABIT:: JSR R2,$SAVVR ; Save R0 - R2. MOV #1.,R0 ; Set to wait MOV #SECNDS,R1 ; for 1 second. JMP DELAY ; Now do the delay. .SBTTL ABOAST - Process an ABORT AST. ;+ ; ; ABOAST - Process an ABORT AST. ; ; This routine is called as the result of RSXNET being ABOrted. The ; first time we are entered, we attempt to exit via the normal exit ; routine. The second time we are entered, we kill any outstanding ; I/O and then exit so we don't become unabortable. ; ; Inputs: ; (SP) = Number of bytes to remove from the stack. ; 2(SP) = The reason for being aborted. ; ;- ABOAST: ADD (SP),SP ; Remove abort information. TST EXFLG ; Second request to ABORT ? BNE 100$ ; If NE, yes. JMP EXIT ; No, use normal exit code. 100$: CALL CANCEL ; Cancel outstanding I/O. EXIT$S ; And exit to the system. .END RSXNET ; Transfer address.