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
				
				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
				
				lda (pPs)
				and #$3F				$ff^S.PS.F.INIT+S.PS.F.RUN
				ora #S.PS.F.QUIT
				sta (pPs)
				bra .3					try executing QUIT now...
				
.4				lda (pPs)
				bit #S.PS.F.SLEEP
				bne .7
				
				bit #S.PS.F.INIT
				beq .5
				
				eor #S.PS.F.INIT+S.PS.F.RUN   go from INIT to RUN
				sta (pPs)
				bra .7
				
.5				bit #S.PS.F.QUIT
				beq .7			
				
				ldy #S.PS.PID
				lda (pPs),y
				jsr CORE.PSFree
				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 #"6"
				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
				
				pha
				
				>PUSHWZ				Param
				>PUSHBI IOCTL.CONTROL	request
				pla
				
				jsr K.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)
				
.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
				dex						devID 1 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 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)				get S.PS.F
				bit #S.PS.F.INIT+S.PS.F.HOLD+S.PS.F.QUIT	Init or Waiting for Another Task to Terminate?
				bne .5

				bit #S.PS.F.EVENT		Accept Events ?
				beq .5

				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
				
				lda (pPs)
				ora #S.PS.F.DOEVENT
				sta (pPs)

				jsr CORE.PSDoEvent
				dec IRQ.InKernel

				lda (pPs)
				eor #S.PS.F.DOEVENT
				sta (pPs)

				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				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+ZPBIN.SIZE-1
				ldx #ZPBIN.SIZE-1

.1				lda (pPs),y
				sta pCode,x
				dey
				dex
				bpl .1

				ldy #S.PS.hSID
				lda (pPs),y
				tax
				lda S.Table.hSession-1,x
				jsr K.GetmemPtr
				>STYA pSession
	
				rts
*--------------------------------------
CORE.PSLeave	ldy #S.PS.ZP+ZPBIN.SIZE-1
				ldx #ZPBIN.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
				
				bit #S.PS.F.RUN
				bne .3

				bit #S.PS.F.QUIT
				bne .2

				ldx #31
				
.1				stz ZPBIN,x
				dex
				bpl .1
	
				ldx #PS.INIT
				.HS 2C					BIT ABS				
.2				ldx #PS.QUIT
				.HS 2C					BIT ABS
.3				ldx #PS.RUN
				.HS 2C					BIT ABS
				
CORE.PSDoEvent	ldx #PS.DOEVENT
				
				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.PSFree
*   In : A = PID to free
*--------------------------------------
CORE.PSFree		sta .10+1				Save PS ID

				jsr CORE.GetPSByID		S.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.hARGV
				jsr .8

				ldy #S.PS.hENV
				jsr .8
				
				ldy #S.PS.hPREFIX
				jsr .8

				ldy #S.PS.hStdOut
				lda (ZPPtr1),y
				tax
				lda OF.Table.hPath-1,x
				beq .10					hDEV

				lda OF.Table.hFD-1,x	hNod
				jsr K.GetMemPtr			get FD
				>STYA pFD
				lda (pFD)
				cmp #S.FD.T.PIPE
				bne .10
				
				txa
				ldx #SYS.fclose
				jsr K.SYSCALL2.BANK

.10				lda #$ff				Self Modified

				ldx #0
				
.2				cmp PS.Table.PID,x
				beq .3

				inx
				cpx CORE.PSCount
				bne .2
				
.3				stz PS.Table.PID,x
				lda PS.TABLE.hPS,x
				stz PS.TABLE.hPS,x
.4				jmp K.FreeMem

.8				lda (ZPPtr1),y
				bne .4
.9				rts
*--------------------------------------
CORE.EvtIndex	.BS 1
CORE.EvtCount	.BS 1
*--------------------------------------
MAN
SAVE USR/SRC/SYS/KERNEL.S.CORE
LOAD USR/SRC/SYS/KERNEL.S
ASM
