PR#3 PREFIX /A2OSX.SRC NEW INC 1 AUTO 6 .LIST OFF .OP 65C02 *-------------------------------------- * S.TskMgrInit *-------------------------------------- S.TskMgrInit stz TSKMGR.LASTID lda #1 sta TSKMGR.SIZE One Slot Busy (Kernel PS=0) >LDYAI TskMgr.Table Clear whole process table >STYA ZPQuickPtr1 ldx #K.PS.MAX .1 lda #0 ldy #S.PS.SIZE-1 .2 sta (ZPQuickPtr1),y dey bpl .2 lda ZPQuickPtr1 clc adc #S.PS.SIZE sta ZPQuickPtr1 bcc .3 inc ZPQuickPtr1+1 .3 dex bne .1 lda #1 ldy #S.PS.hINDEV sta TskMgr.Table,y Make In DEV = SYS ldy #S.PS.hOUTDEV sta TskMgr.Table,y Make OUT DEV = SYS ldy #S.PS.hERRDEV sta TskMgr.Table,y Make ERR DEV = SYS jsr S.CreateEnv bcs * ldy #S.PS.hENV sta TskMgr.Table,y >LDYAI TmpBuffer256 jsr S.MLIGetPrefixYA bcs * >LDYAI TmpBuffer256 jsr S.NewPStrYA bcs * ldy #S.PS.hPREFIX sta TskMgr.Table,y S.TskMgrInit.Env jsr S.SelectProcess0 ldx #DEVMGR.OPEN jsr pDevJmp >PUSHWI TmpBuffer256 push ENV value >PUSHWI ENV.A2osX push ENV name jsr S.SetEnvVarP bcs .9 >PUSHWI ENV.PATH.VALUE >PUSHWI ENV.PATH jsr S.SetEnvVarP bcs .9 >PUSHWI ENV.LIB.VALUE >PUSHWI ENV.LIB jsr S.SetEnvVarP bcs .9 >PUSHWI ENV.DRV.VALUE >PUSHWI ENV.DRV jsr S.SetEnvVarP bcs .9 .9 rts *-------------------------------------- * S.TskMgrRun *-------------------------------------- S.TskMgrRun >LDYAI TskMgr.Table+S.PS.SIZE >STYA pPs lda #1 Skip PS #0 sta TSKMGR.COUNT .1 lda (pPs) get S.PS.F and #S.PS.F.INUSE In use ? beq .5 lda (pPs) get S.PS.F and #S.PS.F.HOLD Waiting for Another Task to Terminate? beq .2 ldy #S.PS.CID lda (pPs),y jsr S.GetPSByIDA bcc .5 yes, running.... lda (pPs) get S.PS.F and #$FF^S.PS.F.HOLD unmark as HOLD sta (pPs) .2 jsr S.SelectProcess ldy #S.PS.PC+1 Is this PS sleeping? lda (pPs),y tax dey ora (pPs),y beq .3 no, call TSKMGR.RUN lda (pPs),y clc adc pCode sta S.TskMgrRunJmp+1 txa adc pCode+1 sta S.TskMgrRunJmp+2 lda #0 Don't forget to reset S.PC ldy #S.PS.PC sta (pPs),y iny sta (pPs),y jsr S.TskMgrRunJmp bra .4 .3 ldx #TSKMGR.RUN jsr pCodeJmp Call RUN function .4 bcc .5 RUN said CS=QUIT? ldx #TSKMGR.QUIT yes, quit this process jsr pCodeJmp Call QUIT function ldy #S.PS.ID lda (pPs),y jsr S.FreeProcessA bcs .99 .5 lda pPs clc adc #S.PS.SIZE sta pPs bcc .6 inc pPs+1 .6 lda TSKMGR.COUNT inc TSKMGR.COUNT cmp TSKMGR.SIZE bne .1 clc rts .99 bra * *-------------------------------------- S.TskMgrRunJmp jmp $FFFF *-------------------------------------- * S.DispatchEvent * IN: * OUT: * CS: Not Dispatched * CC: Event Cleared *-------------------------------------- S.DispatchEvent >LDYAI TskMgr.Table+S.PS.SIZE >STYA pPs lda #1 sta TSKMGR.COUNT .1 lda (pPs) get S.PS.F and #S.PS.F.INUSE In use ? beq .3 lda (pPs) get S.PS.F and #S.PS.F.HOLD Waiting for Another Task to Terminate? bne .3 lda (pPs) get S.PS.F and #S.PS.F.EVENT Accept Events ? beq .3 jsr S.SelectProcess ldx #TSKMGR.DOEVENT jsr pCodeJmp Call DOEVENT function bcc .8 .3 lda pPs clc adc #S.PS.SIZE sta pPs bcc .4 inc pPs+1 .4 lda TSKMGR.COUNT inc TSKMGR.COUNT cmp TSKMGR.SIZE bne .1 sec rts .8 jsr S.DestroyEvent clc rts *-------------------------------------- * S.TskMgrQuit *-------------------------------------- S.TskMgrQuit clc rts *-------------------------------------- * PUBLIC *-------------------------------------- * S.ExecProcessNewEnvYA * S.ExecProcessYA (Blocking Parent PID) * S.CreateProcessNewEnvYA * S.CreateProcessYA (Non Blocking) * in : * A = hMem To Cmd Line * Y = hMem To Args * out : * A = Child PSID *-------------------------------------- S.ExecProcessNewEnvYA ldx #S.PS.F.ENV .HS 2C bit abs S.ExecProcessYA ldx #0 S.ExecProcess jsr S.CreateProcess bcs .9 terminated, do not set PID as HOLD ldy #S.PS.CID sta (pPs),y pha Save Child PID lda (pPs) ora #S.PS.F.HOLD sta (pPs) pla Get Back PID clc .9 rts *-------------------------------------- S.CreateProcessNewEnvYA ldx #S.PS.F.ENV .HS 2C bit abs S.CreateProcessYA ldx #0 S.CreateProcess stx S.CreateChildProcess.Flags sta S.CreateProcessA.Cmd sty S.CreateProcessA.Args * lda #'|' * jsr S.CoutA * lda S.CreateProcessA.Cmd * jsr S.PSTROutA * lda #'|' * jsr S.CoutA * lda S.CreateProcessA.Args * beq .1 * jsr S.PSTROutA *.1 lda #'|' * jsr S.CoutA * lda #13 * jsr S.CoutA jsr S.CreateChildProcess bcs .99 sta S.CreateProcessA.CPSID jsr S.SelectProcessA jsr S.InitProcess bcs .98 Init Failed or exit? ldy #S.PS.PID switch back to Parent Process lda (pPs),y jsr S.SelectProcessA lda S.CreateProcessA.CPSID clc rts .98 pha save error code ldy #S.PS.PID switch back to Parent Process lda (pPs),y jsr S.SelectProcessA lda S.CreateProcessA.CPSID jsr S.FreeProcessA pla get back error code .99 sec rts *-------------------------------------- S.CreateProcessA.Cmd .BS 1 S.CreateProcessA.Args .BS 1 S.CreateProcessA.CPSID .BS 1 *-------------------------------------- * S.GetPSByIDA * In : * A = PID * Out : * Y,A = PTR to TSKSLOT *-------------------------------------- S.GetPSByIDA sta S.GetPSByIDA.PS >LDYAI TskMgr.Table >STYA ZPQuickPtr1 lda S.GetPSByIDA.PS beq .8 ldx #0 .1 inx lda ZPQuickPtr1 clc adc #S.PS.SIZE sta ZPQuickPtr1 bcc .2 inc ZPQuickPtr1+1 .2 lda (ZPQuickPtr1) bpl .3 ldy #S.PS.ID lda (ZPQuickPtr1),y cmp S.GetPSByIDA.PS beq .8 .3 cpx TSKMGR.SIZE bne .1 .9 lda #TSKMGR.ERRNSP sec rts .8 >LDYA ZPQuickPtr1 clc rts *-------------------------------------- S.GetPSByIDA.PS .BS 1 *-------------------------------------- S.Sleep ldy #S.PS.hCS lda (pPs),y >SYSCALL SYS.GetMemPtrA >STYA S.Sleep.SaveCS ldy #S.PS.PC pla get PC LO plx get PC HI inc Advance PC one Byte bne .1 inx .1 sec sbc S.Sleep.SaveCS sta (pPs),y iny txa sbc S.Sleep.SaveCS+1 sta (pPs),y clc No error, rts back to Kernel *-------------------------------------- S.Sleep.SaveCS .BS 2 *-------------------------------------- * PRIVATE *-------------------------------------- * S.CreateChildProcess * in : * out : * A = PSID * we cannot use ZPQuickPtrs * because of calling S.PStrCpyA & S.DupEnvA *-------------------------------------- S.CreateChildProcess >LDYAI TskMgr.Table+S.PS.SIZE >STYA R.AX ldx #0 .1 inx cpx TSKMGR.SIZE beq .2 lda (R.AX) Found an empty slot bpl .3 lda R.AL clc adc #S.PS.SIZE sta R.AL bcc .1 inc R.AH bra .1 .2 cpx #K.PS.MAX bne .30 lda #TSKMGR.ERROOH sec rts .30 inc TSKMGR.SIZE .3 lda #S.PS.F.INUSE ora S.CreateChildProcess.Flags sta (R.AX) .4 inc TSKMGR.LASTID Get a PSID not alredy running beq .4 not = 0 lda TSKMGR.LASTID jsr S.GetPSByIDA bcc .4 ldy #S.PS.ID lda TSKMGR.LASTID sta (R.AX),y lda #0 ldy #S.PS.hCS .5 sta (R.AX),y Blank Everything in this S.PS iny cpy #S.PS.SIZE bne .5 lda S.CreateChildProcess.Flags and #S.PS.F.ENV need to create ENV & Prefix ? beq .6 ldy #S.PS.hPREFIX copy hPREFIX... lda (pPs),y jsr S.PStrCpyA bcs .99 ldy #S.PS.hPREFIX sta (R.AX),y ldy #S.PS.hENV ...and hENV from parent PS lda (pPs),y jsr S.DupEnvA bcs .99 ldy #S.PS.hENV sta (R.AX),y bra .8 .6 ldy #S.PS.hPREFIX reuse same hPREFIX... lda (pPs),y sta (R.AX),y ldy #S.PS.hENV ...and hENV from parent PS lda (pPs),y sta (R.AX),y .8 ldy #S.PS.hINDEV lda (pPs),y sta (R.AX),y ldy #S.PS.hOUTDEV lda (pPs),y sta (R.AX),y ldy #S.PS.hERRDEV lda (pPs),y sta (R.AX),y ldy #S.PS.ID lda (pPs),y ldy #S.PS.PID sta (R.AX),y lda TSKMGR.LASTID clc Exit with A=PSID rts .99 sec rts *-------------------------------------- S.CreateChildProcess.Flags .BS 1 *-------------------------------------- * S.InitProcess * In : * A = hMem To Full Cmd Line *-------------------------------------- S.InitProcess lda S.CreateProcessA.Args beq .1 jsr S.ExpandPStrA .1 ldy #S.PS.hARGS sta (pPs),y set ARGS hMem (0 if none) lda S.CreateProcessA.Cmd jsr S.ExpandPStrA ldy #S.PS.hCMD sta (pPs),y jsr S.LoadBinA A = BinPath hMem bcs .99 >STYA pCode save PTR to Code Segment txa ldy #S.PS.hCS sta (pPs),y save CS hMem in TSKSLOT ldy #H.BIN.BIN.DS.SIZE+1 lda (pCode),y Load DS.SIZE HI tax dey ora (pCode),y beq .2 DS.SIZE=0... lda (pCode),y >PUSHAX Push DS.SIZE >PUSHBI S.MEM.F.INIT0 Clear DS jsr S.GetMem bcs .99 >STYA pData txa ldy #S.PS.hDS sta (pPs),y save DS hMem in TSKSLOT .2 ldx #TSKMGR.INIT jsr pCodeJmp Call INIT function .99 rts *-------------------------------------- * S.SelectProcessA * In : A=PSID *-------------------------------------- S.SelectProcessA tay bne S.SelectProcessN S.SelectProcess0 >LDYAI TskMgr.Table Make PS #0 as current process >STYA pPs bra S.SelectProcessDev S.SelectProcessN jsr S.GetPSByIDA bcs * >STYA pPs S.SelectProcess ldy #S.PS.hCS lda (pPs),y jsr S.GetMemPtrA >STYA pCode ldy #S.PS.hDS lda (pPs),y beq S.SelectProcessDev jsr S.GetMemPtrA >STYA pData S.SelectProcessDev ldy #S.PS.hOUTDEV lda (pPs),y beq .8 jsr S.GetDevByIDA >STYA pDev .8 clc rts *-------------------------------------- * S.FreeProcessA * In : A = PID to free *-------------------------------------- S.FreeProcessA jsr S.GetPSByIDA bcs .9 >STYA ZPQuickPtr1 ldy #S.PS.hARGS lda (ZPQuickPtr1),y beq .1 jsr S.FreeMemA .1 ldy #S.PS.hCMD lda (ZPQuickPtr1),y beq .2 jsr S.FreeMemA lda (ZPQuickPtr1) get S.PS.F and #S.PS.F.ENV do we have to discard duplicated env & prefix ? beq .4 .2 ldy #S.PS.hENV lda (ZPQuickPtr1),y beq .3 jsr S.FreeMemA .3 ldy #S.PS.hPREFIX lda (ZPQuickPtr1),y beq .4 jsr S.FreeMemA .4 ldy #S.PS.hDS lda (ZPQuickPtr1),y beq .5 jsr S.FreeMemA .5 ldy #S.PS.hCS lda (ZPQuickPtr1),y beq .8 jsr S.FreeMemA .8 lda #0 sta (ZPQuickPtr1) Mark TSKSLOT as free clc rts .9 bra * *-------------------------------------- TSKMGR.SIZE .BS 1 TSKMGR.COUNT .BS 1 TSKMGR.LASTID .BS 1 *-------------------------------------- MAN SAVE SYS/KERNEL.S.TSK LOAD SYS/KERNEL.S ASM