.TITLE IO101 .MCALL MRKT$S,QIOW$S,CMKT$S,ASTX$S,WTSE$S .GLOBL IO101 ; ; CALLING SEQUENCE: CALL IO101(LUN,SEN,LENSEN,REC,LENREC,IER) ; WITH: ; LUN : LOGICAL UNIT NUMBER ; SEN : BUFFER TO SEND ; LENSEN: LENGTH OF SEND BUFFER ; REC : RECEIVE BUFFER ; LENREC: NUM OF CHARACTERS RECEIVED (AND MAX NUM) ; IER : ERROR CODE (I/O STATUS) ; IO101: MOV R0,-(SP) ;SAVE REGISTERS MOV R1,-(SP) MOV R2,-(SP) MOV R3,-(SP) MOV @12(R5),NUMREC ;SAVE NUM OF CHARACTERS TO RECEIVE MOV @2(R5),LUN ;SAVE LUN FOR USE IN AST ROUTINE MOV #5,TRY DETACH: QIOW$S #IO.DET,LUN,#1,,#IOST ;DETACH AND FLUSH TYPEAHEAD BUFFER QIOW$S #IO.ATT,LUN,#1,,#IOST ;ATTACH AGAIN MRKT$S #2,#5,#2,#AST ;SET UP MARK TIME FOR 5 SECONDS QIOW$S #IO.WLB!TF.WAL,LUN,#1,,#IOST,,<4(R5),@6(R5),#0> ;WRITE COMMAND CMKT$S #2 ;CANCEL MARK TIME (IF ANY) MOVB IOST,R1 ;COPY ERROR CODE + SIGN EXTENSION.. MOV R1,@14(R5) ;..INTO ERROR ARGUMENT OF CALLER BGT OK1 ;IF GT OKAY JMP WRERR ;IF LE ERROR OK1: MOV NUMREC,R2 ;EXPECTING SOMETHING IN RETURN?? BGT OK2 ;IF GT YES TST ECHO ;ECHO COMING? BNE OK3 ;IF NE YES... GET IT JMP RTSPC ;NO... READY OK3: MOV @6(R5),R2 ;ONLY ECHO EXPECTED BR MARK ;BRANCH OK2: TST ECHO ;ECHO OPTION? BEQ ADDFIL ;IF EQ NO ADD @6(R5),R2 ;ADD CHARACTERS THAT WILL BE ECHOED ADDFIL: ADD NFILL,R2 ;ADD NUM OF FILL CHARACTERS AFTER MARK: MRKT$S #2,#5,#2,#AST ;SET UP TIME OUT FOR READ (5 SECONDS) QIOW$S #IO.RTT!TF.RNE,LUN,#1,,#IOST,,<#REC,R2,,#TAB> ;READ CMKT$S #2 ;CANCEL MARK TIME (IF ANY) MOVB IOST,R1 ;COPY ERROR CODE + SIGN EXTENSION.. MOV R1,@14(R5) ;..INTO ERROR ARGUMENT OF CALLER BLE RDERR ;IF LE ERROR CLR @12(R5) ;CLEAR CALLER'S BYTECOUNT MOV IOST+2,R0 ;GET NUMBER OF BYTES READ BGT OK4 ;IF GT PROCEED JMP RTSPC ;IF NOT... RETURN OK4: MOV #REC,R2 ;R2 POINTS TO RECEIVE BUFFER TST ECHO ;ECHO OPTION? BEQ COPY ;IF EQ NO MOV 4(R5),R1 ;R1 POINTS TO COMMAND STRING MOV @6(R5),R3 ;NUMBER OF CHAR'S IN COMMAND CHECHO: BICB #200,(R2) ;GET RID OF PARITY CMPB (R2)+,(R1)+ ;CHECK ECHO BYTEWISE BNE ECHERR ;IF NE ERROR DEC R0 ;ANOTHER CHAR PROCESSED SOB R3,CHECHO ;LOOP UNTIL FINISHED COPY: TST NUMREC ;CHARACTERS AFTER ECHO? BEQ RTSPC ;IF EQ NO MOV 10(R5),R1 ;R1 POINTS TO CALLER'S RECEIVE BUF AGAIN: TSTB (R2)+ ;NULL CHARACTER? BEQ SOB ;IF EQ DON'T COPY MOVB -1(R2),(R1)+ ;COPY INC @12(R5) ;INCREMENT BYTECOUNT BICB #200,-1(R1) ;GET RID OF PARITY SOB: SOB R0,AGAIN ;LOOP UNTIL READY BR RTSPC ECHERR: DEC TRY ;MAX NUM OF RETRIES ? BLE ECH1 ;IF LE YES MRKT$S #2,#1,#2 ;WAIT 1 SECOND WTSE$S #2 JMP DETACH ;AND TRY AGAIN ECH1: QIOW$S #IO.WVB,#6,#1,,#IOST,,<#ECHER,#ECHERL,#40> CLR @14(R5) ;CLEAR "IER" ARGUMENT BR RTSPC RDERR: MOV #IOSR,R0 ;SET UP REGISTER FOR $CBOMG CLR R2 CALL $CBOMG ;CONVERT I/O STATUS QIOW$S #IO.WVB,#6,#1,,#IOST,,<#RDER,#RDERL,#40> ;PRINT ERROR MESSAGE BR RTSPC ;BACK TO CALLER WRERR: MOV IOSW,R0 ;SET UP REGISTER FOR $CBOMG CLR R2 CALL $CBOMG ;CONVER I/O STATUS QIOW$S #IO.WVB,#6,#1,,#IOST,,<#WRER,#WRERL,#40> ;PRINT ERROR MESSAGE RTSPC: MOV (SP)+,R3 ;RESTORE REGISTERS MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 RTS PC AST: QIOW$S #IO.KIL,LUN,#3 ;HERE IF TIME OUT OCCURRED,SO KILL I/O TST (SP)+ ;REMOVE EVENT FLAG FROM STACK ASTX$S ;EXIT AST ROUTINE TRY: .WORD 0 NUMREC: .WORD 0 NFILL: .WORD 6 ;NUMBER OF FILL CHARACTERS AFTER ECHO: .WORD 1 ;ECHO OPTION PRESENT (0=NOT) REC: .BLKB 30. LUN: .WORD 0 IOST: .BLKB 4 TAB: .WORD 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 ;SPECIAL TERMINATOR: SPACE ;40: FIRST BIT IN 3RD WORD LF=12 ECHER: .ASCII /*** FATAL *** [IO101] ECHO ERROR AFTER 5 RETRIES/ ECHERL=.-ECHER RDER: .ASCII /*** FATAL *** [IO101] READ ERROR -- IOST: / IOSR: .BLKB 6 RDERL=.-RDER WRER: .ASCII /*** FATAL *** [IO101] WRITE ERROR -- IOST: / IOSW: .BLKB 6 WRERL=.-WRER .END