mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-29 20:49:19 +00:00
508 lines
17 KiB
Plaintext
508 lines
17 KiB
Plaintext
;
|
||
; File: SonyPatches.a
|
||
;
|
||
; Contains: patches for the Sony Driver
|
||
;
|
||
; A bit of history: Sony reportedly receives 8,000 800K drives/month for
|
||
; repair, 7,000 of these have head damage. By moving heads to the i.d. of
|
||
; the disk, head damage is vastly reduced (by Sony’s studies).
|
||
;
|
||
; Also, a patch for Format on all Macs. Format used 'DskErr' as a completion flag
|
||
; for synchronous calls to DiskSel and Seek, but other drivers might mess
|
||
; with this (at interrupt level), causing Format to think the Sel/Seek was
|
||
; finished before it really was.
|
||
;
|
||
; Another problem is that Format saved an error code in DskErr around a call
|
||
; to toEmptyPD, then restored from it, but after interrupts were enabled.
|
||
; EmptyPD doesn’t destroy d0, so restoring isn’t necessary (and bad). This
|
||
; is fixed by patching jRdAddr.
|
||
;
|
||
; Written by: Gary Rensberger
|
||
;
|
||
; Copyright: © 1989-1991 by Apple Computer, Inc., all rights reserved.
|
||
;
|
||
; Change History (most recent first):
|
||
;
|
||
; <3> 10/28/91 SAM/KSM Rolled in Regatta file.
|
||
;
|
||
; Regatta Change History:
|
||
;
|
||
; <3> 7/19/91 SAM (GMR) Added patch to fix Prime overpatch code bug in Terror ROM's.
|
||
; <2> 6/30/91 SAM (GMR) Added ReCal patch for Derringer's BuddyLite drive.
|
||
; <1> 6/24/91 SAM Split off from 7.0 GM sources.
|
||
;
|
||
; 7.0 Change History:
|
||
;
|
||
; <2> 8/30/91 DTY Define has3rdFloppy, onMac, onHcMac and onMacPP to make
|
||
; SonyEqu.a happy. (They got taken out of BBSStartup in an effort
|
||
; to make all the files in SysObj.make use {Defs}.)
|
||
; <1> 8/18/90 dba created by merging the eject patch and the format patch (viva la
|
||
; linked patches)
|
||
; Change History of the eject patch:
|
||
;
|
||
; <5> 8/6/90 GMR NEEDED FOR SixPack! Made ComeFrom addresses relative to ROMBase.
|
||
; <4> 7/19/90 GMR Now also patches SEfdhd, IIx, Portable, and IIci ROMS.
|
||
; <3> 7/11/90 gbm get rid of duplicate symbols
|
||
; <2> 12/28/89 dba changed PROC to MAIN to get dead code stripping
|
||
; <1.1> 8/18/89 CCH Removed definition of onMac32.
|
||
; <1.0> 7/25/89 GMR FOR 6.0.4!! Added to EASE for first time.
|
||
;
|
||
; Change History of the format patch:
|
||
;
|
||
; <6> 8/12/90 GMR Needed for SixPack!! Special cased the Erickson ROM because the
|
||
; Sony driver moved in this version of the Mac32 ROM.
|
||
; <5> 8/6/90 GMR Made ComeFrom addresses relative to ROMBase.
|
||
; <4> 7/21/90 GMR Fixed 24/32 bit JSR bug in one of the patches.
|
||
; <3> 7/11/90 gbm change to avoid assembly warnings
|
||
; <2> 12/28/89 dba change PROC to MAIN to get dead code stripping
|
||
; <1.0> 12/11/89 GMR Adding for first time to EASE
|
||
;
|
||
|
||
if (&type('onMac') = 'UNDEFINED') then ; <2>
|
||
onMac: equ 0 ; <2>
|
||
endif ; <2>
|
||
|
||
if (&type('onMacPP') = 'UNDEFINED') then ; <2>
|
||
onMacPP: equ 0 ; <2>
|
||
endif ; <2>
|
||
|
||
if (&type('onHcMac') = 'UNDEFINED') then ; <2>
|
||
onHcMac: equ 0 ; <2>
|
||
endif ; <2>
|
||
|
||
if (&type('has3rdFloppy') = 'UNDEFINED') then ; <2>
|
||
has3rdFloppy: equ 0 ; <2>
|
||
endif ; <2>
|
||
|
||
load 'StandardEqu.d'
|
||
include 'SonyEqu.a'
|
||
include 'LinkedPatchMacros.a'
|
||
|
||
SeekCk ROMBind (II,$2D9C2),(SE,$34986),(Portable,$2CFC0),(IIci,$6CC9C)
|
||
CkDrvNum ROMBind (Plus,$18040),(II,$2DA00),(SE,$349E2)
|
||
RWPowerUp ROMBind (Plus,$1890A),(II,$2E1B0),(SE,$352EC),(Portable,$2DAA6)
|
||
Seek ROMBind (Plus,$18718),(II,$2DFAC),(SE,$350DE)
|
||
SyncCallRtn ROMBind (Plus,$194CA),(II,$2EFFC),(SE,$363AA),(Portable,$2EADE),(IIci,$6EA7C)
|
||
FmtTrkRet ROMBind (Plus,$19230),(II,$2ED66),(SE,$36114),(Portable,$2E82C),(IIci,$6E7CE)
|
||
EmptyPD ROMBind (Plus,$194AE),(II,$2EFE0),(SE,$3638E),(Portable,$2EAC2),(IIci,$6EA60)
|
||
|
||
; second version of some ROM binds used by SE w/FDHD, II w/FDHD and IIci w/bad Erickson overpatch
|
||
|
||
SyncCallRtn2 ROMBind (SE,$3D86C),(II,$3231A),(IIci,$6EEBA)
|
||
FmtTrkRet2 ROMBind (SE,$3D5C4),(II,$3206C),(IIci,$6EC0C)
|
||
EmptyPD2 ROMBind (SE,$3D856),(II,$322FE),(IIci,$6EE9E)
|
||
|
||
|
||
; Used by the Recal Patch for BuddyLite drives
|
||
|
||
GetDrive ROMBind (Portable,$2D7C8)
|
||
InvalTrkCache ROMBind (Portable,$2DA92)
|
||
SetChipMode ROMBind (Portable,$2EB5A)
|
||
AdrAndStrb ROMBind (Portable,$2D85A)
|
||
AdrAndSense ROMBind (Portable,$2D838)
|
||
Pulse ROMBind (Portable,$2D85C)
|
||
Wait100 ROMBind (Portable,$2D902)
|
||
recalSlow ROMBind (Portable,$2D9F6)
|
||
|
||
; Used by the Prime Patch for the Terror overpatch ROM
|
||
|
||
PrimePC EQU $0086CEBE
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; JSeek — patch to make the FDHD Sony driver seek to track 40 instead of track 79 when ejecting
|
||
|
||
ROMs SE,II,Portable,IIci,hasFDHDDriver,hasIWM,notAUX
|
||
|
||
SetupSeek40InsteadOf79Patch InstallProc
|
||
|
||
Import FromSeek0,FromSeek1
|
||
|
||
leaROM SeekCk,d0
|
||
and.l Lo3Bytes,d0
|
||
lea FromSeek0,a0
|
||
move.l d0,(a0) ; put stripped address into patch
|
||
add.l #$10,d0 ; advance to next address
|
||
lea FromSeek1,a0
|
||
move.l d0,(a0) ; put stripped address into patch
|
||
rts
|
||
|
||
EndProc
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
Seek40InsteadOf79Patch PatchProc JSeek
|
||
|
||
Entry FromSeek0,FromSeek1
|
||
|
||
move.l (sp),d0 ; get return address
|
||
and.l Lo3Bytes,d0 ; only check 24 bit part of address
|
||
|
||
FromSeek0 equ *+2
|
||
cmp.l #'GMR',d0 ; were we called by eject?
|
||
beq.s seekAlter ; yes, alter track #
|
||
FromSeek1 equ *+2
|
||
cmp.l #'GMR',d0 ; were we called by eject (2nd try case)?
|
||
bne.s callOld ; no, just call ROM based seek routine
|
||
seekAlter
|
||
moveq #40,d6 ; yes, alter track # from 79 to track 40 (half way out)
|
||
callOld
|
||
jmpOld ; call ROM based Seek routine
|
||
|
||
EndProc
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; JControl — patch to make 800K floppy driver seek to track 40 when ejecting
|
||
|
||
; Seek to track 40 if it’s an Eject call, valid drive, drive installed, not a DCD drive,
|
||
; and there’s a disk in the drive. Then jump back into the ROM to complete the eject.
|
||
|
||
ROMs Plus,SE,II,has800KDriver
|
||
|
||
SetupDCDDriveNumberForSE InstallProc (SE,has800KDriver)
|
||
|
||
Import pDCDNum
|
||
|
||
lea pDCDNum,a0 ; SE has 3 drives before the DCD
|
||
move.w #4,(a0) ; so the DCD drive number is 4, not 3
|
||
rts
|
||
|
||
EndProc
|
||
|
||
ControlSeek40OnEject PatchProc JControl
|
||
|
||
Entry pDCDNum
|
||
|
||
move.l a0,d4 ; save paramBlockPtr (don’t use stack!)
|
||
|
||
cmpi.w #7,CSCode(a0) ; check for eject call
|
||
bne.s oldEject ; no, do old control call
|
||
|
||
jsrROM CkDrvNum ; check drive# validity
|
||
bne.s oldEject ; not valid, exit
|
||
|
||
tst.b Installed(a1,d1.w) ; check if drive actually installed
|
||
bmi.s oldEject ; no, let old control call handle it
|
||
|
||
pDCDNum equ *+2 ; drive number of the DCD drive
|
||
cmpi.w #3,Drive(a1) ; see if DCD drive
|
||
bge.s oldEject ; DCD drive, let old control call handle it
|
||
|
||
tst.b DiskInPlace(a1,d1.w) ; has disk been seen in drive?
|
||
ble.s oldEject ; no, skip seek
|
||
|
||
jsrROM RWPowerUp ; make sure the drive’s powered up
|
||
moveq #40,d6 ; seek to track 40 to get away from shutter edge
|
||
jsrROM Seek
|
||
bgt.s oldEject ; (seek was successful)
|
||
beq.s reSeek ; (recal’d)
|
||
|
||
pea @returnHere
|
||
move.l JRecal,-(sp) ; seek failed: recal first
|
||
rts
|
||
@returnHere
|
||
|
||
bmi.s oldEject
|
||
reSeek
|
||
moveq #40,d6
|
||
jsrROM Seek ; try seeking again
|
||
|
||
oldEject
|
||
movea.l d4,a0 ; restore paramBlockPtr
|
||
jmpOld ; call ROM based Control routine
|
||
|
||
EndProc
|
||
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
ROMs Plus,SE,II,Portable,IIci,notAUX
|
||
|
||
SetupFormatPatchesCommon Proc
|
||
|
||
Import pSyncCallRtnInDiskSel,pSyncCallRtnInSeek,pFmtTrk
|
||
|
||
; pass SyncCallRtn in d0, FmtTrkRet in d1
|
||
|
||
and.l Lo3Bytes,d0 ; mask to get 24 bit compare address <4>
|
||
lea pSyncCallRtnInDiskSel,a0
|
||
move.l d0,(a0) ; stuff address into patch
|
||
lea pSyncCallRtnInSeek,a0
|
||
move.l d0,(a0) ; stuff address into patch
|
||
|
||
sub.l #$18,d1 ; address in ROM to jump back to
|
||
and.l Lo3Bytes,d1 ; mask to get 24 bit compare address <4>
|
||
lea pFmtTrk,a0
|
||
move.l d1,(a0) ; stuff in return check address into patch
|
||
|
||
rts
|
||
|
||
EndProc
|
||
|
||
|
||
|
||
;----------------------------------------------------------------------------------
|
||
SetupFormatPatches1 Proc Export
|
||
|
||
leaROM SyncCallRtn,d0
|
||
leaROM FmtTrkRet,d1
|
||
|
||
jmp SetupFormatPatchesCommon
|
||
|
||
EndProc
|
||
|
||
|
||
|
||
;----------------------------------------------------------------------------------
|
||
SetupFormatPatches2 Proc Export
|
||
|
||
Import pFmtTrkRet,pEmptyPD
|
||
|
||
leaROM SyncCallRtn2,d0
|
||
leaROM FmtTrkRet2,d1
|
||
leaROM EmptyPD2,d2
|
||
|
||
lea pFmtTrkRet,a0
|
||
move.l d1,(a0) ; stuff address into patch
|
||
|
||
lea pEmptyPD,a0
|
||
move.l d2,(a0)
|
||
|
||
jmp SetupFormatPatchesCommon
|
||
|
||
EndProc
|
||
|
||
MakeInstall SetupFormatPatches1,(Plus,SE,II,has800KDriver,notAUX)
|
||
MakeInstall SetupFormatPatches1,(Portable,IIci,notAUX)
|
||
|
||
MakeInstall SetupFormatPatches2,(SE,II,hasFDHDDriver,notAUX)
|
||
MakeInstall SetupFormatPatches2,(IIci,hasEricksonOverpatchMistake,notAUX)
|
||
|
||
|
||
|
||
;----------------------------------------------------------------------------------
|
||
; This routine patches the DiskSelect routine. It first checks to see if
|
||
; we were called in the Format SyncCall routine. If we were, then we clear
|
||
; a new completion flag (instead of using diskErr). We also patch the two return
|
||
; addresses above the caller to this routine, one of which sets the new completion
|
||
; flag, the other which tests the flag. This quick and dirty, but works!
|
||
|
||
DiskSelectSyncCallPatch PatchProc JDiskSel
|
||
|
||
Entry pSyncCallRtnInDiskSel
|
||
Import WaitRtn,DoneRtn
|
||
|
||
nop ; Important..sync the instruction pipe
|
||
|
||
moveq #10,d0 ; return addresses should be 10 bytes apart
|
||
add.l 8(sp),d0 ; 3rd level return address + 10
|
||
sub.l 4(sp),d0 ; compare to 2nd level return address
|
||
bne.s Done ; no, not the one we’re looking for, exit
|
||
|
||
move.l 4(sp),d0 ; yes, get 2nd level address again
|
||
and.l Lo3Bytes,d0 ; only check 24 bit part of address
|
||
pSyncCallRtnInDiskSel equ *+2
|
||
cmpi.l #'GMR',d0 ; were we called by Format SyncCall routine?
|
||
bne.s Done ; no, get out of here
|
||
|
||
move.l a0,d0 ; save a0
|
||
|
||
lea DoneRtn,a0 ; get address of our new Done routine
|
||
move.l a0,4(sp) ; replace old routine
|
||
lea WaitRtn,a0 ; get address of our new Wait routine
|
||
move.l a0,8(sp) ; replace old routine
|
||
|
||
movea.l d0,a0 ; restore a0
|
||
|
||
subq.b #1,Active(a1) ; signal that RWPowerUp isn’t done yet.
|
||
Done
|
||
jmpOld ; go back to original jump vector
|
||
|
||
EndProc
|
||
|
||
|
||
|
||
;----------------------------------------------------------------------------------
|
||
; This routine patches the Seek routine. It first checks to see if
|
||
; we were called by the Format SyncCall routine. If we were, then we clear
|
||
; a new completion flag (instead of using diskErr). We also patch the two
|
||
; return addresses above this routine, one of which sets the new completion
|
||
; flag, the other which tests the flag.
|
||
|
||
SeekSyncCallPatch PatchProc JSeek
|
||
|
||
Entry WaitRtn,DoneRtn,pSyncCallRtnInSeek
|
||
|
||
moveq #10,d0 ; return addresses should be 10 bytes apart
|
||
add.l 4(sp),d0 ; 2nd level return address + 10
|
||
sub.l (sp),d0 ; compare to 1st level return address
|
||
bne.s Done ; no, not the one we’re looking for, exit
|
||
|
||
move.l (sp),d0 ; get 2nd level return address
|
||
and.l Lo3Bytes,d0 ; only check 24 bit part of address
|
||
pSyncCallRtnInSeek equ *+2
|
||
cmpi.l #'GMR',d0 ; were we called by Format SyncCall?
|
||
bne.s Done ; no, get out of here
|
||
|
||
move.l a0,d0 ; save a0
|
||
|
||
lea DoneRtn,a0 ; get address of our new Done routine
|
||
move.l a0,(sp) ; replace old routine
|
||
lea WaitRtn,a0 ; get address of our new Wait routine
|
||
move.l a0,4(sp) ; replace old routine
|
||
|
||
movea.l d0,a0 ; restore a0
|
||
|
||
subq.b #1,Active(a1) ; signal that Seek isn’t done yet.
|
||
Done
|
||
jmpOld ; go back to original jump vector
|
||
|
||
|
||
WaitRtn
|
||
cmpi.b #$FF,Active(a1) ; are we finished?
|
||
bne.s WaitRtn ; no, wait
|
||
rts ; exit
|
||
|
||
|
||
DoneRtn
|
||
st Active(a1) ; we’re finished, set completion bit
|
||
rts
|
||
|
||
EndProc
|
||
|
||
|
||
|
||
|
||
;----------------------------------------------------------------------------------
|
||
; Patch RdAddr to fix Format code, so format doesn’t use DskErr lowmem
|
||
; for saving temporary error results, since an interrupt can get in and
|
||
; clobber this lowmem. The patch first checks to see if we’re called from
|
||
; format, if so, patches in a new routine to return to on the stack. In either
|
||
; case, it continues by jumping to what jRdAddr pointed to.
|
||
|
||
RdAddrFormatPatch PatchProc JRdAddr
|
||
|
||
Entry pFmtTrk,pEmptyPD,pFmtTrkRet
|
||
|
||
move.l (sp),d0 ; get 1st level return address
|
||
and.l Lo3Bytes,d0 ; only check 24 bit part of address
|
||
pFmtTrk equ *+2
|
||
cmpi.l #'GMR',d0 ; were we called by Format FmtTrk1 rtn?
|
||
bne.s @dontPatch ; no, get out of here
|
||
|
||
move.l a0,d0 ; save a0
|
||
lea newFmtRtn,a0 ; get address of our new routine
|
||
move.l a0,(sp) ; replace old routine
|
||
movea.l d0,a0 ; restore a0
|
||
@dontPatch
|
||
jmpOld ; continue by jumping to RdAddr
|
||
|
||
;..................................................................................
|
||
|
||
newFmtRtn
|
||
bmi.s @dontChangeErr ; br if error
|
||
tst.b d2 ; should be sector 0
|
||
beq.s @dontChangeErr
|
||
moveq #Fmt1Err,d0 ; set "not sector 0" error otherwise
|
||
@dontChangeErr
|
||
|
||
pEmptyPD equ *+2
|
||
jsrROM EmptyPD ; get rid of poll data (saves D0 in DskErr)
|
||
andi #$F8FF,SR ; open up interrupts
|
||
lea GapSync(a1),a0 ; useful addr
|
||
tst.w d0 ; check error code
|
||
pFmtTrkRet equ *+2
|
||
jmpROM FmtTrkRet ; 'DecrSn1' back to ROM code...
|
||
|
||
EndProc
|
||
|
||
|
||
|
||
;---------------------------------------------------------------------------------- <2>
|
||
; Patch Recal to use fast (with handshake) step pulses for the
|
||
; new Buddy Lite SuperDrive on Derringer.
|
||
|
||
ROMs Portable
|
||
|
||
RecalPatch PatchProc jRecal
|
||
|
||
move.l (SP)+,A5 ; save return address
|
||
jsrROM GetDrive
|
||
jsrROM InvalTrkCache ; invalidate track cache
|
||
|
||
jsrROM SetChipMode ;Initialize appropriate register set
|
||
bne.s @RecalExit ; couldn't set IWM Mode
|
||
|
||
jsrROM RWPowerUp ;Re-enable the interface
|
||
moveq #80,D7 ; maximum number of steps needed
|
||
|
||
moveq #DirHAdr,D0 ;Set direction out (toward track 0)
|
||
jsrROM AdrAndStrb ;
|
||
|
||
move.w SeekTime(A1),D0 ; assume slow code
|
||
tst.b NewIntf(A1,D1) ; new drive interface?
|
||
bmi.s @fastRecal ; br if so (use fast code)
|
||
jmpROM recalSlow ; else, use slow code
|
||
|
||
;------
|
||
@fastRecal subq #1,D7 ;Adjust count for DBRA
|
||
@SeekLoop moveq #StepLAdr,D0 ;Make sure /STEP starts out high
|
||
jsrROM AdrAndSense ;
|
||
bpl.s @RecalFail ;-> it wasn't, so exit with error
|
||
jsrROM Pulse ;Then set it low
|
||
jsrROM Wait100 ;and wait a while for it to go high
|
||
dbra D7,@SeekLoop ;count track
|
||
|
||
moveq #0,D0 ; track 0
|
||
@RecalExit move.w D0,Track(A1,D1)
|
||
jmp (A5)
|
||
|
||
@RecalFail moveq #cantStepErr,D0 ; no track
|
||
bra.s @RecalExit
|
||
|
||
EndProc
|
||
|
||
|
||
|
||
|
||
|
||
;---------------------------------------------------------------------------------- <3>
|
||
; The following patch applies to the Mac32 ROM's. It fixes a bug in the
|
||
; Terror ($67C) overpatch code for jPrime which had a stack problem.
|
||
;----------------------------------------------------------------------------------
|
||
|
||
ROMs IIci
|
||
|
||
instIODonePatch InstallProc (IIci)
|
||
|
||
IMPORT toOldIODone
|
||
leaResident toOldIODone,a0 ; get location of JMP to address
|
||
move.l jIODone,(a0) ; stuff old vector in JMP location
|
||
leaResident NewIODone,a0 ; get location of new IODone rtn
|
||
move.l a0,jIODone ; stuff in vector
|
||
rts
|
||
|
||
EndProc
|
||
|
||
|
||
|
||
NewIODone Proc ; <3>
|
||
EXPORT toOldIODone
|
||
|
||
move.l (sp),d1 ; check return address
|
||
and.l Lo3Bytes,d1
|
||
cmpi.l #PrimePC,d1 ; are we comming from the Prime area?
|
||
bne.s NewExit ; no, normal exit
|
||
addq.w #4,sp ; yes, fix the stack
|
||
|
||
toOldIODone EQU *+2
|
||
NewExit jmp $40800000 ; exit
|
||
|
||
EndProc
|
||
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
End
|