; TSPAWN.MAC ; ; TIMESHARING "SPAWN" SUBROUTINE TO BE USED IN LIEU OF THE SPAWN DIRECTIVE ; ; THIS IS A FORTRAN CALLABLE SUBROUTINE WHICH TAKES THE SPAWN CALL ; AND CONVERTS INTO A TCS CALL TO RUN THE TASKS VIA PI.... ; NOTE THAT THE END PRODUCT IS NOT AN EXECUTIVE SERVICE REQUEST VIA A ; SYSTEM DIRECTIVE, BUT A TCS REQUEST VIA QIO'S TO PI.... ; ; A SPWN$T MACRO IS INCLUDED TO ENABLE TCS "SPAWNS" FROM MACRO PROGRAMS ; AS WELL. IT USES 16 TO 24 WORDS ON THE STACK TO PASS ARGS TO TSPAWN. ; ; ; THE LINE "SPAWN::" HAS BEEN COMMENTED OUT. IF INCLUDED, THEN ; BY ASSEMBLING THIS SUBROUTINE AND INCLUDING THE OBJECT MODULE IN ; A TASKBUILD, ANY FORTRAN PROGRAM USING THE SPAWN SUBROUTINE SHOULD ; BE TRANSPARANTLY CONVERTED INTO A PROGRAM WHICH RUNS TASKS VIA ; THE TIMESHARING CONTROL SERVICES UNDER IAS. IT IS NOT RECOMMENDED ; THAT YOU THEN PUT THIS ROUTINE INTO YOUR SYSLIB AS IT WILL DISABLE THE ; PROPER SPAWN CALL SHOULD YOU EVER WANT THAT. ; ; *NOTE: UNLIKE THE ACTUAL SPAWN DIRECTIVE, IF THIS TASK EXITS, ITS ; OFFSPRINGS WILL BE ABORTED. (UNDER TCS, CHAINING IS THE PROPER ; MECHANISM TO EXECUTE A TASK AND LEAVE THE SCENE.) ; ; OPTIONALLY, THIS FILE CAN BE EDITTED AND THE LINE WITH THE GLOBAL ; SYMBOL "SPAWN::" REMOVED. THE ALTERNATE SYMBOL, "TSPAWN::" WHICH IS ; CALLED BY THE SPWN$T MACRO, CAN BE USED IN THE SUBROUTINE CALL IN PLACE ; OF "SPAWN", THEREBY ALLOWING BOTH THE SYSTEM SPAWN DIRECTIVE AND THE ; TIMESHARING TSPAWN CALL TO CO-EXIST. ; ; MACRO PROGRAMS CAN MAKE USE OF THIS SUBROUTINE BY INVOKING THE "SPWN$T" MACRO ; WHICH IS DEFINED IN THIS MACRO SOURCE. ; ; IN ADDITION TO THE SPAWN FACILITIES, THIS TIMESHARING VERSION ALLOWS ; THE SPECIFICATION OF AN INITIAL SCHEDULING LEVEL AND RETURNS TASK ; STATISTICS IN IESB (SEE BELOW). ; ; CALLING METHOD: ; (FORTRAN AND F4P) ; ; CALL TSPAWN ([TSK],[IOP],[IEFN],[IESB],[ICMD],[ICMDL],[IVTUN],[IDS]) ; [OR CALL SPAWN (...) ; IF THE "SPAWN::" LABEL IS REINSTATED BELOW.] ; ; TSK - A 2-WORD, 1-6 CHARACTER TASK NAME IN RADIX-50 FORMAT. ; IF IT IS OMITTED, THE COMMAND LINE (ICMD) ; AND LENGTH (ICMDL) MUST BE GIVEN. THE CONTENTS OF THE ; COMMAND LINE ARE USED AS A FILE NAME FOR AN AUTO-INSTALL TASK. ; ; IOP - A 6-WORD ARRAY. WORDS 1-3 ARE IGNORED. WORD 4 MUST BE THE UIC ; IF IOP IS SPECIFIED. WORD 5 IS SPECIAL FOR THIS TCS VERSION: ; IT MUST CONTAIN THE INITIAL SCHEDULING LEVEL FOR THE TASK. ; IF THIS VALUE IS LESS THAN 1 OR GREATER THAN 5, IT DEFAULTS ; TO LEVEL 1. ; ; IEFN - A SINGLE WORD INTEGER VALUE SPECIFYING AN EVENT FLAG TO BE SET ; WHEN THE TASK EXITS. ; ; IF OMITTED, THE TASK RUN REQUEST IS MADE AND THE ROUTINE RETURNS ; CONTROL TO THE MAIN PROGRAM WHICH MAY OBTAIN STATUS INFORMATION ; AFTERWARDS ONLY BY CALLING CKTASK OR CKWAIT (BELOW). ; ; IF EQUAL TO ZERO, NO EVENT FLAG IS USED, BUT WE DON'T RETURN ; UNTIL THE TASK COMPLETES, ABORTS, OR FAILS TO LOAD. ; ; IF THE EVENT FLAG IS GIVEN, IT IS CLEARED. IN ORDER TO SIMULATE ; THE ASYNCRONOUS PROCESSING OF THE ACTUAL SYSTEM DIRECTIVE, A ; MARK TIME AST IS ENTERED EVERY *30 TICKS* TO CHECK ON THE TASK! ; THE SUGGESTED APPROACH IS TO SPECIFY EVENT FLAG AS ZERO AND ; WAIT FOR THE TASK TO COMPLETE. ; ; IESB - AN 8-WORD INTEGER ARRAY: ; WORD 1 = TASK'S EXIT STATUS ; WORD 2 = TERMINATION CODE (SEE GUIDE TO WRITING CLI APNDX B) ; WORD 3 = CPU TIME (TICKS AND DOUBLE LENGTH) ; WORD 4 = TASK'S LOAD SIZE ; WORD 5 = ERROR STATUS BLOCK FROM TCS MACROS ; WORD 6 = 2ND WORD OF ESB FROM TCS MACROS ; WORD 7 = UNUSED ; WORD 8 = UNUSED ; ; ICMD - A 1-79 BYTE ARRAY CONTAINING THE COMMAND LINE. IF THE TASK ; TO BE "SPAWNED" IS AUTO-INSTALL, THIS MUST BE A FILE NAME ; AND THE 1ST CHARACTER *MUST BE BLANK* FOR IT TO WORK. ; ; IF THE TASK IS $$$ OR ..., THE THREE CHARACTERS FOR THE TASK ; MUST ALSO BE THE FIRST THREE CAHRACTERS OF THE COMMAND LINE ; FOLLOWED BY ONE BLANK, THEN ANY COMMAND SYNTAX. ; ; IF ICMD OR ICMDL IS OMITTED, THE TASK IS NOT GIVEN A COMMAND ; LINE. ; ; ICMDL - LENGTH (BYTE COUNT) OF COMMAND LINE. IF EQUAL TO ZERO NO COMMAND ; WILL BE SENT. MUST NOT BE GREATER THAN 79. THE VALUE MUST ; INCLUDE THE 3 CHARACTERS FOR THE TASK AND ONE BLANK IF PRESENT. ; ; IVTUN - ALWAYS IGNORED ; ; IDS - AN INTEGER VARIABLE TO RECEIVE THE CONTENTS OF THE DSW. ; ; DSW CONTENTS FROM THIS ROUTINE ARE A SUBSET OF THE CONTENTS ; RETURNED FROM THE ACTUAL SPAWN DIRECTIVE: ; IS.SUC, IE.INS, IE.AST (PRIV VIOLATION), IE.IEF, ; IE.ADP, IE.SPC ; ; IN ADDITION, A STATUS OF ZERO INDICATES THAT A TCS RELATED ; ERROR HAS OCCURED. THE VALUES OF THE TCS ERROR STATUS BLOCK ; ARE THEN FOUND IN WORDS 5 AND SIX OF IESB. ; ; (MACRO) ; ; SPWN$T TSK,[PRT],[PRI],[UGC],[UMC],[EFN],[AST],[ESB],[CMD],[LEN],[VTUN],[ERR] ; THIS MACRO IS IMPLEMENTED AS A RUN TIME MACRO SIMILIAR TO THE ; $S TYPE MACRO. ; ; TSK - ADDRESS OF 2-WORD RAD50 TASK NAME (SEE TSK ABOVE) ; PRT - IGNORED ; PRI - *NOT PRIORITY* THIS ARGUMENT SPECIFIES THE INITIAL SCHEDULING ; LEVEL. DEFAULT IS LEVEL 1. (SEE IOP ABOVE) ; UGC - UIC GROUP CODE ; UMC - UIC MEMBER CODE ; EFN - EVENT FLAG NUMBER TO BE SET (SEE IEFN ABOVE) ; AST - IGNORED (AST ON COMPLETION NOT IMPLEMENTED IN THIS SOURCE) ; ESB - ADDRESS OF EXIT STATUS BLOCK (SEE IESB ABOVE) ; CMD - ADDRESS OF THE COMMAND LINE BUFFER (SEE ICMD ABOVE) ; LEN - LENGTH OF COMMAND LINE (SEE ICMDL ABOVE) ; VTUN - IGNORED ; ERR - IF OMITTED, THERE WILL BE NO ERROR INDICATION OTHER THAN THE ; STATE OF $DSW AND THE CONTENTS OF THE ESB. ; THIS IS BECAUSE THE CARRY BIT WILL BE ALTERED BY RESTORING ; THE SAVED REGISTERS. ; IF SPECIFIED, "ERR" WILL BE CALLED VIA JSR PC *BEFORE* RESTORING ; REGISTERS!! THEREFORE, THIS AREA IS NOT TRANSPARENT FROM THE ; ACTUAL SYSTEM DIRECTIVE. ; ; THIS MACRO ACTUALLY SETS UP A SUBROUTINE ARGUMENT BLOCK ON THE STACK. ; REGISTERS R0 THROUGH R5 ARE SAVED ON THE STACK FIRST AND RESTORED LAST. ; THE SPAWN ROUTINE IS CALLED USING JSR PC AND R5 POINTS TO THE BLOCK ON ; THE STACK. ; ;/ ; USERS UNFAMILIAR WITH TCS SHOULD READ THE GUIDE TO WRITING COMMAND ; INTERPRETORS, PAGE B-1 FOR VALUSE WHICH WILL BE FOUND IN IESB(2) IF THE ; TASK ABORTS OR FAILS ABNORMALLY. ; ; THE SYSTEM MANAGEMENT GUIDE SHOULD ALSO BE READ CONCERNING THE TP1 AND TP2 ; PRIVILEGE MASKS WHICH CONTROL TASKS' ABILITIY TO USE TCS. ; ; ; ANY QUESTIONS REGUARDING THIS ROUTINE OR THE TIMESHARING CONTROL ; SERVICES IT USES MAY BE DIRECTED TO: ; ; BOB FREEPARTNER ; HOST INTERNATIONAL, INC. ; P.O. BOX 1760 ; SANTA MONICA, CA. 90406 ; (213)450-7566 ;\ ; DEFINE "SPWN$T" MACRO ; .MACRO SPWN$T TSK=#-1,X1,S,UGC,UMC,EFN,X2,ESB=#-1,C=#-1,L,X3,ERR MOV R0,-(SP) ; PUSH REGISTERS R0 ... R5 MOV R1,-(SP) MOV R2,-(SP) MOV R3,-(SP) MOV R4,-(SP) MOV R5,-(SP) ; MOV SP,R4 ; SAVE CURRENT SP IN A FREE REGISTER ; SET UP FORTRAN SUBROUTINE BLOCK ON STACK MOV #$DSW,-(SP) ; IDS MOV #-1,-(SP) ; VTUN OMITTED .IF NB L ; IF LENGTH NON-BLANK CLR -(SP) ; MAKE ROOM FOR ARG ADDR MOV SP,R1 ; AND SAVE ADDRESS .IFF MOV #-1,-(SP) ; ELSE, MAKE IT AN OMITTED ITEM .ENDC MOV C,-(SP) ; ICMD MOV ESB,-(SP) ; IESB .IF NB EFN CLR -(SP) ; IF GIVEN, ALLOW FOR EFN ADDR MOV SP,R3 ; SAVE LOCATION .IFF MOV #-1,-(SP) ; ELSE, FLAG AS OMITTED .ENDC .IF NB UMC NEEDOP=1 ; IOP NEEDED .IFF .IF NB S ; IF SCHED LEVEL, IOP NEEDED NEEDOP=1 .IFF NEEDOP=0 ; IOP ARG NOT NEEDED .ENDC .IF EQ NEEDOP MOV #-1,-(SP) ; IF IOP NOT NEEDED, OMIT ARG .IFF CLR -(SP) ; ELSE MAKE ROOM FOR ARG .ENDC MOV SP,R2 ; SAVE LOCATION MOV TSK,-(SP) ; TSK MOV #10,-(SP) ; # ARGS MOV SP,R5 ; R5 -> ARGUMENT BLOCK .IF NB L ; IF L IS NON-BLANK MOV L,-(SP) ; PUT IT ON THE STACK ALSO MOV SP,(R1) ; AND PUT ADDRESS INTO ARG BLOCK .ENDC .IF NB EFN ; IF AN EVENT FLAG WAS SPECIFIED MOV EFN,-(SP) ; PUT THE NUMBER ON THE STACK MOV SP,(R3) ; AND PUT ADDRESS INTO ARG BLOCK .ENDC .IF NE NEEDOP ; IF IOP ARG IS NEEDED CLR -(SP) ; WORD 6 UNUSED .IF NB S ; IF SCHED LEVEL GIVEN MOV S,-(SP) ; PUT IT INTO THE BLOCK .IFF MOV #1,-(SP) ; ELSE DEFAULT TO 1 .ENDC .IF NB UGC ; IF UIC GROUP GIVEN MOVB UGC,-(SP) ; MOVE UIC INTO IOP MOVB UMC,-(SP) .IFF CLR -(SP) ; ELSE CLEAR UIC ARG .ENDC CLR -(SP) ; WORDS 1 TO 3 IGNORED CLR -(SP) CLR -(SP) MOV SP,(R2) ; INCLUDE ADDR OF IOP IN ARG BLOCK .ENDC MOV R4,-(SP) ; SAVE INITIAL SP ON STACK ; CALL TSPAWN ; CALL THE SPAWN ROUTINE ; .IF NB ERR BCC .+6 JSR PC,ERR .ENDC MOV (SP),SP ; RESTORE SP TO ORIGINAL VALUE MOV (SP)+,R5 ; RESTORE REGISTERS MOV (SP)+,R4 MOV (SP)+,R3 MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 .ENDM SPWN$T ; ; THE FOLLOWING MACRO IS A "BRANCH ON ERROR" PSEUDO-INSTRUCTION ; .MACRO BERR LOC BCC .+6 JMP LOC .ENDM BERR EX$SEV=4 ; ; SPAWN SUBROUTINE ; ; MACRO CALLS ; .MCALL TCSMC$,MRKT$,DIR$,ASTX$S,CLEF$S,SETF$S TCSMC$ ; ; DATA AREAS ; MARK: MRKT$ ,30.,1,CKAST ; SET UP A MARK TIME DPB TDB: TDBDF$ ; DEFINE TASK DESCRIPTOR BLOCK TDEB$A ESB ; DECLARE AN ERROR STATUS BLOCK TASK: .BLKW 03 ; TASK NAME (ASCII) CMDL: .BLKW 40. ; COMMAND LINE BUFFER ESB: .BLKW 02 ; ALLOCATE ERROR STATUS BLOCK EFN: .WORD 0 ; ALLOCATE EVENT FLAG # STORAGE RTNADR: .WORD 0 ; STORE FOR IESB RETURN DSWADR: .WORD 0 ; STORE FOR IDS RETURN ; ; CODE ; ;;SPAWN:: ;- REINSTATE THIS LINE TO CONVERT ACTUAL "SPAWN" CALLS TO TCS. TSPAWN:: ; ; DECLARE TDB. IF A TASK WAS SUCCESSFULLY INITIATED AND HAS NOT ; EXITTED, OR IF IT'S EXIT STATUS HAS NOT BEEN RECOGNIZED BY ; THE CALLING TASK, THE CALL WILL FAIL HERE WITH DSW=IE.ACT ; SINCE THE TDB IS CURRENTLY IN USE. ; TDBD$T #TDB ; DECLARE TDB ACTIVE BERR ERR1 ; ; INITIALIZE DATA AREAS AND DEFAULT PARAMETERS ; 10$: CLR TASK ; CLEAR TASK BUFFER CLR TASK+2 CLR TASK+4 TDCM$R #TDB,#TASK,#6,#TS.INS ; SETUP DEFAULT COMMAND BUFFER CLR EFN ; CLEAR EVENT FLAG NUMBER CLR DSWADR ; CLEAR IDS RETURN ADDRESS ; ; SET UP THE TASK DESCRIPTOR BLOCK (TDB) FROM ARGS ; MOV (R5)+,R4 ; SAVE NUMBER OF ARGS BEQ 15$ ; J IF NONE!!! MOV (R5)+,R3 ; R3 -> TASKNAME IN RAD50 BMI 15$ ; J IF TSK IS AN OMITTED ARG!! MOV #TASK,R0 ; R0 -> TASK BUFFER FOR ASCII TASKNAME MOV (R3)+,R1 ; R1 -> 1ST WORD OF TASKNAME (RAD50) CALL $C5TA ; CONVERT TO ASCII MOV (R3)+,R1 ; SET FOR 2ND WORD CALL $C5TA ; AND CONVERT IT ALSO 15$: DEC R4 ; COUNTDOWN ARGS BGT 20$ ; J IF SOME MORE JMP RUNIT ; ELSE, TRY TO RUN THE TASK ; 20$: MOV (R5)+,R3 ; R3 -> IOP BMI 25$ ; J IF OMITTED TDTA$R #TDB,10(R3),,6(R3) ; RUN TIME SETUP FOR TDB FROM IOP 25$: DEC R4 ; COUNTDOWN ARGS BGT 30$ ; J IF MORE TO GO JMP RUNIT ; ELSE TRY TO RUN IT ; 30$: MOV (R5)+,R3 ; R3-> EVENT FLAG NUMBER BMI 32$ ; J IF OMITTED MOV (R3),EFN ; STORE EVENT FLAG NUMBER BEQ 35$ ; J IF EFN #0 CLEF$S EFN ; ELSE CLEAR EVENT FLAG BERR ERR2 BR 35$ ; AND J 32$: DEC EFN ; FLAG AS OMITTED EVENT FLAG 35$: DEC R4 ; COUNTDOWN # ARGS BGT 40$ ; J IF MORE JMP RUNIT ; ELSE TRY TO RUN IT ; 40$: MOV (R5)+,RTNADR ; RTNADR -> IESB (EXIT STATUS BLOCK) BPL 45$ ; J IF IT'S AN ADDR CLR RTNADR ; ELSE, CLEAR THE ADDRESS 45$: DEC R4 ; COUNTDOWN ARGS BGT 50$ ; J IF MORE JMP RUNIT ; ELSE TRY TO RUN IT ; 50$: MOV (R5)+,R3 ; R3 -> COMMAND LINE BMI 55$ ; J IF OMITTED DEC R4 ; SEE IF THERE'S A LENGTH (ICMDL) BGT 51$ ; J IF PRESENT JMP 56$ ; ELSE TRY TO RUN WITHOUT A COMMAND LINE 51$: MOV (R5)+,R2 ; R2 -> COMMAND LENGTH BMI 56$ ; J IF OMITTED TST TASK ; CHECK TASK FIELD BEQ 54$ ; J IF IT IS AUTO-INSTALL MOV (R2),R1 ; R1 = COMMAND LENGTH BEQ 55$ ; J IF ZERO LENGTH MOV #CMDL,R0 ; R0 -> COMMAND LINE (LOCAL) ADD #3,R3 ; SKIP 3 CHARACTERS TASK NAME SUB #3,R1 ; AND SUBTRACT FROM LENGTH BLE 53$ ; J IF NO MORE COMMAND LINE 52$: MOVB (R3)+,(R0)+ ; MOVE BYTES INTO LOCAL COMMAND LINE DEC R1 ; USING R1 TO COUNTDOWN BGT 52$ ; UNTIL NONE LEFT ; ; SETUP FOR A ... OR $$$ TASK ; 53$: TDCM$R #TDB,#TASK+3,(R2),#TS.DOT; SET UP TDB FOR ... TASK CMP #"$$,TASK ; TEST FOR A $$$ TASK BNE 56$ ; J IF NOT MOVB #TS.DOL,TDB+T.TTYP ; ELSE CHANGE FORMAT TO DOLLARS $$$ BR 56$ ; AND J ; ; SETUP FOR AN AUTO-INSTALL TASK ; 54$: TDCM$R #TDB,R3,(R2),#TS.USE ; DECLARE AUTO-INSTALL COMMAND LINE BR 56$ ; J TO RUN ; ; ANYTHING ELSE MUST BE A RUN OF A USER INSTALLED TASK ; THE COMMAND BUFFER WAS SET UP WITH THIS AS THE DEFAULT ; 55$: TST (R5)+ ; IF ICMD OMITTED, SKIP ICMDL DEC R4 ; AND COUNTDOWN FOR IT 56$: DEC R4 ; COUNTDOWN NEXT ARG BGT 60$ ; J IF MORE JMP RUNIT ; ELSE TRY TO RUN IT ; 60$: TST (R5)+ ; IF PRESENT, VTUN ARG IS SKIPPED DEC R4 ; COUNTDOWN FOR NEXT ARG BGT 70$ ; J IF PRESENT JMP RUNIT ; ELSE TRY TO RUN IT 70$: MOV (R5)+,DSWADR ; STORE ADDR OF DSW RETURN ARG BPL RUNIT ; J IF REALLY THERE CLR DSWADR ; ELSE CLEAR THE ADDRESS ; ; TIMESHARING CONTROL SERVICE TASK EXECUTION ; RUNIT: RUN$T #TDB BERR ERR3 ; ; PROCESS ACCORDING TO EVENT FLAG SPECIFICATION ; TST DSWADR ; WAS IDS SPECIFIED? BLE 10$ ; J IF NOT MOV #IS.SUC,@DSWADR ; ELSE RELAY THE GOOD NEWS. 10$: TST EFN ; TEST EVENT FLAG NUMBER BNE 15$ ; J IF SPECIFIED JMP WAIT ; ELSE, WAIT FOR TASK EVENT; NO RETURN 15$: BMI 20$ ; J IF EFN NUMBER OMITTED DIR$ #MARK ; ISSUE A 30 TICK MARK TIME BERR ERR4 20$: RETURN ; RETURN TO CALLER ; ; WAIT ROUTINE FOR NO-RETURN-UNTIL-EXIT TYPE HANDLING ; WAIT: CKEV$T ,#TDB,WAIT,#ESB ; WAIT FOR A SUBTASK EVENT BCS 5$ ; IF AN ERROR, TRY TO READ AN EVENT TST R0 ; TEST RESULT BLE WAIT ; WAIT AGAIN IF NONSENSE EVENT 5$: CALL READEV ; CALL PART OF THIS ROUTINE TO READ IT BCC WAIT ; FOR NON-EXIT TYPE EVENTS ; CARRY IS SET IF THE TASK EXITS ; RETURN ; ; AST ENTRY EVERY 30 TICKS TO CHECK FOR A TASK EVENT ; (NOTE: INTERVAL MAY BE CHANGED BY ALTERING THE MRKT$ SETUP AT MARK:) ; CKAST: CKEV$T ,#TDB,,#ESB ; CHECK FOR AN EVENT; NO WAIT BCS 5$ ; IF ERROR, TRY TO READ EVENT ANYWAY TST R0 ; SEE IF AN EVENT OCCURED. BLE 10$ ; J IF NO EVENT 5$: CALL READEV ; ELSE CALL PART OF THIS ROUTINE TO READ BCC 10$ ; J IF TASK DID NOT EXIT SETF$S EFN ; SET EVENT FLAG IF IT DID BR 20$ ; AND J AROUND MARKTIME 10$: DIR$ #MARK ; ELSE MARK AGAIN 20$: TST (SP)+ ; CLEAN UP STACK ASTX$S ; AND EXIT AST ROUTINE ; ; THIS ROUTINE READS THE TASK EVENT INTO THE TDB ; ON RETURN, CARRY WILL BE: ; CLEAR IF TASK DID NOT EXIT (E.G. SENT A MESSAGE, CHAINED, ETC.) ; SET IF TASK EXITTED ; READEV: RDEV$T ; READ THE EVENT STATISTICS BITB #IF.SD,T.EVNT(R0) ; DID TASK SEND A MESSAGE? BNE 40$ ; J IF SO BITB #IF.CH,T.EVNT(R0) ; DID TASK CHAIN TO ANOTHER? BNE 40$ ; J IF SO BITB #IF.SU,T.EVNT(R0) ; DID TASK SUSPEND ITSELF? ; NOTE: IN SOME APPLICATIONS, OUR SUBROUTINES AUTOMATICALLY CONTINUE A TASK ; WHICH SUSPENDS ITSELF. HOWEVER, THE SPAWN DIRECTIVE DOESN'T TELL ; YOU WHEN YOUR TASK SUSPENDS, SO NEITHER DOES THIS ROUTINE. HOWEVER, ; YOU MAY CHANGE THE LOCAL SYMBOL TO 30$ TO SET THE EVENT FLAG IF ; SPECIFIED AND RETURN INSTEAD OF CONTINUING TO WAIT FOR AN EXIT ; BNE 40$ ; J IF SUSPENDED BITB #IF.NL,T.EVNT(R0) ; LOAD FAILURE? BNE 20$ ; J IF LOAD FAILURE!! BITB #IF.JA,T.EVNT(R0) ; JOB ABORTED? BNE 20$ ; J IF SO BR 30$ ; TASK EXITTED SUCCESSFULLY ; ; FOR TASKS NOT LOADED OR ABORTED, RETURN "SEVERE-ERROR" STATUS ; 20$: MOV #EX$SEV,TDB+T.EVBF+E.TS ; MOV STATUS INTO TDB ; ; FOR ABOVE AND TASKS EXITTED SUCCESSFULLY, RETURN STATISTICS ; 30$: TST RTNADR ; IS THERE AN EXIT STATUS BLOCK? BLE 35$ ; J IF NOT MOV RTNADR,R0 ; R0 -> ESB MOV TDB+T.EVBF+E.TS,(R0)+ ; PASS STATUS MOV TDB+T.EVBF+E.TR,(R0)+ ; PASS ERROR EXIT QUALIFIER MOV TDB+T.EVBF+E.TIM,(R0)+ ; PASS CPU TIME STATISTICS MOV TDB+T.EVBF+E.SIZ,(R0)+ ; PASS TASKS LOAD SIZE MOV ESB,(R0)+ ; PASS TCS ERROR STATUS BLOCK MOV ESB+2,(R0)+ ; PASS 2ND WORD OF TCS ESB 35$: TST DSWADR ; WAS IDS SPECIFIED? BLE 37$ ; J IF NOT MOV #IS.SUC,@DSWADR ; OPERATION WAS SUCCESSFUL; BUT ONLY ; IESB TELLS IF THE PATIENT SURVIVED. 37$: TDBR$T #TDB ; RELEASE TDB FOR FURTHER USE SEC ; SET CARRY = TASK EXITTED RETURN 40$: CLC ; CLEAR CARRY = TASK STILL ACTIVE RETURN ; ; THE FOLLOWING ROUTINES CAN BE CALLED BY THE TASK TO CHECK ON THE STATUS ; OF ITS TIMESHARING OFFSPRING WHICH IT ELECTED NOT TO KEEP A CLOSE WATCH ; ON. CALLING METHOD IS: ; ; (FORTRAN) ; CALL CKTASK (IESB,IDS) ! CHECK T/S OFFSPRING; RETURN IMMEDIATELY. ; CALL CKWAIT (IESB,IDS) ! CHECK ON OFFSPRING; RETURN WHEN IT EXITS. ; ; IESB - AN 8-WORD INTEGER ARRAY (SEE DESCRIPTION ABOVE) ; ; IDS - DSW RETURN (SEE ABOVE ALSO) ; ; ; ARGUMENTS MAY *NOT* BE OMITTED. IDS WILL BE ZERO IF THE TASK IS STILL ; ACTIVE. ; (MACRO) ; ; MOV R5,-(SP) ; SAVE YOUR R5 ; MOV R0,-(SP) ; SAVE YOUR R0 ; MOV #IDS,-(SP) ; MOVE ADDRESS OF DSW WORD (OR #$DSW) ; MOV #IESB,-(SP) ; MOVE ADDRESS OF EXIT STATUS BLOCK ; MOV #2,-(SP) ; MOVE # ARGS ; MOV SP,R5 ; R5 -> ARG BLOCK ON STACK ; CALL CKTASK ; CHECK TASK ; (OR CALL CKWAIT) ; ADD #6,SP ; RESET STACK POINTER ; MOV (SP)+,R0 ; RESTORE R0 ; MOV (SP)+,R5 ; RESTORE R5 ; ETC... ; CKTASK:: TST (R5)+ ; SKIP # ARGS MOV (R5)+,RTNADR ; GET ADR OF ESB CLR @RTNADR ; MOV (R5)+,DSWADR ; GET ADR OF DSW CLR @DSWADR CKEV$T ,#TDB,,#ESB ; CHECK FOR A TASK EVENT BCS 5$ ; IF ERROR, TRY TO READ EVENT ANYWAY TST R0 ; DID AN EVENT OCCUR? BLE 10$ ; J IF NO EVENT 5$: CALL READEV ; ELSE READ THE EVENT 10$: RETURN ; RETURN; IDS IS SET; CARRY SET IF EXIT ; ; CKWAIT - CALLS CKTASK. IF THE TASK HAS NOT EXITTED, ; JUMPS TO "WAIT" WHERE RETURN WILL OCCUR UPON TASK ; EXIT. IF THE TASK HAS EXITTED, RETURNS IMMEDIATELY. ; CKWAIT:: CALL CKTASK ; TAKES CARE OF ARGS AND CHECKS ONCE BCC 10$ ; J IF TASK HAS NOT EXITTED RETURN ; ELSE RETURN TO CALLER 10$: JMP WAIT ; GO AND WAIT FOR TASK TO EXIT. ; ; ERROR ROUTINES ; ; COULD NOT DECLARE TDB ; ERR1: TST DSWADR ; IS THERE AN IDS ADDRESS> BLT ERRTCS CMP #PE.PRI,ESB ; PRIV VIOLATION BEQ ERR1A CMP #PE.ABO,ESB ; REQUEST ABORTED? BEQ ERR1B CLR @DSWADR ; UNKNOWN TCS ERROR BR ERRTCS ; J TO INCLUDE TCS ESB ; THERE ARE 3 TYPES OF PRIVILEGE VIOLATIONS: ; ESB+2 = #PE.ILL - TASK DOESN'T HAVE PROPER TCP PRIVILEGE MASK ; ESB+2 = #0 - TASK HAS NO TCP PRIVILEGES ; ESB+2 = #PE.NTS - TASK IS NOT A TIMESHARING TASK ; ERR1A: MOV #IE.AST,@DSWADR ; PRIVILEGE VIOLATION BR ERRTCS ; THERE ARE 3 TYPES OF PE.ABO FAILURES: ; 1. TASK DESCRIPTOR BLOCK IS ACTIVE (IE.ACT RETURNED - *TDB*, NOT ; NECESSARILY THE TASK, IS ALREADY ACTIVE.) ; 2. PE.BUF = UNAVAILABLE BUFFER SPACE FOR EVENT REPORTING ; 3. IDS = 0, ESB+2=#PE.MJN - MAXIMUM TASKS IN SYSTEM EXCEEDED ; ERR1B: CMP #PE.TDB,ESB+2 ; TDB ACTIVE BNE ERRTCS MOV #IE.ACT,@DSWADR BR ERRTCS ; ; ERROR ON CLEAR EVENT FLAG ; ERROR ON MARK TIME ; ERR2: ERR4: TST DSWADR ; IS THERE ON IDS? BLE ERREX MOV $DSW,@DSWADR ; PASS ON DSW BR ERREX ; ; RUN$T FAILED ERR3: TST DSWADR ; IDS? BLT ERRTCS CMP #PE.BAD,ESB ; ESB IS PE.BAD OR PE.ABO BNE ERRRUN ; SUBLET PROCESS IF PE.ABO TST ESB+2 ; TEST 2ND WORD BEQ ERRTCS ; J IF ZERO MOV #IE.AST,@DSWADR ; PRIV VIOLATION BR ERRTCS ; ; THERE ARE NUMEROUS TASK PE.ABO RUN FAILURES: ; 1. IE.UPN = SCOM POOL SPACE EXHAUSTED ; 2. IE.INS = TASK NOT INSTALLED ; 3. ALL OTHER ERRORS ARE DESCRIBED ON PAGE 8-29 OF THE GUIDE TO ; WRITING A COMMAND LINE INTERPRETOR. THE VALUES OF T.ERR ; END T.ERR+2 ARE FOUND IN WORDS 4 & 5 OF IESB. ; ERRRUN: CMP #PE.UPN,ESB+2 ; POOL EXHAUSTED? BNE 10$ MOV #IE.UPN,@DSWADR BR ERRTCS 10$: CMP #PE.TNI,ESB+2 ; TASK NOT INSTALLED? BNE ERRTCS MOV #IE.INS,@DSWADR BR ERRTCS ; ERRTCS: TST RTNADR ; IS THERE AN IESB BLT ERREX ; J IF NOT MOV RTNADR,R0 ; R0 -> ESB MOV ESB,6(R0) ; PASS TCS ESB MOV ESB+2,10(R0) ERREX: SEC ; SET CARRY ON ERROR RETURN ; GO BACK TO LAST CALLER, WHOEVER? .END