/68 RTS-8 SMALL REAL TIME SYSTEM V3 /BASED ON T-O-Y JUNE 5, 1973 / /EDIT HISTORY: /RICHARD LARY LAST EDITED AUG 18, 1974 /SHAWN SPILLMAN EDITED THIS ON 14-SEP-74. /STANLEY RABINOWITZ EDITED THIS ON 5-APR-75 / ADDED PDP-12 SUPPORT / FIXED ANGLE BRACKET BUG OF SHAWNS /RICHARD LARY EDITED THIS ON 20-NOV-75 / ADDED KL8A SUPPORT AND RESCHED FUNCTION /RICHARD LARY EDITED THIS ON 28-DEC-75 / ADDED FREE-PARTITION OPTION TO WAITM, FIXING BUG / FIXED NON-RESIDENT TASK BUG IN FREEJ AND STOPJ /STANLEY RABINOWITZ EDITED THIS DURING SEP, OCT 1976 (V2B) / REMOVED KL8A SUPPORT (NOW IN KL8ASR.PA) / ADDED HELPER STUFF FOR KL8A INTERRUPT SKIP CHAIN / ADDED WAITX ER / ALLOWED RECEIVE TO FALL THROUGH IF NO MSG AND AC NEGATIVE / ZERO CERTAIN DECNET TABLES / FIXED RACE CONDITION IN SCHEDULER / #30 V2B CONVERSION TO MACREL / #31 FIX V2B POWER FAIL PROBLEM; YEAR / #32 CHANGE EAE CONDITIONALS, MQ, EAE, MQSV, EAESV / #33 KT8A CODE INSERTION, (NO BREAK INIT YET) / #34 .GLOBALS FOR TABLE REFERENCE, FIX WRAP / #35 TAKE OUT PDP8E CONDITIONAL, PUT IN OMNI INSTEAD / #36 TAKE MCREF OUT OF EXEC, TAKE OUT MORE PDP8E CONDITIONALS / #37 PUT NMTBL INTO EXEC, FIX GLOBAL, EXTERNAL TO MATCH, RTFLD / #38 MAKE TASKX A GLOBAL / #39 FIX TWO KT8A BUGS / #40 CONDITIONAL OUT OF ORDER / #41 GUARD SOME ['S WITH /'S / #42 CONTEXT FIXES (LN) / #43 MOVE KL8LOC GLOBAL / #44 ADDED RTFLD (SYMBIONT SUPPORT) S.R. / #45 FIXED CONDITIONAL BUG S.R. / TOOK OUT PAL8/MACREL CONDITIONALS, CLEANED UP CODE / (IN MOST CASES, CLEAN UP DOES NOT INCLUDE CHANGE BARS) / #46 TWO BUGS IN UNWRAP / #47 SLASHK FOR LINKAGE CONTROL / #48 GLOBALS FOR USE BY CLOCK (S.R.) / #50 BACK TO .FSECT LITERALS, LEVEL=0 / #51 CHANGE SWAPPER TO SWAP / #52 KL8A CHANGE, FIX PAGE OVRFLW ON 400 PAGE, SWAP ADJUSTMENT / #53 CHANGE LINKAGE TO SWAP / #54 LINK ERROR ON XFREE / #55 ODDS AND ENDS FOR SWAP / #56 MOVE SWPTAB TO SWAP MODULE / #57 CHANGE .SECT NAME FROM RTS8 / #58 SIZE OF NAME TABLE / #59 PUT KL8A BACK IN FOR PACKAGING REASONS, RTFLD TO MATCH SCRIPT / #60 MODIFY SWAPPER INIT / #61 CHANGED MCRZ TO MCRF1, FIXED POWER FAIL BUG / #62 CHANGED MCRF1 TO MC.RES / #63 ADDED KT BREAK MAP INIT J.R. / #64 GOT RID OF EXTRA GLOBAL, FIXED [ AFTER > IN KT CODE STAN / ADDED ARG CHECKING FOR CAL / #65 DRAW TABLE BACK IN / #66 TOOK OUT GENERATED LINK TO FIX BUG, FIXED RECEIVE STAN / #67 INCREASE POWER FAIL START-UP DELAY / #67 FIELD FLOAT NAME TABLE / #68 TAKE OUT VESTIGIAL *200; NULJOB TO RTS8 SECT / / / / / / / / / /COPYRIGHT (C) 1974,1975,1976,1977,1978,1979 BY DIGITAL EQUIPMENT CORPORATION / / / / / / / / / / /THE INFORMATION IN THIS DOCUMENT IS SUBJECT TO CHANGE WITHOUT NOTICE /AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT /CORPORATION. DIGITAL EQUIPMENT CORPORATION ASSUMES NO RESPONSIBILITY /FOR ANY ERRORS THAT MAY APPEAR IN THIS DOCUMENT. / /THE SOFTWARE DESCRIBED IN THIS DOCUMENT IS FURNISHED TO THE PURCHASER /UNDER A LICENSE FOR USE ON A SINGLE COMPUTER SYSTEM AND CAN BE COPIED /(WITH INCLUSION OF DIGITAL'S COPYRIGHT NOTICE) ONLY FOR USE IN SUCH /SYSTEM, EXCEPT AS MAY OTHERWISE BE PROVIDED IN WRITING BY DIGITAL. / /DIGITAL EQUIPMENT CORPORATION ASSUMES NO RESPONSIBILITY FOR THE USE /OR RELIABILITY OF ITS SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY /DIGITAL. / / / / / / / / / / XLIST 0 /LIST EXEC RTCDF=++ /CDF OR CIF TO EXEC FIELD RTGTS=+ /GTS WORD (GTF IS SUBSET) TO EXEC FIELD DCA SVSFLG /NULL JOB RUNS STATELESS JMP . /THIS IS IN SECT RTS8 ESTABLISHED IN PARAM FILE! /IOT'S FOR OPTIONAL HARDWARE: IFZERO OMNI < IFZERO PDP12 /HALT TO LET USER CLEAR FLAGS IFNZRO PDP12 /ISSUE I/O PRESET ON PDP-12 > IFNZRO OMNI /MACHINE WILL CLEAR FLAGS SINT= 6254 /SKIP ON USER INTERRUPT SUF= 6274 /SET USER MODE FLAG SPL= 6102 /SKIP ON POWER LOW LINC= 6141 /ENTER LINC MODE PDP= 2 /ENTER PDP-8/I MODE ESF= 4 /ENABLE SPECIAL FUNCTIONS IFNZRO KT8A < LXM= 6200 /SET CONTROL REGISTER GTS= 6210 /GET INTERRUPT STATE RTS= 6220 /RESTORE INTERRUPT STATE RACA= 6175 /BIT TWIDDLE CDF TO DATA FIELD RACB= 6176 /BIT TWIDDLE DATA FIELD TO INSTRUCTION FIELD RACC= 6177 /BIT TWIDDLE INSTRUCTION FIELD TO CDF KTINIT=5500 /DEFAULT, 64K AND THE BREAK MAP ON IFNZRO KTFLDS&7740 /MORE THAN 64K > / PHYSICAL PAGE 0 /// BELOW WAS DONE ON EDIT /// IFDEF PWRF < /// IFNZRO PWRFAL < /// .GLOBAL PFLADR /// .EXTERNAL PFLRTN /// >> IFNZRO RTFLD < IFDEF PWRF < .ASECT PWRF00, LEVEL=0 *0 0 /SET TO JMP PWRFKL ON POWER FAILURE CIF RTCDF JMP .-1 /GO TO FIELD OF RTS8 IFNZRO PWRFAL < PWRFKL, CIF CDF RTCDF JMP I PFLADR PFLADR, PFLRTN >> > IFNZRO RTFLD < IFNDEF PWRF < .ASECT RTS0, LEVEL=0 *0 0 CIF RTCDF JMP .-1 >> /PAGE 0 OF FIELD RTFLD .ASECT RTS8II, LEVEL=0 FIELD RTFLD *0 /INTERRUPT "VECTOR" 0 /SET TO JMP I 3 ON POWER FAILURE JMP I .+1 INTRPT IFZERO RTFLD < IFNZRO PWRFAL < PFLADR, PFLRTN >> .XSECT RTS8X, LEVEL=0 FIELD RTFLD XR, 0 /INDEX REGISTER USED BY EXEC .ASECT RTS8A0, LEVEL=0 FIELD RTFLD .GLOBAL TSWFLG,TODL,TODH,DATE,YEAR,TASKX,T .GLOBAL TFTABL,TSTABL /LET OTHERS GET AT TABLES IFNDEF SWAP < .GLOBAL MSGTBL > .GLOBAL CLKSKP,CLKMIS IFDEF SWAP < .EXTERNAL SWINIT,XFREE,MSGTBL /INIT AND FREE IN SWAPPER > IFDEF MCR < .GLOBAL NMTBL / > *20 LOC20, 0 /MONITOR CALL LOCATION ** MUST BE AT 20 ** DCDF, CDF RTCDF CALIOF, IOF JMP I CALEXC DSPOST /** MUST BE AT LOC 24 ** XWAITM /** MUST BE AT LOC 25 ** CALEXC, EXEC /** MUST BE 400 ** ACARG, 0 /HOLDS AC ARG ON EXEC CALLS MPTR, ION /POINTS TO FIRST WORD OF MESSAGE Q POINTER MPT2, JMP I ACARG /" " SECOND " " TASKX, 0 /CURRENT TASK NUMBER INTT, 0 /INTERRUPT-LEVEL TEMPORARY SVSFLG, -1 /SAVE STATE FLAG - /-1 MEANS CPU STATE COUNTS & SHOULD BE SAVED, /0 MEANS CPU STATE IS UNIMPORTANT. TSWFLG, 1 /TASK SWITCHING INHIBITED FLAG - / 1 = TASK SWITCHING ALLOWED / 0 = TASK SWITCHING INHIBITED /-1 = TASK SWITCHING INHIBITED, RESCAN ASAP TODL, 0 /TIME-OF-DAY LOW ORDER TODH, 0 /TIME-OF-DAY HIGH ORDER DATE, TSTCLK /DATE WORD - USED TO INIT CLOCK HANDLER /PROBABLY NO LONGER NEEDED, SHOULD CHECK T, 0 /NON-INTERRUPT LEVEL TEMPORARY IFDEF SWAP < .GLOBAL COMMAND COMMAND, SWINIT /CALL SWAPPER INIT CODE /HOLDS FREE-PARTITION FLAG IN SIGN BIT / SWAPPER STARTS INIT WHEN IT RUNS > YEAR, 0 /YEAR-1970 FOR EXTENDED DATE ECDIF0, CDF CIF 0 /HELP OVERFLOW ON 400 PAGE ECDF0, CDF 0 /MORE FOR PAGE 400 /SET UP EXEC LINKAGE IN FIELDS 1-37 RN=RTFLD+1 /RUNNING FIELD NUMBER XLIST .REPT SLASHK+1-RN .ASECT RAF\RN, LEVEL=0 FIELD RN *20 0 CDTEMP=<++> CDF CDTEMP CIF RTCDF JMP CALIOF DSPOST XWAITM RN=RN+1 .ENDR XLIST /INTERRUPT ROUTINE .ASECT RTS8EX, LEVEL=0 FIELD RTFLD *200 IFZERO RTFLD < .START 200,RTFLD > TS8LOC, CAFHLT /SO WE CAN START AT 200 IFNZRO TS8LOC-200 /OS8SUP NEEDS THIS HERE IFNZRO KT8A < TAD (KTINIT /START UP THE KT8A (STILL NEED BREAK INIT!) LXM /MAP ENABLED IF GREATER THAN 32K, VRDF ENABLED JMS I (BRKINI /ENTER FSECT TO DO BREAK MAP INIT NOW > IFDEF SWAP < /INIT THE SWAPPER JMS I COMMAND /ADDR PLACED HERE BY LINKER > NEWTSK, ION INTFGS, JMP I .+1 /GO AND FIND THE FIRST INTAC, FINDJ /TASK TO RUN INTRPT, IFDEF OS8 < SINT /MUST BE FIRST SKIP IN INTERRUPT CHAIN! SKP JMP I TS8LOC > DCA INTAC /SAVE AC IFZERO KT8A < /NO KT8A, DO THE OLD WAY IFNZRO OMNI IFZERO OMNI < RAR /COMBINE LINK, IF AND DF INTO ONE WORD RIB > > IFNZRO KT8A < GTS /LINK, USERMODE, DF AND IF > DCA INTFGS IFNZRO RTFLD < CDF 0 TAD I (0 DCA 0 /MOVE UP PC > USERSK, /VERY HIGH PRIORITY USER FLAG TESTS GO HERE IFNZRO KL8A /KL8A INTERRUPT DISPATCHER IFZERO KL8A-2 /NOP IS FASTER THAN '0' IFZERO KL8A-3 IFNZRO PWRFAL /SKIP ON POWER LOW JMP TSTCLK /NO MORE H.P. SKIPS - GO TO SKIP CHAIN IFNZRO PWRFAL < IFZERO EAE < IFNZRO MQ < MQA /IF JUST MQ, SAVE IT SIMPLE WAY DCA I (PWSAV > > IFNZRO EAE < TAD (PWSAV-1 /SET POINTER TO SAVE AREA DCA XR /INTERRUPT LEVEL POINTER JMS I (WRAP /SAVE WHOLE EAE > TAD 0 DCA INTT /SAVE LOCATION ZERO IFZERO RTFLD < TAD (JMP I PFLADR DCA 0 /SET UP 0 FOR RESTART > IFNZRO RTFLD < CDF 0 TAD (JMP PWRFKL DCA I (0 CDF CUR > / /REMOVING SAVE CODE TO WRAP AND UNWRAP PWHLT, HLT /DON'T TRY ANYTHING FANCY > BSKCHN, DISMIS /BEGINNING OF SKIP CHAIN LIST TSTCLK, CDF CIF RTCDF /ADDRESS FOLLOWED BY CDF CIF FIELD CLKSKP, NOP /SET TO CLSK BY CLOCK ROUTINE JMP I BSKCHN DCDIF0, CDF CIF RTCDF /CLOCK HANDLER ALWAYS IN FLD 0 JMP I .+1 CLKMIS, DISMIS /CHANGED BY CLOCK HANDLER (IF ANY) .SBTTL POST EVENT FLAG AND DISMISS /SUBROUTINE TO POST AN EVENT FLAG AND DISMISS FROM INTERRUPTS /ENTER WITH IOF, DF=D.F. OF EVENT FLAG, AC=ADDRESS OF EVENT FLAG DSPOST, SNA JMP DISMIS /NO EVENT FLAG - JUST DISMISS DCA INTT AC4000 TAD I INTT /LINK=1 IF EVENT FLAG.LT.0, 0 IF.GT.0 DCA NEWTSK /SAVE OLD VALUE OF EVENT FLAG DCA I INTT /ZERO EVENT FLAG TO INDICATE EVENT COMPLETION TAD NEWTSK SPA /** LINK MUST BE 0 HERE IF AC IS NEGATIVE ** JMP .+3 /IF E.F. .LT. 0, TASK WAS WAITING FOR EVENT JMS I (FREEJ /SO CLEAR "EVENT WAIT" BIT IN FLAG WORD. EFWT!EORMWT /IF THE TASK WHICH WAS WAITING ON THIS SNL CLA /EVENT FLAG IS HIGHER PRIORITY THAN THE TASK JMP DISMIS /CURRENTLY RUNNING, SUSPEND THE CURRENT TASK IFZERO KT8A < TAD 0 /UNLESS WE ARE IN A NON-INTERRUPTABLE ZONE IFDEF OS8 /(NAMELY LOCS 0-77 OF A FIELD AND (7700 /NOT USED BY OS/8 BACKGROUND) SZA CLA /OR TASK SWITCHING HAS BEEN SPECIFICALLY > IFNZRO KT8A < IFDEF OS8 < RIB /CHECK IF IN USER MODE AND (100 /LEAVING AC=100 IF WE WERE > TAD 0 /ADD IN INTERRUPTED PC TAD (7700 /CARRY TO LINK IF INTERRUPTABLE!!! SNL CLA /SKIP IF CAN'T BE INTERUPTED > TAD TSWFLG /INHIBITED BY THE SOFTWARE SMA SZA CLA /(BY MAKING TSWFLG LE 0) JMP STOPJ STA /IF TASK SWITCHING IS INHIBITED, DCA TSWFLG /SET FLAG TO INSURE A RESCAN OF THE TASK LIST JMP DISMIS /WHEN WE UNINHIBIT IT, THEN DISMISS NORMALLY. .SBTTL STOPJ STOPJ, ISZ SVSFLG /IS THE STATE OF THE CURRENT TASK WORTH SAVING? JMP NOSVST /NO - FORGET IT. TAD TASKX CLL RTL IFNZRO EAESV < /FIFTH TABLE ENTRY TO SAVE EAE TAD TASKX /SO MULTIPLY BY 5 > TAD (TSTABL-1 DCA XR /SAVE THE CURRENT TASK'S STATE TAD INTFGS DCA I XR TAD 0 DCA I XR TAD INTAC DCA I XR IFZERO EAESV < /GO TO WHOLE THING ON EAESV IFNZRO MQSV < MQA DCA I XR /SAVE THE MQ > > IFNZRO EAESV < JMS I (WRAP /PACKAGE WHOLE THING > NOSVST, TAD NEWTSK /SET THE CURRENT PRIORITY TO THAT OF THE DCA TASKX /HIGHER PRIORITY TASK AND ATTEMPT TO START IT. ION /ENABLE INTERRUPTS WITH THE "DON'T SAVE STATE" /FLAG ON TO ALLOW FURTHER RESCHEDULING IFDEF SWAP < / TAD NEWTSK /FORM A POINTER TO THE TASK FLAGS WORD / TAD (TFTABL /OF THE NEW TASK / DCA INTT /AND STORE IT IN INTT /(ACTUALLY "FREEJ" DID IT FOR US) /**NOTE** IF YOU ENABLE THE PRECEDING 3 LINES, DON'T USE INTT! TAD I INTT /GET TASK FLAGS WORD /(INTERRUPTS COME ON N O W !) SZA CLA /IF ITS 0 (RUNNABLE) THEN RUN IT JMP I (FINDJ /IF ITS 4000 THEN GO SCHEDULE SWAPPER > /THIS MEANS THAT IF ANYBODY WITH HIGHER PRIORITY THAN "NEWTSK" /GETS AN EVENT-FLAG-SETTING INTERRUPT NOW, WE'LL JUST DASH OFF /AND START HIM INSTEAD. .SBTTL STARTJ /CODE TO START UP A TASK /ENTER WITH TASK# IN "TASK", DF=0, ION, NO STATE (SVSFLG=0) STARTJ, IFZERO HGHFLD /INTERRUPTS ALREADY ON IF CIF WORKS TAD TASKX CLL RTL IFNZRO EAESV < /FIFTH TABLE ENTRY TO SAVE EAE TAD TASKX /SO MULTIPLY BY 5 > TAD (TSTABL-1 /FORM POINTER INTO TASK STATE TABLE DCA XR STA IOF /OK, THINGS ARE GETTING SENSITIVE - TURN INTS OFF DCA SVSFLG /AND RESET SAVE-STATE FLAG TO "YES" TAD I XR DCA INTFGS TAD I XR DCA 0 /SIMULATE AN INTERRUPT FROM THE TASK TAD I XR DCA INTAC /AND DISMISS IT IFZERO EAESV < /EAESV, UNWRAP DOES ALL IFNZRO MQSV < TAD I XR MQL /RESTORE MQ > > IFNZRO EAESV < / /UNWRAP DOES IT JMS I (UNWRAP /TO PROPER PLACES > /** NOW FALL INTO "DISMIS" ON NEXT PAGE ** .SBTTL DISMISS /INTERRUPT DISMISS ROUTINE - ALSO USED TO START TASKS DISMIS, IFNZRO OMNI < SRQ /ANY OTHER INTERRUPTS PENDING? SKP /NO JMP USERSK /YES - SKIP PREAMBLE STUFF FOR EXTRA SPEED > IFZERO KT8A < /NO KT8A, DO THE OLD WAY TAD INTFGS IFNZRO OMNI < IFNZRO HGHFLD IFZERO HGHFLD /RTF DOESN'T WORK RIGHT ON 4K 8E'S CLA > IFZERO OMNI < IFDEF OS8 < TAD (700 /PROPAGATE USER-MODE BIT FROM BIT 5 TO BIT 2 > CLL RTL RAL /USER-MODE BIT NOW IN LINK AND (70 /FAKE AN RTF IF NOT ON A OMNIBUS TAD ECDF0 /LITERAL CDF 0 IN PAGE 0 DCA DISCDF IFDEF OS8 < SZL /IF USER MODE WAS ON WHEN WE INTERRUPTED, SUF /TURN IT ON WHEN WE DISMISS > AC4000 TAD INTFGS AND (70 /NOTE THAT THE LINK IS NOW RESTORED TAD (CIF 0 DCA DISCIF DISCIF, 0 DISCDF, 0 > TAD INTAC IFZERO -PDP8E&HGHFLD /FOR PRE 8E OR 4K 8E MACHINES > IFNZRO KT8A < AC4000 /RTS DOESN'T PUT BACK LINK, SO TAD INTFGS /THE TAD DOES IT BY CARRY RTS /PUTS BACK DF NOW; CLA; IF AND USER ON NEXT JMP TAD INTAC /BRING BACK THE AC ION /RTS DOESN'T TURN INTERRUPTS ON, (BUT THEY / /ARE DISABLED THRU THE JMP I 0) > JMP I 0 IFNZRO PDP12 < IOPRST, 0 TAD (20 / I/O PRESET BIT IN SPECIAL FUNCTIONS REGISTER LINC /ENTER LINC MODE ESF /ENABLE SPECIAL FUNCTION PDP /BACK TO 8-MODE CLA JMP I IOPRST > PAGE .SBTTL EXECUTIVE /RTS-8 EXECUTIVE - PROCESSES USER REQUESTS /CALLED BY: JMS 20 /IN ANY FIELD / ARGS / /CODE AT LOC 20 TURNS IOF, DOES CDF CUR AND CIF 0 AND JUMPS HERE EXEC, DCA ACARG /SAVE POSSIBLE AC ARGUMENT TAD TSWFLG /TSWFLG=1 HERE UNLESS WE WERE INTERRUPTED SMA CLA /WHEN WE WERE IN THE PAGE 0 CODE, IN WHICH CASE DCA TSWFLG /ITS -1 - ZERO IT IF IT WAS 1 ION /IT IS NOW OK TO TURN INTERRUPTS BACK ON RDF TAD ECDIF0 DCA EXRET /SAVE RETURN FIELD TAD I (LOC20 /GET LOC 20 OF THE CALLING FIELD DCA LOC20 /SAVE IT IN FIELD 0 IFDEF SWAP < TAD I LOC20 /SAVE A COPY OF THE COMMAND FOR LATER DCA COMMAND /IN CASE HE WANTS TO "FREE" > AC3777 AND I LOC20 /GET COMMAND MINUS WAIT BIT ISZ LOC20 TAD (-15 /RANGE CHECK SMA JMP I (ERR /CAL ARG OUT OF RANGE TAD CMDJMP /BUILD JMP I DCA TMP$ /WATCH IT! CALLER'S DATA FIELD MUST BE PASSED ON! TMP$: . CMDJMP, JMP I .+1+15 /MOVE 15 TO CANCEL TEST $SEND /SEND MESSAGE TO A TASK $RECEIV /GET A MESSAGE FROM THE MESSAGE QUEUE $WAITE /WAIT FOR AN EVENT FLAG TO BE POSTED $RUN /RUN A TASK (IF NOT BEING RUN) $SUSPND /SUSPEND EXECUTION OF A TASK $POST /POST AN EVENT FLAG $SKPINS /INSERT SKIP INTO INTERRUPT CHAIN $DERAIL /DERAIL A TASK $BLKARG /BLOCK TASK FOR REASON SPECIFIED BY ARG $SENDW /SEND MESSAGE AND WAIT FOR COMPLETION $UNBARG /UNBLOCK TASK FOR REASON SPECIFIED BY ARG $RESCHD /FORCE A RESCHEDULE $WAITX /WAIT FOR EXACTLY THIS EVENT FLAG .SBTTL RUN - SCHEDULE A TASK TO RUN $RUN, TAD (RUNWT JMP I (UNBLOK .SBTTL DERAIL /ROUTINE TO DERAIL A TASK'S EXECUTION INTO A SUBROUTINE $DERAIL,TAD I LOC20 ISZ LOC20 DCA T /SAVE ADDR OF DERAIL SUBR JMS I (ARGCHK /GET AC CLL RTL IFNZRO EAESV < /FIFTH TABLE ENTRY TO SAVE EAE TAD ACARG /SO MULTIPLY BY 5 > TAD (TSTABL /GET POINTER INTO TASK STATE TABLE DCA MPTR CDF RTCDF TAD I MPTR IFZERO KT8A < AND (70 /GET INSTRUCTION FIELD > IFNZRO KT8A < RACC /BITS FROM IF FORMAT TO CDF FORMAT > TAD ECDF0 /LITERAL CDF 0 ON PAGE 0 DCA C$ ISZ MPTR TAD I MPTR /GET CURRENT TASK PC C$: HLT /CDF TO TASK FIELD DCA I T /STORE PC IN SUBR HEADER CDF RTCDF TAD T IAC DCA I MPTR /SET PC TO SUBR HEADER + 1 JMP EXRET /RETURN TO CALLING TASK .SBTTL SKPINS - INSERT INTO SKIP CHAIN /INSERT A DEVICE SKIP INTO THE INTERRUPT CHAIN $SKPINS,TAD I LOC20 /GET THE ADDRESS OF THE SKIP - 2 ISZ LOC20 DCA T TAD I T SZA CLA /IF ARGUMENT LOC IS NON-ZERO, JMP EXRET /IT IS ALREADY IN THE SKIP CHAIN - IGNORE TAD (DISMIS /CHAIN IT TO THE END OF THE CHAIN DCA I T ISZ T TAD ECDIFL DCA I T IFNZRO HGHFLD < TAD EXRET /GET CDF TO NEW "LAST SKIP" INTCDF, CDF CIF RTCDF /CDF TO FLD OF OLD "LAST SKIP" AND INH INTS /**NOTE: THE IF IS NOW GARBAGE /DO NOT JUMP ANYWHERE! DCA INTCDF /UPDATE "LAST SKIP" FIELD TO NEW ONE > TAD T DCA I INTEND /CHAIN OLD SKIP TO NEW ONE ISZ INTEND IFNZRO HGHFLD < TAD INTCDF > DCA I INTEND STA TAD T DCA INTEND /UPDATE POINTER TO END OF SKIP CHAIN /FALLING INTO EXRET FIXES INSTRUCTION FIELD EXRET, HLT /CDF CIF RETURN FIELD (ALSO INHIBIT INTERRUPTS) IFZERO HGHFLD /INTERRUPTS OFF FOR ISZ! ISZ TSWFLG /ALLOW TASK SWITCHING (SKIPS IF RESCAN NECESSARY) IFZERO HGHFLD < JMP .+3 /NO RESCAN NECESSARY ION /TASK SWITCHING STILL INHIBITED, TURN ION AND JMP ECDIFL /STOP CURRENT JOB AND GO TO RESCAN ION /NOW ITS SAFE TO TURN INTERRUPTS BACK ON > JMP I LOC20 /RETURN TO CALLING TASK ECDIFL, CDF CIF RTCDF /OOPS - WE MUST TASK SWITCH IMMEDIATELY! JMP I (TSTOP /GO STOP THIS TASK AND RUN SOMEONE ELSE INTEND, BSKCHN / /MOVE TO PAGE 0 .SBTTL FINDJ IFNDEF SWAP < /RTS-8 SCHEDULER - SCANS TASK FLAGS TABLE TO DETERMINE HIGHEST /PRIORITY RUNNABLE TASK - RUNS WITH INTERRUPTS ON (SOMETIMES) /AND IS STATELESS. FINDJ, CLA CLL IAC /CODE TO FIND FIRST RUNNABLE TASK DCA TASKX /INITIALIZE TASK NUMBER DCA SVSFLG /THE MACHINE STATE IS NOW UNIMPORTANT CLA IAC /AND WE SHOULD RE-ENABLE TASK SWITCHING DCA TSWFLG /SO THAT IF A TASK BECOMES RUNNABLE TAD (TFTABL /AFTER WE SCAN IT, IT WILL INTERRUPT DCA XR /THE SCAN LOOP AND RUN. FINDJL, IFNZRO HGHFLD /AS WE SEARCH A TASK'S ENTRY IN THE LIST, IFZERO HGHFLD TAD I XR /WE ASSUME THAT TASK'S PRIORITY SNA CLA /LOOK FOR FIRST TABLE ENTRY OF 0 JMP I (STARTJ /(THERE HAS TO BE ONE - NAMELY THE NULL TASK) IFZERO HGHFLD ISZ TASKX /BUMP THE TASK NUMBER (AND PRIORITY) /ALLOW INTERRUPTS FOR ONE CYCLE SINCE JMP FINDJL /"TASKX" IS BIGGER THAN CURRENT REJECTED TASK > IFDEF SWAP < /RTS-8 SCHEDULER - SCANS TASK FLAGS TABLE TO DETERMINE HIGHEST /PRIORITY RUNNABLE TASK - RUNS WITH INTERRUPTS ON (SOMETIMES) /AND IS STATELESS. /THIS SCHEDULER, USED WITH THE SWAPPER, IS SLIGHTLY /SLOWER THAT THE PREVIOUS SCHEDULER, USED WITHOUT THE SWAPPER. /NOTE: THIS ROUTINE IS VERY PRONE TO RACE CONDITIONS. /DO NOT MODIFY IT UNLESS YOU VERY CAREFULLY CHECK OUT WHAT /MIGHT HAPPEN IF AN INTERRUPT OCCURS AFTER EACH STATEMENT ACTION, SNL /IS HE NONRESIDENT? JMP I (STARTJ /NO: START HIM UP IFNZRO EXEC-SWPWT /CALEXC.NE.SWPWT TAD CALEXC /AC='SWPWT' / /BUG FIX, INTERRUPT HERE, SWAPPER NEVER GETS / /WOKEN UP IFZERO HGHFLD IFNZRO HGHFLD DCA I NXR /PUT HIM IN SWAP WAIT TAD (-RUNWT-1 AND I (SWAP+TFTABL DCA I (SWAP+TFTABL /TAKE SWAPPER OUT OF RUN WAIT /GO FIND SOMEONE ELSE; HOPEFULLY SWAPPER /** NOTE: AC MAY BE NON-ZERO ON ENTRY ** FINDJ, CLA IAC /CODE TO FIND FIRST RUNNABLE TASK DCA TASKX /INITIALIZE TASK NUMBER DCA SVSFLG /THE MACHINE STATE IS NOW UNIMPORTANT /IN CASE WE ARE TASK-SWITCHED OUT OF THE SCAN LOOP /WE WILL NOT SAVE STATE CLA IAC /NOW (NOT EARLIER) WE CAN RE-ENABLE TASK SWITCHING DCA TSWFLG /SO THAT IF A TASK BECOMES RUNNABLE TAD (TFTABL /AFTER WE SCAN IT, IT WILL INTERRUPT DCA NXR /THIS SCAN LOOP AND RUN FINDJL, IFNZRO HGHFLD /AS WE SEARCH A TASK'S ENTRY IN THE LIST IFZERO HGHFLD ISZ NXR /(BUMPING TO NEXT ENTRY) TAD I NXR /WE ASSUME THAT TASK'S PRIORITY CLL RAL /PUT NON-RESIDENT BIT INTO LINK SNA CLA /LOOK FOR THE FIRST TABLE ENTRY OF 0 JMP ACTION /FOUND ONE, START HIM UP IFZERO HGHFLD ISZ TASKX /BUMP THE TASK NUMBER (AND OUR PRIORITY) JMP FINDJL /ALLOW INTERRUPTS FOR ONE CYCLE SINCE /'TASK' IS BIGGER THAN CURRENT REJECTED TASK /WE MAY RESCHEDULE OUT OF HERE NXR, 0 > PAGE .SBTTL SEND - SEND A MESSAGE .SBTTL SENDW - SEND AND WAIT /SEND A MESSAGE TO A TASK / ***** N O L I T E R A L S O N T H I S P A G E ! $SENDW, STA /SET OR $SEND, DCA SWTFLG /CLEAR WAIT FLAG TAD I LOC20 ISZ LOC20 /GET THE DCA ACARG /TASK NUMBER FROM THE ARGUMENT LIST TAD I LOC20 /GET THE ADDRESS OF THE MESSAGE DCA MSGADR TAD I MSGADR SNA CLA /IS THE MESSAGE ALREADY IN A QUEUE? JMP MSGFRE /NO AC7775 TAD LOC20 DCA LOC20 /BUMP PC BACK TO DO CALL AGAIN MSEFWT, TAD MSGADR JMP I PWAITS /WAIT FOR MESSAGE TO BE FREE MSGFRE, ISZ LOC20 JMS I PARGCHK /GET THE ADDRESS OF THE TARGET TASKS' JMS SRCOMN /MESSAGE QUEUE POINTER DCA MSGCDF /SAVE CDF TO NEW MESSAGE'S FIELD TAD CDFL ADDTOQ, DCA MPTCDF /SAVE CDF TO FIELD OF CURRENT QUEUE POINTER CLA IAC TAD MPTR DCA MPT2 /GET POINTER TO SECOND WORD OF POINTER TAD I MPT2 DCA T /SAVE ADDRESS OF NEXT QUEUE ENTRY TAD I MPTR /FIRST WORD IS A CDF SNA /ZERO TERMINATES THE QUEUE JMP ENDOFQ DCA NXTCDF /SAVE CDF RCVPTR, NXTCDF, HLT AC3777 AND I T /FIRST WORD OF MESSAGE HEADER IS TASK# CIA CLL /COMPARE TO NUMBER OF SENDING TASK TAD TASKX /IF NUMBER IS LOWER WE INSERT SNL CLA /THE MESSAGE BEFORE THIS ONE JMP ENDOFQ CLA IAC TAD T DCA MPTR /OTHERWISE GO ON TO THE NEXT TAD NXTCDF /QUEUE ENTRY JMP ADDTOQ PARGCHK,ARGCHK /COME HERE WHEN WE HAVE FOUND THE PLACE TO INSERT THE MESSAGE ENDOFQ, MPTCDF, HLT /SET DF TO FIELD OF PREVIOUS POINTER TAD I MPTR DCA MPTCDF /SAVE PREVIOUS CDF TAD MSGCDF /LINK THE NEW MESSAGE BETWEEN TWO DCA I MPTR /EXISTING MESSAGES ON THE QUEUE TAD MSGADR DCA I MPT2 /OK - HALF THE LINKAGE IS DONE IOF /MUST TURN INTERRUPTS OFF TO CALL FREEJ! TAD ACARG JMS I PFREEJ /CLEAR MESSAGE WAIT BIT FOR RECEIVER MSGWT!EORMWT /(DO IT NOW SO DF WILL BE CORRECT LATER) TAD TASKX /*** CODE IN THIS RANGE MUST NOT TOUCH LINK *** MSGCDF, HLT /* NOW GO TO THE MESSAGE'S DATA FIELD ION /* WE'RE SAFE - TURN INTERRUPTS ON DCA I MSGADR /* STORE THE SENDING TASK NUMBER ISZ MSGADR /* TAD MPTCDF /* DCA I MSGADR /* STORE CDF TO NEXT MESSAGE IN Q ISZ MSGADR /* TAD T /* DCA I MSGADR /* STORE ADDRESS OF NEXT MESSAGE IN Q ISZ SWTFLG /* SHOULD WE WAIT ON THIS MESSAGE? JMP I PPOSTEX /* NO - RUN RECEIVER IF ITS /* HIGHER PRIORITY, ELSE EXIT AC7776 /DON'T WORRY ABOUT RECEIVER - /WAITING WILL FORCE RESCAN OF TASK LIST - JMP MSEFWT /GO WAIT ON MESSAGE EVENT FLAG /** DF MUST BE SET TO CALLER'S FIELD HERE ** SRCOMN, 0 /SUBROUTINE USED BY SEND AND RECEIVE CLL RAL /GET POINTER TO A TASK'S TAD PMSGTBL /MESSAGE QUEUE POINTER DCA MPTR CDFL, CDF RTCDF AC7776 TAD I PEXRET JMP I SRCOMN .SBTTL RECEIVE-RECEIVE A MESSAGE /RECEIVE A MESSAGE FROM THE TASK'S MESSAGE QUEUE $RECEIV,TAD TASKX JMS SRCOMN /GET THE MESSAGE QUEUE PTR FOR THIS TASK DCA STOCDF /SAVE CDF TO CALLING FIELD TAD CDFL RCVLP, DCA PRVCDF /SAVE PREVIOUS Q ENTRIES' FIELD TAD I MPTR /GET MESSAGE QUEUE POINTER SNA /IF ZERO, THERE ARE NO MESSAGES IN THE Q JMP NOMSG /SO HANG THE TASK DCA CHNCDF CLA IAC TAD MPTR DCA MPT2 /GET POINTER TO SECOND WORD OF Q POINTER TAD I MPT2 DCA RCVPTR SWTFLG, CHNCDF, HLT /CDF TO FIELD OF Q ENTRY JMS I .+1 /PATCH CHK377 CIA SZA /IS RECEIVER DEDICATED TO ANYONE? TAD I RCVPTR /YES - CHECK ORIGIN OF THIS MESSAGE ISZ RCVPTR CLL RAL /HIGH-ORDER BIT (WAIT BIT) IRRELEVANT SNA CLA /CAN THIS MESSAGE BE RECEIVED? JMP RCVOK /YES - PASS IT ON TAD RCVPTR /NO - CHAIN TO NEXT MESSAGE IN Q DCA MPTR TAD CHNCDF JMP RCVLP RCVOK, TAD I RCVPTR /GET FIRST WORD OF ENTRY DCA T ISZ RCVPTR TAD I RCVPTR PRVCDF, HLT /SET FIELD OF PREVIOUS Q ENTRY DCA I MPT2 /SET PREV Q ENTRIES' POINTER (BOTH WORDS) TAD T /TO THE CONTENTS OF THIS Q ENTRIES' DCA I MPTR /POINTER, REMOVING THIS ENTRY FROM THE Q CLA IAC /FORM A POINTER TO THE FIRST WORD OF TAD RCVPTR /INFORMATION IN THE REMOVED MESSAGE MSGADR, STOCDF, HLT DCA I LOC20 /AND STORE IT IN THE FIRST ARGUMENT TAD CHNCDF /RETURN WITH CDF TO MESSAGE IN AC STOCD2, ISZ LOC20 /SKIP ARG JMP I PEXRET /LITERALS: PWAITS, WAITS PFREEJ, FREEJ PPOSTEX,POSTEX PMSGTBL,MSGTBL PEXRET, EXRET NOMSG, TAD ACARG /LOOK AT AC AGAIN SPA CLA /DID USER WANT TO WAIT IF NO MESSAGE? JMP STOCD2 /NO /YES, FLOW INTO WAITM3 IFNZRO .&1000 /PAGE TOO BIG /WAIT FOR MESSAGE WAITM3, AC7776 TAD LOC20 DCA LOC20 /MOVE PC BACK TO "JMS 20" STL /SET LINK TO PRESERVE AC ACROSS "TSTOP" TAD (MSGWT /BLOCK TASK ON MESSAGE WAIT /COME HERE WITH BLOCKING BITS IN AC. /TASK AC WILL BE CLEARED IF LINK IS 0, PRESERVED IF LINK IS 1 TSWAIT, DCA BLKMSK /ENTER HERE WITH BLOCKING BITS IN AC TSWATX, TAD TASKX /ENTER HERE WITH BLOCKING BITS IN "BLKMSK" TAD (TFTABL /GET INDEX INTO JOB FLAGS TABLE. DCA T TAD BLKMSK /GET BLOCKING BITS CDF RTCDF DCA I T /NO NEED TO OR THEM IN - WORD WAS ZERO BEFORE. ION /(IN CASE WE CAME FROM "WAITE" OR "WAITM") SNL /SHOULD WE CLEAR TASK AC? TSTOP, DCA ACARG /ENTER HERE WITH TASK AC IN AC $RESCHD,TAD TASKX /TO STOP THE CURRENT TASK BUT NOT BLOCK IT. CLL RTL /GET A POINTER INTO THE TASK'S STATE TABLE ENTRY IFNZRO EAESV < /FIFTH TABLE ENTRY TO SAVE EAE TAD TASKX /SO MULTIPLY BY 5 > TAD (TSTABL-1 DCA XR CDF RTCDF IFNZRO HGHFLD < TAD I (EXRET IFZERO KT8A < CLL RAR RTR TAD I (EXRET TAD (-5023 /5023 = 6203 + (6203 SHIFTED RIGHT 3) > IFNZRO KT8A < RACA /BITS TO FORM OF DATA FIELD DCA T /SAVE; 99% SURE CAN USE T AS TEMPORARY HERE TAD T /DATA FIELD FBITS RACB /BITS IN FORM OF INSTRUCTION FIELD TAD T /DATA FIELD AND INSTRUCTION FIELD > > DCA I XR /STORE RETURN IF AND DF=IF TAD LOC20 DCA I XR /STORE RETURN PC TAD ACARG DCA I XR /STORE RETURN AC IFZERO EAE < IFNZRO MQSV < MQA /EVEN PRESERVE THE MQ OVER MONITOR CALLS DCA I XR /(WHAT THE HECK, ITS ONLY 2 INSTRUCTIONS) > > IFNZRO EAESV < JMS I (EWRAP /EWRAP DOES IOF, CALLS WRAP, DOES ION > IFDEF SWAP < TAD COMMAND SPA CLA /FREE THE PARTITION? WIPCAL, JMS I (XFREE /YES: LET SWAPPER CODE DO IT > JMP I (FINDJ /NO: FIND NEXT TASK TO RUN $UNBARG,TAD I LOC20 /UNBLOCKING CODE IN ARGUMENT ISZ LOC20 .SBTTL UNBLOK -UNBLOCK A TASK UNBLOK, DCA MSK$ /AC CONTAINS REASON FOR UNBLOCKING TASK "ACARG" JMS I (ARGCHK IOF /FREEJ IS AN INTERRUPT-LEVEL ROUTINE! JMS FREEJ /REMOVE THE GIVEN BLOCKING BIT MSK$: 0 ION POSTEX, SNL CLA /SHOULD THE NEW TASK BE RUN NOW? JMP I (EXRET /NO JMP TSTOP /YES-PUT TASK TO SLEEP WITHOUT BLOCKING IT .SBTTL SUSPND -SUSPEND A TASK /SUSPEND EXECUTION OF A TASK $SUSPND,TAD (RUNWT JMP BLOK $BLKARG,TAD I LOC20 /BLOCKING CODE IN ARGUMENT ISZ LOC20 BLOK, DCA BLKMSK /SAVE BLOCKING CODE JMS I (ARGCHK /GET TASK TO BE BLOCKED SNA JMP TSWATX /0 MEANS CURRENT TASK! / ^ NOTE THE LINK IS RANDOM HERE BUT SINCE ACARG=0 / IT DOESN'T MATTER IF WE CLEAR IT OR NOT CDF RTCDF TAD (TFTABL DCA T TAD BLKMSK /GET THE BLOCKING FLAG(S) CMA AND I T TAD BLKMSK /OR THEM INTO THE TASK FLAG WORD DCA I T JMP I (EXRET /THIS DOESN'T AFFECT US - JUST RETURN .SBTTL FREEJ /ROUTINE TO UNBLOCK A TASK'S EXECUTION /ENTER WITH TASK# IN AC, INTERRUPTS OFF, UNBLOCKING BIT IN CALL+1 FREEJ, 0 CDF RTCDF TAD (TFTABL DCA INTT TAD I FREEJ /GET UNBLOCKING BIT ISZ FREEJ /BUMP RETURN POINTER CMA AND I INTT DCA I INTT /REMOVE THE FLAG FROM THE TASK FLAG WORD TAD I INTT IFDEF SWAP < CLL RAL /IGNORING NON-RESIDENT WAIT, > SNA CLA /IF THE TASK IS NOW RUNNABLE TAD TASKX /AND HAS A HIGHER PRIORITY THAN THE CURRENTLY TAD (TFTABL /RUNNING TASK, RETURN WITH THE LINK ON. CIA STL TAD INTT CLA /OTHERWISE RETURN WITH THE LINK OFF. JMP I FREEJ .SBTTL WAITE - WAIT FOR EVENT FLAG .SBTTL WAITX - WAIT FOR EXACTLY THIS EVENT FLAG /WAIT FOR EVENT FLAG $WAITX, STA /USE 'ACARG' AS FLAG (-1 INDICATES WAITX) $WAITE, DCA ACARG TAD I LOC20 /GET ADDRESS OF EVENT FLAG ISZ LOC20 /SEND HAS ACARG RANDOM BUT NOT -1 WAITS, DCA T /ENTER HERE FROM SEND IFZERO HGHFLD /INHIBIT INTERRUPTS IFNZRO HGHFLD /WHILE TESTING FLAG! TAD I T /EVENT FLAG IS IN SAME FIELD AS CALL SNA CLA /ZERO MEANS EVENT COMPLETED JMP I (EXRET /SO EXIT IMMEDIATELY IFNZRO HGHFLD /INTERRUPTS MUST BE OFF BETWEEN SETTING EF /AND SETTING EF WAIT! AC4000 /SET EVENT FLAG TO TASK NUMBER TAD TASKX /WITH HIGH-ORDER BIT ON TO INDICATE DCA I T /THAT TASK IS WAITING FOR EVENT COMPLETION AC2000 / EVENT FLAG WAIT KNOWN TO HAVE THIS VALUE ISZ ACARG /WAS THIS A WAITE OR WAITX? JMP TSWAIT /WAITE; AND BLOCK CURRENT TASK ON EVENT WAIT /** NOTE LINK=0 SO ACARG WILL BE CLEARED ** AC7775 /WAITX TAD LOC20 /BUMP PC BACK TO CAL DCA LOC20 /ALSO CLEAR LINK TAD (EORMWT JMP TSWAIT .SBTTL POST - POST AN EVENT FLAG /POST AN EVENT FLAG $POST, TAD I LOC20 /GET DATA FIELD OF EVENT FLAG ISZ LOC20 DCA .+1 BLKMSK, HLT /CDF TO IT AC4000 TAD I ACARG /ADDRESS WAS IN AC AT CALL DCA T DCA I ACARG /ZERO EVENT FLAG SNL /WAS A TASK WAITING ON EVENT FLAG? JMP I (EXRET /NO - WE'RE DONE TAD T /YES - LOW ORDER BITS ARE TASK NUMBER DCA ACARG TAD (EFWT!EORMWT JMP UNBLOK /UNBLOCK THIS TASK FROM EVENT FLAG WAIT PAGE .SBTTL WAITM - WAIT FOR MULTIPLE EVENTS .FSECT RTWAIT,LEVEL=0 FIELD RTFLD /SUBROUTINE TO WAIT FOR MULTIPLE EVENTS /CALLED VIA JMS I 25 WITH INTERRUPTS OFF. /THIS ROUTINE SHOULD BE CALLED AFTER SCANNING THE MULTIPLE EVENT FLAGS /(WITH INTERRUPTS OFF) TO AVOID TURNING INTERRUPTS ON BEFORE THE /WAIT MASK IS PLACED IN TFTABL. THE "BLKARG" CALL TO THE RTS EXEC /WOULD TURN INTERRUPTS ON (IN THE EXEC), THUS INVITING /RACE CONDITIONS. XWAITM, 0 IFDEF SWAP < /THE "FREE PARTITION" FLAG DCA COMMAND /IS IN THE SIGN BIT OF THE AC > CLA CLL /CLEAR AC (IN CASE SWAPPER NOT PRESENT) /AND LINK (SO TSWAIT WILL ZERO THE TASK AC) TAD XWAITM DCA LOC20 /FAKE A CALL TO EXEC (IN CASE WE MUST WAIT) RDF TAD ECDIF0 DCA T1$ DCA TSWFLG /THIS IS STILL PART OF THE FAKE CALL TAD I LOC20 /GET THE WAIT MASK ISZ LOC20 DCA T2$ CDF RTFLD TAD T1$ DCA I (EXRET TAD T2$ JMP I (TSWAIT /GO WAIT ON MASK T1$: 0 T2$: 0 .SBTTL ARGUMENT CHECKING .FSECT RTARGS,ROOT FIELD RTFLD ARGCHK, 0 SNA /USE REAL AC IF ONE IS GIVEN TAD ACARG SPA JMP ERR TAD (-NTASKS-1 SMA CLA JMP ERR /ERROR IF TASK NUMBER OUT OF RANGE TAD ACARG JMP I ARGCHK CHK377, 0 AC3777 /IGNORE SIGN BIT AND ACARG SZA JMS ARGCHK AC3777 /CLEAR AC AND ACARG /ACARG CONTAINS TASK DEDICATION (IF ANY) ISZ CHK377 JMP I CHK377 ERR, CLA /IF ARG IS OUT OF RANGE, CDF RTCDF DCA ACARG /DISABLE TASK, MAKE IT NON-EXISTENT AND TAD (DNEWT+ENABWT /PUT TASK IN RUN-WAIT JMP I ($SUSPND IFNZRO PWRFAL < .SBTTL POWER FAIL RESTART CODE .FSECT RTPWRF,ROOT FIELD RTFLD PWFLEF, 0 /POWER FAILURE EVENT FLAG PFLRTN, /** MUST BE AT PWFLEF+1 ** CAF /IN CASE ONLY A POWER DIP IFNZRO PDP8A < 6103 /CLEAR THE POWER LOW FLAG, FOR PDP8A > / / / /ANY OTHER SPECIFIC FLAG CLEARING HERE / /PDP8A OPTION BOARD ETC. / / IFDEF RX8A < / IFNDEF RXDVCD / 6005+RXDVCD /FLOPPY ON POWER UP READS FIRST BLOCK JMP .-1 /WAIT FOR IT TO FINISH UP > /SAME FOR ANY OTHER FLOPPY CONTROLLERS! /// IFNZRO PDP8A < /DELAY IF PDP8A TAD (7200 /SET UP BIG WAIT FOR ALL DCA T1$ / D$: ISZ T2$ / JMP D$ / ISZ T1$ / JMP D$ / SPL /DID POWER GO DOWN AGAIN!?!? SKP /SKIP IF OK HLT /POWER DOWN AGAIN, JUST HALT /// > / TAD INTT / DCA 0 /RESTORE LOCATION OF POWER LOW INTERRUPT IFZERO EAE < IFNZRO MQ < TAD I (PWSAV /IF JUST MQ, DO IT THE SIMPLE WAY MQL > > IFNZRO EAE < TAD (PWSAV-1 /SET UP FETCH POINTER DCA XR JMS I (UNWRAP /WHOLE EAE > TAD (PWFLEF /POST THE POWER-FAIL INTERRUPT POSTDS /TO EXECUTE THE POWER-FAIL TASK (IF ANY) /// IFNZRO PDP8A < T1$: 0 /TEMPORARIES FOR DELAY LOOP T2$: 0 / /// > > IFNZRO KT8A < /DO KT8A BREAK MAP INIT J.R. / KT8A INITIALIZATION IS NOT TOO CLEAN. FIRST WE CLEAR THE BREAK MAP /TO ZERO. NEXT, FOR EACH DMA DEVICE WE SYNCHRONIZE ACCESS TO THE KT TABLE /BY INHIBITING TASK SWITCHING. THEN EACH HANDLER DOES A READ TO A BUFFER IN /FIELD 0 AND WAITS FOR A BREAK TO THAT BUFFER TO FLY BY TO ESTABLISH ITS /KT8A BREAK ADDRESS. THIS PROCEDURE ASSURES CONFIGURATION INDEPENDANCE. LBM= 6170 /LOAD BREAK MAP ENTRY WITH AC10-11 RLB= 6172 /READ LAST BREAK THAT OCCURRED .FSECT KTBRKF, LEVEL=0 FIELD RTFLD BRKINI, 0 BRKINL, TAD BADR /CLEAR NEXT BREAK ADDR LBM TAD (4 TAD BADR /BUMP ADDR UP DCA BADR ISZ BCNT /DO 16. ENTRIES JMP BRKINL JMP I BRKINI /OK, EXIT BADR, RTFLD%10 /BUFFER RESIDES IN RTS/8 EXEC FIELD BCNT, -20 .GLOBAL KTTAB /ALLOW ACCESS TO KT FLAG TABLE KTTAB, .REPT 17 /SET ALL ENTRIES TO -1 FIRST -1 .ENDR 0 /ILLEGAL, FROM CAF .DSECT KTBUF /NOW DEFINE DUMMY BUFFER FOR FAKE DMA TRANSFERS FIELD RTFLD ZBLOCK 200 /ONE PAGE FOR NOW > / WHOLE PAGE EDIT / ACL=7701 NMI=7411 SCA=7441 CAM=7621 LSR=7417 IFNZRO EAE&PWRFAL+EAESV < .FSECT RTWR, LEVEL=0 FIELD RTFLD / / WRAP UP EAE INFORMATION THRU XR POINTER / MUST CALL WITH INTERRUPT OFF IF PWRFAL EXISTS! / IFZERO PWRFAL < EWRAP, > WRAP, 0 MQA DCA I XR IFZERO OMNI < SCA DCA I XR > IFNZRO OMNI < IFNZRO KT8A < GTF AND L2000 > SCA DCA WRAPT 7621 7451 SKP CLA AC4000 TAD WRAPT DCA I XR > JMP I WRAP WRAPT, 0 /LOCAL TERMPORARY IFNZRO OMNI < IFNZRO KT8A < L2000, 2000 > > / IFNZRO PWRFAL < / / EWRAP TURNS OF INTERRUPTS (INCASE POWER FAIL DURING WRAP) / AND CALLS WRAP / EWRAP, 0 IOF JMS WRAP ION JMP I EWRAP / > / .FSECT RTUW, LEVEL=0 FIELD RTFLD / / UNWRAP EAE / SAME CONSTRANTS AS WRAP / UNWRAP, 0 IFZERO OMNI < TAD I XR DCA UWRAPT TAD I XR DCA UNTEM / /DON'T NEED CAM HERE AC4000 LSR UNTEM, 0 NMI TAD UWRAPT MQL > IFNZRO OMNI < IFZERO KT8A < TAD I XR 7431 TAD I XR 7403 SMA CLA 7447 > IFNZRO KT8A < TAD I XR 7431 TAD I XR 7403 AND L6000 RTF IOF /RTF TURNS INTERRUPTS ON!! IFNZRO RTFLD < /CORRECT FOR RTF!! CDF CIF RTCDF > SNL CLA 7447 > > JMP I UNWRAP UWRAPT, 0 IFNZRO KT8A < L6000, 6000 > > / /DUMMY TABLE ENTRIES (EACH TASK OVERLAYS ITS ENTRY WHEN IT LOADS): IFDEF MCR < .DSECT NMTBLX, LEVEL=0 NMTBL==.-3 ZBLOCK NTASKS^3 > IFNDEF SWAP < /SWAPPER HOLDS MESSAGE TABLE! .DSECT MSGTBX, LEVEL=0 FIELD RTFLD MSGTBL==.-2 ZBLOCK NTASKS^2 0;0 /MESSAGES FOR NULL TASK > .DSECT TSTABX, LEVEL=0 FIELD RTFLD IFZERO EAESV < TSTABL==.-4 > IFNZRO EAESV < TSTABL==.-5 > ZBLOCK NTASKS^<4+EAESV> RTGTS /GTS (GTF IS SUBSET) TO RTFLD RTS8 /FIELDS, PC, AC FOR NULL TASK 0 0 IFNZRO EAESV < 0 /FIFTH ENTRY FOR NULL > IFNZRO PWRFAL < /TWO LOC'S FOR POWERFAILSTORAGE PWSAV, ZBLOCK 2 /TO SAVE MQ AND EAE > .DSECT TFTABX, LEVEL=0 FIELD RTFLD TFTABL==.-1 ZBLOCK NTASKS,1 0 /NULL TASK ALWAYS RUNNABLE IFNZRO TFTABX-TFTABL-1 IFDEF SWAP < .DSECT RESTBL, LEVEL=0 FIELD RTFLD ZBLOCK NTASKS-SWAP^2 > .SBTTL KT8A SUPPORT IFNZRO KL8A < /15 KL8A SERVICE ROUTINE FOR RTS/8 V3 / / #10 V2B CONVERSION TO MACREL / #11 CDF,CIF 0 / #12 UNWIRE KL8ACT PROBLEMS, FIX / #13 TWO DEVICE PAGE PROBLEM, LEVEL=0, CUR OUT / #14 CHANGE KL8LOC BY AN INDIRECTION / #15 MERGE BACK WITH EXEC / VERS=15. / ORIGINALLY WRITTEN BY RICHARD LARY (LATE 1975) / CHANGES BY S. RABINOWITZ: / 28-SEP-76 BROKEN OUT OF EXEC / ADDED MULTIPLE KL8A SUPPORT / 14-DEC-76 ADDED A CDF TO FIX A BUG / KL8A SERVICE MODULE /THIS IS NOT A TASK - RATHER IT IS A MODULE WHICH ALLOWS /INDEPENDENT TASKS TO CONNECT TO A LINE OF THE KL8A AS /A PSEUDO-KL8J. /**************************************** / / NO LITERALS PERMITTED! / /**************************************** /CONNECT ROUTINE - CALLED VIA / CDF .FLD / CIF KL8ACT / IOF / TAD (KL8ALINENUMBER^4 / JMS I (KL8ACT / KEYBOARD INTERRUPT ROUTINE / PRINTER INTERRUPT ROUTINE / KL8A IOT DEFINITIONS IFNDEF KL8ADV IFNDEF KLDV2 IFNDEF KLDV3 MSIE= KL8ADV^10+6000 MSAB= KL8ADV^10+6001 MSRD= KL8ADV^10+6005 MSCT= KL8ADV^10+6006 MSCD= KL8ADV^10+6010 MSLB= KL8ADV^10+6012 IFZERO KL8A-2&4000 < MSIE2= KLDV2^10+6000 MSAB2= KLDV2^10+6001 MSRD2= KLDV2^10+6005 MSCT2= KLDV2^10+6006 MSCD2= KLDV2^10+6010 MSLB2= KLDV2^10+6012 > IFZERO KL8A-3&4000 < MSIE3= KLDV3^10+6000 MSAB3= KLDV3^10+6001 MSRD3= KLDV3^10+6005 MSCT3= KLDV3^10+6006 MSCD3= KLDV3^10+6010 MSLB3= KLDV3^10+6012 > .RSECT KL8AT, LEVEL=0 FIELD RTFLD .ENTRY KL8ACT KL8ACT, 0 JMP AROUND /JUMP AROUND POWER FAIL ROUTINE KL8APF, 0 /KL8A POWER FAIL ROUTINE - MUST BE AT KL8ACT+2 RDF TAD LCDFI0 DCA KLPFRT /SAVE RETURN FIELD JMS KLINIT /INITIALIZE INT ENABLES AND VECTOR ADDRESS KLPFRT, HLT /RESTORE RETURN FIELDS JMP I KL8APF AROUND, TAD PKB0CDF /INDEX INTO DISPATCH TABLE DCA STORP RDF TAD LCDFI0 DCA KL8ART /STORE RETURN CDF CIF TAD I KL8ACT /PICK UP ARGUMENTS DCA INR /GET INPUT ADDRESS ISZ KL8ACT /POINT TO SECOND ARGUMENT TAD I KL8ACT /GET OUTPUT ADDRESS DCA OUTR /SAVE THEM IN APPROPRIATE SPOTS ISZ KL8ACT /POINT TO RETURN LOCATION JMS KLINIT /INITIALIZE THE KL8A DCA .-1 /ONLY ONCE! CDF .FLD JMS KLCOMN /GET INPUT ADDRESS INR, 0 TAD STORP /GET STORE ADDRESS TAD DIF DCA STORP /BUMP TO OUTPUT TABLE JMS KLCOMN /GET OUTPUT ADDRESS OUTR, 0 KL8ART, HLT ION /TURN INTERRUPTS BACK ON JMP I KL8ACT /RETURN PKB0CDF,KB0+1 DIF, TT0-KB0-4 LCDFI0, CDF CIF 0 KLCOMN, 0 TAD I KLCOMN /GET INPUT INTERRUPT ROUTINE ADR CMA SNA /-1 MEANS LEAVE IT ALONE JMP LVKMN CMA SZA CLA /ZERO MEANS DISABLE THIS SIDE OF THIS LINE TAD KL8ART /GET CDF CIF JMS STORE /STORE CDF CIF OR 0 TAD I KLCOMN /GET ADDRESS AGAIN SNA TAD PIGNORE /IF ZERO SUBSTITUTE THROWAWAY ROUTINE JMS STORE SKP LVKMN, TAD L4 /FIXUP 'STORP' AS THIS ROUTINE NORMALLY WOULD TAD STORP DCA STORP ISZ KLCOMN /SKIP ARGUMENT JMP I KLCOMN /RETURN KLINIT, 0 /KL8A INITIALIZE ROUTINE MSCD /INITIALIZE THE KL8A CLA IAC MSIE /ENABLE INTERRUPTS CLA TAD PKLAD1 MSLB /AND LOAD KL8A BRANCH POINTER CLA IFZERO KL8A-2&4000 < MSCD2 /INITIALIZE THE KL8A CLA IAC MSIE2 /ENABLE INTERRUPTS CLA TAD PKLAD2 MSLB2 /AND LOAD KL8A BRANCH POINTER CLA > IFZERO KL8A-3&4000 < MSCD3 /INITIALIZE THE KL8A CLA IAC MSIE3 /ENABLE INTERRUPTS CLA TAD PKLAD3 MSLB3 /AND LOAD KL8A BRANCH POINTER CLA > CIF CDF RTCDF TAD PMSAB1 /GET KL8A INTERRUPT DISPATCH INSTRUCTION DCA I KL8A1 /STORE IT IN THE RTS8 EXEC IFZERO KL8A-2&4000 < TAD PMSAB2 DCA I KL8A2 /STORE NEXT ONE > IFZERO KL8A-3&4000 < TAD PMSAB3 DCA I KL8A3 /STORE IT TOO > JMP I KLINIT PIGNORE,IGNORE PKLAD1, KLADR1 PMSAB1, MSAB KL8A1, KL8LOC /SKIP LOCATION FOR FIRST ONE IFZERO KL8A-2&4000 < PKLAD2, KLADR2 PMSAB2, MSAB2 KL8A2, KL8LOC+1 /SKIP LOCATION FOR SECOND ONE > IFZERO KL8A-3&4000 < PKLAD3, KLADR3 PMSAB3, MSAB3 KL8A3, KL8LOC+2 /SKIP LOCATION FOR THIRD > L4, 4 STORE, 0 /ROUTINE TO STORE INTO DISPATCH TABLES DCA I STORP ISZ STORP ISZ STORP JMP I STORE STORP, KB0+1 IGNORE, CLA /MAKE SURE AC CLEAR! CDF CIF RTCDF POSTDS /DISMISS INTERRUPT / KL8A HARDWARE DISPATCH TABLE / IFZERO KL8A-2&4000 /MORE ROOM NEEDED? / IFNZRO KL8A-2&4000 < *.-KL8ACT-1&7770+10 /MUST BE ON 8 WORD BOUNDARY! > KLADR1, JMP TT0 JMP TT1 JMP TT2 JMP TT3 JMP KB0 JMP KB1 JMP KB2 JMP KB3 IFZERO KL8A-2&4000 < KLADR2, JMP TT02 JMP TT12 JMP TT22 JMP TT32 JMP KB02 JMP KB12 JMP KB22 JMP KB32 > IFZERO KL8A-3&4000 < KLADR3, JMP TT03 JMP TT13 JMP TT23 JMP TT33 JMP KB03 JMP KB13 JMP KB23 JMP KB33 > /KL8A INDIVIDUAL DISPATCH ROUTINES - MUST ALL BE 4 WDS LONG! /MUST START AT AN EVEN ADDRESS KB0, MSRD /READ CHAR FROM SILO CDF CIF .FLD JMP I .+1 IGNORE KB1, MSRD CDF CIF .FLD JMP I .+1 IGNORE KB2, MSRD CDF CIF .FLD JMP I .+1 IGNORE KB3, MSRD CDF CIF .FLD JMP I .+1 IGNORE TT0, CLA CDF CIF .FLD JMP I .+1 IGNORE TT1, CLA CDF CIF .FLD JMP I .+1 IGNORE TT2, CLA CDF CIF .FLD JMP I .+1 IGNORE TT3, CLA CDF CIF .FLD JMP I .+1 IGNORE IFZERO KL8A-2&4000 < KB02, MSRD2 /READ CHAR FROM SILO CDF CIF .FLD JMP I .+1 IGNORE KB12, MSRD2 CDF CIF .FLD JMP I .+1 IGNORE KB22, MSRD2 CDF CIF .FLD JMP I .+1 IGNORE KB32, MSRD2 CDF CIF .FLD JMP I .+1 IGNORE TT02, CLA CDF CIF .FLD JMP I .+1 IGNORE TT12, CLA CDF CIF .FLD JMP I .+1 IGNORE TT22, CLA CDF CIF .FLD JMP I .+1 IGNORE TT32, CLA CDF CIF .FLD JMP I .+1 IGNORE > IFZERO KL8A-3&4000 < KB03, MSRD3 /READ CHAR FROM SILO CDF CIF .FLD JMP I .+1 IGNORE KB13, MSRD3 CDF CIF .FLD JMP I .+1 IGNORE KB23, MSRD3 CDF CIF .FLD JMP I .+1 IGNORE KB33, MSRD3 CDF CIF .FLD JMP I .+1 IGNORE TT03, CLA CDF CIF .FLD JMP I .+1 IGNORE TT13, CLA CDF CIF .FLD JMP I .+1 IGNORE TT23, CLA CDF CIF .FLD JMP I .+1 IGNORE TT33, CLA CDF CIF .FLD JMP I .+1 IGNORE > PAGE >