.TITLE RSXNET - COMMUNUNICATIONS TO ANOTHER CPU .IDENT /3.4/ .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 ; ; Modification History: ; ;- .ENABL AMA .MCALL ALUN$S, ASTX$S, CLEF$S, CMKT$S, DIR$, DSAR$S, ENAR$S .MCALL GMCR$, MRKT$S, QIOW$, QIOW$S, QIO$S, SETF$S, TTSYM$ .MCALL WTSE$S, FINIT$ TTSYM$ ; DEFINE TERMINAL SYMBOLS ; ; Equates. ; LF == 10. ; LINE FEED CR == 13. ; CARRIAGE RETURN XOFF = 17. ; CONTROL/Q XON = 19. ; CONTROL/S CTRLC = 03. ; CONTROL/C CTRLO = 15. ; CONTROL/O CTRLY = 25. ; CONTROL/Y ; Remote Equates. COMCHR = 500. ; XX CHARS LONG (MUST BE EVEN) COMTIM = 10. ; MAX TIME FOR BUFFER FILL (TICKS) COMNBF = 5. ; NUMBER OF BUFFERS COMMAX = 3. ; MAX # CHARS PER QIO OUTPUT TO REMOTE COMSIZ = 5120. ; SIZE OF REMOTE BUFFER COMCTS = 1024. ; NEARNESS TO EOB BEFORE CTRL-S ; Local Equates. TTYMAX = 64. ; 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 ; File transmission modes: DUMP == 0 ; DUMP MODE GET == 1 ; GET A FILE SEND == 2 ; SEND A FILE .SBTTL DATA AREA ;+ ; ; Terminal characteristics: ; ; 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.RAT - Typeahead. ; TC.SCP - Scope ; TC.SMR - Upper-case conversion disabled. ; TC.SLV - Slave terminal. ; TC.TTP - Terminal type. ; ;- .NLIST BEX TTYSV:: .BYTE TC.ACR,7,TC.BIN,7,TC.FDX,7,TC.HLD,7,TC.NEC,7,TC.RAT,7 .BYTE TC.SCP,7,TC.SMR,7,TC.SLV,7,TC.TTP TTYPE:: .BYTE T.V100 ; Default terminal type. TTYSVL= .-TTYSV COMSV:: .BYTE TC.ACR,7,TC.BIN,7,TC.FDX,7,TC.HLD,7,TC.NEC,7,TC.RAT,7 .BYTE TC.SCP,7,TC.SMR,7,TC.SLV,7 SMODM:: .BYTE TC.DLU,7 COMSVL= .-COMSV FIXCH:: .BYTE TC.BIN,0,TC.NEC,0 FIXCHL=.-FIXCH .WORD 0 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 .WORD 0 COMCH:: .BYTE TC.ACR,0,TC.BIN,1,TC.FDX,1,TC.HLD,0,TC.NEC,1,TC.RAT,1 .BYTE TC.SCP,1,TC.SMR,1,TC.SLV,1 COMCHL= .-COMCH .WORD 0 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 CTRLY ; INTERRUPT CHARACTER INCMD:: .BLKB 80. ; IN COMING COMMAND INIFLN::.BLKB 30. ; INITILIZATION FILE NAME (IF ANY FROM GMCR) TTYBUF::.WORD 0 ; LOCAL INPUT BUFFER RBUFF:: COMBUF::.BLKW COMSIZ ; REMOTE INPUT BUFFER COMEND:: ; -=USER DID CTRL-S ;+=BUFFER OVRFLW CAUSED CTRL-S ;0=NO CTRL-S COMCTL::.WORD 0 ; REMOTE FLAG WORD LSTCOM::.WORD SRTCOM ; BUFFER POINTER LBUFF:: ; LOCAL INPUT BUFFER XBUFF == LBUFF+512. ; TRANSMIT BUFFER SRTCOM::.BLKB > ; CREATE "COMNBF" BUFFERS, EACH "COMCHR" BYTES. ENDCOM:: ; END OF BUFFER FLGCOM::.WORD -COMNBF ; NEGATIVE OF NUMBER OF BUFFRS FREE FL1COM::.WORD 0 ; NUMBER OF BUFFERS QUEUED 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 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 ; ABORTION FLAG <> 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 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 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,LOCAL ; KILL LOCAL TERMINAL I/O KILREM::QIOW$ IO.KIL,REMOTE,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 -1(R1) ; CLEAR THE TERMINATOR MOV #-1,GMCFLG ; SHOW WE GOT A COMMAND LINE 20$: CALL STARTUP ; GO ASK ALL THE QUESTIONS 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 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 #,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 50$ ; IF LE, NO CMP COMCNT,# ; STILL NEAR BUFFER OVERFLOW ? BHIS 50$ ; IF HIS, YES BIC #77777,COMCTL ; CLEAR CTRL/S FLAG QIO$S #IO.WAL,#REMOTE,,,,,<#CTRLQ,#1,#0> ; SEND XOFF 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 CALL GETCMD ; ELSE GET USER COMMAND CLR FL1COM ; CLEAR # OF BUFFERS QUEUED MOV #-COMNBF,FLGCOM ; SET ALL 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 60$: BR LOOP ; AND CONTINUE ... .SBTTL TTYAST - TERMINAL CHARACTER AST ROUTINE ;+ ; ; TTYAST - Local terminal character AST routine. ; ;- 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 #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$: JMP 90$ ; AND EXIT THE AST ; Check for the local interrupt character. 20$: CMPB INTRPT,TTYBUF ; INTERRUPT BYTE TYPED ? BNE 30$ ; IF NE, NO MOV #-1,INTFLG ; SHOW INTERRUPT TYPED SETF$S #WAITEF ; LET MAINLINE KNOW BR 90$ ; AND RETURN ; Check for special control characters. 30$: CMPB #XON,TTYBUF ; CONTROL/S TYPED ? BNE 40$ ; IF NE, NO BIS #100000,COMCTL ; YES, SHOW XON TYPED BR 70$ ; SEND IT TO REMOTE 40$: CMPB #XOFF,TTYBUF ; CONTROL/Q TYPED ? BNE 50$ ; IF NE, NO BIC #100000,COMCTL ; YES, CLEAR XON FLAG SETF$S #WAITEF ; LET MAINLINE KNOW BR 70$ ; SEND IT TO REMOTE 50$: CMPB #CTRLC,TTYBUF ; CONTROL/C TYPED ? BEQ 60$ ; IF EQ, YES CMPB #CTRLO,TTYBUF ; CONTROL/O TYPED ? BNE 70$ ; IF NE, NO 60$: CLR COMCNT ; YES, CLEAR REMOTE COUNT MOV #COMBUF,COMPTR ; RESET THE BUFFER POINTER QIO$S #IO.KIL,#LOCAL ; KILL LOCAL WRITE ; Write the character to the remote system. 70$: TSTB ECHFLG ; DO LOCAL ECHOING ? BEQ 80$ ; IF EQ, NO QIO$S #IO.WAL!TF.CCO,#LOCAL,,,,,<#TTYBUF,#1,#0> 80$: QIO$S #IO.WAL!TF.CCO,#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 ; APPEND BYTE TO BUFFER TST EXFLG ; EXIT FLAG SET ? BNE 10$ ; IF NE, YES (IGNORE BYTE) TST INTFLG ; PROCESSING A COMMMAND ? BEQ 20$ ; IF EQ, NO (CONTINUE) 10$: ASTX$S ; ELSE IGNORE THE BYTE 20$: INC COMPTR ; POINT TO THE NEXT BYTE INC COMCNT ; COUNT THIS BYTE CMP COMPTR,#COMEND ; AT END OF BUFFER ? BNE 30$ ; IF NE, NO MOV #COMBUF,COMPTR ; YES, SET TO BEGINNING 30$: CMP COMCNT,# ; NEAR BUFFER OVERFLOW ? BLO 40$ ; IF LT, NO QIO$S #IO.WAL,#REMOTE,,,,,<#CTRLS,#1,#0> ; SEND CTRL-S INC COMCTL ; SHOW WE SENT XON 40$: .ENABL LSB MOV R4,-(SP) ; SAVE R4 & R5 MOV R5,-(SP) ; 10$: TST FLGCOM ; BUFFER IN USE ? BEQ 30$ ; IF EQ, YES INC FLGCOM ; SET BUFFER IN USE MOV LSTCOM,R4 ; ADDR OF I/O STAT BLOCK MOV R4,R5 ; FIND ADDR OF BUFFER ADD #4,R5 ; FOUND! QIOCOM:: QIO$S #IO.RAL,#REMOTE,,,R4,#ASTCOM, MRKT$S ,#COMTIM,#1,#TIMCOM ; WAIT HOW LONG BEFORE IO.KIL? INC FL1COM ; INCREM NUMBER OF BUFFRS QUEUED INC COMMKT ; INCREM NUMBER OF MRKT$'S MOV R4,LSTCOM ; UPDATE LSTCOM ADD #COMCHR+4,LSTCOM ; POINT TO NEXT FREE BUFFER CMP LSTCOM,#ENDCOM ; END-OF-BUFFER AREA? BNE 20$ ; NE- NO. MOV #SRTCOM,LSTCOM ; YES...INIT TO BEGINNING 20$: BR 10$ ; TRY AGAIN 30$: ; REF LABEL MOV (SP)+,R5 ; RESTORE R4 & R5 MOV (SP)+,R4 ; SETF$S #WAITEF ; LET MAINLINE KNOW ASTX$S ; EXIT 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 ASTCOM 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 ; remote I/O so RSXNET commands will not get screwed. 10$: CMKT$S ; CANCEL ANYMORE 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! CLR FL1COM ; CLEAR NUMBER OF BUFFERS QUEUED 40$: TST (SP)+ ; CLEAN THE STACK ASTX$S ; AND RETURN ASTCOM:: 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$: DEC FL1COM ; DECRM NUMBER OF BUFFERS QUEUED BGT 30$ ; GT- OK. CLR FL1COM ; ELSE SET TO ZERO 30$: 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) ; ANY ERRORS ? BPL 50$ ; IF PL, NO CMPB #IE.ABO,(R4) ; WAS I/O KILLED ? BEQ 40$ ; IF EQ, YES (EXPECTED) MOV (R4),RIOSB ; COPY THE ERROR CODE CALL CHKRIO ; WRITE THE ERROR MESSAGE 40$: CMP #COMCHR,2(R4) ; IS BYTE COUNT TOO LARGE ? BLT 80$ ; IF LT, YES (SKIP IT) 50$: MOV 2(R4),R4 ; COPY THE BYTE COUNT BEQ 80$ ; IF EQ, THERE WAS NONE 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,# ; NEAR BUFFER OVERFLOW ? BLO 80$ ; IF LT, NO QIO$S #IO.WAL,#REMOTE,,,,,<#CTRLS,#1,#0> ; YES, SEND XON INC COMCTL ; SHOW WE SENT XON 80$: MOV 10(SP),R4 ; POINT TO RIOSB AGAIN MOV FL1COM,R5 ; NUMBER OF BUFFERS QUEUED SUB FLGCOM,R5 ; PLUS NUMBER FREE MOV R1,COMPTR ; SAVE THE BUFFER POINTER MOV R3,COMCNT ; AND THE BYTE COUNT MOV (SP)+,R3 ; RESTORE R3 MOV (SP)+,R1 ; AND R1 CMP #COMNBF,R5 ; ALREADY ENOUGH BUFFERS QUEUED ? BGT 90$ ; GT- ANOTHER CAN'T HURT MOV (SP)+,R5 ; AND R5 MOV (SP)+,R4 ; AND R4 SETF$S #WAITEF ; LET MAINLINE KNOW THAT CHARS ARRIVED ASTX$S ; EXIT AST 90$: MOV R4,R5 ; POINT R5 TO BUFFER AREA ADD #4,R5 ; MOV 2(SP),4(SP) ; MOVE R4 AND R5 MOV (SP)+,(SP) ; CLEAN THE STACK JMP QIOCOM ; AND ISSUE QIO AGAIN .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!TF.CCO,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!TF.CCO,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!TF.CCO,BUFLUN,#SYNCEF,,#XIOSB,, CALL CHKXIO ; CHECK FOR ERRORS 20$: RETURN ;+ ; ; Cancel local and remote I/O. ; ;- CANCEL:: DIR$ #KILLOC ; KILL I/O ON LOCAL TTY DIR$ #KILREM ; KILL I/O ON REMOTE TTY RETURN .END RSXNET ; TRANSFER ADDRESS