PR#3 PREFIX /A2OSX.BUILD LOMEM $A00 INC 1 AUTO 6 *-------------------------------------- SYS.BASL0 .EQ $800 *-------------------------------------- CORE.Run lda CORE.PSCount sta CORE.Counter bne .1 SHOULD NEVER HAPPEN!!! jmp CORE.Events .1 ldx CORE.Counter lda PS.Table.PID-1,x beq .8 lda PS.Table.hMem-1,x jsr K.GetMemPtr.A >STYA pPS lda (pPs) get S.PS.F bit #S.PS.F.HOLD Waiting for Another Task to Terminate? beq .2 ldy #S.PS.CPID lda (pPs),y jsr CORE.GetPSByID.A bcc .8 yes, still running.... lda (pPs) get S.PS.F again and #$FF^S.PS.F.HOLD unmark as HOLD sta (pPs) .2 jsr CORE.PSEnter Restore at least ZP & Ptrs lda (pPs) get S.PS.F again bit #S.PS.F.SLEEP Is this PS sleeping? beq .3 no, call INIT/RUN and #$FF^S.PS.F.SLEEP unmark as SLEEP sta (pPS) jsr CORE.PSResume Restore PC....and JMP to bcc .7 bcs .5 .3 bit #S.PS.F.INIT beq .4 and #$FF^S.PS.F.INIT unmark as INIT sta (pPS) ldx #TSKMGR.INIT .HS 2C BIT abs .4 ldx #TSKMGR.RUN jsr pCodeJmp Call INIT/RUN function bcc .7 INIT/RUN/RESUME said CS=QUIT? .5 tax save RC ldy #S.PS.PPID Notify Parent Process for exit code... lda (pPs),y jsr CORE.GetPSByID.A X unmodified bcs .6 parent is dead.....skipping... >STYA ZPPtr1 lda (ZPPtr1) Parent PS is HOLD? bit #S.PS.F.HOLD beq .6 no... eor #S.PS.F.HOLD yes, release hold... sta (ZPPtr1) txa ...probably waiting for this PS to terminate.... ldy #S.PS.RC give it RC sta (ZPPtr1),y .6 ldx #TSKMGR.QUIT Quit this process jsr pCodeJmp Call QUIT function ldy #S.PS.PID lda (pPs),y jsr CORE.PSFree.A bra .8 .7 jsr CORE.PSLeave Save ZP & Ptrs .8 dec CORE.Counter bne .1 *-------------------------------------- CORE.Events jsr CORE.GetEvents bcs .4 CS=no event jsr CORE.DispatchEvents bcc .4 CC=All Events Dispatched jsr CORE.PSSelect0 lda #EvtMgr.Table sta pEvent .1 lda (pEvent) beq .3 bmi .2 Ignore & Discard any timer event jsr CORE.DumpEvent .2 jsr CORE.DestroyEvent .3 lda pEvent clc adc #S.EVT sta pEvent lda EVTMGR.COUNT bne .1 *-------------------------------------- .4 lda A2osX.ASCREEN cmp #2 is SYS active? bne .6 ldx CORE.CPULoadI lda CORE.CPULoadC,x sta SYS.BASL0+38 dex bpl .5 ldx #3 .5 stx CORE.CPULoadI .6 bit OPENAPPLE bpl .8 lda KBD bpl .8 cmp #"1" bcc .8 cmp #"5" bcs .8 sta KBDSTROBE jsr CORE.ScreenSelect .8 jmp CORE.Run *-------------------------------------- * CORE.GetEvents : * IN : * OUT : * CS = no event, A = ERROR * CC * event in YA * (pEvent) *-------------------------------------- CORE.GetEvents lda #EvtMgr.Table sta pEvent point to start of event list stz EvtMgr.Count reset Size lda K.IrkMgr.VBL do we have IRQ enabled for VBL ? bpl .10 no, regular poll lda K.IrkMgr.VBLINT beq .3 no dec K.IrkMgr.VBLINT bra .11 .10 lda VBL get VLINE status tax eor EvtMgr.VBLState bpl .3 no change,no tick txa sta EvtMgr.VBLState save new bpl .3 Up2down transition,no tick .11 inc A2osX.TIMER16 bne .1 inc A2osX.TIMER16+1 .1 dec EvtMgr.HZ.CNT bne .3 not yet 100ms ldx A2osX.HZ stx EvtMgr.HZ.CNT lda #S.EVT.F.T10TH dec EvtMgr.10TH.CNT bne .2 ldx #10 stx EvtMgr.10TH.CNT ora #S.EVT.F.T1SEC .2 sta (pEvent) inc EvtMgr.Count Add one event to Queue lda pEvent clc adc #S.EVT sta pEvent if CS, EVT queue full!!! ($100) .3 sec lda EvtMgr.Count if 0, exit with CS (from cmp), and A=0 "no event" beq .9 .8 clc .9 rts *-------------------------------------- * CORE.DispatchEvents * IN: * OUT: * CS: Not Dispatched * CC: Event Cleared *-------------------------------------- CORE.DispatchEvents lda CORE.PSCount sta CORE.Counter beq .9 .1 ldx CORE.Counter lda PS.Table.PID-1,x beq .5 lda PS.Table.hMem-1,x jsr K.GetMemPtr.A >STYA pPS lda (pPs) get S.PS.F bit #S.PS.F.INIT+S.PS.F.HOLD Init or Waiting for Another Task to Terminate? bne .5 bit #S.PS.F.EVENT Accept Events ? beq .5 jsr CORE.PSEnter lda #EvtMgr.Table sta pEvent Select first event in list lda EVTMGR.COUNT sta TSKMGR.EVENTCNT .2 lda (pEvent) Empty event, select next beq .3 ldx #TSKMGR.DOEVENT jsr pCodeJmp Call DOEVENT function bcs .3 not for this PS, try next event in list jsr CORE.DestroyEvent this PS handled the EVT, destroy it... lda EVTMGR.COUNT beq .8 no more event, exit .3 dec TSKMGR.EVENTCNT beq .4 all EVT submitted to this PS, try other PS lda pEvent try next EVT to this PS clc adc #S.EVT sta pEvent bra .2 .4 jsr CORE.PSLeave .5 dec CORE.Counter bne .1 .9 sec rts .8 clc rts *-------------------------------------- CORE.Quit clc rts *-------------------------------------- * PS.Free.A * In : A = PID to free *-------------------------------------- CORE.PSFree.A sta .1+1 Save PS ID jsr CORE.GetPSByID.A PS in ZPPtr1 bcs .9 >STYA ZPPtr1 ldy #S.PS.hSS jsr .8 ldy #S.PS.hDS jsr .8 ldy #S.PS.hCS jsr .8 ldy #S.PS.hARGS jsr .8 lda (ZPPtr1) get S.PS.F and #S.PS.F.ENV do we have to discard duplicated env & prefix ? beq .1 ldy #S.PS.hENV jsr .8 ldy #S.PS.hPREFIX jsr .8 .1 lda #$ff Self Modified ldx CORE.PSCount .2 cmp PS.Table.PID-1,x beq .3 dex bne .2 bra * .3 stz PS.Table.PID-1,x lda PS.TABLE.hMem-1,x .4 jmp K.FreeMem.A .8 lda (ZPPtr1),y bne .4 .9 rts *-------------------------------------- * X unmodofied *-------------------------------------- CORE.GetPSByID.A ldy CORE.PSCount beq .9 .1 cmp PS.Table.PID-1,y beq .2 dey bne .1 .9 lda #TSKMGR.ERRNSP sec rts .2 lda PS.TABLE.hMem-1,y jmp K.GetMemPtr.A *-------------------------------------- CORE.DumpEvent ldy #S.EVT-1 .1 >PUSHB (pEvent),y dey bpl .1 >LDYAI .2 jmp K.PrintF.YA .2 >CSTR "!Evt:F=%b,Dev=$%h,LO=$%h,HI=$%h,W1=$%H,W2=$%H\n" *-------------------------------------- CORE.ScreenSelect and #$0F cmp A2osX.ASCREEN Same as active screen...nothing to do beq .8 tax lda A2osX.SCRNDEVS-1,x beq .8 No device claimed this screen jsr K.GetDevByID.A x unmodified..... bcs .8 ??? stx A2osX.ASCREEN >STYA pDev ldx #DEVMGR.CONTROL jmp pDevJmp .8 rts *-------------------------------------- CORE.DestroyEvent lda (pEvent) beq .9 bit #S.EVT.F.hMEM1 beq .1 pha ldy #S.EVT.DATALO lda (pEvent),y jsr K.FreeMem.A pla .1 bit #S.EVT.F.hMEM2 beq .2 ldy #S.EVT.DATAHI lda (pEvent),y jsr K.FreeMem.A .2 lda #0 sta (pEvent) dec EvtMgr.Count .9 rts *-------------------------------------- CORE.PSSelect0 >LDYAI CORE.S.PS0 Select PS0 >STYA pPs >LDYA CORE.S.PS0+S.PS.Context+4 >STYA pStack rts */-------------------------------------- * # Sleep * Make current process suspend until next RUN * ## In : * (none) * ## Out : * (none) *\-------------------------------------- K.Sleep pla get PC LO sec sbc pCode ldy #S.PS.PC sta (pPs),y pla get PC HI sbc pCode+1 iny sta (pPs),y lda (pPs) ora #S.PS.F.SLEEP sta (pPs) *-------------------------------------- CORE.PSLeave ldy #S.PS.Context+23 ldx #23 .1 lda pCode,x sta (pPs),y dey dex bpl .1 clc No error, rts back to Kernel *-------------------------------------- CORE.PSEnter ldy #S.PS.Context+23 ldx #23 .1 lda (pPs),y sta pCode,x dey dex bpl .1 rts *-------------------------------------- CORE.PSResume ldy #S.PS.PC lda (pPs),y sec Advance PC by one as it was saved by a JSR adc pCode setup by PS.Select sta .8+1 iny lda (pPs),y adc pCode+1 sta .8+2 .8 jmp $FFFF *-------------------------------------- TSKMGR.EVENTCNT .BS 1 *-------------------------------------- DevMgr.Stat .DA DevMgr.NUL.Code DevMgr.Free .DA DevMgr.FreeMem .DA DevMgr.HiMem DevMgr.Count .DA #2 NUL,SYS *-------------------------------------- EvtMgr.VBLState .BS 1 EvtMgr.10TH.CNT .BS 1 EvtMgr.HZ.CNT .BS 1 EvtMgr.Count .BS 1 *-------------------------------------- CORE.CPULoadI .BS 1 CORE.CPULoadC .AS -"/-\|" CORE.Counter .BS 1 CORE.PSCount .DA #0 CORE.LastPSID .DA #0 CORE.S.PS0 .BS S.PS *-------------------------------------- MAN SAVE /A2OSX.SRC/SYS/KERNEL.S.CORE LOAD /A2OSX.SRC/SYS/KERNEL.S ASM