; CL1QIO - ISSUE A PROMPT AND START AN INPUT REQUEST ; LAST EDIT: 13-NOV-81 ; .NLIST .TITLE CL1QIO .LIST ; TEXT$ ON ;+ ; CL1QIO - START A TERMINAL INPUT REQUEST ; ; INPUT: R2 ADDRESS OF ZERO TERMINATED PROMPT STRING ; ; NO REGISTERS ARE MODIFIED ; ; ON RETURN THE INPUT REQUEST IS ACTIVE. THE AST MECHANISM WILL COMPLETE ; THE REQUEST AND SET A BUFFER POINTER AT PL.DBF ; ; THIS VERSION OF THE ROUTINE TRANSMITS THE REQUEST TO AN EXTERNAL TASK ; NAMED CL1... WHICH PERFORMS ALL INPUT REQUESTS FOR CLONE. THIS LEAVES ; CLONE FREE TO CHECKPOINT, DETACH REGIONS AND EXTEND ITSELF. ; ; THE MESSAGE SENT TO CL1... HAS THE FORMAT: ; .BLKW 1 FUNCTION CODE (NOT USED) ; .BLKW 1 ADDRESS OF CURRENT PROCESS ITEM ; .BLKW 1 NUMBER OF ADDITIONAL MESSAGE PACKETS ; .BLKW 1 DEVICE NAME ; .BLKW 1 DEVICE UNIT ; .BLKW 8. START OF PROMPT MESSAGE ; ; THE PROMPT MAY CONTINUE THROUGH THE SPECIFIED NUMBER OF ADDITIONAL PACKETS. ; ; THE REPLY RECEIVED FROM CL1... HAS THE FORMAT: ; .BLKW 2 TASK NAME (CL1...) ; .BLKW 1 REPLY TYPE (NOT USED) ; .BLKW 1 CLONE PROCESS ADDRESS ; .BLKW 1 NUMBER OF ADDITIONAL MESSAGE PACKETS ; .BLKW 2 QIO STATUS BLOCK FROM REQUEST ; .BLKW 8. START OF REPLY BUFFER ; ; THE REPLY BUFFER MAY CONTINUE IN ADDITIONAL PACKETS. ; ; ; THE PACKET(S) SHOULD BE QUEUED TO CL1... THEN A REQUEST FOLLOWED BY AN ; UNSTOP SHOULD BE ISSUED. ; ; CL1... WILL FIFO THE REPLIES AND UNSTOP ITS CALLER WHEN THE REQUEST COMPLETES. ; ;- TEXT$ OFF ; ; .PSECT CL1QIO ; .MCALL DIR$,SDAT$,RCVD$,WSIG$S,RQST$,USTP$,SETF$S ; CTRLZ=32 ; ; ; QIO:: CALL DISAST MOV R0,-(SP) MOV R1,-(SP) MOV R2,-(SP) MOV R3,-(SP) MOV R4,-(SP) MOV PROC,R0 ;GET THE PROCESS POINTER BIS #PF.WTI,PL.FLG(R0) ;SET TERMINAL INPUT ACTIVE CLR PL.DBF(R0) ;NO BUFFER AVAILABLE MOV #SBUF,R3 ;POINT TO BUFFER CLR (R3)+ ;NULL FUNCTION WORD MOV R0,(R3)+ ;SET OUR PROCESS POINTER CLR R4 ;INIT ADDITIONAL MESSAGE COUNT CALL STRLEN ;GET THE PROMPT STRING LENGTH SUB #16.,R1 ;SUBTRACT WHAT WILL FIT IN THIS BUFFER BLE 2$ ;SKIP IF IT ALL WILL 1$: INC R4 ;WE NEED ANOTHER BUFFER SUB #26.,R1 ;AND SUBTRACT THAT BGT 1$ ;KEEP COUNTING IF ANYTHING LEFT 2$: MOV R4,(R3)+ MOV PL.TI(R0),(R3)+ ;SAVE TI DEVICE NAME MOV PL.TI+2(R0),(R3)+ ;AND UNIT NUMBER MOV #16.,R1 ;SET UP BYTE COUNT FOR FIRST PACKET 3$: MOVB (R2)+,(R3)+ ;COPY PROMPT STRING SOB R1,3$ DIR$ #QSEND ;SEND OFF THE PACKET BCS 20$ ;ERRORS ARE ABSOLUTELY FATAL DEC R4 ;ANY MORE PACKETS TO SEND ? BMI 4$ ;SKIP IF NOT MOV #SBUF,R3 ;RESET SEND BUFFER POINTER MOV #26.,R1 ;AND RESET BYTE COUNT BR 3$ ; 4$: DIR$ #QRQST ;REQUEST INCASE IT IS NOT ACTIVE DIR$ #QUSTP ;AND UNSTOP IT INCASE IT WENT TO SLEEP MOV (SP)+,R4 MOV (SP)+,R3 MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 RETURN ; 20$: ERROR$ $DSW MOV #QERMES,R2 CALL OUT ;PRINT THE ERROR MESSAGE JMP ABORT ; QERMES: .ASCIZ /CLONE -- PROBLEMS WITH INPUT PROCESSOR CL1.../ .EVEN ; ; ; ; QIOFIN - FINISH AN INPUT REQUEST STARTED WITH QIO. ; ; THIS ROUTINE IS CALLED TO PROCESS A REQUEST COMPLETION MESSAGE. IT WILL ; NORMALY BE CALLED BY A RECEIVE AST. ; ; INPUT: NONE ; ; OUTPUT: IF CL1... HAS REPLY DATA READY THIS IS READ AND PLACED ; IN A BUFFER POINTED TO BY PL.DBF. THE PF.WTI FLAG IS ; CLEARED. IF THE LINE WAS TERMINATED BY ESCAPE THE BUFFER ; IS QUEUED IN PL.CBF. ; ; THIS ROUTINE SAVES NO REGISTERS ; ; QIOFIN::DIR$ #QRCVD ;ANY MESSAGES ? BCS 21$ ;JUST RETURN IF NONE TST FUNC ;CHECK FUNCTION WORD BNE QIOFIN ;IGNORE PACKET IF INVALID MOV PRCADR,R0 ;GET THE PROCESS POINTER BIC #PF.WTI,PL.FLG(R0) ;CLEAR INPUT IN PROGRESS MOV QST1,PL.QST(R0) ;SAVE QIO STATUS MOV QST2,PL.QST+2(R0) MOV QST2,R1 ;GET THE BYTE COUNT ADD #13,R1 ;ALLOW FOR ZERO BYTE AND HEADER ASR R1 ;CONVERT TO WORDS CALL GETSPA ;ALLOCATE A BUFFER BCS 20$ ;IF THAT FAILS JUST SKIP MOV R0,R2 ;COPY ITEM ADDRESS MOV PRCADR,R0 ;RESTORE PROCESS MOV R2,PL.DBF(R0) ;SET THE BUFFER POINTER ADD #6,R2 ;SKIP HEADER MOV #M.STR,(R2)+ ;STRING ITEM MOV #BUF,R1 ;POINT TO REPLY STRING MOV QST2,R4 ;GET BYTE COUNT BEQ 10$ ;SKIP IF NULL MOV NPKT,NPKT1 ;COPY NUMBER OF ADDITIONAL PACKETS MOV #16.,R3 ;BYTE CAPACITY OF PACKET 2$: MOVB (R1)+,(R2)+ ;COPY STRING DEC R4 ;ONE BYTE LESS BLE 3$ ;SKIP IF NO MORE SOB R3,2$ ;COPY TO END OF BUFFER ; ; SEE IF THERE ARE ANY MORE DATA PACKETS 3$: DEC NPKT1 ;ONE LESS PACKET BMI 10$ ;SKIP IF NO MORE 4$: DIR$ #QRCVD ;TRY TO RECEIVE THE NEXT PACKET BCC 5$ ;SKIP IF WE GET IT WSIG$S ;ELSE PAUSE A LITTLE WHILE BR 4$ ;AND TRY AGAIN 5$: MOV #SBUF,R1 ;RESET BUFFER POINTER MOV #26.,R3 ;RESET BYTE COUNT BR 2$ ;AND GO COPY SOME MORE ; ; NOW COMPLETE THE INPUT PROCESSING ; IF BUFFER WAS TERMINATED BY CTRL-Z WE PUT AN EOF INTO THE BUFFER ; IF BUFFER WAS TERMINATED BY ESCAPE WE QUEUE THE BUFFER AS A COMMAND ; 10$: CMPB PL.QST(R0),#IS.SUC ;DID REQUEST SUCCEDE ? BEQ 12$ ;SKIP IF SO CMPB PL.QST(R0),#IE.EOF ;CONTROL Z ? BNE 11$ ;IF NOT ITS AN ERROR MOVB #CTRLZ,(R2)+ ;ELSE SAVE CTRLZ IN BUFFER BR 12$ ; ; IF AN INPUT REQUEST RESULTS IN AN ERROR WE DE-ALLOCATE THE BUFFER ; THIS WILL RESULT IN THE REQUEST BEING RE-STARTED. 11$: MOV R0,-(SP) ;SAVE PROCESS POINTER MOV PL.DBF(R0),R0 ;GET BACK THE BUFFER ITEM CALL FREESP ;DEALLOCATE IT MOV (SP)+,R0 ;RESTORE PROCESS CLR PL.DBF(R0) ;CLEAR BUFFER POINTER BR 20$ ;AND QUIT ; 12$: CLRB (R2)+ ;TERMINATE THE BUFFER CMP PL.QST(R0),#IS.ESC ;DID ESCAPE TERMINATE INPUT ? BNE 20$ ;IF NOT JUST RETURN MOV PL.DBF(R0),PL.CBF(R0) ;ELSE QUEUE AS A COMMAND CLR PL.DBF(R0) ;AND CLEAR THE DATA BUFFER ; 20$: SETF$S #CL1EFN ;WAKE UP CLONE BR QIOFIN ;TRY FOR ANOTHER MESSAGE ; 21$: RETURN ;AND QUIT ; ; ; DEFINE OUR DPBS FOR COMUNICATION WITH CL1... ; QSEND: SDAT$ CL1...,SBUF QRCVD: RCVD$ CL1...,RBUF QRQST: RQST$ CL1... QUSTP: USTP$ CL1... ; ; AND THE SEND/RECEIVE BUFFERS RBUF: .WORD 0,0 SBUF: .BLKW 13. FUNC=RBUF+4 PRCADR=RBUF+6 NPKT=RBUF+10 QST1=RBUF+12 QST2=RBUF+14 BUF=RBUF+16 ; NPKT1: .WORD 0 ;PACKET COUNT FOR TRANSFER ; .END