PR#3 PREFIX /A2OSX.BUILD LOMEM $A00 INC 1 AUTO 6 *-------------------------------------- SYS.BASL0 .EQ $800 *-------------------------------------- CORE.Run jsr CORE.TskMgrRun stx A2osX.RANDOM16 jsr CORE.GetEvents txa eor KBD sta A2osX.RANDOM16+1 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 CORE.Run lda KBD bpl CORE.Run cmp #"1" bcc CORE.Run cmp #"5" bcs CORE.Run jsr CORE.ScreenSelect bra CORE.Run *-------------------------------------- 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 sta KBDSTROBE 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.CPULOADI .BS 1 CORE.CPULOADC .AS -"/-\|" *-------------------------------------- CORE.TskMgrRun >LDYAI TskMgr.Table+S.PS skip PS 0 >STYA pPs lda TskMgr.Count sta TskMgr.Idx .1 dec TskMgr.Idx skip PS 0 beq .8 lda (pPs) get S.PS.F * bit #S.PS.F.INUSE In use ? * beq .7 bpl .7 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 .7 yes, running.... lda (pPs) get S.PS.F and #$FF^S.PS.F.HOLD unmark as HOLD sta (pPs) .2 jsr CORE.PSSelect lda (pPS) bit #S.PS.F.INIT bne .30 bit #S.PS.F.SLEEP Is this PS sleeping? beq .3 no, call TSKMGR.RUN jsr CORE.PSWakeUp bra .4 .30 and #$FF^S.PS.F.INIT unmark as INIT sta (pPS) ldx #TSKMGR.INIT .HS 2C BIT abs .3 ldx #TSKMGR.RUN .31 jsr pCodeJmp Call INIT/RUN function .4 bcc .7 INIT/RUN said CS=QUIT? pha save RC ldy #S.PS.PPID Notify Parent Process for exit code... lda (pPs),y jsr CORE.GetPSByID.A will set ZPPtr1 if success bcs .5 parent is dead.....skipping... lda (ZPPtr1) Parent PS is HOLD? bit #S.PS.F.HOLD beq .5 no... eor #S.PS.F.HOLD yes, release hold... sta (ZPPtr1) pla ...probably waiting for this PS to terminate.... ldy #S.PS.RC give it RC sta (ZPPtr1),y .HS B0 BCS .5 pla .6 ldx #TSKMGR.QUIT yes, quit this process jsr pCodeJmp Call QUIT function ldy #S.PS.PID lda (pPs),y jsr CORE.PSFree.A .7 lda pPs clc adc #S.PS sta pPs bcc .1 inc pPs+1 bcs .1 Always .8 clc rts *-------------------------------------- CORE.GetPSByID.A pha >LDYAI TskMgr.Table >STYA ZPPtr1 pla beq .8 sta .20+1 ldx #0 .1 inx lda ZPPtr1 clc adc #S.PS sta ZPPtr1 bcc .2 inc ZPPtr1+1 .2 lda (ZPPtr1) bpl .3 ldy #S.PS.PID lda (ZPPtr1),y .20 cmp #$ff Self Modified beq .8 .3 cpx TskMgr.Count bne .1 .9 lda #TSKMGR.ERRNSP sec rts .8 >LDYA ZPPtr1 clc rts *-------------------------------------- CORE.PSSelect0 >LDYAI TskMgr.Table Select PS0 >STYA pPs >LDYA K.STACK >STYA pStack rts *-------------------------------------- CORE.PSSelect ldy #S.PS.hCS lda (pPs),y jsr K.GetMemPtr.A >STYA pCode ldy #S.PS.hDS lda (pPs),y beq .1 jsr K.GetMemPtr.A >STYA pData .1 ldy #S.PS.hSS lda (pPs),y jsr K.GetMemPtr.A >STYA pStack clc rts *-------------------------------------- CORE.PSLeave rts *-------------------------------------- * PS.Free.A * In : A = PID to free *-------------------------------------- CORE.PSFree.A jsr CORE.GetPSByID.A PS in ZPPtr1 ldy #S.PS.hARGS jsr .2 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 .2 ldy #S.PS.hPREFIX jsr .2 .1 ldy #S.PS.hSS jsr .2 ldy #S.PS.hDS jsr .2 ldy #S.PS.hCS jsr .2 lda #0 sta (ZPPtr1) Mark TSKSLOT as free clc .9 rts .2 lda (ZPPtr1),y beq .9 jmp K.FreeMem.A *-------------------------------------- * 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.PSWakeUp and #$FF^S.PS.F.SLEEP unmark as SLEEP sta (pPS) 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 .1+1 iny lda (pPs),y adc pCode+1 sta .1+2 .1 jmp $FFFF *-------------------------------------- * CORE.DispatchEvents * IN: * OUT: * CS: Not Dispatched * CC: Event Cleared *-------------------------------------- CORE.DispatchEvents >LDYAI TskMgr.Table+S.PS >STYA pPs lda TskMgr.Count Number of actual processes... sta TskMgr.Idx ...to give event list .1 dec TskMgr.Idx skip PS 0 beq .9 lda (pPs) get S.PS.F bpl .4 * bit #S.PS.F.INUSE In use ? * beq .4 bit #S.PS.F.INIT+S.PS.F.HOLD Init or Waiting for Another Task to Terminate? bne .4 bit #S.PS.F.EVENT Accept Events ? beq .4 jsr CORE.PSSelect 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 lda (pCode) cmp #H.BIN.HEADER.BIN65 bne * 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 lda pPs go to next PS in PS list clc adc #S.PS sta pPs bcc .1 inc pPs+1 bne .1 always .8 clc rts .9 sec rts *-------------------------------------- CORE.TskMgrQuit clc 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 *-------------------------------------- TskMgr.Idx .BS 1 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 *-------------------------------------- TskMgr.Count .DA #1 One Slot Busy (Kernel PS=0) TskMgr.LastID .DA #0 *-------------------------------------- MAN SAVE /A2OSX.SRC/SYS/KERNEL.S.CORE LOAD /A2OSX.SRC/SYS/KERNEL.S ASM