NEW
  AUTO 3,1
*--------------------------------------
CORE.Run		ldx #1

				bra .80					Skip PS0

.1				stx CORE.PSIndex

				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.UpdPPS			Yes, go Update Parent PS

				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

				ldy #S.PS.PID
				lda (pPS),y
				cmp #1					INITD ?
				bne .6

				jmp CORE.Quit

.6				>PUSHA					PID
				>PUSHBI 2				SIG
				>SYSCALL2 Kill
				bra .8

.7				jsr CORE.PSLeave		Save ZP & Ptrs

.8				ldx CORE.PSIndex
				inx
.80				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

				bpl .3

				jsr CORE.DestroyEvent	Discard any timer event

.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.Quit		php
				sei
				jsr CORE.IRQ.Off

				plp

				lda IRQ.INTNUM
				sta K.MLI.PARAMS+1

				>MLICALL MLIDEALLOCIRQ

				ldx #5

.1				stz K.MLI.PARAMS+1,x
				dex
				bpl .1

				lda #4
				ldx #MLIQUIT
				jmp GP.MLICall
*--------------------------------------
CORE.UpdPPS		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 A2osX.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	ldx #1					skip PS0
				bra .80

.1				stx CORE.PSIndex

				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

				ldx #S.PS.S.DOEVENT
				jsr CORE.PSExecX
				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				ldx CORE.PSIndex
				inx
.80				cpx CORE.PSCount
				bne .1

*				sec

				rts
*--------------------------------------
* X unmodified
*--------------------------------------
CORE.GetPSByID	jsr CORE.GetPS
				bcs .9

				lda PS.TABLE.hPS,y
				jmp K.GetMemPtr
				
.9				rts				
*--------------------------------------
* X,A unmodified
*--------------------------------------
CORE.GetPS		tay
				beq .8					PS0 requested

				ldy #0
				bra .2					Skip PS0

.1				cmp PS.Table.PID,y
				beq .8

.2				iny
				cpy CORE.PSCount
				bne .1

.9				lda #E.NSP
*				sec
				rts

.8				clc
				rts
*--------------------------------------
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

				ldy #S.PS.S
				lda (pPS),y
				tax

CORE.PSExecX	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.TickPerSec	.BS 1
CORE.TickPer10t	.BS 1
CORE.TickSec	.BS 1
CORE.Tick10t	.BS 1
CORE.CPUStatCnt	.DA #100
CORE.LastPSID	.DA #0
*--------------------------------------
CORE.EvtIndex	.BS 1
CORE.EvtCount	.BS 1
*--------------------------------------
* Called by :
*  - Kernel IRQ Manager (AuxLC)
*  - ProDOS IRQ Manager (GP)
*--------------------------------------
CORE.IRQ.IIGS	lda IO.IIGS.INTFLAG
				and #$08
				beq CORE.IRQ.DEV

				stz IO.IIGS.CLRVBLINT

				bra CORE.IRQ.Switch
*--------------------------------------
CORE.IRQ.TCLOCK	ldy IRQ.n0

				lda $c080,y
				and #$20
				beq CORE.IRQ.DEV

				lda $c088,y
				lda $c080,y

				bra CORE.IRQ.Switch
*--------------------------------------
CORE.IRQ.MOUSE	jsr $FFFF				SELF MODIFIED,SERVEMOUSE
				bcs CORE.IRQ.DEV		Not From Mouse

				ldx IRQ.0n
				lda MOUSESTSx,x
				and #MOUSESTSx.INTVBL	IRQ was caused by VBL ?
				beq CORE.IRQ.DEV

				ldx CORE.IRQ.MOUSE.2+2	$Cn
				ldy IRQ.n0

CORE.IRQ.MOUSE.2
				jsr $FFFF			SELF MODIFIED,READMOUSE
*--------------------------------------
CORE.IRQ.Switch	inc IRQ.Tick

				dec CORE.CPUStatCnt
				bne .2

				lda #100
				sta CORE.CPUStatCnt
				ldx #K.PS.MAX-1

.1				lda PS.Table.Hits,x
				stz PS.Table.Hits,x
				sta PS.Table.Stats,x
				dex
				bpl .1

.2				lda IRQ.InKernel
				bpl .3

				inc PS.Table.Hits

.9				clv
				clc
				rts

.3				ldx CORE.PSIndex
				inc PS.Table.Hits,x

				bit A2osX.F				A2osX.F.PMODE .EQ %01000000
				bvc .8

				ldy #S.PS.S
				lda (pPS),y
				eor #S.PS.S.RUN
				bne .9

				lda IRQ.InLib
				bmi .9					we are in LIB, no switching

.8				clc						exit with V flag set
				rts
*--------------------------------------
CORE.IRQ.DEV	ldx #0

.1				lda IRQ.Vectors+1,x
				beq .9

				sta .10+2
				lda IRQ.Vectors,x
				sta .10+1

				phx

.10				jsr $ffff				SELF MODIFIED

				plx
				bcc .8					CC, IRQ cleared by device

.2				inx
				inx
.3				cpx #K.IRQDEV.MAX*2
				bne .1

.9				sec

.8				clv						clear V (no task switching)
				rts
*--------------------------------------
CORE.IRQ.IIGS.Off
				lda #$08
				trb IO.IIGS.INTEN

				rts
*--------------------------------------
CORE.IRQ.TCLOCK.Off
				ldx IRQ.n0
				stz $c080,x

				lda $c088,x
				lda $c080,x

				ldx IRQ.0n
				sta SETPAGE2
				stz $478,x
				stz $7f8,x

				sta CLRPAGE2
				stz $478,x
				stz $7f8,x
*--------------------------------------
CORE.IRQ.Off	rts
*--------------------------------------
CORE.IRQ.MOUSE.Off
				ldy CORE.IRQ.MOUSE.Off.1+2	Cn
				ldy IRQ.n0
				lda #0
CORE.IRQ.MOUSE.Off.1
				jmp $ffff				SELF MODIFIED
*--------------------------------------
IRQ.InKernel	.BS 1
IRQ.InLib		.BS 1
IRQ.Skip		.BS 1

IRQ.IntNum		.BS 1
IRQ.n0			.BS 1
IRQ.0n			.BS 1
IRQ.Mode		.BS 1
IRQ.Tick		.BS 1
*--------------------------------------
IRQ.Vectors		.BS K.IRQDEV.MAX*2
*--------------------------------------
MAN
SAVE usr/src/sys/kernel.s.core
LOAD usr/src/sys/kernel.s
ASM
