NEW AUTO 3,1 *-------------------------------------- GP.Sleep php sei phy ldy #S.PS.A sta (pPS),y txa iny #S.PS.X sta (pPS),y pla iny #S.PS.Y sta (pPS),y pla iny #S.PS.P sta (pPS),y pla get PC LO plx get PC HI inc Advance one byte because of return by RTI bne GP.Sleep2 inx GP.Sleep2 ldy #S.PS.PC sta (pPS),y txa iny #S.PS.PC+1 sta (pPS),y tsx inx inx keep PC HI,LO from KERNEL jsr PSExec/PSResume inx Stack Ptr is $1ff if empty txa beq .3 tay Save !Byte count for later .2 pla >PUSHA inx bne .2 tya .3 >PUSHA push CPU Stack BC to restore on top of Soft Stack inc $1fe PC=PC+1 bne .4 inc $1ff because of RTI .4 lda (pPS) ora #S.PS.F.SLEEP sta (pPS) lda #0 cld,clc,cli pha rti exit to kernel with CC *-------------------------------------- * *** MUST BE REINTRANT *** *-------------------------------------- GP.SysCall dec IRQ.InKernel pha phy ldy #S.PS.A sta (pPS),y txa iny #S.PS.X sta (pPS),y pla iny #S.PS.Y sta (pPS),y tay pla jsr JMP.2 bcc .2 no error quit... tax CS,A=0 ? beq .3 Yes, BLOCKING I/O .2 inc IRQ.InKernel rts Unmodified Carry .3 sei inc IRQ.InKernel GO.Sleep2 pla get PC LO plx get PC HI * sec sbc #2 bcs GP.Sleep2 dex .1 bra GP.Sleep2 *-------------------------------------- GP.LibCall dec IRQ.InLib pha phy ldy #S.PS.A sta (pPS),y txa iny #S.PS.X sta (pPS),y pla iny #S.PS.Y sta (pPS),y jsr K.GetMemPtr Get LIB Code Segment (MemMgr in $E000, no BNK change) >STYA .1+1 pla .1 jsr $FFFF SELF MODIFIED bcc .2 tax beq .3 .2 inc IRQ.InLib rts .3 sei inc IRQ.InLib bra GO.Sleep2 *-------------------------------------- GP.AtkCall dec IRQ.InKernel >STYA .1 jsr GO.MainIC jsr MLI .DA #MLI.ATALK .1 .DA * jsr GO.AuxLC inc IRQ.InKernel rts */-------------------------------------- * # Add32,Sub32,Mul32,IMul32,Div32,IDiv32,Mod32,IMod32,Cmp32,ICmp32 * Return X+Y, X-Y, X*Y, X/Y, X mod Y.... * ## ASM * `>PUSHL X (long)` * `>PUSHL Y (long)` * `>FPU add32` * `...` * ## RETURN VALUE * On stack (long) *\-------------------------------------- GP.FpuCall dec IRQ.InKernel cpx #FPU.FMUL bcs .1 jsr MATH math16 & math32, direct JMP inc IRQ.InKernel rts .1 phx jsr GP.SetFAC Get float from stack plx cpx #FPU.PWR+1 bcs GP.GetFAC */-------------------------------------- * # FAdd,FSub,FMul,FDiv,FPwr * Return X*Y, X/Y, X+Y, X-Y * ## C * `float pwr ( float x, float y);` * ## ASM * `>PUSHF X (float)` * `>PUSHF Y (float)` * `>FPU fmul` * `>FPU fdiv` * `>FPU fmod` TODO * `>FPU fadd` * `>FPU fsub` * `>FPU fpwr` * ## RETURN VALUE * On stack (float) *\-------------------------------------- lda pStack clc adc #5 sta pStack phx jsr GP.SetARG plx */-------------------------------------- * # Log,Sqr,Exp,Cos,Sin,Tan,ATan * Return Log(x), Sqr(x), E^X, Cos(x), Sin(X), Tan(x), ATan(x) * ## C * `float log ( float x);` * `float sqr ( float x);` * `float exp ( float x);` * `float cos ( float x);` * `float sin ( float x);` * `float tan ( float x);` * `float atan ( float x);` * ## ASM * `>PUSHF x (Float)` * `>FPU log` * ## RETURN VALUE * On stack (Float) *\-------------------------------------- GP.GetFAC jsr GP.ROMCALL lda pStack ldy pStack+1 sta FORPNT Ptr to dst buffer sty FORPNT+1 ldx #FPU.GETFAC *-------------------------------------- GP.RomCall phx ldx $D000 stx .8+1 bit IO.RROMBNK1 plx jsr MATHF .8 ldx #$ff bit $C000,x * bit $C000,x rts *-------------------------------------- GP.SetARG ldx #FPU.SETARG .HS 2C BIT ABS GP.SetFAC ldx #FPU.SETFAC lda pStack ldy pStack+1 bra GP.RomCall */-------------------------------------- * # float * Return 'floated' long * ## C * `float f = (float)l; * ## ASM * `>PUSHL l` (long) * `>FPU float` * ## RETURN VALUE * On stack (float) *\-------------------------------------- GP.Float ldy #3 .1 lda (pStack),y sta FAC+1,y Reverse Order dey bpl .1 dec pStack keep 5 bytes on stack stz FAC.SIGN lda #$80+32 sta FAC Positive + Exp=32 ldx #FPU.LTOF bra GP.GetFAC */-------------------------------------- * # lrintf * Return float rounded into a long * ## C * `long int lrintf (float x);` * ## ASM * `>PUSHF x` * `>FPU lrintf` * ## RETURN VALUE * On stack (long) *\-------------------------------------- GP.lrintf jsr GP.SetFAC inc pStack keep 4 bytes on stack ldx #FPU.QINT jsr GP.ROMCALL ldy #3 .1 lda FAC+1,y sta (pStack),y dey bpl .1 rts *-------------------------------------- * MLI : From Kernel Aux LC to Main LC *-------------------------------------- GP.MLICall stx .1 sta K.MLI.PARAMS jsr GO.MainIC jsr MLI .1 .BS 1 .DA K.MLI.PARAMS jsr GO.AuxLC rts *-------------------------------------- GO.MainIC pha lda $D000 We re coming from AUXLC, saving bank... sta GO.AuxLC.BNK+1 pla php clc .HS 2C BIT ABS GO.AuxLC php sec sei sta GO.EXIT.SaveA+1 stx GO.EXIT.SaveX+1 sty GO.EXIT.SaveY+1 pla Restore P in A for later plx Get PC and add 1 for return ply inx bne .1 iny .1 stx GO.EXIT.JMP+1 sty GO.EXIT.JMP+2 bcs .2 if CS, go AUXLC tsx stx SaveSX ldx SaveSM txs sta IO.CLRALTZP ldx #IO.RRAMWRAMBNK1 Go MAINLC (ProDOS), always BNK1 bra GO.EXIT .2 sta IO.SETALTZP tsx stx SaveSM ldx SaveSX txs GO.AuxLC.BNK ldx #$FF Self Modified, initialized to BNK1 for INIT3 *-------------------------------------- GO.EXIT bit $C000,x Select Proper LC bank * bit $C000,x pha push P on stack GO.EXIT.SaveY ldy #$ff GO.EXIT.SaveX ldx #$ff GO.EXIT.SaveA lda #$ff plp GO.EXIT.JMP jmp $FFFF SELF MODIFIED *-------------------------------------- * Called from ProDOS IRQ Manager (LCBNK1) * A,X,Y, $FA->$FF Already Saved * Main RAM,ZP/LC selected * must begin with CLD * must exit with RTS * - CC if IRQ cleared, CS if NOT *-------------------------------------- GP.IRQ cld bit IRQ.Skip After A2osX IRQ.H ? bmi GP.IRQ.Exit sta IO.SETALTZP switch to aux LC tsx stx SaveSM ldx SaveSX txs GP.IRQ.JSR jsr CORE.IRQ.DEV SELF MODIFIED tsx go back to Main stx SaveSX ldx SaveSM txs sta IO.CLRALTZP rts GP.IRQ.Exit stz IRQ.Skip reset flag sec rts *-------------------------------------- *GO.Reset jsr GO.AuxLC * jmp CORE.Run *-------------------------------------- *BrkHandler bra * *-------------------------------------- CORE.Run ldx #1 bra .80 Skip PS0 .1 stx CORE.PSIndex lda PSs.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 PSs.PID Select PS0 jsr K.GetMemPtr >STYA pPs >LDYAI K.STACKTOP >STYA pStack lda #K.S.EVT 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 IO.OPENAPPLE bpl .8 lda IO.KBD bpl .8 cmp #"0" bcc .8 cmp #"9"+1 bcs .8 sta IO.KBDSTROBE and #$0F cmp A2osX.ASCREEN Same as active screen...nothing to do beq .8 tax lda A2osX.SCRNDEVS,x Get DevID beq .8 No device claimed this screen >PUSHA >PUSHBI IOCTL.CONTROL request >PUSHWZ Param >SYSCALL2 IOCTL .8 jmp CORE.Run *-------------------------------------- CORE.Quit php sei jsr CORE.IRQOff plp lda IRQ.INTNUM sta K.MLI.PARAMS+1 >MLICALL MLI.DEALLOCIRQ bit IO.RDIOUDIS sta IO.SETIOUDIS sta IO.CLRDHIRES bmi .1 sta IO.CLRIOUDIS .1 ldx #5 .2 stz K.MLI.PARAMS+1,x dex bpl .2 lda #4 ldx #MLI.QUIT 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... bpl .8 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 #K.S.EVT 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 IO.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 /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.T16 bne .5 inc A2osX.T16+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 PSs.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 #K.S.EVT 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 PSs.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 PSs.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 IIgs formware, Native Mode, 8bits *-------------------------------------- CORE.IRQGS .OP 65816 pha phb phx phy phk plb stz IO.GS.CLRVBLINT jsr CORE.IRQ.Switch ply plx plb pla * clc rtl * bra CORE.IRQ.Switch .OP 65C02 *-------------------------------------- * Called by : * - Kernel IRQ Manager (AuxLC) * - ProDOS IRQ Manager (GP) *-------------------------------------- CORE.IRQTK ldy IRQ.n0 lda $c080,y and #$20 beq CORE.IRQ.DEV lda $c088,y lda $c080,y bra CORE.IRQ.Switch *-------------------------------------- CORE.IRQM 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.IRQM.2+2 $Cn ldy IRQ.n0 CORE.IRQM.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 PSs.Hits,x stz PSs.Hits,x sta PSs.Stats,x dex bpl .1 .2 lda IRQ.InKernel bpl .3 inc PSs.Hits .9 clv clc rts .3 ldx CORE.PSIndex inc PSs.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.IRQGSOff .OP 65816 clc xce go to native mode rep #$30 long M,X pea $0003 Disable vertical blanking interrupts >TKCALL IntSource bcs * pea $000C Vertical blanking interrupt handler lda IRQ.GSVect+2 pha lda IRQ.GSVect pha >TKCALL SetVector bcs * sep #$30 short M,X sec xce back to emulation mode .OP 65C02 rts *-------------------------------------- CORE.IRQTKOff ldx IRQ.n0 stz $c080,x lda $c088,x lda $c080,x ldx IRQ.0n stz $478,x stz $7f8,x *-------------------------------------- CORE.IRQOff rts *-------------------------------------- CORE.IRQMOff ldy CORE.IRQMOff.1+2 Cn ldy IRQ.n0 lda #0 CORE.IRQMOff.1 jmp $ffff SELF MODIFIED *-------------------------------------- IRQ.InKernel .BS 1 IRQ.InLib .BS 1 IRQ.Skip .BS 1 IRQ.GSVect .BS 4 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