NEW
  AUTO 3,1
*--------------------------------------
CORE.Run		stz CORE.PSIndex

				bra .8					Skip PS0
.1				lda PS.Table.hPS,x
				beq .8
				jsr K.GetMemPtr
				>STYA pPs
				lda (pPS)				get S.PS.F 
*				bit #S.PS.F.HOLD		Waiting for Another Task to Terminate?
*				beq .2

				bpl .2
				ldy #S.PS.CPID
				lda (pPS),y
				jsr CORE.GetPS
				bcc .8					yes, still running....
				lda (pPS)				get S.PS.F again
				eor #S.PS.F.HOLD		unmark as HOLD
				sta (pPS)
.2				jsr CORE.PSSelect		Restore ZP & Ptrs

.3				jsr CORE.PSExec			INIT/RUN/QUIT/RESUME
				dec IRQ.InKernel
				bcc .4					INIT/RUN Exit ?

				jsr CORE.UpdateParentPS
				ldy #S.PS.S
				lda #S.PS.S.QUIT
				sta (pPS),y
				bra .3					try executing QUIT now...
.4				lda (pPS)
				bit #S.PS.F.SLEEP
				bne .7
				ldy #S.PS.S
				lda (pPS),y
				bne .5
				lda #S.PS.S.RUN			go from INIT to RUN
				sta (pPS),y
				bra .7
.5				cmp #S.PS.S.QUIT
				bne .7			
				>PUSHBI 2
				ldy #S.PS.PID
				lda (pPS),y
				>SYSCALL2 Kill
				bra .8
.7				jsr CORE.PSLeave		Save ZP & Ptrs
.8				inc CORE.PSIndex
				ldx CORE.PSIndex
				cpx CORE.PSCount
				bne .1
*--------------------------------------
CORE.Events		jsr CORE.GetEvents
				bcs .4					CS=no event

				jsr CORE.Dispatch
				bcc .4					CC=All Events Dispatched

				lda PS.Table.PID		Select PS0
				jsr K.GetMemPtr
				>STYA pPs
				>LDYAI K.STACKTOP
				>STYA pStack
				lda #Evt.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 CORE.EvtCount
				bne .1
*--------------------------------------			
.4				bit OPENAPPLE
				bpl .8

				lda KBD
				bpl .8

				cmp #"0"
				bcc .8

				cmp #"9"+1
				bcs .8

				sta KBDSTROBE
				and #$0F
				tax
				lda A2osX.SCRNDEVS,x	Get DevID
				beq .8					No device claimed this screen

				cmp A2osX.ASCREEN		Same as active screen...nothing to do
				beq .8
				
				>PUSHA
				>PUSHBI IOCTL.CONTROL	request
				>PUSHWZ					Param
				>SYSCALL2 IOCTL
.8				jmp CORE.Run
*--------------------------------------
CORE.UpdateParentPS
				tax						save RC From INIT or RUN

				ldy #S.PS.PPID			Notify Parent Process for exit code...
				lda (pPS),y
				beq .8					no parent process
				jsr CORE.GetPSByID		X unmodified
				bcs .8					parent is dead.....skipping...

				>STYA ZPPtr1
				lda (ZPPtr1)			Parent PS is HOLD? 
				bit #S.PS.F.HOLD
				beq .8					no...

				ldy #S.PS.CPID
				lda (ZPPtr1),y
				dey						#S.PS.PID
				cmp (pPS),y
				bne .8					Hold, but not waiting this PS
				txa						waiting for this PS to terminate....
				ldy #S.PS.RC			give it RC
				sta (ZPPtr1),y
				lda (ZPPtr1)
				eor #S.PS.F.HOLD		release Parent PS HOLD...
				sta (ZPPtr1)
*				clc
.8				rts
*--------------------------------------
* CORE.GetEvents :
*  IN :
*  OUT : 
*   CS = no event, A = ERROR
*   CC * event in YA
*   (pEvent)
*--------------------------------------
CORE.GetEvents	lda #Evt.Table
				sta	pEvent				point to start of event list
				stz CORE.EvtCount		reset Size
				bit CORE.IRQMode		do we have IRQ enabled for Ticks ?
				bpl .1					no, regular poll
				lda IRQ.Tick			a Tick ?
				beq .8					no, no event
				dec IRQ.Tick
				bra .2

.1				lda VBL					get VLINE status
				tax
				eor CORE.VBLState		
				bpl .8					no change,no tick
				txa
				sta CORE.VBLState		save new
				bpl .8					Up2down transition,no tick
.2				lda #0
				dec CORE.TickSec
				bne .3					not yet One Sec

				lda IRQ.Mode
				eor #$C0
				sta IRQ.Mode
				ldx A2osX.ASCREEN
				cpx #3					devID 3 is /DEV/CONSOLE
				bne .22
				sta SYS.BASL0+38
.22				ldx CORE.TickPerSec
				stx CORE.TickSec

				lda #S.EVT.F.T1SEC
				bra .4					Force Resync T1 & T10...

.3				dec CORE.Tick10t
				bne .6
				
.4				inc DevMgr.Timer
				inc A2osX.TIMER16
				bne .5
				inc A2osX.TIMER16+1

.5				ldx CORE.TickPer10t
				stx CORE.Tick10t

				ora #S.EVT.F.T10TH
.6				tax						Finally, do we have an event ?
				beq .8					no....
				sta (pEvent)
				inc CORE.EvtCount		Add one event to Queue

*				lda pEvent
*				clc
*				adc #S.EVT
*				sta pEvent				if CS, EVT queue full!!! ($100)

