; ; File: SWIMIOP.aii ; ; Contains: Interface between the Kernel and Drivers for the SWIM IOP. ; ; Written by: Gary G. Davidian ; ; Copyright: © 1987-1990 by Apple Computer, Inc., all rights reserved. ; ; Change History (most recent first): ; ; <2> 1/2/90 GGD NEEDED FOR ZONE-5: Adding Idle Loop Task Dispatching. ; <1.3> 11/2/89 GGD NEEDED FOR ZONE-5 Moved the routines HandleDMA1Int, ; HandleDMA2Int, SWIMShutDown, SWIMStopPolling, and SWIMGetIcon ; into SWIMDriver.aii ; <1.2> 7/8/89 CCH Added EASE comments to file. ; <•1.1> 6/15/89 GGD Updated to use equates for the latest rev of the IOP chip, ; re-formated tab stops in source. ; <1.0> 11/9/88 CCH Adding to EASE. ; ; To Do: ; eject title 'SWIM IOP - Kernel / Driver Interface for the SWIM IOP' machine m65C02 codechk off datachk off longa off longi off print nomdir include 'IOPDefs.aii' include 'SWIMDefs.aii' title 'SWIM IOP - Initialization and Unused Interrupt Handlers' import InitADBDrvr import InitSWIMDrvr entry Primes seg 'code' SWIMIOP proc export InitDrivers InitDrivers lda #1*SCCISM+1*BYPASS sta SCCControlReg ; initialize SCC Control Reg lda #SwimIOCtlReg sta IOControlReg ; initialize I/O Control Reg lda #3 ; max send / receive sta RCVMsgMax ; initialize receive max sta XMTMsgMax ; initialize transmit max jsr InitADBDrvr ; initialize the ADB Driver jmp InitSWIMDrvr ; initialize the SWIM Driver and return export HandleSCCInt export HandleXMTMsg4 export HandleXMTMsg5 export HandleXMTMsg6 export HandleXMTMsg7 export HandleRCVMsg1 export HandleRCVMsg4 export HandleRCVMsg5 export HandleRCVMsg6 export HandleRCVMsg7 HandleSCCInt HandleXMTMsg4 HandleXMTMsg5 HandleXMTMsg6 HandleXMTMsg7 HandleRCVMsg1 HandleRCVMsg4 HandleRCVMsg5 HandleRCVMsg6 HandleRCVMsg7 Unimplemented brk bra Unimplemented export RunIdleTasks RunIdleTasks pha phx phy jsr Primes ; look for primes jsr @unused ; reserve space to patch in jsr @unused ; a few more tasks jsr @unused ply plx pla @unused rts endproc title 'SWIM IOP - Idle Task for Prime Number Computations' ResultWidth equ 32 ; Page zero variables seg 'zdata' PrimeVarsZ record Remainder ds.b 1 ; byte Numerator ds.b 4 ; long endr seg 'data' PrimeVars record PrimeVarsStart equ * ds.b 1 ; 1 byte of padding for logic analyzer alignment PrimesFound ds.b 4 ; long PrimesFoundOff equ *-PrimeVarsStart HighestPrime ds.b 4 ; long HighestPrimeOff equ *-PrimeVarsStart CurrentDenom ds.b 2 ; word CurrentDenomOff equ *-PrimeVarsStart ds.b 2 ; word MaxDenom ds.b 2 ; word (2 bytes of zeros needed before) MaxDenomOff equ *-PrimeVarsStart ; (2 bytes of zeros needed after) ds.b 2 ; word PossiblePrime ds.b 4 ; long (1 byte of zeros needed before) PossiblePrimeOff equ *-PrimeVarsStart MaxDenomSquared ds.b 4 ; long MaxDenomSquaredOff equ *-PrimeVarsStart PrimeVarsSize equ *-PrimeVarsStart ; number of bytes of PrimeVars endr seg 'code' Primes proc with PrimeVarsZ,PrimeVars; globals used throughout ; Depends upon memory being initialized to zeros at reset lda CurrentDenom+1 ; get the last denom used lsr a ; test the low bit bcs Resume ; if odd, resume the computations bne Suspend ; if even and non-zero, we found all primes ; if zero, it's initialization time lda #3 sta PossiblePrime+3 ; PossiblePrime := 3 sta MaxDenom+1 ; MaxDenom := 3 lda #9 sta MaxDenomSquared+3 ; MaxDenomSquared := 9 inc PrimesFound+3 ; PrimesFound := 1 FoundPrime ldx #PossiblePrimeOff ldy #HighestPrimeOff jsr MoveLong ; HighestPrime := PossiblePrime ldy #PrimesFoundOff lda #1 jsr AddImmedLong ; PrimesFound := PrimesFound + 1 bra TryNextPossible ; goto TryNextPossible PrimeCheckLoop ldy #CurrentDenomOff lda #2 jsr AddImmedWord ; CurrentDenom := CurrentDenom + 2 CheckForPrime ldx #CurrentDenomOff ldy #MaxDenomOff jsr TestEqualWord ; if CurrentDenom = MaxDenom beq FoundPrime ; then goto FoundPrime ; Before each divide, we return to the Idle Loop to give other tasks a chance Suspend rts ; go back to idle loop Resume ; retuned from idle loop if ResultWidth <= 16 then ; Remainder := PossiblePrime MOD CurrentDenom lda PossiblePrime+3 ; Numerator := PossiblePrime sta 0 bne PrimeCheckLoop ; then goto PrimeCheckLoop else ; Remainder := PossiblePrime MOD CurrentDenom ldx #5 ; loop count/index for 5 byte copy @RemCopyLoop lda PossiblePrime-1-1,x ; Numerator := PossiblePrime sta 0 bne PrimeCheckLoop ; then goto PrimeCheckLoop endif TryNextPossible lda #3 sta CurrentDenom+1 stz CurrentDenom+0 ; CurrentDenom := 3 ldy #PossiblePrimeOff lda #2 jsr AddImmedLong ; PossiblePrime := PossiblePrime + 2 ldx #PossiblePrimeOff ldy #MaxDenomSquaredOff jsr TestEqualLong ; if PossiblePrime <> MaxDenomSquared bne CheckForPrime ; then goto CheckForPrime ldy #MaxDenomOff lda #2 if ResultWidth <= 16 then jsr AddImmedByte ; MaxDenom := MaxDenom + 2 bne Done ; if carry out, we're done else ; The divide algorithm used only allows 15 bit denominators, it would be ; considerrably slower and bigger to handle all 16 bits, so we exit when we ; reach 16 bits, which allows prime checking up to $3FFF0001 (1,073,676,289) jsr AddImmedWord ; MaxDenom := MaxDenom + 2 lda MaxDenom ; see if carry into sign bit bmi Done ; if negative, we're done endif ; MaxDenomSquared := MaxDenom * MaxDenom ldx #MaxDenomOff+2 ; MaxDenom High, Zeros Low ldy #MaxDenomSquaredOff jsr MoveLong ; MaxDenomSquared := MaxDenom High, Zeros Low lda #16 ; loop counter for 16x16 multiply @SquareLoop pha ; save loop counter ldx #MaxDenomSquaredOff jsr AddToMaxDenomSquared; MaxDenomSquared := MaxDenomSquared * 2 bcc @SquareNext ; if no carry, skip the add ldx #MaxDenomOff jsr AddToMaxDenomSquared; MaxDenomSquared := MaxDenomSquared + MaxDenom @SquareNext pla ; restore loop counter dea ; decrement loop counter bne @SquareLoop ; loop for all 16 bits bra TryNextPossible ; goto TryNextPossible Done asl CurrentDenom+1 ; force an even, non-zero value rts ; all done MoveLong jsr MoveWord MoveWord jsr MoveByte MoveByte dex lda PrimeVarsStart,x dey sta PrimeVarsStart,y rts AddImmedLong jsr AddImmedWord AddImmedWord jsr AddImmedByte AddImmedByte clc dey adc PrimeVarsStart,y sta PrimeVarsStart,y lda #0 rol a rts AddToMaxDenomSquared ldy #4-1 clc @AddLoop dex lda PrimeVarsStart,x adc MaxDenomSquared,y sta MaxDenomSquared,y dey bpl @AddLoop rts TestEqualLong jsr TestEqualWord bne NotEqual TestEqualWord jsr TestEqualByte bne NotEqual TestEqualByte dex lda PrimeVarsStart,x dey cpa PrimeVarsStart,y NotEqual rts endwith endproc end