sys7.1-doc-wip/Drivers/Sony/SonyPatches.a
2019-07-27 22:37:48 +08:00

508 lines
17 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;
; 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 Sonys 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 doesnt destroy d0, so restoring isnt 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 its an Eject call, valid drive, drive installed, not a DCD drive,
; and theres 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 (dont 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 drives 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 ; (recald)
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 were 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 isnt 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 were 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 isnt 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) ; were finished, set completion bit
rts
EndProc
;----------------------------------------------------------------------------------
; Patch RdAddr to fix Format code, so format doesnt 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 were 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