*				MORE EVENT PROCESSING HERE

.8				lda CORE.EvtCount		if 0, exit with CS (from cmp), and A=0 "no event"
				beq .9
				clc
				rts
.9				sec
				rts
*--------------------------------------
* CORE.Dispatch
*  IN: 
*  OUT:
*	CS: Not Dispatched
*	CC: Event Cleared 
*--------------------------------------
CORE.Dispatch	stz CORE.PSIndex
				bra .5					skip PS0
.1				lda PS.Table.hPS,x
				beq .5
				jsr K.GetMemPtr
				>STYA pPS
			
				lda (pPS)
				bit #S.PS.F.EVENT		Accept Events ?
				beq .5

				ldy #S.PS.S
				lda (pPS),y
				cmp #S.PS.S.RUN
				bne .5

				lda #S.PS.S.DOEVENT		Flag this PS for IRQ Mgr
				sta (pPS),y
				jsr CORE.PSSelect

				lda #Evt.Table
				sta pEvent				Select first event in list
				lda CORE.EvtCount
				sta CORE.EvtIndex

.2				lda (pEvent)			Empty event, select next
				beq .3
				jsr CORE.PSExec2
				dec IRQ.InKernel

				bcs .3					not for this PS, try next event in list
				jsr CORE.DestroyEvent	this PS handled the EVT, destroy it...

				lda CORE.EvtCount
				beq .4					no more event, exit

.3				dec CORE.EvtIndex
				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				ldy #S.PS.S
				lda #S.PS.S.RUN
				sta (pPS),y
				jsr CORE.PSLeave
.5				inc CORE.PSIndex
				ldx CORE.PSIndex
				cpx CORE.PSCount
				bne .1
*				sec
				rts
*--------------------------------------
* X unmodified
*--------------------------------------
CORE.GetPSByID	jsr CORE.GetPS
				bcs CORE.GetPS.RTS
				lda PS.TABLE.hPS,y
				jmp K.GetMemPtr
*--------------------------------------
* X,A unmodified
*--------------------------------------
CORE.GetPS		tay
				beq CORE.GetPS.8		PS0 requested

				ldy #0
				bra .2					Skip PS0
.1				cmp PS.Table.PID,y
				beq CORE.GetPS.8
.2				iny
				cpy CORE.PSCount
				bne .1
.9				lda #E.NSP
*				sec
				rts
CORE.GetPS.8
				clc
CORE.GetPS.RTS	rts
*--------------------------------------
*CORE.DumpEvent	ldy #S.EVT-1
*.1				>PUSHB (pEvent),y
*				dey
*				bpl .1
*				>LDYAI .2
*				jmp K.printf
*.2				.AZ "!Evt:F=%b,Dev=$%h,LO=$%h,HI=$%h,W1=$%H,W2=$%H\n"
*--------------------------------------
CORE.DestroyEvent
				lda (pEvent)
				beq .9
			
				bit #S.EVT.F.hMEM1
				beq .1
				pha
				ldy #S.EVT.B1
				lda (pEvent),y
				jsr K.FreeMem
				pla
.1				bit #S.EVT.F.hMEM2
				beq .2
				ldy #S.EVT.B2
				lda (pEvent),y
				jsr K.FreeMem
.2				lda #0
				sta (pEvent)
				dec CORE.EvtCount
.9				rts
*--------------------------------------
CORE.PSSelect	ldy #S.PS.ZP.CODE+PSCTX.SIZE-1
				ldx #PSCTX.SIZE-1

.1				lda (pPS),y
				sta pCode,x
				dey
				dex
				bpl .1
	
				rts
*--------------------------------------
CORE.PSLeave	ldx #PSCTX.SIZE-1
				ldy #S.PS.ZP.CODE+PSCTX.SIZE-1
				
.1				lda pCode,x
				sta (pPS),y
				dey
				dex
				bpl .1
				rts
*--------------------------------------
CORE.PSExec		lda (pPS)
				bit #S.PS.F.SLEEP
				bne CORE.PSResume

CORE.PSExec2	ldy #S.PS.S
				lda (pPS),y

				tax
				lda pCode+1
				pha
				lda pCode
				pha
				php
				sei
				inc IRQ.InKernel
				rti
*--------------------------------------
CORE.PSResume	sei

				eor #S.PS.F.SLEEP		unmark as SLEEP
				sta (pPS)

				>PULLA					Get !BC 
				tax

				beq .2

.1				>PULLA
				pha

				inx
				bne .1
.2				ldy #S.PS.PC+1
				lda (pPS),y
				pha
				dey						#S.PS.PC
				lda (pPS),y
				pha
				dey						#S.PS.P
				lda (pPS),y
				pha
				dey						#S.PS.Y
				lda (pPS),y
				pha
				dey						#S.PS.X
				lda (pPS),y
				tax
				dey						#S.PS.A
				lda (pPS),y

				ply
				inc IRQ.InKernel
				rti
*--------------------------------------
CORE.VBLState	.BS 1
CORE.IRQMode	.BS 1
CORE.TickPerSec	.BS 1
CORE.TickPer10t	.BS 1
CORE.TickSec	.BS 1
CORE.Tick10t	.BS 1
CORE.CPUStatCnt	.DA #100
CORE.LastPSID	.DA #0
CORE.FSID		.BS 1
*--------------------------------------
CORE.EvtIndex	.BS 1
CORE.EvtCount	.BS 1
*--------------------------------------
MAN
SAVE USR/SRC/SYS/KERNEL.S.CORE
LOAD USR/SRC/SYS/KERNEL.S
ASM
