.TITLE DUPLEX DO COMMUNICATIONS BETWEEN TERMINALS (MACHINES?) .IDENT /1.05A/ .MCALL QIO$S,QIOW$S,CLEF$S,WTSE$S,ASTX$S,EXIT$S,SETF$S .MCALL FCSMC$,CSI$,CSI$1,CSI$2,DIR$,QIO$,QIOW$ FCSMC$ .PAGE ;--------------------------------------------------------------------------- ; ; AUTHOR: MARTIN HELLER DATE:24-OCT-79 ; DUPLEX: ; The idea here is to provide the wiring (in software) ; so that a single terminal (unit 1, by convention) can ; be hard wired to the PDP-11 and yet function as a terminal ; to any computer that can be called on the telephone or ; wired to another terminal port. ; For dial-up use, a full-duplex modem needs to be ; connected to another port on the PDP-11. This is useful ; anyway, so that you can dial into the PDP-11; this program ; lets you reverse the process and dial out. When you ; task-build, ASG=TI:1, and explicitly assign the proper ; port to unit 2. ; There is no reason that the second port couldn't be ; hardwired as well. Therefore, if you have two computers within ; a few hundred yards of each other, you can connect them together ; through EIA ports and have just one terminal at your desk ; to talk to both of them. ; CONTROL-B CAUSES EXIT FROM THE PROGRAM ; ;** 26-OCT-79: VERSION 1.01 -- CTRL-T IS TRANSMIT A FILE ; ; TO USE: TYPE CONTROL AND T SIMULTANEOUSLY. THIS WILL NOT BE TRANSMITTED. ; THE PROGRAM WILL PROMPT FOR AN INPUT FILE SPECIFICATION, I.E. ; DUPLEX>=SY0:[25,34]FILENAME.TYP;4 ; THE USUAL RULES FOR DEFAULTS APPLY; NO WILDCARDS OR LISTS ARE ALLOWED. ; NOTICE THAT THE EQUALS SIGN IS NOT OPTIONAL--PARSING IS FOR AN INPUT FILE. ; ; ** 31-OCT-79: VERSION 1.02 ; CTRL-P TOGGLES BETWEEN FILE TRANSMISSION AND LINE TRANSMISSION ; CTRL-N CAUSES TRANSMISSION OF NEXT LINE OF FILE IN LINE MODE ; ; VERSION 1.03 ; CTRL-A ABORTS A FILE TRANSMISSION ; CTRL-F OPENS/CLOSES FILE OF RECEIVED DATA ; ; ** 26-NOV-79: VERSION 1.04 ; MESSAGES FOR CTRL-F ; USE DIR$ FORM FOR QIO'S ISSUED FROM AST HANDLERS ; ; ** 7-DEC-79: VERSION 1.05 ; HANDLING OF CONTROL CHARACTERS FROM TERMINAL 2 CHANGED: ; ALL BOTHERSOME NULLS AND CONTROL CHARACTERS IGNORED FROM TERM 2 ; ;--------------------------------------------------------------------------- .PAGE .SBTTL DIRECTIVES .PSECT DIRECT,D,REL,RW ; AQ1: QIO$ IO.WVB,2,2,,,,<,1> AQ2: QIO$ IO.WVB,1,1,,,,<,1> OPERR: QIOW$ IO.WVB,1,1,,,,<OPNERR,OPNERL,'0> ROMSG: QIOW$ IO.WVB,1,1,,,,<ROMT,ROML,'0> RCMSG: QIOW$ IO.WVB,1,1,,,,<RCMT,RCML,'0> .PAGE .SBTTL INITIALIZATION FSRSZ$ 2 ;INITIALIZE FCS RECORD BUFFER CSI$ ;DEFINE CSI CONTROL BLOCK .PSECT DUPLEX,I,REL,RO DUPLEX:: QIOW$S #IO.ATA,#1,#1,,,,<#AST1> ;ATTACH DEVICE 1 QIOW$S #IO.ATA,#2,#2,,,,<#AST2> ;ATTACH DEVICE 2 FINIT$ ;INITIALIZE FCS MOV #BUF1,B1PTR ;INITIALIZE BUFFERS FOR EACH TERMINAL MOV #BUF2,B2PTR 1$: CLEF$S #3 ;WAIT FOREVER: ALL WE WANT IS THE AST HANDLING WTSE$S #3 MOVB SENTIN,R1 ;SOMETHING SPECIAL CALLED FOR? BGT 20$ ;YES QIOW$S #IO.KIL,#1,#1 ;NO -- EXIT QIOW$S #IO.KIL,#2,#2 QIOW$S #IO.DET,#1,#1 QIOW$S #IO.DET,#2,#2 TSTB RCVFIL ;FILE OPEN? BEQ 10$ ;NO CLOSE$ #RCVFDB ;YES - CLOSE IT 10$: EXIT$S ; ;SPECIAL FUNCTION DESIRED: R1 HOLDS INDEX ; 20$: CMP #ENTRIES,R1 ;CHECK FOR NON-EXISTENT CALL BLT 25$ ;NO GOOD -- IGNORE DEC R1 ASL R1 ;CHANGE INDEX TO OFFSET CALL @TABLE(R1) ; GO DO THE GOOD WORK 25$: CLRB SENTIN ;SET UP FOR ANOTHER REQUEST BR 1$ ;GO WAIT (PROCESS AST'S) .PAGE .SBTTL BUFFERS AND POINTERS .PSECT DATA,D,REL,RW CIRSIZ = 256. BUFSIZ = 136. B1PTR: .WORD 0 B2PTR: .WORD 0 SAVE: .WORD 0 RPTR: .WORD 0 IOSB: .BLKW 2 ; XMTFDB: FDBDF$ FDRC$A ,XMTBUF,BUFSIZ FDOP$A 3,CSIBLK+C.DSDS ;FILENAME WILL BE PARSED BY CSI XMTBUF: .BLKB BUFSIZ FILENAME: .BLKB 30. .EVEN CSIBLK: .BLKB C.SIZE RCVFDB: FDBDF$ FDRC$A ,RCVBUF,BUFSIZ FDOP$A 4,,RCVNAM RCVBUF: .BLKB BUFSIZ RCVNAM: NMBLK$ RECEIVED,DAT ; BUF1: .BLKB CIRSIZ ;THESE CIRCULAR BUFFERS JUST HAVE TO BE BUF2: .BLKB CIRSIZ ;BIG ENOUGH TO PROVIDE A REASONABLE TYPE-AHEAD SENTIN: .BYTE 0 ;CAPABILITY WHEN THE TERMINALS GO AT DIFFERENT SPEEDS XFMODE: .BYTE 0 XABORT: .BYTE 0 RCVFIL: .BYTE 0 XACTIV: .BYTE 0 ; FASK: .ASCII /DUPLEX>/ FASKL = .-FASK OPNERR: .ASCII /ERROR OPENING FILE/ OPNERL = .-OPNERR LMSG: .ASCII /TYPE CTRL-N TO TRANSMIT A LINE/ LMSGL = .-LMSG ROMT: .ASCII /RECEIVED DATA FILE HAS BEEN OPENED/ ROML = .-ROMT RCMT: .ASCII /RECEIVED DATA FILE HAS BEEN CLOSED/ RCML = .-RCMT .SBTTL TABLES .PSECT TABLE,D,REL,RO ; ; SUBROUTINES FOR SPECIAL FUNCTIONS ; TABLE: XMIT ;#1 -- CTRL-T RECV ;#2 -- CTRL-F ENTRIES = .-TABLE/2 .PAGE .SBTTL ASYNCHRONOUS TRAP HANDLERS .PSECT AST,I,REL,RO ; ; AST SERVICE ROUTINE FOR TERMINAL 1 ; AST1: MOV R0,SAVE ;ON GENERAL PRINCIPLES MOV (SP)+,R0 ;CHARACTER RECIEVED AND PARAMETER2 BIC #177400,R0 ;LOW BYTE FOR KEY PRESSED ;NOTE THE TEST FOR EXIT IS NOW CONTROL B. THIS ALLOWS CONTROL C TO BE ;USED TO CONTROL THE REMOTE COMPUTER. CMP #2,R0 ;CTRL-B WANTS IMMEDIATE EXIT FROM PROGRAM BEQ XIT ;EXIT TASK CMP #24,R0 ;CTRL-T BEQ 10$ ;TRANSMIT FILE CMP #20,R0 ;CTRL-P BEQ 20$ ;TOGGLE XMIT MODE CMP #16,R0 ;CTRL-N BEQ 30$ ;XMIT NEXT LINE CMP #1,R0 ;CTRL-A BEQ 15$ ;ABORT TRANSMISSION CMP #6,R0 ;CTRL-F BEQ 25$ ;RECEIVE FILE OPEN/CLOSE MOVB R0,@B1PTR ;TRANSMIT BYTE MOV B1PTR,AQ1+Q.IOPL DIR$ #AQ1 INC B1PTR ;MAINTAIN CIRCULAR BUFFER CMP B1PTR,#BUF1+CIRSIZ BLE 5$ MOV #BUF1,B1PTR 5$: MOV SAVE,R0 ;GENERAL PRINCIPLES AGAIN ASTX$S ;RETURN FROM AST SERVICE ; 10$: MOVB #1,SENTIN 11$: SETF$S #3 BR 5$ ; CTRL-A: ABORT TRANSMISSION 15$: INCB XABORT BR 5$ ; CTRL-P: TOGGLE TRANSMISSION MODE 20$: COMB XFMODE CLEF$S #4 BR 5$ ; CTRL-F: OPEN/CLOSE FILE FOR DATA RECEIVED 25$: MOVB #2,SENTIN BR 11$ ; CTRL-N: TRANSMIT NEXT LINE 30$: SETF$S #4 BR 5$ ; ; CONTROL-B PRESSED: IMMEDIATE EXIT ; XIT: CLRB SENTIN SETF$S #3 MOV SAVE,R0 ASTX$S ; ; AST HANDLER FOR 2ND TERMINAL ; AST2: MOV R0,SAVE MOV (SP)+,R0 BIC #177400,R0 ;1 BYTE FOR KEY PRESSED CMP #3,R0 ;CTRL-C BEQ 5$ ;IGNORE CTRL-C ( THIS IS A CHANGE ) CMP #24,R0 ;CTRL-T (DC4) BEQ 5$ ;IGNORE DC4 (GENERATED BY 6800 EDITOR) CMP #25,R0 ;CTRL-U (NAK) BEQ 5$ ;IGNORE NAK (GENERATED BY 6800 BASIC) CMP #177,R0 ;DEL BEQ 5$ ;IGNORE DEL (GENERATED BY 6800 BASIC) MOVB R0,@B2PTR ;TRANSMIT BYTE MOV B2PTR,AQ2+Q.IOPL DIR$ #AQ2 TSTB RCVFIL ;FILE OPEN TO RECEIVE DATA? BEQ 2$ ;NO CALL RCVCHR ;YES: PUT CHARACTER INTO FILE 2$: INC B2PTR CMP B2PTR,#BUF2+CIRSIZ BLE 5$ MOV #BUF2,B2PTR 5$: MOV SAVE,R0 ASTX$S ;RETURN FROM AST SERVICE .PAGE .SBTTL XMIT - TRANSMIT A FILE .PSECT XMIT,I,REL,RO ; ; GET FILE DESCRIPTER, PARSE IT, OPEN INPUT FILE ; XMIT: QIOW$S #IO.RPR,#1,#1,,#IOSB,,<#FILENAME,#30.,#6,#FASK,#FASKL,#'$> CSI$1 #CSIBLK,#FILENAME,IOSB+2 ;COMPRESS LINE BCS 20$ ;ERROR HANDLING CSI$2 #CSIBLK,INPUT ;PARSE FILE DESCRIPTOR BCS 20$ ;ERROR HANDLING OPEN$R #XMTFDB ;OPEN FILE FOR READING BCS 20$ ;ERROR HANDLING CLRB XABORT ;INITIALIZE INCB XACTIV ;FLAG FILE ACTIVE TSTB XFMODE BEQ 5$ QIOW$S #IO.WVB,#1,#1,,,,<#LMSG,#LMSGL,#'0> ;SAY LINE MODE ACTIVE ; ; READ A RECORD FROM FILE AND WRITE IT TO TERMINAL 2 ; 5$: TSTB XABORT ;STOP NOW? BNE 10$ ;YES TSTB XFMODE ;TRANSMIT WHOLE FILE INTACT? BEQ 8$ ;YES WTSE$S #4 ;NO- WAIT FOR PERMISSION FOR THIS LINE CLEF$S #4 ;INHIBIT NEXT LINE 8$: GET$ #XMTFDB BCS 10$ ; END AND ERROR HANDLING QIOW$S #IO.WVB,#2,#2,,,,<XMTFDB+F.NRBD+2,XMTFDB+F.NRBD,#'+> BR 5$ ; ; DONE WITH FILE (EITHER END OR ERROR) -- CLOSE IT ; 10$: CLOSE$ #XMTFDB CLRB XACTIV ;FLAG FILE CLOSED RETURN ; ; ERROR OPENING FILE -- SAY SO AND WAIT ; 20$: DIR$ #OPERR RETURN .PAGE .SBTTL RECV - HANDLE DATA RECEIVED .PSECT RECV,I,REL,RO RECV: TSTB RCVFIL ;IS A FILE OPEN BNE 10$ ;YES -- CLOSE IT ;OPEN FILE FDAT$R #RCVFDB,#R.VAR,#FD.CR,,#-5,#-5 OPEN$W #RCVFDB BCS 20$ ; ERROR HANDLING MOVB #1,RCVFIL ;MARK FILE OPEN MOV #RCVBUF,RPTR DIR$ #ROMSG ;SAY FILE OPENED RETURN ;CLOSE FILE 10$: CLOSE$ #RCVFDB CLRB RCVFIL ;MARK FILE CLOSED DIR$ #RCMSG ;SAY FILE CLOSED RETURN ; ; ERROR OPENING FILE -- SAY SO AND WAIT ; 20$: DIR$ #OPERR RETURN ; RECIEVE A CHAR: BYTE IN R0 IS TO BE STUFFED INTO BUFFER ; WHEN BUFFER IS FULL OR CR DETECTED, FLAG BUFFER FOR WRITING RCVCHR: CMPB #15,R0 ;CR? BEQ 20$ ;YES - PUT BUFFER CMPB #12,R0 ;LF? BEQ 10$ ;IGNORE LF TSTB R0 ;NUL? BEQ 10$ ;IGNORE NUL MOVB R0,@RPTR ;STUFF CHAR INTO BUFFER INC RPTR ;MAINTAIN POINTER CMP RPTR,#RCVBUF+BUFSIZ ;CHECK FOR BUFFER FULL BGT 20$ ;NEED TO PUT BUFFER 10$: RETURN ;ALL DONE 20$: MOV RPTR,R0 ;COMPUTE RECORD LENGTH SUB #RCVBUF,R0 BLT 25$ ;NEGATIVE CHARS WOULD BE AN ERROR MOV R0,RCVFDB+F.NRBD ;SET LENGTH PUT$ #RCVFDB ;SHIP IT OUT 25$: MOV #RCVBUF,RPTR ;SET UP FOR NEW BUFFER RETURN .END DUPLEX