A2osX/SYS/KERNEL.S.CORE.txt

538 lines
10 KiB
Plaintext
Raw Normal View History

PR#3
PREFIX /A2OSX.BUILD
LOMEM $A00
INC 1
AUTO 6
*--------------------------------------
SYS.BASL0 .EQ $800
*--------------------------------------
CORE.Run jsr CORE.PSRun
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.PSRun >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
sta pStack+1
ldy #S.PS.SP
lda (pPs),y
sta 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.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
*/--------------------------------------
* # 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 pStack Save DATA Stack Pointer
ldy #S.PS.SP
sta (pPs),y
lda (pPs)
ora #S.PS.F.SLEEP
sta (pPs)
clc No error,
rts back to Kernel
*--------------------------------------
CORE.PSWakeUp and #$FF^S.PS.F.SLEEP unmark as SLEEP
sta (pPS)
ldy #S.PS.SP
lda (pPs),y
sta pStack
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.CPULOADI .BS 1
CORE.CPULOADC .AS -"/-\|"
*--------------------------------------
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