.TITLE MCRREQ .IDENT /23JUN7/ ;+ ; MCRREQ - TASK TO REQUEST MCR FUNCTIONS ; ; AUTHOR: M. KELLOGG ; SYSTEM: RSX-11D V6.2 ; DATE: 16-JUN-77 ; REVISIONS: ; 16-JUN-77 (MK) WRITTEN; THIS IS A COMPLETE RE-WRITE OF MCRREQ. ; IT IS FUNCTIONALLY COMPATIBLE WITH EARLIER VERSIONS, ; EXCEPT THAT IT RECOGNIZES MFT FUNCTIONS FOR V6.2 ; COMPATIBILITY. ; 18-JUN-77 (MK) ADD CHECK TO WAIT ROUTINE TO SEE IF OFFSPRING ; TASK SNEAKED OUT WITHOUT GOING THROUGH TS.EXT ; STATE ; 23-JUN-77 (MK) SET AF.GC FLAG IN ATL TO KEEP FROM LOSING NODES ; IF OFFSPRING TASK DOESN'T TO A GMCR$. ; ; THIS TASK ALLOWS ANOTHER TASK TO REQUEST AN MCR FUNCTION. ; THE REQUEST IS DONE BY SENDING A MESSAGE TO MCRREQ, IN THE ; FOLLOWING FORMAT: ; ; WORD CONTENT ; ; 0 IF ZERO, THE CALLING TASK IS RESUMED IMMEDIATELY ; AFTER REQUESTING THE MCR FUNCTION. ; IF NON-ZERO, THE CALLING TASK IS RESUMED ON ; COMPLETION OF THE MCR FUNCTION. ; 1 MCR FUNCTION NAME (SECOND HALF OF TASK NAME) ; IN RAD50. IF THIS IS BLANK (ZERO), MCR IS KILLED AT ; THE CURRENT TERMINAL. ; 2 BYTE COUNT OF COMMAND STRING FOR MCR FUNCTION, ; INCLUDING STRING TERMINATOR. ; 3 START OF ASCII COMMAND STRING (80 BYTES MAXIMUM, ; PLUS TERMINATOR). ; ; AFTER THE SEND-AND-REQUEST TO MCRREQ, THE CALLING TASK SHOULD LOOP ; ON A RECEIVE-OR-SUSPEND UNTIL IT RECEIVES AN ANSWER FROM MCRREQ ; (DSW SET TO +1). THE ANSWER IS A ONE-WORD MESSAGE CONTAINING ; A CODE INDICATING WHETHER THE REQUEST WAS SUCCESSFUL, AS FOLLOWS: ; ; +1 FUNCTION REQUESTED SUCCESSFULLY ; -100 (OCTAL) ILLEGAL BYTE COUNT OR REQUEST MESSAGE TOO LONG ; -101 NOT ENOUGH NODES TO CREATE MCR BUFFER ; -102 REQUEST FOR FUNCTION FAILED ; ; EXAMPLE OF USE: ; ; VSDR$C MCRREQ,,,,,BUF,LENGTH ;RCV: VRCS$C MCRREQ,ANSWER,1 ; DEC $DSW ; BNE RCV ; TST ANSWER+4 ; BMI ERR ; (SUCCESSFUL REQUEST OF FUNCTION) ; . ; . ; . ;BUF: .WORD 0 (TO CONTINUE) OR 1 (TO WAIT) ; .RAD50 /MAC/ ; .WORD BYTECT ;STR: .ASCII /MAC A,A=A/<33> ;BYTECT=.-STR ; .EVEN ;LENGTH=.-BUF/2 ;ANSWER:.WORD 0,0,0 ; ; RESTRICTIONS AND NOTES: ; ; 1. MCRREQ PERFORMS NO SYNTAX CHECKING OR BLANK SQUEEZING ON THE ; COMMAND LINE. IT IS UP TO THE CALLER TO ASSURE THAT IT IS ; IN THE PROPER FORMAT. ; ; 2. THE CALLER SHOULD USE A VRCS$ TO SUSPEND AND RECEIVE THE ANSWER, ; AS SHOWN IN THE EXAMPLE, RATHER THAN DOING A SEPARATE SUSPEND ; FOLLOWED BY A RECEIVE. THIS AVOIDS A SITUATION WHERE MCRREQ ; TRIES TO RESUME THE CALLER BEFORE IT HAS SUSPENDED, AND THE ; CALLER WAITS FOREVER. ; ; 3. THE STRING TERMINATOR SHOULD NORMALLY BE AN ESCAPE (ASCII 33) ; TO PREVENT MCR FROM PROMPTING WHEN THE REQUESTED FUNCTION IS ; COMPLETE. IF AN MCR PROMPT IS DESIRED, A CARRIAGE RETURN MAY BE ; USED. ; ; 4. THE ANSWER CODES ARE OCTAL. THEY WERE PROBABLY ORIGINALLY ; INTENDED TO BE DECIMAL, AND BECAME OCTAL THROUGH AN OVERSIGHT. ; THEY CONTINUE TO BE OCTAL FOR COMPATIBILITY'S SAKE. ; ; 5. MCRREQ SHOULD BE INSTALLED AT THE SAME PRIORITY AS MCR ; (CURRENTLY 230). LIKE MCR, IT DEPENDS HEAVILY ON RUNNING AT ; A PRIORITY HIGHER THAN ANY FUNCTION IT REQUESTS. ; ; 6. MCRREQ RECOGNIZES THE COMMANDS ABO, ALT, CAN, DIS, ENA, FIX, ; LOA, RES, AND UNF, AND GENERATES A REQUEST TO THE MCR TASK ; ...MFT TO HANDLE THEM. THIS IS TRANSPARENT TO THE USER, EXCEPT ; THAT HE CANNOT SUBSTITUTE HIS OWN PROCESSOR TO HANDLE ANY OF ; THESE COMMANDS. ;- .MCALL DIR$,EXIT$S,WSIG$S .MCALL QIO$,RQST$,VRCD$,VRCX$,VSDR$ .MACRO .INH0 MOV @#PS.EXP,-(SP) BISB #140,@#PS.EXP .ENDM .INH0 .MACRO .ENB0 CALL ..ENB0 .ENDM .ENB0 .MACRO ANS CODE JSR R5,REPLY .WORD CODE .ENDM ANS .PSECT PDATA,D,RO DUMMSG: VRCX$ ,DUMBUF,1 KILLIO: QIO$ IO.KIL,1,1 MCR: .RAD50 /...MCR/ MFT: .RAD50 /MFT/ MFTLST: .RAD50 /ABOALTCANDISENAFIXLOARESUNF / .PSECT IDATA,D,RW ANSWER: .WORD 0 DUMBUF: .WORD 0,0,0 GETMSG: VRCD$ ,,45.,TI RQST: RQST$ ...CMD,,,0,0 SNDR: VSDR$ CALLER,,,,,ANSWER,1 TI: .WORD 0 WAITFL: .WORD 0 .PSECT CODE,I,RO START: MOV #6,R3 ;GET A 96-BYTE NODE CALL ..PICV BCC 10$ ;GOT IT DIR$ #DUMMSG ;CAN'T GET NODE - RECEIVE DUMMY MSG MOV DUMBUF,SNDR+S.DRTN MOV DUMBUF+2,SNDR+S.DRTN+2 ANS -101 ;RETURN OUT-OF-NODES ANSWER BR START ;TRY AGAIN 10$: MOV R4,R1 ;SAVE NODE ADDR ; ; WE HAVE A NODE - TRY TO RECEIVE A MESSAGE INTO IT - ; IF NO MESSAGE, RELEASE THE NODE AND EXIT ; NEXT: MOV R1,R4 ;POINT R4 TO NODE TST (R4)+ ;POINT TO START OF MSG MOV R4,GETMSG+R.VDBA ;PUT START ADDR IN RECEIVE DPB .INH0 ;;INHIBIT TASK SWITCH TO PREVENT RACE DIR$ #GETMSG ;;RECEIVE THE MSG BCC 20$ ;;GOT IT OK ; ; COULDN'T GET MESSAGE - RETURN NODE AND HANDLE ERROR ; CMP $DSW,#IE.ITS ;;OUT OF MESSAGES? BNE 10$ ;;NO - BAD MESSAGE CALL ..NADV ;;YES - RETURN NODE EXIT$S ;;QUIT 10$: .ENB0 ;;ENABLE TASK SWITCHING MOV (R4)+,SNDR+S.DRTN ;PUT TASK NAME IN REPLY DPB MOV (R4)+,SNDR+S.DRTN+2 BR BADMSG ;HANDLE BAD MSG ERROR ; ; GOT THE MESSAGE - THE SITUATION IS NOW AS FOLLOWS: ; ; R1 = ADDR OF MCR BUFFER NODE ; R3 = 6 = NUMBER OF 8-WD BLOCKS IN NODE ; R4 = R1+2 = ADDR OF SENDING TASK NAME ; ; THE NODE CONTAINS THE FOLLOWING INFORMATION: ; ; WORD BYTE CONTENT ; ; 0 0 UNDEFINED; WILL BECOME FORWARD PTR ; 1 2 1ST HALF OF SENDING TASK NAME; ; WILL BECOME BACK PTR ; 2 4 2ND HALF OF SENDING TASK NAME; WILL ; BECOME UNUSED, SINCE NODE IS NOT ACCOUNTED ; 3 6 "WAIT TO RESUME" FLAG; WILL BECOME ; 2ND HALF OF MCR TASK NAME ; 4 10 2ND HALF OF MCR TASK NAME; WILL ; BECOME TI PUD ADDRESS ; 5 12 BYTE COUNT OF COMMAND LINE ; 6 14 START OF COMMAND LINE ; 20$: .ENB0 ;;ENABLE TASK SWITCHING MOV (R4)+,SNDR+S.DRTN ;SAVE TASK NAME IN REPLY DPB MOV (R4)+,SNDR+S.DRTN+2 MOV (R4)+,WAITFL ;SAVE WAIT FLAG MOV (R4),-(R4) ;MOVE MCR TASK NAME BEQ KILMCR ;KILL MCR IF IT'S BLANK MOV #MFTLST,R0 ;LOOK FOR MFT FUNCTION 30$: TST (R0) ;END OF MFT LIST? BEQ 35$ ;YES CMP (R0)+,(R4) ;MFT FUNCTION? BNE 30$ ;NO MOV MFT,(R4) ;CHANGE TASK NAME TO 'MFT' 35$: MOV (R4)+,RQST+R.QSTN+2 ;PUT TASK NAME IN REQUEST DPB MOV TI,R0 ;GET TI ADDRESS MOV U.UI(R0),RQST+R.QSPC ;PUT UIC IN REQUEST DPB MOV R0,(R4)+ ;MOVE IN TI ADDRESS DEC (R4) ;ADJUST BYTE COUNT BLT BADMSG ;BAD BYTE COUNT CMP (R4),#80. ;CHECK BYTE COUNT BLE REQ ;BYTE COUNT OK ; ; BAD MESSAGE ; BADMSG: ANS -100 ;RETURN BAD MSG ANSWER BR NEXT ;TRY NEXT MESSAGE ; ; THE MCR BUFFER IS NOW PROPERLY DIDDLED, AND WE CAN REQUEST ; THE TASK, WHICH IS THE POINT OF THIS WHOLE BUSINESS ; REQ: DIR$ #RQST ;REQUEST THE TASK BCC 20$ CMP $DSW,#IE.ACT ;TASK ALREADY ACTIVE? BEQ 10$ ;YES - WAIT UNTIL IT ISN'T ANS -102 ;RETURN BAD REQ ANSWER BR NEXT ;TRY NEXT MESSAGE 10$: WSIG$S BR REQ ; ; THE TASK IS REQUESTED - NOW QUEUE THE COMMAND BUFFER ; 20$: MOV #.MCRLH,R4 CALL ..NADD ;QUEUE THE BUFFER CALL WAIT ;WAIT FOR EXIT IF REQUESTED 30$: ANS 1 ;RETURN SUCCESS ANSWER BR START ;DO ANOTHER MESSAGE ; ; KILL THE MCR ; KILMCR: MOV #MCR,R5 ;POINT R5 TO '...MCR' .INH0 ;;INHIBIT TASK SWITCH CALL FIND ;;FIND MCR IN ATL BCS 10$ ;;NOT THERE MOV .CRTSK,-(SP) ;;SAVE CRTSK MOV R0,.CRTSK ;;MAKE MCR THE CURRENT TASK DIR$ #KILLIO ;;KILL IT MOV (SP)+,.CRTSK ;;RESTORE CRTSK 10$: .ENB0 ;;ENABLE TASK SWITCH ANS 1 ;RETURN SUCCESS ANSWER BR NEXT ;DO ANOTHER MESSAGE ; INTERNAL SUBROUTINES ; ; WAIT - SUBROUTINE TO WAIT FOR OFFSPRING TASK TO EXIT ; WAIT: MOV #RQST+R.QSTN,R5 ;POINT TO TASK NAME 10$: .INH0 ;;INHIBIT TASK SWITCHING CALL FIND ;;FIND TASK IN ATL BCC 20$ ;;GOT IT .ENB0 ;;ENABLE TASK SWITCHING WSIG$S ;WAIT A BIT BR 10$ ;LOOK AGAIN 20$: MOV A.TD(R0),R2 ;;REMEMBER STD ADDRESS BIS #AF.GC,A.TF(R0) ;;REMEMBER THAT TASK HAS AN MCR BUFFER .ENB0 TST WAITFL ;WAIT FOR EXIT? BEQ 30$ ;NO 21$: CMPB A.TS(R0),#TS.EXT ;TASK EXITED? BEQ 30$ ;YES CMP A.TD(R0),R2 ;TASK STILL THERE? BNE 30$ ;NO - HE SNEAKED OUT WSIG$S ;WAIT A BIT BR 21$ ;CHECK AGAIN 30$: RETURN ; ; FIND - SUBROUTINE TO FIND A TASK IN THE ATL ; ; INPUTS: ; ; R5 = POINTER TO RAD50 TASK NAME ; TI = TI ADDRESS ; TASK SWITCHING SHOULD BE INHIBITED ; ; CALL FIND ; ; OUTPUTS: ; ; R0 = POINTER TO ATL NODE IF TASK FOUND ; R0 = UNDEFINED IF TASK NOT FOUND ; CC IF TASK FOUND ; CS IF TASK NOT FOUND ; FIND: MOV R1,-(SP) MOV .ATLLH,R0 ;GET FIRST ATL NODE 10$: MOV A.TD(R0),R1 ;POINT TO STD ENTRY BEQ 15$ ;NO STD (NULL TASK) CMP (R1)+,(R5) ;FIRST HALF MATCH? BNE 15$ ;NO CMP (R1),2(R5) ;SECOND HALF MATCH? BNE 15$ ;NO CMP A.TI(R0),TI ;TI MATCH? BEQ 20$ ;YES - RETURN SUCCESS (C CLEARED BY CMP EQUAL) 15$: MOV (R0),R0 ;GET NEXT ATL NODE CMP R0,#.ATLLH ;DONE? BNE 10$ ;NO SEC ;YES - RETURN FAILURE 20$: MOV (SP)+,R1 RETURN ; ; REPLY - SUBROUTINE TO RETURN AN ANSWER TO CALLING TASK ; ; JSR R5,REPLY ; .WORD CODE ; REPLY: MOV (R5)+,ANSWER ;PUT ANSWER CODE IN MESSAGE DIR$ #SNDR ;SEND MESSAGE AND RESUME CALLER RTS R5 ; .END START