.TITLE TTYOUT 'REMOTE' TERMINAL ROUTINES .IDENT /V 1.1/ .GLOBL INPTTW I$$AS=0 ; ; WRITTEN BY MICHAEL D. LAMPI DAC CAT ; ; WRITTEN 10/2/79 ; ; LAST UPDATE 11/9/79 ; ; REMOTE LINE HANDLING SUBROUTINES DESIGNED TO REPLACE ; FORTRAN VERSIONS WRITTEN FOR RT-11 ; ; USES STANDARD QIO FUNCTION IO.ATA TO ATTACH TO 'REMOTE' ; TERMINAL WITH AN ASYNCHRONOUS TRAP TO (HOPEFULLY) CATCH ; ALL THE INPUT CHARACTERS. ; .MCALL QIOW$,CLEF$S,ENAR$S,DSAR$S,ALUN$,QIO$,DIR$,ASTX$S .MCALL MRKT$S,WTSE$S,WSIG$S ; .GLOBL IOUTT1 .GLOBL INPTT1 ; IOUTT1: CMP #-10.,@2(R5) ;SEE IF FIRST PARAMETER IS 'SETUP' (-10.) BEQ 36$ JMP OUTPUT ; BNE OUTPUT ;NOPE - JUST PLAIN OLD OUTPUT 36$: ; MOV @4(R5),ALUN+A.LUNU ;GET TERMINAL NUMBER (BINARY) & PUT IN ALUN DPB DIR$ #ALUN ;ASSIGN A LUN TO THE REMOTE TERMINAL BCS LUNERR ;ERROR??!!? .IF NDF,I$$AS DIR$ #QIOATA ;NOW ATTACH TO THE TERMINAL & SET UP AST BCS ATAERR ;ERROR!!??! .ENDC DIR$ #QIOSET ;SET MULTIPLE CHARACTERISTICS BCS SETERR ;ERROR? CLEF$S #9. ;OK BUT LEAVE FLAG OFF CLR R0 ;RETURN SUCCESS CODE (0) RETRN1: RTS PC ;AND RETURN TO CALLING PROGRAM ; LUNERR: MOV #2,R0 ;2 IS THE LUN ERROR BR RETRN1 ; ATAERR: MOV #3,R0 ;3 IS THE ATTACH FAILURE BR RETRN1 ; SETERR: MOV #4,R0 ;4 IS THE SET FAILURE CLEF$S #9. ;LEAVE EVENTA FLAG OFF BR RETRN1 ; ALUN: ALUN$ 3,TT,0 ; QIOATA: QIOW$ IO.ATA,3,,,,, ; ** IAS MAKE IT A QIOW$ ** ; READ: QIOW$ IO.RAL!TF.RNE,3,9.,,,,<0,0> .IF NDF,I$$AS WREAD: QIOW$ IO.RAL!TF.RNE,3,16,,,, WRBF: .WORD 0 ;WAITED-READ BUFFER .IFF WREAD: QIOW$ IO.RAL!TF.RNE,3,9.,,,, UWREAD: QIO$ IO.RAL!TF.RNE,3,9.,,,, WRBF: .WORD 0 ;WAITED-READ BUFFER WRFG: .WORD 0 ;FLAG A READ IS OUTSTANDING .ENDC ; ; QIOSET: QIOW$ SF.SMC,3,9.,,,, ; ** IAS MAKE IT A QIOW$ SETBUF: .IF NDF,I$$AS .BYTE TC.NEC,1 ;NO ECHO .IFF ; .BYTE TF.RNE,1 ;NO ECHO ;NO-ECHO IMPLIED BY FULL-DUPLEX IN IAS .ENDC .BYTE TC.SLV,1 ;SLAVED .BYTE TC.SMR,1 ;LOWER-CASE .IF DF,I$$AS .BYTE TC.BIN,1 ;BINARY READ .ENDC .BYTE TC.FDX,1 ;FULL DUPLEX ; .BYTE TC.8BC,1 ;EIGHT-BIT CHARACTERS .BYTE TC.RAT,1 ;TYPE-AHEAD BUFFER .BYTE TC.WID,255. ;255. CHARACTER BUFFER ; CLRBUF: .IF NDF,I$$AS .BYTE TC.NEC,0 ;RESET ECHO .IFF .BYTE TC.BIN,0 .ENDC .BYTE TC.FDX,0 ;SET NOT FULLDUPLEX .BYTE TC.SLV,0 ;SET NOSLAVE CLRBFL=.-CLRBUF .EVEN QIOCLR: QIO$ SF.SMC,3,9.,,,, .IF DF,I$$AS QIO: QIO$ IO.WAL!TF.WBT!TF.CCO,3,10,,,WRTAST,<0,1,0> .IFF QIO: QIO$ IO.WAL!TF.WBT!TF.CCO,3,10,,,,<0,1,0> .ENDC ;BREAK IS NOT REALLY SUPPORTED. HOWEVER, USE A NULL CHARACTER. CLOSEST WE CAN ;COME. BRKQIO: QIO$ IO.WAL!TF.WBT!TF.CCO,3,9.,,,, ;EMIT 32 NULLS BRKBUF: .WORD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;16 WORDS OF NULLS ; ; COMES HERE IF ALL THAT'S WANTED IS OUTPUT TO THE REMOTE DEVICE ; OUTPUT: CLR R0 ;INITIALIZE RETURN FLAG CMPB #-1,@2(R5) ;SEE IF HE WANTS A BREAK BNE PREDMP ;NOPE ; ; DEFAULT COMMAND IS 'BREAK', OR LOGICAL SPACING CONDITION WANTED ; SINCE WE HAVE NO STANDARD METHOD FOR THIS REQUEST OF THE TERMINAL ; DRIVER, WE MUST DIRECTLY ADDRESS THE 3 DL-11 & 1 DZ-11 CSR'S TO ; ACCESS THE 'BREAK' FUNCTION OF THESE DEVICES. ; MOV ALUN+A.LUNU,R0 ;GET TERMINAL # FROM ALUN$ DPB MOV R0,R1 ;COPY IT ASL R1 ;MULTIPLY BY TWO ; BISB BPOS(R0),@CLRAD(R1) ;SET THE 'BREAK' BIT FOR THIS TERMINAL DIR$ #BRKQIO ;EMIT THE PHONY "BREAK" MRKT$S #6,#20.,#1 ;WAIT FOR THE BREAK TO BE NOTICED WTSE$S #6 ;(ABOUT 1/3 SECOND SHOULD BE ENOUGH) ; BICB BPOS(R0),@CLRAD(R1) ;CLEAR THE 'BREAK' CONDITION CLR R0 ;TELL 'EM IT'S OK RTS PC ;CAN'T DO A BREAK IN RSX-11, SO JUST RETURN ; ; THE FOLLOWING IS A TABLE OF THE TERMINAL BREAK BIT POSITIONS ; AS WELL AS THEIR RESPECTIVE CSR ADDRESSES. ; NOTE THAT 11 (10) TERMINALS ARE IN THE TABLE, CORRESPONDING (IN ORDER) ; FROM TT0: THRU TT12: ; .IF DF,$R$T11 BPOS: .BYTE 1,1,1,1,2,4,10,20,40,100,200 .EVEN CLRAD: .WORD 177560,176500,176520,176540 .WORD 176600,176610,176620,176630 .WORD 160107,160107,160107 .ENDC ; .GLOBL WTSGEV WTSGEV: WSIG$S JSR PC,WLOS RTS PC ;FORTRAN ENTRY FOR WAITING WHERE NOTHING IS GOING ON PREDMP: TST @2(R5) ;SEE IF HE BPL DUMP ;MUST WANT TO REALLY DUMP A CHARACTER CMP #-2,@2(R5) ;SEE IF AST RECOGNITION IS TO BE DISABLED BEQ DISABL ;YES ; ENAR$S ;ENABLE AST RECOGNITION RTS PC ;THEN RETURN ; DISABL: DSAR$S ;DISABLE AST RECOGNITION DIR$ #QIOCLR ;RESET TERMINAL ATTRIBUTES RTS PC ;THEN RETURN ; .IF DF,I$$AS TRIES: .WORD 0 .ENDC DUMP: .IF DF,I$$AS CLR TRIES DUMP2: INC TRIES ;COUNT TO AVOID INFINITE LOOP .ENDC .IF NDF,I$$AS CLEF$S #10 ;CLEAR THE EVENT FLAG CMPB #IS.SET,$DSW ;SEE IF FLAG WAS SET BEQ DUMPIT ;YES - I/O COMPLETE - OK TO SHIP IT OFF .ENDC .IF DF,I$$AS CLEF$S #10 ;CLEAR THE EVENT FLAG TST DGOIN ;ANY I/O IN PROGRESS? BEQ DUMPIT ;IF NOT, GO AHEAD RIGHT AWAY ;ALREADY DOING SOMETHING SO SEE WHAT WE CAN DO TO WAIT WSIG$S JSR PC,WLOS ;AWAIT SOMETHING OR OTHER ;NOW SEE HOW MANY OUTSTANDING OUTPUTS THERE ARE. ;IF MORE THAN 7 WAIT UNTIL THE NUMBER DECREASES, ELSE ;GO AHEAD. CMP DGOIN,#7 ;ARE WE OVERSTUFFING IAS? BLO DUMPIT ;NO, GO AHEAD AND STASH ANOTHER QIO$ .MCALL ENAR$S ENAR$S ;IF OVERFULL BE CERTAIN WE SEE ASTS. CMP TRIES,#7 ;TOO MANY LOOPS AROUND? BHI DUMPIT ;IF SO ESCAPE BR DUMP2 ;ELSE LOOP BACK AND RETRY .ENDC WSIG$S JSR PC,WLOS BR DUMPIT ; DEC R0 ;NO - INDICATE I/O STILL IN PROCESS ; RTS PC ;THEN RETURN ; DUMPIT: MOV #1,QIO+Q.IOPL+2 ;MOVE BUFFER LENGTH MOV 2(R5),QIO+Q.IOPL ;MOVE ADDRESS OF BUFFER .IIF DF, I$$AS, INC DGOIN DIR$ #QIO ;NOW WRITE IT OUT RTS PC ;THEN RETURN DGOIN: .WORD 0 ;FLAG THAT I/O IS IN PROGRESS VIA QIO IF 1 .IF DF,I$$AS WRTAST: TST (SP)+ ;POP IOSB ADDRESS WE DONT REALLY HAVE .MCALL ASTX$S DEC DGOIN ;COUNT DOWN PENDING CHARS BGT 1$ ;BUT CLAMP POSITIVE CLR DGOIN 1$: ASTX$S ;EXIT THE AST .ENDC ; ; ; ; THE FOLLOWING ROUTINE HANDLES THE ASYNCHRONOUS TRAP FOR INPUT .GLOBL OUTCHR OUTCHR: .WORD 0 ;CHARS IN, NOT HANDLED ON REMOTE TTY ; OUTAST: CMP IEND,#300.+BUFF ;SEE IF AT END OF 300 CHARACTER BUFFER BLO 5$ ;NO (BUT TAKE CARE OF OVERFLOWS) ; BNE 5$ ;NOPE MOV #BUFF,IEND ;YUP - SET POINTER TO BEGINNING 5$: INC IEND ;POINT TO NEXT POSITION IN BUFFER CMP IPTR,IEND ;SEE IF DE-QUEUEING POINTER AT THIS POSITION BEQ OVRFLO ;YUP - WE HAVE AN OVERFLOW INC OUTCHR ;COUNT CHARACTERS IN FROM REMOTE BUT NOT READ GETCHO: MOVB (SP)+,@IEND ;MOVE CHARACTER FROM STACK TO BUFFER ASTX$S ;RETURN FROM AST ; ;OVRFLO: IOT ;ABORT!! (SHOULD RARELY HAPPEN--JUST TESTING) OVRFLO: WSIG$S WSIG$S DEC IEND ;AVOID WRAPAROUND BR GETCHO ;JUST IGNORE (FOR NOW) ; INPTTW: .IF NDF,I$$AS CMP IEND,IPTR BNE INPTT1 ;IF INPUT IS THERE GO GRAB IT DIR$ #WREAD MOVB WRBF,R0 ;AWAIT AND GET A LETTER RTS PC .IFF ;IAS GET A CHARACTER AND WAIT FOR IT ENTRY TST WRFG ;READ IN PROGRESS NOW? BEQ 1$ ;NO, GO AND DO ONE ;READ ALREADY GOING. EVENT FLAG 9 SO WAIT FOR IT. WTSE$S #9. ;WAIT FOR THE READ TO FINISH BR 2$ ;THEN GO GRAB IT 1$: DIR$ #WREAD ;WAIT FOR A CHAR AND GET IT 2$: MOVB WRBF,R0 ;GET IT CLR WRFG ;SAY NO READ GOING ANY MORE BIC #177400,R0 ;MAKE SURE ONLY LOW BYTE RETURNS RTS PC ;THEN BACK TO CALLER .ENDC ; INPTT1: .IF NDF,I$$AS CMP IEND,IPTR ;SEE IF ANYTHING IN BUFFER BNE 5$ ;YES - CONTINUE MOV #-1,R0 ;NO - SET NOTHING THERE FLAG WSIG$S ;WAIT A BIT BEFORE RETURN JSR PC,WLOS RTS PC ;RETURN 5$: CMP IPTR,#300.+BUFF ;SEE IF AT END OF RING BUFFER BNE 10$ ;NO MOV #BUFF,IPTR ;YES - RESET TO BEGINNING OF BUFFER 10$: INC IPTR ;POINT TO NEXT CHARACTER MOV IPTR,R0 ;GET POINTER MOVB (R0),R0 ;GET CHARACTER BIC #177400,R0 ;KNOCK OFF ANY HIGH-ORDER STUFF DEC OUTCHR ;COUNT DOWN CHARACTERS AVAIL FROM REMOTE TTY BGE 15$ CLR OUTCHR ;CLAMP + 15$: .IFF ;IAS GET CHAR OR RETURN -1 ROUTINE TST WRFG ;WAS A READ GOING? BNE 3$ ;NO, GOTTA START ONE (1 CHAR AT A TIME...TOO BAD) DIR$ #UWREAD ;START BUT DONT WAIT FOR A CHAR IN INC WRFG ;AND FLAG READ UNDERWAY .MCALL CLEF$S ;CLR FLAG ;SEE IF READ DONE 3$: CLEF$S #9. ;CLEAR E.F. #9. CMPB #IS.SET,@#$DSW ;WAS IT SET? (WOULD MEAN I/O DONE) BEQ 2$ ;IF SO GO GET CHARACTER JSR PC,WLOS ;ELSE WAIT A BIT FOR WHATEVER WSIG$S ;(THEN JUST A TAD MORE) MOV #-1,R0 ;RETURN NOTHING RTS PC 2$: CLR WRFG ;SAY READ IS DONE MOVB WRBF,R0 ;GET THE CHARACTER BIC #177400,R0 ;AND CLEAR HI BYTE .ENDC RTS PC ;THEN RETURN ; IPTR: .WORD BUFF IEND: .WORD BUFF BUFF: .BLKB 302. .WORD 0,0,0,0 ;SAFETY ; .END