File RTS8.PA (PAL assembler source file)

Directory of image this file is from
This file as a plain text file

/RTS-8  SMALL REAL TIME SYSTEM V2
/
/
/
/
/
/
/
/
/
/COPYRIGHT  (C)  1974,1975 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.
/
/
/
/
/
/
/
/
/
/

/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 SHWANS /BASED ON T-O-Y JUNE 5, 1973 /IOT'S FOR OPTIONAL HARDWARE: IFNDEF PDP12 <PDP12=0> /IF NOT SURE, YOU'RE NOT A PDP-12 IFZERO PDP8E < IFZERO PDP12 <CAFHLT=HLT> /HALT TO LET USER CLEAR FLAGS IFNZRO PDP12 <CAFHLT=JMS IOPRST> /ISSUE I/O PRESET ON PDP-12 > IFNZRO PDP8E <CAFHLT=CAF> /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
/PAGE 0 OF FIELD 0 *0 /INTERRUPT "VECTOR" 0 /SET TO JMP I 3 ON POWER FAILURE JMP I .+1 INTRPT IFNZRO PWRFAL < PFLADR, PFLRTN /CHANGED BY POWER FAIL TASK > *17 XR, 0 /INDEX REGISTER USED BY EXEC LOC20, 0 /MONITOR CALL LOCATION ** MUST BE AT 20 ** DCDF, CDF 0 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, 0 /POINTS TO FIRST WORD OF MESSAGE Q POINTER MPT2, 0 /" " 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 MCREF, 0 /MCR STARTUP EVENT FLAG T, 0 /NON-INTERRUPT LEVEL TEMPORARY IFDEF SWAPPER < IFNZRO COMMAN-.<__ERROR: CHANGE SWAPPER__> *.+2 /SWAPPER LOADS TWO ENTRY POINTS HERE > ZBLOCK 50-. /RESERVED FOR FUTURE EXPANSION
/SET UP EXEC LINKAGE IN FIELDS 1-7 IFZERO HGHFLD-10&4000 < FIELD 1 *21 CDF 10 CIF 0 JMP CALIOF DSPOST XWAITM > IFZERO HGHFLD-20&4000 < FIELD 2 *21 CDF 20 CIF 0 JMP CALIOF DSPOST XWAITM > IFZERO HGHFLD-30&4000 < FIELD 3 *21 CDF 30 CIF 0 JMP CALIOF DSPOST XWAITM > IFZERO HGHFLD-40&4000 < FIELD 4 *21 CDF 40 CIF 0 JMP CALIOF DSPOST XWAITM >
IFZERO HGHFLD-50&4000 < FIELD 5 *21 CDF 50 CIF 0 JMP CALIOF DSPOST XWAITM > IFZERO HGHFLD-60&4000 < FIELD 6 *21 CDF 60 CIF 0 JMP CALIOF DSPOST XWAITM > IFZERO HGHFLD-70&4000 < FIELD 7 *21 CDF 70 CIF 0 JMP CALIOF DSPOST XWAITM > FIELD 0
/INTERRUPT ROUTINE *200 TS8LOC, CAFHLT /SO WE CAN START AT 200 IFNZRO TS8LOC-200 <ERROR> /OS8SUP NEEDS THIS HERE IFDEF SWAPPER < NEWTSK, JMS I COMMAND /DO SWAPPER INITIALIZATION > /(SEE SWAP TASK FOR DETAILS) IFNDEF SWAPPER < 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 IFNZRO PDP8E <GTF> IFZERO PDP8E < RAR /COMBINE LINK, IF AND DF INTO ONE WORD RIB > DCA INTFGS USERSK, /VERY HIGH PRIORITY USER FLAG TESTS GO HERE IFNZRO PWRFAL <SPL> /SKIP ON POWER LOW JMP TSTCLK /NO MORE H.P. SKIPS - GO TO SKIP CHAIN IFNZRO PWRFAL < TAD 0 DCA INTT /SAVE LOCATION ZERO TAD (JMP I PFLADR DCA 0 /SET UP 0 FOR RESTART HLT /DON'T TRY ANYTHING FANCY PWFLEF, 0 /POWER FAILURE EVENT FLAG PFLRTN, TAD INTT /** MUST BE AT PWFLEF+1 ** DCA 0 /RESTORE LOCATION OF POWER LOW INTERRUPT TAD (PWFLEF /POST THE POWER-FAIL INTERRUPT POSTDS /TO EXECUTE THE POWER-FAIL TASK (IF ANY) > BSKCHN, DISMIS /BEGINNING OF SKIP CHAIN LIST TSTCLK, CDF CIF 0 /ADDRESS FOLLOWED BY CDF CIF FIELD NOP /SET TO CLSK BY CLOCK ROUTINE JMP I BSKCHN DCDIF0, CDF CIF 0 /CLOCK HANDLER ALWAYS IN FLD 0 JMP I .+1 DISMIS /CHANGED BY CLOCK HANDLER (IF ANY)
/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 TAD 0 /UNLESS WE ARE IN A NON-INTERRUPTABLE ZONE IFDEF OS8 <RIB> /(NAMELY LOCS 0-77 OF A FIELD AND (7700 /NOT USED BY OS/8 BACKGROUND) SZA CLA /OR TASK SWITCHING HAS BEEN SPECIFICALLY 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. STOPJ, ISZ SVSFLG /IS THE STATE OF THE CURRENT TASK WORTH SAVING? JMP NOSVST /NO - FORGET IT. TAD TASKX CLL RTL 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 IFNZRO EAE < MQA DCA I XR /SAVE THE MQ > NOSVST, TAD NEWTSK /WE NOW ATTEMPT TO START UP THE HIGHER ION /PRIORITY TASK. - HOWEVER, SINCE INTERRUPTS DCA TASKX /HAVE BEEN OFF FOR A WHILE, WE RE-ENABLE THEM /WITH THE "DON'T SAVE STATE" FLAG ON. /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. /** NOW FALL INTO "STARTJ" ON THE NEXT PAGE **
/CODE TO START UP A TASK /ENTER WITH TASK# IN "TASK", DF=0, ION, NO STATE (SVSFLG=0) STARTJ, IFZERO HGHFLD <ION> /INTERRUPTS ALREADY ON IF CIF WORKS TAD TASKX CLL RTL 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 IFNZRO EAE < TAD I XR MQL /RESTORE MQ > /** NOW FALL INTO "DISMIS" ON NEXT PAGE **
/INTERRUPT DISMISS ROUTINE - ALSO USED TO START TASKS DISMIS, IFNZRO PDP8E < SRQ /ANY OTHER INTERRUPTS PENDING? SKP /NO JMP USERSK /YES - SKIP PREAMBLE STUFF FOR EXTRA SPEED > TAD INTFGS IFNZRO PDP8E < IFNZRO HGHFLD <RTF> IFZERO HGHFLD <RAL> /RTF DOESN'T WORK RIGHT ON 4K 8E'S CLA > IFZERO PDP8E < 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 PDP8E TAD DCDF 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 DCDIF0 DCA DISCIF DISCIF, 0 DISCDF, 0 > TAD INTAC IFZERO -PDP8E&HGHFLD <ION> /FOR PRE 8E OR 4K 8E MACHINES 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
/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 TAD I LOC20 /GET THE COMMAND IFDEF SWAPPER < DCA COMMAND /SAVE A COPY FOR LATER TAD COMMAND /IN CASE HE WANTS TO "FREE" > ISZ LOC20 AND (17 TAD CMDJMP DCA .+1 /TURN COMMAND INTO DISPATCH JUMP HLT CMDJMP, JMP I .+1 XSEND /SEND MESSAGE TO A TASK XRECEIV /GET A MESSAGE FROM THE MESSAGE QUEUE XWAITE /WAIT FOR AN EVENT FLAG TO BE POSTED XRUN /RUN A TASK (IF NOT BEING RUN) XSUSPND /SUSPEND EXECUTION OF A TASK XPOST /POST AN EVENT FLAG XSKPINS /INSERT SKIP INTO INTERRUPT CHAIN XDERAL /DERAIL A TASK XBLKARG /BLOCK TASK FOR REASON SPECIFIED BY ARG XSENDW /SEND MESSAGE AND WAIT FOR COMPLETION XUNBARG /UNBLOCK TASK FOR REASON SPECIFIED BY ARG
/ROUTINE TO DERAIL A TASK'S EXECUTION INTO A SUBROUTINE XDERAL, TAD I LOC20 ISZ LOC20 DCA T /SAVE ADDR OF DERAIL SUBR TAD ACARG CLL RTL TAD (TSTABL /GET POINTER INTO TASK STATE TABLE DCA MPTR CDF 0 TAD I MPTR AND (70 /GET INSTRUCTION FIELD TAD DCDF DCA DRLCDF ISZ MPTR TAD I MPTR /GET CURRENT TASK PC DRLCDF, HLT /CDF TO TASK FIELD DCA I T /STORE PC IN SUBR HEADER CDF 0 TAD T IAC DCA I MPTR /SET PC TO SUBR HEADER + 1 JMP EXRET /RETURN TO CALLING TASK /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 /MULTIPLE-UPDATE PROBLEMS. XWAITM, 0 TAD XWAITM DCA LOC20 /FAKE A CALL TO EXEC (IN CASE WE MUST WAIT) RDF TAD ECDIF0 DCA EXRET DCA TSWFLG /THIS IS STILL PART OF THE FAKE CALL TAD I LOC20 /GET THE WAIT MASK ISZ LOC20 CLL /MAKE SURE TSWAIT ZEROS TASK AC JMP I (TSWAIT /GO WAIT ON MASK
/INSERT A DEVICE SKIP INTO THE INTERRUPT CHAIN XSKPINS,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 ECDIF0 DCA I T IFNZRO HGHFLD < RDF /GET CDF TO NEW "LAST SKIP" TAD ECDIF0 INTCDF, CDF CIF 0 /CDF TO FLD OF OLD "LAST SKIP" AND INH INTS CIF 0 /CORRECT I.F. FROM LAST KLUDGEY INSTRUCTION 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 EXRET, HLT /CDF CIF RETURN FIELD (ALSO INHIBIT INTERRUPTS) IFZERO HGHFLD <IOF> /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 ECDIF0 /STOP CURRENT JOB AND GO TO RESCAN ION /NOW ITS SAFE TO TURN INTERRUPTS BACK ON > JMP I LOC20 /RETURN TO CALLING TASK ECDIF0, CDF CIF 0 /OOPS - WE MUST TASK SWITCH IMMEDIATELY! JMP I (TSTOP /GO STOP THIS TASK AND RUN SOMEONE ELSE INTEND, BSKCHN
IFNDEF SWAPPER < /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 <CIF 0> /AS WE SEARCH A TASK'S ENTRY IN THE LIST, IFZERO HGHFLD <IOF> 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 <ION> ISZ TASKX /BUMP THE TASK NUMBER (AND PRIORITY) /ALLOW INTERRUPTS FOR ONE CYCLE SINCE JMP FINDJL /"TASK" IS BIGGER THAN CURRENT REJECTED TASK >
IFDEF SWAPPER < /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: AC MAY BE NON-ZERO ON ENTRY ** 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 <CIF 0>/AS WE SEARCH A TASK'S ENTRY IN THE LIST, IFZERO HGHFLD <IOF> TAD I XR /WE ASSUME THAT TASK'S PRIORITY CLL RAL /NON-RESIDENT BIT TO LINK SZA CLA /LOOK FOR FIRST TABLE ENTRY OF 0 JMP NORUN /(THERE HAS TO BE ONE - NAMELY THE NULL TASK) SNL /IS HE NONRESIDENT? JMP I (STARTJ /NO: START HIM UP CLL CMA TAD XR DCA XR /BACK UP AUTOBUMP REGISTER IFNZRO EXEC-SWPWT <__ERROR: CALEXC .NE. SWPWT__> TAD CALEXC /AC = "SWPWT" DCA I XR /PUT HIM IN SWAP WAIT TAD (-RUNWT-1 AND I (SWAPPER+TFTABL DCA I (SWAPPER+TFTABL JMP FINDJ /FIND SOMEONE ELSE - HOPEFULLY SWAPPER NORUN, IFZERO HGHFLD <ION> ISZ TASKX /BUMP THE TASK NUMBER (AND PRIORITY) /ALLOW INTERRUPTS FOR ONE CYCLE SINCE JMP FINDJL /"TASK" IS BIGGER THAN CURRENT REJECTED TASK > PAGE
/SEND A MESSAGE TO A TASK XSENDW, STA /SET OR XSEND, 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 (WAITS /WAIT FOR MESSAGE TO BE FREE MSGFRE, ISZ LOC20 TAD ACARG /GET THE ADDRESS OF THE TARGET TASKS' JMS SRCOMN /MESSAGE QUEUE POINTER DCA MSGCDF /SAVE CDF TO NEW MESSAGE'S FIELD TAD DCDF 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
/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 (FREEJ /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 (POSTEX /* 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 (MSGTBL /MESSAGE QUEUE POINTER DCA MPTR CDF 0 AC7776 TAD I (EXRET JMP I SRCOMN
/RECEIVE A MESSAGE FROM THE TASK'S MESSAGE QUEUE XRECEIV,TAD TASKX JMS SRCOMN /GET THE MESSAGE QUEUE PTR FOR THIS TASK DCA STOCDF /SAVE CDF TO CALLING FIELD TAD DCDF 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 I (WAITM3 /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 TAD ACARG /ACARG CONTAINS TASK DEDICATION (IF ANY) 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 ISZ LOC20 TAD CHNCDF /RETURN WITH CDF TO MESSAGE IN AC JMP I (EXRET PAGE
/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 0 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 TAD TASKX /TO STOP THE CURRENT TASK BUT NOT BLOCK IT. CLL RTL /GET A POINTER INTO THE TASK'S STATE TABLE ENTRY TAD (TSTABL-1 DCA XR CDF 0 IFNZRO HGHFLD < TAD I (EXRET CLL RAR RTR TAD I (EXRET TAD (-5023 /5023 = 6203 + (6203 SHIFTED RIGHT 3) > 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 IFNZRO EAE < MQA /EVEN PRESERVE THE MQ OVER MONITOR CALLS DCA I XR /(WHAT THE HECK, ITS ONLY 2 INSTRUCTIONS) > IFDEF SWAPPER <SWPENT=COMMAND+1 /2ND SWAPPER ENTRY POINT TAD COMMAND SPA CLA /FREE THE PARTITION? JMS I SWPENT> /YES: LET SWAPPER CODE DO IT JMP I (FINDJ /NO: FIND NEXT TASK TO RUN
/SCHEDULE A TASK TO BE RUN XRUN, TAD (RUNWT JMP UNBLOK XUNBARG,TAD I LOC20 /UNBLOCKING CODE IN ARGUMENT ISZ LOC20 UNBLOK, DCA UNBMSK /AC CONTAINS REASON FOR UNBLOCKING TASK "ACARG" TAD ACARG IOF /FREEJ IS AN INTERRUPT-LEVEL ROUTINE! JMS FREEJ /REMOVE THE GIVEN BLOCKING BIT UNBMSK, 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 /SUSPEND EXECUTION OF A TASK XSUSPND,TAD (RUNWT JMP BLOK XBLKARG,TAD I LOC20 /BLOCKING CODE IN ARGUMENT ISZ LOC20 BLOK, DCA BLKMSK /SAVE BLOCKING CODE TAD ACARG /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 0 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
/ROUTINE TO UNBLOCK A TASK'S EXECUTION /ENTER WITH TASK# IN AC, INTERRUPTS OFF, UNBLOCKING BIT IN CALL+1 FREEJ, 0 CDF 0 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 CLL RAL 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
/WAIT FOR EVENT FLAG XWAITE, TAD I LOC20 /GET ADDRESS OF EVENT FLAG ISZ LOC20 WAITS, DCA T /ENTER HERE FROM SEND IFZERO HGHFLD <IOF> /INHIBIT INTERRUPTS IFNZRO HGHFLD <CIF 0> /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 IOF /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 TAD (EFWT JMP TSWAIT /AND BLOCK CURRENT TASK ON EVENT WAIT /** NOTE LINK=0 SO ACARG WILL BE CLEARED ** /POST AN EVENT FLAG XPOST, 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
/DUMMY TABLE ENTRIES (EACH TASK OVERLAYS ITS ENTRY WHEN IT LOADS): MSGTBX, ZBLOCK NTASKS^2 0;0 /MESSAGES FOR NULL TASK TSTABX, ZBLOCK NTASKS^4 0 .+1 /FIELDS, PC, AC FOR NULL TASK DCA SVSFLG /NULL TASK RUNS STATELESS JMP . TFTABX, IFNZRO NTASKS&40 < 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1> IFNZRO NTASKS&20 < 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1> IFNZRO NTASKS&10 < 1;1;1;1;1;1;1;1> IFNZRO NTASKS&4 <1;1;1;1> IFNZRO NTASKS&2 <1;1> IFNZRO NTASKS&1 <1> 0 /NULL TASK ALWAYS RUNNABLE IFNZRO TFTABX-TFTABL-1 <TBLERR,__ERROR__> IFDEF SWAPPER < *RESTBL ZBLOCK NTASKS-SWAPPER^2 *PARTBL ZBLOCK PARTNS^4 > $-$-$



Feel free to contact me, David Gesswein djg@pdp8online.com with any questions, comments on the web site, or if you have related equipment, documentation, software etc. you are willing to part with.  I am interested in anything PDP-8 related, computers, peripherals used with them, DEC or third party, or documentation. 

PDP-8 Home Page   PDP-8 Site Map   PDP-8 Site Search