mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-22 23:29:27 +00:00
4325cdcc78
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
341 lines
8.9 KiB
Plaintext
341 lines
8.9 KiB
Plaintext
;
|
|
; 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 <Numerator+3
|
|
lda PossiblePrime+2
|
|
sta <Numerator+2
|
|
|
|
lda #0 ; Remainder := 0
|
|
|
|
ldy #16 ; loop counter for 16/8 remainder
|
|
|
|
@RemLoop rol <Numerator+3 ; Shift Numerator into Remainder
|
|
rol <Numerator+2
|
|
rol a
|
|
bcs @RemSub
|
|
|
|
cpa CurrentDenom+1 ; compare denominator
|
|
blt @RemNext ; If Remainder < CurrentDenom, leave it
|
|
|
|
@RemSub sbc CurrentDenom+1 ; Remainder := Remainder - CurrentDenom
|
|
|
|
@RemNext dey ; decrement loop counter
|
|
bne @RemLoop ; loop for all 32 bits
|
|
|
|
tax ; test remainder for zero
|
|
; if PossiblePrime mod CurrentDenom <> 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 <Remainder-1,x ; Remainder := 0
|
|
dex ; update loop count/index
|
|
bne @RemCopyLoop ; loop through all 5 bytes
|
|
|
|
ldy #32+1 ; loop counter for 32/15 remainder
|
|
* ldx #0 ; Remainder := 0 (from dex above)
|
|
|
|
@RemLoop txa ; get low byte of remainder
|
|
dey ; decrement loop counter
|
|
beq @RemDone ; loop for all 32 bits
|
|
|
|
@RemShift rol <Numerator+3 ; Shift Numerator into Remainder
|
|
rol <Numerator+2
|
|
rol <Numerator+1
|
|
rol <Numerator+0
|
|
rol a
|
|
tax
|
|
rol <Remainder+0
|
|
|
|
cpx CurrentDenom+1 ; compare low byte of remainder
|
|
lda <Remainder+0 ; get high byte of remainder
|
|
sbc CurrentDenom+0 ; subtract denominator
|
|
blt @RemLoop ; If Remainder < CurrentDenom, leave it
|
|
|
|
sta <Remainder+0 ; Remainder := Remainder - CurrentDenom
|
|
* sec ; setup carry for subtraction
|
|
txa ; get low byte of remainder
|
|
sbc CurrentDenom+1 ; subtract denominator
|
|
dey ; decrement loop counter
|
|
bne @RemShift ; loop for all 32 bits
|
|
|
|
@RemDone ora <Remainder+0 ; if PossiblePrime mod CurrentDenom <> 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
|
|
|
|
|