* MTK16 - MULTI TASKING KERNEL FOR DDP516/H316 - V1.3 JULY 5 2007 * * THIS PROGRAM WAS MADE TO TEST ON THE H316 EMULATOR IN A MULTI THREADING * STRUCTURE: * - THE BASIC INTERRUPT HANDLING MECHANISM OF SIMH-H316, * - THE REAL TIME CLOCK, * - THE INTERRUPT HANDLING OF THE TTY * - THE INTERRUPT HANDLING OF THE PTR AND PTP * * THE TEST PROGRAM IS BUILT AS A SMALL EXECUTIVE LIKE THE ONES WHICH WERE * VERY POPULAR ON MINICOMPUTERS IN THE LATE SIXTIES AND IT IS STRUCTURED IN * 3 RINGS: * * RING-0: INTERRUPT HANDLING * RING-1: INTERRUPT INITIATION, SERVICE PRIMITIVES, TASK SCHEDULING * RING-2: PROGRAM TASKS/TESTING PROGRAMS * * THE RINGS ARE NOT PROTECTED FROM EACH OTHER, AND ALL CODE OF THE 3 RINGS * MUST RUN IN THE LOWEST 16K MEMORY BLOCK (NO EXTENDED ADDRESSING IS SUPPORTED). * THE KERNEL (RING-0 AND RING-1) WITHOUT EXTENTIONS, TAKES A SINGLE MEMORY * SECTOR (EXCEPT TABLE SPACE) AND ITS DEFAULT LOCATION IS THE HIGHEST SECTOR * IN THE 1ST 16K MEMORY BLOCK. * * A COMPLETE SYSTEM CONSISTS OF AT LEAST 3 MODULES: * - THE KERNEL (THIS FILE) * - THE FILE CONTAINING THE CONFIGURATION DATA AND TABLES: MTK16-CONFIG * - ONE OR MORE FILES WITH CODE OF THE TASKS * THE ASSEMBLED OBJECT CODE OF THE MODULES MUST BE LINKED TOGETHER TO OBTAIN * A LOADABLE AND WORKING SYSTEM. * * HONEYWELL X16 16 BIT COMPUTER SOFTWARE * MTK16 IS CREATED BY THEO ENGEL (THEO.ENGEL@HETNET.NL) * * SERVICE PRIMITIVES FOR TASKS RUNNING IN RING-2 SUBR SLEEP,SLEP SET TIMER SUBR ATTW ATTACH DEVICE (BLOCKING) SUBR ATT ATTACH DEVICE (NON-BLOCKING) SUBR REL RELEASE DEVICE SUBR ASRI READ CHAR FROM TTY SUBR ASRO PRINT CHAR ON TTY SUBR PTRI READ CHAR FROM HSR SUBR PTPO PUNCH CHAR ON PTP SUBR WAIT WAIT FOR AN EVENT SUBR SIGNAL,SIG SIGNAL AN EVENT SUBR REVENT,RSEV RESET AN EVENT SUBR EXEW EXEC A TASK (BLOCKING) SUBR EXE EXEC A TASK (NON-BLOCKING) SUBR EXIT EXIT CURRENT TASK SUBR KILL KILL ANOTHER TASK SUBR YIELD,YIEL SWITCH TO NEXT READY TASK SUBR PAUSE,PA SUSPEND ANOTHER TASK SUBR RESUME,RESU RESUME A SUSPENDED TASK * * SCHEDULER ENTRY POINTS FOR RING-1 CODE SUBR SKED SCHEDULER ENTRY POINT AFTER INITIALIZATION SUBR RESH ENABLE INTERRUPT AND SCHEDULE THE NEXT READY TASK SUBR BLOK SET WAITING FOR EVENT; SCHEDULE THE NEXT READY TASK SUBR BUSY SET PENDING FOR CONDITION; SCHEDULE NEXT READY TASK SUBR SAVE INHIBIT INTERRUPT AND SAVE CPU STATE IN TCB * * OTHER ENTRIES/LOCATIONS SUBR ILINK,LINK INTERRUPT SERVICE ENTRY POINT ADDRESS SUBR ISKPCH,INSC RETURN ADDRESS TO INTERNAL INTERRUPT SKIP CHAIN SUBR IBACK,BACK RETURN ADDRESS FOR AN EXTERNAL INTERRUPT HANDLER SUBR T POINTER TO TCB OF CURRENT RUNNING TASK SUBR DEVS ALLOCATED DEVICES SUBR KSTR BEGIN ADDRESS OF BASIC KKERNEL ADDRESS RANGE SUBR KEND END ADDRESS OF BASIC KKERNEL ADDRESS RANGE EJCT * MTK16 CAN BE LOADED ANYWHERE IN THE LOWEST 16K WORD BLOCK. HOWEVER TO * PREVENT USE OF CROSS SECTOR REFERENCES, THE PREFERED LOCATION IS TO START * LOADING MTK16 AT A SECTOR BOUNDARY. THE CODE OF THE BASIC * KERNEL FITS WITHIN A SINGLE SECTOR. ORG '17000 DEFAULT START ADDRESS (LAST SECTOR 8K) KSTR EQU * BEGIN ADDRESS OF BASIC KKERNEL ADDRESS RANGE ********************************************************** * RING-0, INTERRUPT HANDLERS FOR CLOCK, TTY, PTR AND PTP * ********************************************************** LINK DAC *+1 POINTER TO INTERRUPT SERVICE ENTRY POINT * * INTERRUPT ENTERS HERE *** ** INTERRUPT SERVICE ENTRY POINT STA SA SAVE A STX SX SAVE X INK STA SK SAVE KEYS * CHECK FOR A CLOCK INTERRUPT SKS '20 JMP CLCK RTC INTERRUPT SERVICE ROUTINE * CHECK FOR A PTR INTERRUPT SKS '401 JMP PTI PAPERTAPE READER INTERRUPT SERVICE ROUTINE * CHECK FOR A PTP INTERRUPT SKS '402 JMP PTO PAPERTAPE PUNCHER INTERRUPT SERVICE ROUTINE * CHECK FOR A TTY INTERRUPT SKS '404 JMP TTY TTY INTERRUPT SERVICE ROUTINE * * TO EXTERNAL SKIP CHAIN (SKIP CHAIN EXTENSION) * VIA THE EXTERNAL SKIP CHAIN, ADDITIONAL EXTERNAL INTERRUPT SERVICE * ROUTINES CAN BE ADDED TO THE KERNEL. * JMP* EXSC * THE EXTERNAL INTERRUPT SKIP CHAIN HAS TO RETURN TO HERE. * NO RTC, TTY, PTR, PTP (OR OTHER ALLOWED) INTERRUPT, SO ERROR * INSC HLT ********** ERROR STOP ************* JMP *-1 EXSC XAC ESKPCH EXTERNAL SKIP CHAIN ENTRY POINT EJCT *****RTC INTERRUPT RTC EQU '61 CLOCK LOCATION * RELOAD THE RTC LOCATION AND RESET THE CLOCK CLCK LDA TICK RESET CLOCK VALUE FOR GETTING THE NEXT TICK STA RTC INTERRUPT OCP '20 RESET CLOCK INTERRUPT * UPDATE USED TIMERS LDX PTIM POINTER TO TIMERTABLE, X = POINTER TO TIMER(EVENT) CKC LDA* 0 TCB ADDRESS, THEN TIMER USED (OR TABLE END) STA TEM0 SAVE TCB ADDRESS IF THERE SNZ JMP NXC NO, TCB FIELD EMPTY, SO FREE; CHECK NEXT TIMER AOA SNZ JMP BACK TABLE END * ACTIVE TIMER IRS 1,1 INCREMENT TIME VALUE JMP NXC GO TO NEXT TIMER * TIMER DUE; AWAKE SLEEPING TASK LDA* TEM0 STATE SSP STA* TEM0 RESET BLOCKED-BIT IN STATE OF WAITING TASK CRA STA* 0 DISCONNECT TIMER FROM THREAD (FREE TIMER) * GO TO NEXT TIMER NXC IRS 0 IRS 0 JMP CKC X = POINTER TO NEXT TIMER EJCT ********************************************************************* * END OF INTERRUPT HANDLER * ********************************************************************* * INTERRUPT HANDLERS MUST END THEIR PROCESSING WITH A JUMP TO THIS * ENTRY POINT: * LEAVE THE INTERRUPT STATE, RELOAD CPU STATE, ENABLE INTERRUPT AND BACK * TO INTERRUPTED PROGRAM BACK EQU * * * RING-1 (SCHEDULER+PRIMITIVES) IS NOT REENTRANT AND AT LEAST IN PART OF RING-1 * THE INTERRUPT IS ENABLED. SO IT IS NOT ALLOWED TO ENTER FOR HERE RING-1 IF * THE INTERRUPT HAPPENED DURING PROCESSING OF RING-1 CODE. IT IS HOWEVER ALLOWED * TO ENTER THE SCHEDULER WHEN RING-2 CODE WAS EXECUTED DURING THE INTERRUPT. * MOST SIMPLE IS TO JUST RETURN TO THE INTERRUPTED CODE AFTER AN INTERRUPT * SERVICE. TO ENABLE HOWEVER IS SIMPLE FORM OF CLOCK PREEMPTION THERE IS AN * OPTION (WHEN THE PREEMPT FLAG IS SET) TO ENTER THE SCHEDULER AFTER PROCESSING * AN INTERRUPT WHICH HAPPENED DURING EXECUTION OF RING-2 CODE. * LDA* PREE PREEMPT FLAG SET? SNZ JMP RET * PREEMPTION FLAG IS SET. IS IT ALLOWED TO GO TO THE SCHEDULER? * CHECK WHETHER ADDRESS WHERE CODE IS INTERRUPTED IS WITHIN RING-1. * IF NO THEN IT IS ALLOWED TO ENTER THE SCHEDULER. LDA LINK+1 ADDRESS WHERE CODE IS INTERRUPTED CAS* XEND END OF MTK16 PROTECTED RANGE OF ADDRESSES JMP R2 GT NOP CAS* XSTR START OF MTK16 PROTECTED RANGE OF ADDRESSES NOP JMP RET INTERRUPT WITHIN RING-1 * INTERRUPT NOT IN RING-1; ENTER SCHEDULER R2 LDX T TCB ADDRESS OF CURRENT TASK IAB STA B,1 SAVE B LDA SA STA A,1 SAVE A LDA SK STA KEYS,1 SAVE KEYS LDA SX STA X,1 SAVE X IAB A = LINK+1 JMP BUSY+2 * RET LDA SK OTK RESTORE KEYS LDX SX RESTORE X LDA SA RESTORE A ENB JMP* LINK+1 * PREE XAC PREEMT POINTS TO PREEMPT FLAG LOCATION IN MTK16-TAB XSTR XAC MTKSTR RING-1 CODE START ADDRESS (MTK16-TAB) XEND XAC MTKEND RING-1 CODE END ADDRESS (MTL16-TAB) EJCT *****PTR INTERRUPT PTI INA '1001 CLEAR A AND INPUT CHARACTER, RESET INTERRUPT HLT OCP '101 STOP READER STA TEM0 SAVE OCTAD READ LDA EVPI TCB ADDRESS OF TASK WAITING FOR CHARACTER SNZ JMP BACK INTERRUPT, BUT NO EVENT DECLARED (TASK KILLED?) STA 0 X = TCB ADDRESS OF TASK WAITING FOR CHARACTER LDA TEM0 STA A,1 STORE CHAR IN A-REG OF WAITING TASK LDA* EVPI STATE SSP STA* EVPI RESET BLOCKED-BIT IN STATE OF WAITING TASK CRA STA EVPI DISCONNECT PTR INTERRUPT HANDLER FROM TASK JMP BACK EXIT FROM PTR INTERRUPT * *****PTP INTERRUPT PTO LDA EVPO TCB ADDRESS OF TASK WAITING FOR CHARACTER SNZ JMP POFF INTERRUPT, BUT NO EVENT DECLARED => POWEROFF STA 0 LDA A,1 GET CHAR TO PUNCH OTA 2 PUNCH CHAR, RESET INTERRUPT HLT LDA* EVPO STATE SSP STA* EVPO RESET BLOCKED-BIT IN STATE OF WAITING TASK CRA STA EVPO DISCONNECT PTR INTERRUPT HANDLER FROM TASK JMP BACK EXIT FROM PTP INTERRUPT POFF OCP '102 POWER OFF, RESET INTERRUPT JMP BACK EXIT FROM PTP INTERRUPT EJCT *****TTY INTERRUPT TTY LDA MODE SLZ INPUT MODE? JMP OMOD NO, OUTPUT MODE * TTY IN INPUT MODE INA '1004 INPUT CHARACTER, RESET INTERRUPT HLT STA TEM0 SAVE SUB ESC ESCAPE ? SZE JMP TI NO ESCAPE * ESCAPE! ATTENTION HANDLER REQUEST? LDA ATTH AN ATTENTION HANDLER ACTIVE? SZE JMP TI YES; SO DISCARD ESC LDA EVAT NO HANDLER ACTIVE; CHECK ATTENTION HANDLER EVENT SNZ ATTENTION HANDLER WAITING FOR THIS EVENT? JMP TI CHAR IS NOT FOR A WAITING ATTENTION HANDER STA ATTH YES; SET ATTENTION HANDLER ACTIVATED FLAG (=TCB) LDA =1 ATTENTION EVENT IGNORES THE PAUSE STATE STA* EVAT RESET BLOCKED-BIT OF TASK WAITING FOR ATTENTION. CRA CLEAR ATTENTION EVENT AND STA EVAT DISCONNECT TTY INTERRUPT HANDLER FROM TASK JMP BACK EXIT FROM TTY INTERRUPT * CHAR REQUESTED BY A TASK WAITING FOR INPUT? TI LDA EVTY TASK WAITING FOR A TTY EVENT? SNZ JMP BACK NO, EXIT FROM TTY INTERRUPT * YES, A TASK IS WAITING FOR INPUT STA 0 X = TCB ADDRESS OF TASK WAITING FOR INPUT LDA TEM0 READ CHARACTER STA A,1 STORE IN A REG OF WAITING TASK EXTY LDA* EVTY STATE SSP STA* EVTY RESET BLOCKED-BIT IN STATE OF WAITING TASK CRA CLEAR TTY EVENT AND STA EVTY DISCONNECT TTY INTERRUPT HANDLER FROM TASK JMP BACK EXIT FROM TTY INTERRUPT * TTY IN OUTPUT MODE OMOD LDA EVTY TASK WAITING FOR A TTY EVENT? SNZ JMP RSTY NO CHARS TO PRINT ANYMORE; RESET INTERRUPT * YES, TASK WAITING FOR OUTPUT STA 0 X = TCB ADDRESS OF TASK WAITING FOR OUTPUT LDA A,1 GET CHARACTER TO PRINT OTA 4 PRINT CHAR, RESET INTERRUPT HLT JMP EXTY * RESET THE INTERRUPT BY SWITCHING THE TTY TO INPUT RSTY OCP 4 NO OUTPUT REQUEST, RESET TTY INTERRUPT STA MODE MODE = 0, INPUT MODE JMP BACK AND RETURN EJCT * * WORKING STORAGE RING-0 ************************ * TEM0 OCT 0 TEMPORARY FOR RING-0 SA OCT 0 SAVE A SX OCT 0 SAVE X SK OCT 0 SAVE KEYS TICK DEC -5 RTC CLOCK PULSES PER TICK ESC OCT 233 ATTENTION KEYCODE * * TTY READ/PRINT EVENT PVTY DAC *+1 POINTER TO TTY EVENT EVTY OCT 0 TCB ADDRESS OF TASK WAITING FOR TTY EVENT * 0 WHEN NO TASK IS WAITING FOR AN TTY EVENT * TTY ATTENTION HANDLER EVENT PVAT DAC *+1 POINTER TO ATTENTION EVENT EVAT OCT 0 TCB ADDRESS OF TASK WAITING FOR ATTENTION EVENT * 0 WHEN NO TASK IS WAITING FOR AN ATTENTION EVENT ATTH OCT 0 TCB ADDRESS OF ATTENTION HANDLER IF ATTENTION * HANDLER ACTIVE; ELSE 0 * * PTR EVENT PVPI DAC *+1 POINTER TO PTR EVENT EVPI OCT 0 TCB ADDRESS OF TASK WAITING FOR PTR EVENT * 0 WHEN NO TASK IS WAITING FOR AN PTR EVENT * PTP EVENT PVPO DAC *+1 POINTER TO PTP EVENT EVPO OCT 0 TCB ADDRESS OF TASK WAITING FOR PTP EVENT * 0 WHEN NO TASK IS WAITING FOR AN PTP EVENT EJCT *************************************************************** * RING-1: THE SERVICE PRIMITIVES FOR RING-2 AND THE SCHEDULER * *************************************************************** * RING-2 ENTERING RING-1: T POINTS TO THE TCB OF THE CURRENT TASK. * THE RING-1 PRIMITIVES ARE NOT REENTRANT: RING-1 CODE IS NOT ALLOWED TO CALL * RING-1 PRIMITIVES AND, BECAUSE THE INTERRUPT IS ENABLED IN PARTS OF RING-1 * AND WHEN RING-1 IS ENTERED, ALSO RING-0 IS NOT ALLOWED TO USE RING-1 * PRIMITIVES. (E.G. THE PRIMITIVE'S CALL ADDRESS COULD BE OVERWRITTEN). * THE MAIN CONSEQUENCE OF THIS DESIGN IS THAT RING-0, AFTER HANDLING AN * INTERRUPT, IS NOT ALLOWED TO GO TO THE SCHEDULER. * AFTER INTERRUPT COMPLETION, RING-0 HAS JUST TO RESUME AT THE * LOCATION WERE THE PROCESSING WAS INTERRUPTED (EITHER ON RING-2 OR RING-1). * * TIMER SERVICE (TO BE USED BY RING-2) *************** * * POINTER TO THE TABLE WITH TIMERS PTIM XAC CTAB POINTER TO TIMER TABLE * * EACH TIMER CONSISTS OF TWO WORDS: * WORD1 = POINTER TO TCB OF TASK WAITING FOR THIS TIMER (TIMER EVENT) * A TIMER IS FREE WHEN THE POINTER VALUE IS 0 * WORD2 = - THE TIMER VALUE IN TICKS OF 0.1 SEC * * TIMERS ARE DEFINED IN THE TIMER TABLE CTAB. IF A TASK REQUESTS A TIMER * SERVICE, A FREE TIMER IS ALLOCATED AND CONNECTED TO THE TASK. A TIMER IS * LINKED TO A TASK BY EXECUTING: * CALL SLEEP * OCT (A TICK IS 0.1 SEC) * WITH THIS CALL, THE TASK SLEEPS FOR THE SPECIFIED TIME AND IS RESTARTED * AFTER THE TIMER IS DUE. THE TIMER IS RELEASED. * SLEP DAC ** JST SAVE SAVE CPU STATE * LOOK FOR A FREE TIMER ST LDX PTIM POINTER TO TIMER LDA* 0 TCB ADDRESS? SNZ JMP FRTI NO, SO A FREE TIMER FOUND AOA SNZ HLT END OF TABLE, STOP, TO FEW TIMERS DEFINED IRS 0 IRS 0 POINTER TO NEXT TIMER JMP ST+1 * SET THE TIMER (X = TIMER ADDRESS) FRTI LDA* SLEP STORE TICK VALUE TCA STA 1,1 INTO TIMER LDA T STA* 0 STORE TCB ADDRESS OF SLEEPING TASK IN TIMER LDA 0 EVENT ADDRESS JMP BLOK BLOCK THE TASK AND RESCHEDULE EJCT * DEVICE MANAGEMENT SERVICES (TO BE USED BY RING-2) **************************** * * ATTACH DEVICE(S) CALLING SEQUENCE: * CALL ATTW (BLOCKING) * DAC TTY ATTENTION HANDLER * OR * CALL ATTW (BLOCKING) * OCT DEV (ONE OR MORE DEVICES; BITS 9-16) * OR * CALL ATT (NON BLOCKING) * OCT DEV (ONE OR MORE DEVICES; BITS 9-16) * *** *** NO SUCCESS RETURN * *** *** SUCCESS RETURN * DEVS OCT 0 GLOBAL DEVICE ATTACHEMENT STATE * * BIT ALLOCATION IN DEVS FOR 8 DEVICES MAX. * BITS 9-13 FREE * BIT 14 PTP * BIT 15 PTR * BIT 16 TTY * **** ATTW - BLOCKING REQUEST ATTW DAC ** JST SAVE SAVE CPU STATE LDA* ATTW CAR DEVICE MASK, BITS 9-16 = 0 SNZ JMP DATT DEVICE ATTACH * SPECIAL REQUEST: ATTENTION HANDLER REQUEST FOR THE TTY LDA EVAT OTHER TASK IS ALREADY WAITING FOR AN ATTENTION SNZ EVENT. WAIT JMP IDL NO, SO PROCEED * AN ATTENTION HANDLER IS ACTIVE, OR REQUESTED DEVICE(S) ALREADY ATTACHED TBUS LDA ATTW BACK TO RING-2, BUSY WAITING JMP BUSY UNTIL RELEASED BY OTHER TASKS * * ATTACH ATTENTION HANDLER IDL LDA* ATTW ATTW POINTS TO ATTENTION HANDLER ADDRESS STA LABL,1 SAVE AS TASK CONTINUATION ADDRESS STX EVAT ATTACH TASK TO ATTENTION EVENT (RING-0) LDA PVAT SET TASK WAITING FOR ATTENTION EVENT JMP BLOK BLOCK THE TASK, SAVE ITS STATE AND SCHEDULE * ATTACH 'NORMAL' DEVICES DATT LDA DEVS ARE THE REQUESTED DEVICES FREE ? ANA* ATTW SZE JMP TBUS REQUESTED DEV(S) NOT FREE, WAIT FOR RELEASE * * UPDATE THE DEVICE STATUS (FOR ATTACH/RELEASE) * UDEV LDA DEV,1 ERA* ATTW STA DEV,1 SET THE DEVICES ATTACHED/RELEASED IN TASK LDA DEVS ERA* ATTW STA DEVS SET THE DEVICES ATTACHED/RELEASED GLOBALLY JMP RESH EXIT, RESCHEDULE * **** ATT - NON BLOCKING REQUEST ATT DAC ** JST SAVE SAVE CPU STATE LDA DEVS CHECK WHETHER THE REQUESTED DEVICES ARE FREE ANA* ATT SZE JMP RESH REQUESTED DEV(S) NOT FREE, NO SUCCESS RETURN * REQUESTED DEVICES ARE FREE, SO CAN BE ATTACHED SUC IRS LABL,1 SET CONTINUATION ADDRESS (SUCCESS RETURN) LDA ATT MOVE POINTER STA ATTW JMP UDEV AND UPDATE THE DEVICE STATUS * **** RELEASE DEVICE(S), CALLING SEQUENCE: * CALL REL * OCT DEV (ONE OR MORE DEVICES) * * A RELEASE WITH OCT 0 RELEASES THE TTY OF AN ACTIVE ATTENTION HANDLER * (ACTIVATED BY THE ATTENTION EVENT). WITH THIS RELEASE THE ATTENTION * HANDLER BECOMES A NORMAL TASK, WHICH CAN ATTACH/RELEASE THE TTY IN THE * STANDARD WAY. * * ONLY A TASK WHICH ATTACHES A DEVICE IS ALLOWED TO RELEASE THAT DEVICE * REL DAC ** JST SAVE SAVE CPU STATE LDA* REL SZE RELEASE ATTENTION HANDLER TTY? JMP NR NO * RELEASE THE ATTENTION HANDLER TTY LDA ATTH ATTENTION HANDLER ACTIVE? SUB 0 TCB ADDRESS CURRENT TASK SZE JMP NR THIS TASK IS NOT THE ATTENTION HANDLER * ATTENTION HANDLER ACTIVE, AND THIS TASK IS THE ATTENTION HANDLER STA ATTH MAKE ATTENTION HANDLER INACTIVE, WHICH MAKES JMP RESH THE TTY AVAILABLE FOR OTHER TASKS * NORMAL DEVICE RELEASE NR LDA DEV,1 ATTACHED DEVICES ANA* REL ERA* REL SZE * TASK TRIES TO RELEASE A NOT ATTACHED DEVICE HLT ********** ERROR STOP ********** * GENERAL DEVICE RELEASE LDA REL MOVE POINTER JMP SUC+2 AND UPDATE THE DEVICE STATUS EJCT * TTY SERVICES (TO BE USED BY RING-2) ************** * * THE TTY IS A HALFDUPLEX DEVICE USED FOR EITHER INPUT OR OUTPUT, SO IT * IS NOT A STATELESS DEVICE. THE CONTROL UNIT HOWEVER SHARES A SINGLE * INTERRUPT FOR INPUT AND OUTPUT AND IS NOT ABLE TO REPORT ITS STATE TO * THE PROGRAM. SO THE PROGRAM HAS TO MAINTAIN THE TTY STATE. * * IN THIS PROGRAM THE FOLLOWING TTY STATES ARE DISTINGUISHED (MAINTAINED * IN A 16 BIT WORD 'MODE': * - INPUT MODE: * 'MODE' INPUT: 0000000000000000 * ONE OR MORE CHARACTERS CAN BE READ FROM THE TTY (CHAR BY CHAR WITH * 'ASRI'). THE TTY REMAINS IN THIS MODE UNTIL SWITCHED TO 'OUTPUT'. * - OUPUT MODE: * 'MODE' OUTPUT: 0000000000000001 * ONE OR MORE CHARACTERS ARE PRINTED ON THE TTY (CHAR BY CHAR WITH * 'ASRO'). WHEN NO CHARACTERS ARE DELIVERED FOR PRINTING, THE TTY IS * SWITCHED TO INPUT MODE (AND PHYSICAL SWITCHED TO INPUT TO RESET THE * LAST OUTPUT INTERRUPT) * * THE TTY EVENT (EVTY) INDICATES AN IO REQUEST FOR THE TTY. THIS EVENT IS SET * BY THE ASRI/ASRO ROUTINES. IF AN INTERRUPT OCCORS WHILE THE EVENT IS NOT SET: * - IN INPUT MODE, WITH AN INA INSTRUCTION THE INTERRUPT IS RESET AND THE * READ CHARACTER IS DISCARDED * - IN OUTPUT MODE, THE INTERRUPT IS RESET BY SWITCHING THE TTY TO INPUT WITH * AN OCP 4 * * WITH AN INTERRUPT IN INPUT MODE THE TTY EVENT (EVTY) IS OVERRULED BY A * ATTENTION EVENT (EVAT) IF SET. WHEN THE READ CHARACTER IS AN ESC, THE * ATTENTION HANDLER IS ACTIVATED AND THE TTY IS REALLOCATED TO THE ATTENTION * HANDLER. TTY IO OF A TASK TO WHICH THE TTY IS ATTACHED IS STALLED UNTIL * THE ATTENTION HANDLER EXITS, OR RELEASES THE ATTENTION HANDLING TTY. * * TTY PRIMITIVES: * -ASRI, SETS THE TTY IN INPUT MODE AND INPUTS THE NEXT CHARACTER FOR THE * PROGRAM TASK. * -ASRO, SETS THE TTY IN OUTPUT MODE AND PRINTS THE NEXT CHARACTER FOR THE * PROGRAM TASK. * **** ASRI, READ CHAR FROM TTY; CALLING SEQUENCE: * CALL ASRI SWITCH TTY INPUT MODE * *** *** RETURNS HERE WITH THE NEXT CHAR FROM THE TTY IN A-REG * * ASRI IS A 'BLOCKING' PRIMITIVE * ASRI DAC ** JST SAVE SAVE CPU STATE, X = T = ADDRESS CURRENT TCB LDA ASRI JST CHTY CHECK REQUEST AND WAIT FOR NON BUSY TTY * SWITCH TTY TO INPUT MODE, WHICH RESETS READY OCP 4 SET INPUT MODE CRA TTY MODE = INPUT MODE JMP COEX TO COMMON PART * **** ASRO, PRINT CHAR ON TTY; CALLING SEQUENCE: * LDA CHAR A = CHAR TO PRINT ON TTY * CALL ASRO SETS TTY IN OUTPUT MODE * *** *** RETURNS HERE * * ASRO IS A 'BLOCKING' PRIMITIVE * ASRO DAC ** JST SAVE X = T = TCB ADDRESS LDA ASRO JST CHTY CHECK REQUEST AND WAIT FOR NON BUSY TTY * SWITCH TTY TO OUTPUT MODE (WHICH MAKES THE TTY READY) OCP '104 SET OUTPUT MODE LDA =1 TTY MODE = OUTPUT MODE * COEX STA MODE SET TTY MODE + REQUEST BIT LDA ASRO POINTER TO JST ASRI/ASRO + 1 STA LABL,1 SAVE AS TASK CONTINUATION ADDRESS STX EVTY ATTACH TASK TO TTY EVENT (RING-0) AND SET LDA PVTY TASK WAITING FOR THIS EVENT JMP BLOK BLOCK THE TASK, SAVE ITS STATE AND SCHEDULE * MODE OCT 0 TTY MODE STATUS WORD * * CHECK WHETHER REQUEST IS FROM ATTENTION HANDLER TASK (OR OTHER TASK) * AND WAIT FOR TTY IS NOT BUSY. * WHEN AN ATTENTION HANDLER IS ACTIVE AND THE REQUEST IS THE ATTENTION * HANDLER, THE HONOR THE REQUEST. * WHEN AN ATTENTION HANDLER IS ACTIVE AND THE REQUEST IS NOT FROM THE ATTENTION * HANDLER, DO NOT THE HONOR THE REQUEST. * WHEN NO ATTENTION HANDLER IS ACTIVE, HONOR THE REQUEST. CHTY DAC ** STA ASRO SAVE RETURN ADDRESS LDA ATTH ATTENTION HANDLER ACTIVE? SNZ JMP TBU NO, TEST FOR NON BUSY TTY * ATTENTION HANDLER IS ACTIVE. IF THIS REQUEST IS FROM THE ATTENTION HANDLER * THEN THE TTY REQUEST CAN BE HONORED. IF THE REQUEST IS NOT FROM THE * ATTENTION HANDLER, THE THE TASK HAS TO WAIT UNTIL THE TTY IS RELEASED BY * THE ATTENTION HANDLER . SUB 0 IS CURRENT TASK THE ATTENTION HANDLER? SNZ JMP TBU YES, PROCEED LDA ASRO REQUEST NOT FROM THE ATTENTION HANDLER, JMP BUSY SO WAIT TILL TTY IS RELEASED TBU LDA ASRO SKS '104 BACK TO RING-2 IF TTY BUSY JMP BUSY TTY BUSY; SET TASK PENDING FOR TTY NOT BUSY JMP* CHTY EJCT * HIGH SPEED PAPERTAPE SERVICES (TO BE USED BY RING-2) * **** PTRI, READ CHARACTER FROM PTR (HIGH SPEED PAPERTAPE READER) * CALLING SEQUENCE: * CALL PTRI * *** *** RETURNS HERE WITH HE NEXT CHAR IN A-REG * PTRI DAC ** JST SAVE SAVE CPU STATE OCP 1 START READER LDA PTRI STA LABL,1 SET TASK CONTINUATION ADDRESS STX EVPI SET PAPERTAPE READER EVENT LDA PVPI EVENT ADDRESS JMP BLOK AND BLOCK CURRENT TASK * **** PTPU, PUNCH CHARACTER FROM PTP (HIGH SPEED PAPERTAPE PUNCHER) * CALLING SEQUENCE: * LDA CHAR A = CHAR TO PUNCH * CALL PTPO * *** *** RETURNS HERE * PTPO DAC ** JST SAVE SAVE CPU STATE SKS '102 SKIP IF PUNCHER ON OCP 2 PUNCHER ON LDA PTPO STA LABL,1 SET TASK CONTINUATION ADDRESS STX EVPO SET PAPERTAPE PUNCHER EVENT LDA PVPO EVENT ADDRESS JMP BLOK AND BLOCK CURRENT TASK EJCT * * TASK SYNCHRONISATION SERVICES (TO BE USED BY RING-2) ******************************* * TWO TYPES OF TASK SYNCHRONISATION ARE SUPPORTED: * 1) WITH TASK-LINKED EVENTS * 2) SOFT-EVENTS, OPERATING AS COUNTING SEMAPHORES * * TASK-LINKED EVENTS CAN BE USED TO WAIT FOR EXIT OF A SPECIFIC TASK OR ON * A SIGNAL FROM A SPECIFIC TASK. WHEN A TASK EXECUTES ANOTHER TASK WITH * THE EXEW PRIMITIVE, THE CALLING TASK IS BLOCKED UNTIL THE EXECUTED TASK * EXITS, OR PROVIDES A SIGNAL (SIG 0). IF THE TASK IS STARTED WITH THE EXE * PRIMITIVE, THE CALLING TASK IS NOT BLOCKED, BUT STILL CAN EXECUTE A WAIT * FOR THE EARLIER STARTED TASK. IN CASE THE STARTED TASK DID NOT EXIT YET, * THE CALLING TASK IS BLOCKED AND UNBLOCKED BY THE EXIT OF THE STARTED TASK * (OR BY A SIG 0 OF THE STARTED TASK). IN THE SAME WAY A TASK CAN WAIT FOR * EXIT OR A SIG 0 OF ANY OTHER SPECIFIC TASK. * * SOFT-EVENTS ARE CONTROLED BY 3 PRIMITIVES: WAIT (SEMEPHORE DOWN), SIGNAL * (SEMAPHORE UP) AND RSIG (RESET/INIT THE SIGNAL WITH AN INITIAL COUNT). * SOFT-EVENTS ARE IDENTIFIED BY A NUMBER, STARTING WITH NUMBER 1 (EVENT 0 * IS THE TASK-LINKED EVENT; EACH TASK HAS ITS OWN EVENT 0). ALLOCATION OF * A SOFT-EVENT FOR A SPECIFIC PURPOSE IS TO BE DONE BY THE PROGRAMMER; THE * SOFT-EVENTS ARE NOT MANAGED AS RESOURCES BY THE SYSTEM. * RSIG 1 INITIALIZES A BINARY SEMAPHORE WHICH CAN BE USED TO CONTROL A CRITICAL * SECTION. MAXIMUM NUMBER OF SUPPORTED SOFT-EVENTS IS OCTAL 77; THE MAXIMUM * INITIAL VALUE OF A SOFT-EVENT CAN BE OCTAL 77. * PSET XAC ETAB,1 INDEXED POINTER TO SOFT-EVENT TABLE * * WAIT FOR AN EVENT; CALLING SEQUENCE: ****** * 1) WAIT FOR TASK EXIT OR ON A SIG-0 OF A TASK * CALL WAIT * DAC TCB (TCB ADDRESS OF THE TASK TO WAIT FOR) * * 2) WAIT FOR A SOFT-EVENT (SEMAPHORE DOWN) * CALL WAIT * OCT XX (SOFT-EVENT NUMBER, 1-MAX '77) * WAIT DAC ** JST SAVE SAVE CPU STATE * SET CONTINUATION ADDRESS LDA* WAIT SIGNAL NBR OR TCB ADDRESS OF TASK TO WAIT FOR STA TEM1 CAR BITS 9-16 = 0 SNZ JMP SOFT SOFT EVENT * WAIT FOR TASK EVENT LDA* TEM1 STATE OF TASK TO WAIT FOR SNZ JMP RESH TASK REQUESTED TO WAIT FOR IS NOT RUNNING * THE REQUESTED TASK TO WAIT FOR IS RUNNING LDA TEM1 TCB ADDRESS ADD =7 OFFSET TASK EVENT (TEVT) STA TEM1 POINTS TO TASK EVENT OF TASK TO WAIT FOR LDA* TEM1 OTHER TASK WAITING? SNZ JMP FREE NO, SO THE EVENT CAN BE SET * YES, ALREADY ANOTHER TASK IS WAITING FOR THIS EVENT * QUEUE THE CURRENT REQUEST W LDA WAIT JMP BUSY * STORE THE TCB ADDRESS OF THE WAITING TASK IN THE TASK-EVENT FREE STX* TEM1 X = TCB ADDRESS OF THE CALLING TASK LDA TEM1 EVENT ADDRESS JMP BLOK AND BLOCK THE CALLING TASK * * WAIT FOR A SOFT-EVENT SOFT LDX* WAIT SOFT-EVENT NUMBER LDA* PSET GET ITS COUNT VALUE SPL IF POSITIVE, TASK MAY PROCEED JMP W WAIT FOR A SIGNAL SUB =1 DOWN STA* PSET AND RESTORE THE COUNT VALUE JMP RESH * * SIGNAL AN EVENT; CALLING SEQUENCE: * * 1) SIGNAL TASK EVENT * CALL SIGNAL * OCT 0 (REFERING TO THE TASK-LINKED EVENT) * * 2) SIGNAL A SOFT-EVENT * CALL SIGNAL * OCT XX (SOFT-EVENT NUMBER 1-MAX '77) * SIG DAC ** JST SAVE SAVE CPU STATE LDA* SIG EVENT NUMBER SZE JMP SS * SIGNAL TASK EVENT LDA TEVT,1 TCB ADDRESS OF TASK TO UNBLOCK SNZ JMP RESH NO WAITING TASK STA TEM1 LDA* TEM1 STATE SSP SET STATE READY STA* TEM1 CRA STA TEVT,1 CLEAR TASK EVENT JMP RESH * SIGNAL SOFT EVENT SS STA 0 X = EVENT NUMBER IRS* PSET UP NOP JMP RESH * * REVENT - RESET SOFT EVENT, SET INITIAL COUNT ******** * CALLING SEQUENCE: * CALL REVENT * OCT XXYY (BITS 5-16) * WHERE XX = INITIAL COUNT BITS 5 - 10 * YY = SOFT EVENT NUMBER BITS 11 - 16 * RSEV DAC ** JST SAVE SAVE CPU STATE LDA* RSEV ANA ='77 SOFT EVENT NUMBER SNZ JMP RESH NUMBER 0 (TASK EVENT) CAN NOT BE RESET STA 0 X = EVENT NUMBER LDA* RSEV LGR 6 SUB =1 = COUNT VALUE STA* PSET STORE IN SOFT EVENT JMP RESH EJCT * * * TASK MANAGEMENT SERVICES (TO BE USED BY RING-2) ************************** * **** TASK EXECUTION * 1) EXEC TASK AND WAIT FOR EXIT; CALLING SEQUENCE: * CALL EXEW * DAC TCB (TCB ADDRESS OF THE TASK TO START) * * THE STARTING TASK (='PARENT') IS BLOCKED AND UNBLOCKED AFTER EXIT OF THE * STARTED (='CHILD') TASK (OR BY A SIG-0 OF THE STARTED TASK). * THE DEVICES ATTACHED TO THE STARTING TASK (='PARENT') ARE ALSO ATTACHED TO * THE STARTED TASK (='CHILD') AND NOT RELEASED WHEN THE STARTED TASK EXITS. * * 2) EXEC TASK; CALLING SEQUENCE: * CALL EXE * DAC TCB (TCB ADDRESS OF THE TASK TO START) * * THE CALLING TASK IS NOT BLOCKED (SO REMAINS READY); NO ATTACHED DEVICES * OF THE STARTING TASK ARE ATTACHED TO THE STARTED TASK. IF THE TASK TO * START IS ALREADY STARTED, THE STARTING TASK IS BLOCKED UNITL THE TASK TO * START CAN BE STARTED. * * 3) EXIT THE CURRENT TASK; CALLING SEQUENCE: * CALL EXIT * * SIGNALS EXIT AND RELEASES (STILL) ATTACHED DEVICES NOT ATTACHED TO THE * PARENT TASK, IF THE TASK WAS STARTED BY EXEW. * AT KERNEL LEVEL, THE TCB IS NOT CLEARED, SO THE TASK CAN BE RESTARTED * WITH EXE OR EXEW (THE TASK MUST THEN OF COURSE BE ABLE TO REINIT ITSELF). * * 4) KILL ANOTHER TASK; CALLING SEQUENCE: * CALL KILL * DAC TCB (TCB ADDRESS OF THE TASK TO KILL) * * INDEPENDENT OF ITS STATE, THE TASK IS KILLED, AN EVENT THE TASK WAS * WAITING FOR IS CLEARED, EXIT IS SIGNALLED AND (STILL) ATTACHED DEVICES, * NOT ATTACHED TO THE PARENT TASK, IF THE TASK WAS STARTED BY EXEW, ARE * RELEASED. * AT KERNEL LEVEL, THE TCB IS NOT CLEARED, SO THE TASK CAN BE RESTARTED * WITH EXE OR EXEW (THE TASK MUST THEN OF COURSE BE ABLE TO REINIT ITSELF). * * 5) SUSPEND ANOTHER TASK, CALLING SEQUENCE: * CALL PAUSE * DAC TCB (TCB ADDRESS OF THE TASK TO SUSPEND) * * PAUSE SUSPENDS A TASK AND THE TASK'S DEVICES ARE RELEASED FOR USE BY OTHER * TASKS. AN ACTIVE ATTENTION HANDLER CAN NOT BE SUSPENDED (A PASSIVE * ATTENTION HANDLER, WHICH IS A TASK WAITING FOR AN ATTENTION EVENT, CAN BE * SUSPENDED, BUT THE ATTENTION EVENT ACTIVATES THE ATTENTION HANDLER). * * 6) RESUME A SUSPENDED TASK, CALLING SEQUENCE: * CALL RESUME * DAC TCB (TCB ADDRESS OF THE TASK TO RESUME= * *** NO SUCCESS RETURN ADDRESS (RELEASED DEVICES CAN NOT BE REATTACHED) * *** SUCCESS RETURN * * RESUME REACTIVATES A SUSPENDED TASK AFTER REATTACHMENT OF THE RELEASED * DEVICES WITH THE SUSPEND. * * 7) YIELD, LEAVE THE CURRENT TASK, AND SCHEDULE THE NEXT READY TASK * CALL YIELD (THE CURRENT TASK REMAINS READY) * **** EXE, EXEC TASK * EXE DAC ** JST SAVE SAVE CPU STATE CRA E1 STA TEM1 SET EXE FLAG: 0 = EXE, 1 = EXEW LDX* EXE X = TCB ADDRESS OF TASK TO START LDA* 0 STATE? SNZ JMP E2 NOT RUNNING * REQUESTED TASK IS RUNNING; QUEUE THE CURRENT REQUEST LDA EXE JMP BUSY * REQUESTED TASK IS NOT RUNNING; FILL TCB E2 AOA STA* 0 SET START BIT LDA STRT,1 STA LABL,1 SET CONTINUATION ADDRESS (PC) * EXE OR EXEW ? LDA TEM1 SNZ JMP RESH EXE * POSTPROCESS EXEW LDA T STORE TCB ADDRESS OF CURRENT TASK INTO TASK EVENT, STA TEVT,1 TO SET THE CURRENT TASK WAITING FOR EXIT. LDA 0 X = TCB ADDRESS OF TASK TO START ADD =7 + TASK EVENT OFFSET = EVENT ADDRESS JMP BLOK BLOCK THE CURRENT TASK * **** EXEW, EXEC TASK AND WAIT FOR EXI * EXEW DAC ** JST SAVE LDA EXEW MOVE LINK STA EXE LDA =1 SET EXE FLAG: 0 = EXE, 1 = EXEW JMP E1 * **** EXIT, EXIT CURRENT TASK * EXIT DAC ** JST SAVE SAVE CPU STATE * RELEASE THE NORMAL DEVICES EXIK LDA DEV,1 ATTACHED DEVICES TO RELEASE CMA ANA DEVS RELEASE ATTACHED DEVICES OF CURRENT TASK STA DEVS * IS THE ATTENTION HANDLER EXITING? EXSU LDA ATTH ATTENTION HANDLER ACTIVE? SUB 0 TCB ADDRESS OF CURRENT TASK SZE SKP NOT AN EXIT OF THE ATTENTION HANDLER STA ATTH ATTH=0; ATT. HANDLER INACTIVE, TTY RELEASED * UPDATE TCB CRA STA* 0 STATE = 0 STA DEV,1 NO DEVICES ATTACHED IMA TEVT,1 TASK EVENT RESET SNZ JMP RESH NO TASK WAITING FOR THIS TASK STA TEM1 POINTER TO TCB OF TASK TO UNBLOCK LDA* TEM1 STATE SSP RESET BLOCKED BIT TO MAKE TASK READY STA* TEM1 UPDATE STATE JMP RESH * **** KILL ANOTHER TASK; CALLING SEQUENCE * CALL KILL * DAC TCB (TCB ADDRESS OF TASK TO KILL) * KILL DAC ** JST SAVE SAVE CPU STATE * TASK BLOCKED? LDX* KILL TCB ADDRESS OF TASK TO KILL LDA* 0 STATE SMI JMP K2 NOT BLOCKED; TASK SUSPENDED? * YES, THE TASK TO KILL IS BLOCKED => CLEAR EVENT/DECOUPLE EVENT FROM TASK CRA STA* PWEV,1 CLEAR EVENT * TASK SUSPENDED? K2 LDA =2 ANA* 0 SNZ JMP EXIK NOT SUSPENDED; EXIT THE TASK JMP EXSU EXIT SUSPENDED TASK; NO DEVICE RELEASE * **** PAUSE, CALLING SEQUENCE: * CALL PAUSE * DAC TCB (TCB ADDRESS OF THE TASK TO SUSPEND) * * PAUSE SUSPENDS ANOTHER TASK AND ITS DEVICES ARE RELEASED FOR USE BY OTHER * TASKS. AN ACTIVE ATTENTION HANDLER CAN NOT BE SUSPENDED (A PASSIVE ATTENTION * HANDLER, WHICH IS A TASK WAITING FOR AN ATTENTION EVENT CAN BE SUSPENDED BUT * THE ATTENTION EVENT ACTIVES THE ATTENTION HANDLER). * PA DAC ** JST SAVE SAVE CPU STATE LDA* PA TCB ADDRESS OF THE TASK TO SUSPEND STA 0 X = TCB ADDRESS OF THE TASK TO SUSPEND SUB ATTH IS IT THE ATTENTION HANDLER? SNZ IT IS NOT ALLOWED TO SUSPEND AN ACTIVE ATTENTION JMP RESH HANDLER LDA* 0 STATE SSP RESET A POSSIBLE BLOCKED BIT SUB =1 SZE ONLY READY/BLOCKED TASKS CAN BE SUSPENDED JMP RESH LDA =2 ERA* 0 SET PAUSE STATE STA* 0 LDA DEV,1 RELEASE ATTACHED DEVICES ERA DEVS STA DEVS JMP RESH * **** RESUME, CALLING SEQUENCE: * CALL RESUME * DAC TCB (TCB ADDRESS OF THE TASK TO RESUME= * *** NO SUCCESS RETURN ADDRESS (RELEASE DEVICES CAN NOT BE ATTACHED) * *** SUCCESS RETURN * * RESUME REACTIVATES A SUSPENDED TASK AFTER REATTACHMENT OF THE RELEASED * DEVICES WITH THE SUSPEND * RESU DAC ** JST SAVE SAVE CPU STATE LDX* RESU X = TCB ADDRESS OF TASK TO RESUME LDA DEVS DEVICES FREE? ANA DEV,1 SZE JMP RESH NO, NO SUCCESS RETURN LDA ='177775 ANA* 0 STA* 0 RESET PAUSE STATE LDA DEVS ERA DEV,1 STA DEVS REATTACH THE DEVICES IRS LABL,1 SET SUCCESS RETURN ADDRESS JMP RESH * **** YIELD, CALLING SEQUENCE: * CALL YIELD * * YIELD LEAVES THE CURRENT TASK AND ALLOWS FOR SCHEDULING THE * NEXT READY TASK. THE CURRENT TASK REMAINS READY. * YIEL DAC ** JST SAVE SAVE CPU STATE LDA YIEL CONTINUATION ADDRESS JMP BUSY+1 SAVE ************* END OF THE RING-2 CALL INTERFACE ********************** EJCT ************* * SCHEDULER * ************* * * THE SCHEDULER IS A SIMPLE ROUND ROBIN SCHEDULER AND RUNS THE TASKS IN * RING-2 DEPENDING ON THEIR STATE: * - TASK NOT STARTED (STOP) 0000000000000000 * - TASK STARTED, NOT WAITING FOR EVENT (READY) 0000000000000001 * - TASK STARTED, WAITING FOR EVENT (BLOCKED) 1000000000000001 * - TASK STARTED, BUT SUSPENDED (PAUSED) X000000000000011 * (WHEN A TASK IS SUSPENDED, THE BLOCKED BIT CAN BE 1: X = 0 OR 1) * * A TAST IS BLOCKED WHEN WAITING FOR: * - IO EVENT (SIGNALLED BY AN INTERRUPT HANDLER) * - TASK EVENT (SIGNALLED BY EXIT OR SIG-0 OF THE TASK WAITING FOR) * - TIMER EVENT (SIGNALLED BY RTC INTERRUPT HANDLER) * - ATTENTION EVENT (SIGNALLED BY TTY INTERRUPT HANDLER) * * WHEN A TASK IS BLOCKED, THE PWEV ENTRY IN THE TASK'S TCB POINTS TO THE * EVENT THE TASK IS WAITING FOR. * * THE SCHEDULER RUNS AT RING-1 AND HAS THE FOLLOWING ENTRY POINTS * FOR RING-1 CODE: * SKED - SCHEDULER ENTRY POINT AFTER INITIALIZATION * RESH - ENABLE INTERRUPT AND SCHEDULE THE NEXT READY TASK * BLOK - SET TASK WAITING FOR AN EVENT, AND SCHEDULE THE NEXT READY TASK * BUSY - TASK PENDING FOR A CONDITION, SCHEDULE NEXT READY TASK * SAVE - INHIBIT INTERRUPT AND SAVE CPU STATE IN TCB * * THESE ENTRY POINTS MUST BE ENTERED WITH A JMP! * * EACH TASK IN RING-2 IS PRESENTED TO THE SCHEDULER BY A DATA STRUCTUCE: * THE TASK CONTROL BLOCK (TCB). THE LOCATION T ALWAYS POINTS TO THE TCB OF * THE CURRENT RUNNING TASK. * * TASK CONTROL BLOCK STRUCTURE STAT EQU 0 TASK STATE LABL EQU 1 ADDRESS WHERE TASK MUST CONTINUE (P) A EQU 2 SAVED A B EQU 3 SAVED B X EQU 4 SAVED X KEYS EQU 5 SAVED KEYS STRT EQU 6 TASK START ADDRESS TEVT EQU 7 TASK EVENT DEV EQU 8 ATTACHED DEVICES PWEV EQU 9 POINTER TO EVENT BLOCKED FOR TCBL EQU PWEV+1 LENGTH TCB (WHEN CHANGED, CHANGE SCHEDULER!) * T OCT 0 POINTER TO TCB OF RUNNING TASK PTAB XAC TTAB TASK CONTROL BLOCK (TCB) TABLE START ADDRESS TEND OCT '177777 TASK CONTROL BLOCK (TCB) TABLE END * * ***** SCHEDULER ENTRY POINT (TO BE USED BY INIT) SKED EQU * LDA PTAB POINTER TO 1ST TASK CONTROL BLOCK (TCB) NXTR STA T POINTER TO NEXT TCB TO CHECK ITS STATE LDA* T A = STATE, OR TABLE END CAS TEND =177777? END OF TABLE, OR STATE? SKP JMP SKED YES, TABLE END, RESTART FROM TOP * STATE IS READY ? SUB =1 SNZ JMP RUN STATE=1; READY * TASK BLOCKED, WAITING ON AN EVENT * ***** RESCHEDULER ENTRY POINT (TO BE USED BY RING-1) * LOOK FOR NEXT 'READY' TASK IN THE TASK QUEUE * T = POINTER TO TCB OF TASK WHICH GIVES UP THE CONTROL * WHEN ENTERED FROM RING-1 THE TCB OF THE TASK ASKING RESCHEDULE MUST BE * UPDATED (AT LEAST ITS CONTINUATION ADDRESS) RESH ENB LDA T ADDRESS CURRENT TCB ADD =10 + OFFSET TO NEXT TCB (****TCBL****) JMP NXTR * READY TASK FOUND => RUN * T = POINTER TO TCB OF THE 'READY' TASK RUN LDX T X = TCB ADDRESS LDA B,1 RESTORE B IAB LDA KEYS,1 OTK RESTORE C, ... LDA X,1 STA SAVX LDA LABL,1 GET CONTINUATION ADDRESS STA TEM1 LDA A,1 RESTORE A LDX SAVX RESTORE X JMP* TEM1 JUMP INTO TASK * ***** SET TASK BLOCKED ENTRY POINT (TO BE USED BY RING-1) * SET TASK BLOCKED, SAVE ITS STATE AND SCHEDULE NEXT 'READY' TASK * T = POINTER TO TCB OF CURRENT TASK * A = EVENT ADDRESS THE BLOCKED TASK IS WAITING FOR BLOK LDX T X = TCB ADDRESS CURRENT TASK STA PWEV,1 STORE EVENT ADDRESS IN TCB LDA* 0 GET STATE SSM SET BLOCKED BIT STA* 0 SET TASK STATE: WAITING FOR EVENT * RESCHEDULE; RUN NEXT NON-BLOCKED TASK JMP RESH * ***** SET TASK PENDING ENTRY POINT (TO BE USED BY RING-1) * ENTRY POINT FOR RING-1 TO SET A TASK PENDING (IN A 'BUSY WAITING LOOP') * A RING-1 PRIMITIVE MUST JUMP TO THIS ENTRY WITH THE ADDRESS OF THE * PRIMITIVE CALL AT RING-2 IN REG-A. THE PRIMITIVE CALL ADDRESS IN THE TASK * IS SAVED AS THE CONTINUATION ADDRESS OF THE THREAD. * * 'CALLING' SEQUENCE: * C JST P PRIMITIVE CALL IN THREAD (RING-2) * *** *** * * P *** *** PRIMITIVE ENTRY POINT (RING-1) * *** *** * LDA P A-REG = ADDRESS C+1 * SKS *** * JMP BUSY * * IN CASE THE SKS DOES NOT SKIP, THE JMP BUSY IS EXECUTED WITH AS RESULT THAT. * THE TASK IS RESTARTED AT ADDRESS C (THE CONTINUATION ADDRESS SAVED WITH * THE JMP TO BUSY) * A = CONTINUATION ADDRESS + 1; T = TCB ADDRESS CURRENT THREAD BUSY LDX T X = TCB ADDRESS CURRENT TASK SUB =1 STA LABL,1 SAVE CONTINUATION ADDRESS JMP RESH AND RESCHEDULE, STARTING AT NEXT THREAD EJCT ***** SAVE CPU STATE ENTRY POINT (TO BE USED BY RING-1) * WHEN ENTERING RING-1 TO EXECUTE THE RING-1 PRIMITIVE CODE. * THE JST TO SAVE MUST BE THE 1ST INSTRUCTION OF THE PRIMITIVE CODE. * CALLING SEQUENCE: * JST SAVE * RETURNS INH, WITH X = T = ADDRESS OF TCB OF CURRENT TASK * AND ALSO SETS THE DEFAULT CONTINUATION ADDRESS OF THE TASK EXECUTING * THE RING-1 PRIMITIVE (PRIMIITIVE CALL ADDRESS + 2). * SAVE DAC ** INH STX SAVX X, TEMPORARY SAVE LDX T X = TCB ADDRESS CURRENT TASK STA A,1 SAVE A IAB STA B,1 SAVE B INK STA KEYS,1 SAVE KEYS LDA SAVX STA X,1 SAVE X LDA SAVE SUB =2 STA SAVX = POINTER TO PRIMITIVE CALL ADDRESS + 1 LDA* SAVX AOA STA LABL,1 SET DEFAULT CONTINUATION ADDRESS JMP* SAVE * * TEMPORARY SPACE RING-1 SAVX OCT 0 TEM1 OCT 0 TEMPORARY FOR RING-1 FIN LITERALS RING-0 AND RING-1 KEND EQU *-1 END ADDRESS OF BASIC KERNEL ADDRESS RANGE END ********************************************************************** ********************** END OF MTK16 BASIC KERNEL ********************* **********************************************************************