supermario/base/SuperMarioProj.1994-02-09/DeclData/SecondaryInit.a
2019-06-29 23:17:50 +08:00

583 lines
24 KiB
Plaintext
Raw 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: SecondaryInit.a
;
; Written by: Mike Puckett, October 3, 1991
;
; Copyright: © 1988-1993 by Apple Computer, Inc. All rights reserved.
;
; Change History (most recent first):
;
; <SM5> 12/13/93 PN Roll in KAOS and Horror to add support for Malcom and AJ
; <SM4> 08-03-93 jmp Updated sources to reflect necessary changes from HORROR.
; <SM3> 01-11-93 jmp Updated various BoxFlag names.
; <SM2> 10/28/92 SWC Changed VideoEqu.a->Video.a and ShutdownEqu.a->Shutdown.a.
; <1> 10/6/92 GDW New location for ROMLink tool.
; <SM5> 09-03-92 jmp (jmp,H9) Corrected .s vs. non-.s branches and odd-alignment
; problems.
; (ag,H8) Change to use new power manger calling convention.
; (jmp,H7) Needed to add Wombat-class CPUs to those that need to
; run the Sound-Input VBL-killer code.
; <SM4> 6/4/92 KW (djw,H6) moved power mgr code to after EndSecondaryInit label so
; the code would be called. (ag,H5) Added call to power dispatch
; to allow power manager code execution at secondary init time.
; <SM3> 5/16/92 kc Roll in Horror Changes. Comments follow:
; <H4> 01/29/92 jmp (jmp,Z4) Added in some code that eliminates the System 7 Tuners
; secure-mode unfriendly keyboard patches.
; <2> 3/31/92 JSM Rolled this file into Reality.
; <H3> 01/27/92 jmp (BG,Z3) Added miscellaneous Zydeco-specific SoundMgr fixes.
; <H2> 01/22/92 jmp (jmp,Z2) Added a way to temporarily disable the altsense code.
; <H1> 10/24/91 jmp first checked in
;---------------------------------------------------------------------
STRING C
PRINT OFF
LOAD 'StandardEqu.d'
INCLUDE 'DockingEqu.a'
INCLUDE 'EgretEqu.a'
INCLUDE 'GestaltEqu.a'
INCLUDE 'GestaltPrivateEqu.a'
INCLUDE 'HardwarePrivateEqu.a'
INCLUDE 'IOPrimitiveEqu.a'
INCLUDE 'PowerPrivEqu.a'
INCLUDE 'ROMEqu.a'
INCLUDE 'Video.a'
INCLUDE 'SlotMgrEqu.a'
INCLUDE 'ShutDown.a'
INCLUDE 'SonicEqu.a'
INCLUDE 'UniversalEqu.a'
INCLUDE 'DepVideoEqu.a'
PRINT ON
SEG '_sSecondaryInitRec'
MACHINE MC68020
LSecondaryInit PROC
;---------------------------------------------------------------------
; Header
;---------------------------------------------------------------------
Dc.b sExec2 ; code revision
Dc.b sCPU68020 ; CPU type is 68020
Dc.w 0 ; reserved
DC.L BeginSecondaryInit-* ; offset to code
;---------------------------------------------------------------------
; Local variables, definitions, etc....
;---------------------------------------------------------------------
SInitStackFrame Record {A6Link},Decrement
Return Ds.l 1 ; Return address.
A6Link Ds.l 1 ; Saved A6.
spBlk Ds SpBlock ; SpBlock for generic use.
sPRAMBlk Ds.b SizesPRAMRec ; SpRAMRec for generic use.
theDrHwID Ds.w 1 ; The DrHwID in use.
theBoardID Ds.b 1 ; The boardID in use.
Ds.b 1 ; <pad>
SInitStackSize Equ *
Endr
GestaltSelectorFrame Record {A6Link},Decrement
Result Ds.w 1 ; The Gestalt OSErr result.
GSFStartParams Equ *
Selector Ds.l 1 ; Selector, OSType.
ResponsePtr Ds.l 1 ; Response, VAR-type.
GSFParamSize Equ GSFStartParams-*
Return Ds.l 1 ; Return address.
A6Link Ds.l 1 ; Save A6.
Org
GSFSize Equ *
ENDR
;---------------------------------------------------------------------
; Data
;---------------------------------------------------------------------
; This is the VBL from System 7.0.1 ({SoundMgr}SoundMgrPatch.a) that is unnecessary
; on the Quadra 950.
SndVBLTask ; 7.0.1 System Disk Sound VBL Task (stored as data here)
dc.w $317C, $001E, $000A ; MOVE.W #$001E,$000A(A0)
dc.w $2278, $0CC0 ; MOVEA.L $0CC0,A1
dc.w $40E7 ; MOVE SR,-(A7)
dc.w $007C, $0700 ; ORI.W #$0700,SR
dc.w $4A29, $0F09 ; TST.B $0F09(A1)
dc.w $6706 ; BEQ.S *+$0008
dc.w $4A29, $0F29 ; TST.B $0F29(A1)
dc.w $661A ; BNE.S *+$001C
dc.w $137C, $0001, $0F09 ; MOVE.B #$01,$0F09(A1)
dc.w $137C, $0001, $0F29 ; MOVE.B #$01,$0F29(A1)
dc.w $4229, $0F09 ; CLR.B $0F09(A1)
dc.w $4229, $0F29 ; CLR.B $0F29(A1)
dc.w $317C, $0001, $000A ; MOVE.W #$0001,$000A(A0)
dc.w $46DF ; MOVE (A7)+,SR
dc.w $4E75 ; RTS
SndVBLSize equ *-SndVBLTask ;
; The System 7.0 Tuner is not secure-switch friendly. So, we need to tell it to not apply the
; “putter” keyboard fixes. This routine is installed into the System heap as a Gestalt proc; it
; is not executed from within this file.
;
With GestaltSelectorFrame
FixKBFix
Link A6,#GSFSize ; Set up a Gestalt-style stackframe.
Move.l ResponsePtr(A6),A0 ; Get a pointer to the response variable.
Move.l #(1<<gestaltKeyboardFix),D0 ; Say that the keyboard fix is unnecessary.
Move.l D0,(A0) ; Return it.
Move.w #noErr,Result(A6) ; We dont need to return an error here.
Unlk A6 ; Clean up the stackframe.
Move.l (Sp)+,A0 ; Get the return address.
addq #GSFParamSize,Sp ; Do Pascal-stlye clean up.
Jmp (A0) ; Return to caller.
EndKBFix
Endwith
; On the sucky FSTN LCD Panels, we want to alert the System (for WDEFs, CDEFs, etc…) that they
; may not want to do deep gray drawing in wide areas. This routine is used as either
; a new Gestalt selector or a replacement if it already exists. It doesnt get called
; from within this file, so its just data here.
;
With GestaltSelectorFrame
NewGraysFlicker
Link A6,#GSFSize ; Set up a Gestalt-style stackframe.
Lea OldGraysFlicker,A0 ; Point to the holder of the original response.
Move.l (A0),D0 ; Get that value.
Movea.l ResponsePtr(A6),A0 ; Get a pointer to the response variable.
Ori.l #(1<<0),D0 ; Say that the Slot 0 screen flickers.
Move.l D0,(A0) ; Return it.
Move.w #noErr,Result(A6) ; We dont need to return an error here.
Unlk A6 ; Clean up the stackframe.
Move.l (Sp)+,A0 ; Get the return address.
addq #GSFParamSize,Sp ; Do Pascal-stlye clean up.
Jmp (A0) ; Return to caller.
OldGraysFlicker Dc.l 0 ; Previous value.
EndNewGraysFlicker
Endwith
;---------------------------------------------------------------------
; Utils
;---------------------------------------------------------------------
;---------------------------------------------------------------------
;
; Routine: ChkScrn
;
; Inputs: D0.w - contains theDrHwID
;
; Outputs: None
;
; Destroys: A0-A2/D0-D1
;
; Function: Classically, the Monitors control panel writes out an
; 'scrn' resource that would flip us into 1bpp (i.e.,
; mode $80) on family mode changes. We attempt to
; solve that problem here by re-writing the appropriate
; value into the 'scrn' resource itself.
;
; Note: Because this is a shared SecondaryInit, we do all of
; this somewhat obscurely by using the ScrnInval (VidType)
; and VidMode lo-memory globals as a single word-sized
; value. It is the job of the individual PrimaryInits
; to write out the appropriate DrHwID if a family
; mode change has occurred since the last re-boot. Since
; all of our DrHwIDs are actually byte-sized, the ScrnInval
; byte is generally cleared, which keeps the ROM version
; of CheckDevicesInit from whacking us back into 1bpp.
; If this werent a shared SecondaryInit we would (more
; appropriately) use Slot PRAM for this sort of thing.
;
; ScrnInval & VidMode arent used during the boot-up
; process so this sort of hacking is okay.
;---------------------------------------------------------------------
With SInitStackFrame,SpBlock,ScrnRecord,SP_Params
ChkScrn Cmp.w ScrnInval,D0 ; If 'scrn' resource doesnt need validating by us,
Bne @EndScrn ; then just go on.
Move.w #-1,ScrnInval ; Clean up after ourselves.
; Check to see that Slot 0 video is actually running…
;
Lea spBlk(A6),A0 ; Point to our spBlock.
Clr.b spId(A0) ; Begin at id 0.
Clr.b spTBMask(A0) ; No mask in search.
Move.w #catDisplay,spCategory(A0) ; Look for: Display,
Move.w #typVideo,spCType(A0) ; Video,
Move.w #drSwApple,spDrvrSW(A0) ; Apple,
Move.w D0,spDrvrHW(A0) ; <DrHwID>.
Clr.l spParamData(A0) ; Look only for enabled sRsrcs.
_GetTypeSRsrc ; If we didnt find ourselves,
Bne.s @EndScrn ; then just go on.
; Check to see if theres an 'scrn' resource available…
;
Clr.l -(Sp) ; Make room for the function result.
Move.l #'scrn',-(Sp) ; Push desired resource type.
Clr.w -(Sp) ; Resource ID = 0.
_GetResource ; Get the resource.
Move.l (Sp)+,D0 ; Get the resource handle.
Beq.s @EndScrn ; If nil, then just go on.
Move.l D0,-(Sp) ; Save Handle for _ReleaseResource call.
Movea.l D0,A2 ; Save it for easy access later on.
Movea.l D0,A0 ; Set up to lock it down for now.
_HNoPurge ; Make it non-purgeable and…
_HLock ; …lock it down.
; Check to see if were in the 'scrn' resource…
;
Movea.l (A0),A0 ; Get a pointer to the 'scrn' resource.
Move.w (A0)+,D0 ; Get the number of 'scrn' records to search.
Subq #1,D0 ; Make it zero-based.
@ScrnLoop Tst.w srSlot(A0) ; If this entry is for Slot 0,
Beq.s @ChkDrHwID ; then check the drHwID.
Adda.w #ScrnRecSize,A0 ; Otherwise, point A0 at the next entry.
Dbra D0,@ScrnLoop ; Loop until done.
Bra.s @EndScrnChk ; We couldnt find our 'scrn' entry, so just go on.
@ChkDrHwID Move.w theDrHwID(A6),D0 ; Get our drHwID back into D0.
Cmp.w srDrvrHW(A0),D0 ; If the drHwIDs dont match,
Bne.s @EndScrnChk ; then just go on.
; Make sure the depth (mode) setting is correct…
;
Lea sPRAMBlk(A6),A1 ; Point to our sPRAM block.
Moveq #0,D0 ; Clear D0 for good measure.
Move.b SP_Depth(A1),D0 ; Get the mode wed like to be at.
Cmp.w srMode(A0),D0 ; If the modes match,
Beq.s @EndScrnChk ; then just go on.
Move.w D0,srMode(A0) ; Otherwise, write out what we want.
Move.l A2,-(Sp) ; Set up to mark our change.
_ChangedResource ; Do it.
Move.l A2,-(Sp) ; Set up to write our change out.
_WriteResource ; Do it.
; Clean up and go home…
;
@EndScrnChk _ReleaseResource ; Release the scrn resource.
@EndScrn Rts ; And return home.
Endwith
;---------------------------------------------------------------------
; Main
;---------------------------------------------------------------------
With SInitStackFrame,SEBlock,SpBlock
BeginSecondaryInit
Link A6,#SInitStackSize ; Allocate some space on the stack.
Move.w #seSuccess,seStatus(A0) ; No reason to fail here.
; Perform some generic intializations.
Clr.b spBlk.spSlot(A6) ; This is always a slot 0 SecondaryInit.
Clr.b spBlk.spExtDev(A6) ; Dont ask why, always clear this guy.
With ProductInfo,VideoInfo,SP_Params
Lea spBlk(A6),A0 ; Point to our spBlock.
Lea sPRAMBlk(A6),A2 ; Point to a sPRAM block.
Move.l A2,spResult(A0) ; Set up read buffer.
_sReadPRAMRec ; Read Slot 0s pRAM.
Movea.l UnivInfoPtr,A0 ; Point to the ProductInfo record.
Adda.l VideoInfoPtr(A0),A0 ; Point to the VideoInfo record.
Move.w DrvrHwID(A0),D0 ; Get the DrHwID.
Move.w D0,theDrHwID(A6) ; Remember it for later.
Move.b BoardSRsrcID(A0),theBoardID(A6) ; Remember the board ID.
Endwith
; For built-in videos that support it, go seek out and cleanse the 'scrn' resource if it is
; invalid. Note: This is generally used to prevent family-mode swapping from forcing the
; screen back to 1bpp due to a historical oversight on the part of the Monitors control
; panel.
;
Bsr.s ChkScrn ; D0.w contains theDrHwID.
; We cant read the keyboard without lots of non-generic stuff during PrimaryInit, so we do that
; here. The reason we are doing this is to temporarily disable the type-6 multimode support.
; To be consistent with the System, we use the shift key to disable.
;
With SP_Params,SpBlock
Cmpi.w #drHwDAFB,theDrHwID(A6) ; If were using the DAFB driver,
Beq.s @AltSense ; then do the AltSense stuff.
Cmpi.w #drHwSonora,theDrHwID(A6) ; If were using the Sonora driver,
Beq.s @AltSense ; then do the AltSense stuff.
Bra.s @EndAltSense ; Otherwise, keep going.
@AltSense Lea sPRAMBlk(A6),A2 ; Point to a sPRAM block.
Lea spBlk(A6),A0 ; Point to our spBlock.
Move.b SP_AltSense(A2),D0 ; Get the alternate senseID pRAM byte into D0.
Move.b D0,D4 ; Save it for later.
Andi.b #spAltSenseValidMask,D0 ; If the alternate senseID is not valid,
Beq.s @ChkForRestore ; just go on.
Movem.l KeyMap,D0-D3 ; Get the KeyMap.
Bclr #7,D3 ; Clear off the power key.
Bclr #1,D1 ; Clear off capslock key.
Bclr #0,D1 ; Clear off and test the shift key.
Beq.s @EndAltSense ; Dont disable if shift key is not held down.
Or.l D1,D0 ; Also, dont disable if
Or.l D2,D0 ; various other stray
Or.l D3,D0 ; keys are being.
Bne.s @EndAltSense ; held down
Move.b D4,D0 ; Get the alternate senseID pRAM byte again.
Andi.b #spAltSenseMask,D0 ; Strip off the validation code.
Ori.b #spAltSenseDisable,D0 ; Temporarily disable the alternate senseID.
Move.b D0,SP_AltSense(A2) ;
Move.l A2,spsPointer(A0) ; Set up parameter block.
_sPutPRAMRec ; Write pRAM out.
_SDRestart ; Restart the machine.
@ChkForRestore Move.b D4,D0 ; Get the alternate senseID pRAM byte again.
Andi.b #spAltSenseDisable,D0 ; If it is not the temporary disable code,
Beq.s @EndAltSense ; then just go on.
Move.b D4,D0 ; Get the alternate senseID pRAM byte again.
Andi.b #spAltSenseMask,D0 ; Strip off the validation bits.
Ori.b #spAltSenseValidMask,D0 ; Re-validate the alternate senseID byte.
Move.b D0,SP_AltSense(A2) ;
Move.l A2,spsPointer(A0) ; Set up parameter block.
_sPutPRAMRec ; Write pRAM out.
EndWith
@EndAltSense
; We only want the following to execute on CPUs with caboose keyswitches. We are telling the
; System 7 Tuner to not load its secure-mode unfriendly version of the Keyboard fixes.
;
; Note: The method used below to “fix” the System 7 Tuner is actually incomplete. We really
; should check to see if the gestaltBugFixAttrs selector actually exists, and if so, use
; _ReplaceGestalt to OR-in the fact that we dont want the keyboard fix (gestaltKeyboardFix)
; to be applied. Instead, we “know” that if the gestaltBugFixAttrs does exist, then the
; problem we are addressing here must have already been fixed.
Move.l #KeySwMask,D0 ; Get isolation mask ready. <4>
And.l UnivROMFlags,D0 ; Grab keyswitch bits in UnivROMFlags. <4>
Sub.l #KeyswCaboose,D0 ; Do we have a Keyswitch? <4>
Bne.s @EndKBFixes ; No, skip keyboard fixes. <4>
Move.l #gestaltBugFixAttrs,D0 ; Setup to load the bug-fix selector.
_Gestalt ; Try to load it.
Beq.s @EndKBFixes ; If its there, assume its okay.
Lea FixKBFix,A1 ; Point to the beginning of the keyboard fix.
Lea EndKBFix,A0 ; Point to the end of the keyboard fix.
Sub.l A1,A0 ; Determine the keyboard fix size.
Move.l A0,D0 ; Set up for _NewPtr (size in D0).
Move.l D0,D1 ; Save the size for BlockMove.
_NewPtr Sys ; Attempt to get a block in the System heap.
Bne.s @EndKBFixes ; If failed, just go on.
Lea FixKBFix,A1 ; Otherwise, point back at keyboard fix.
Exg A0,A1 ; Set up for BlockMove (A0=Src,A1=Dest).
Move.l D1,D0 ; D0 is size of block to move.
_BlockMove ; Do it.
Move.l A1,D2 ; Save System heap address for later if necessary.
Move.l #gestaltBugFixAttrs,D0 ; Setup to install bug-fix selector.
Exg A1,A0 ; Point to keyboard fix in System heap.
_NewGestalt ; Do it.
@ChkForErr Beq.s @EndKBFixes ; If the call worked, just go on.
Movea.l D2,A0 ; Otherwise, point to System heap code.
_DisposPtr ; And throw it away.
@EndKBFixes
; There are two parts to the following pieces of code. For the first piece, we want to execute on the
; Quadra 950 and the Wombat-class machines running the System 7.0.1 version of the Sound Manager.
; Supposed, the problem that this code addresses will be fixed in Cube-E. For the second piece,
; we only want to run on the Qudara 950.
;
kSndMgrVersion EQU $02018000 ; System 7.0.1 Version of the Sound Manager.
TestFor djMEMCChipBit ; If were on a Wombat-class CPU, then
Bne.s @StrtSndFix ; apply this fix.
cmpi.b #boxQuadra950,BoxFlag ; are we a Quadra 950?
Bne.s @EndSoundFixes ; nope ... we're outta here
@StrtSndFix
clr.l -(sp) ; make room for PASCAL return value
_SndSoundManagerVersion ; get current soundMgr version
move.l (sp)+,d0 ; retrieve returned value
cmpi.l #kSndMgrVersion,d0 ; are we the 7.0.1 soundmgr?
bne.s @EndSoundFixes ; nope ... we're outta here
;
; This will go and hunt down the Sound VBL Task and kill it. The reason for that is
; that in the Zydeco ROM, the "problem" this attempted to fix is fixed for real, so
; this VBL is no longer needed.
move sr,-(a7) ; save the status register
ori.w #$0100,sr ; mask off vbl interrupts
lea VBLQueue,a1 ; A1 points to the queue
lea qHead-vblink(a1),a0 ; setup to fetch head of list
@VBLloop move.l vblink(a0),d0 ; advance to next block
beq.s @VBLDone ; if queue is empty, exit
movea.l d0,a0 ; get pointer to next VBL control block
move.l vblAddr(a0),a1 ; get pointer to their code
lea SndVBLTask,a2 ; get pointer to our code
move.w #(SndVBLSize/2-1),d0 ; size of code
@checkLoop cmp.w (a1)+,(a2)+ ; compare source bytes
dbne d0,@checkLoop ; until not equal or out of bytes to check
bne.s @VBLloop ; not found - keep looking
_VRemove ; REMOVE the VBL
@VBLDone move (a7)+,sr ; restore interrupts
; We also want to UNpatch the InputSelect routine for the Quadra 950, since it
; shouldn't have been patched out in 7.0.1 ANYWAY, and we fixed a problem in the
; Q950 ROM routine, so we should use that one.
cmpi.b #boxQuadra950,BoxFlag ; are we a Quadra 950?
bne.s @EndSoundFixes ; nope ... we're outta here
With ExpandMemRec,ProductInfo
Move.l UnivInfoPtr,A0 ; Point to the ProductInfo table.
Adda.l SndControlPtr(A0),A0 ; Point to the sound primitives.
Adda.l sndInputSelect*4(A0),A0 ; Point to the input-select routine.
Move.l A0,D0 ; Save pointer.
movea.l expandMem,a0 ; get base of ExpandMemRec
movea.l emSndPrimitives(a0),a0 ; get base of SoundMgr Primitives Tbl
move.l D0,sndInputSelect*4(a0) ; replace input select mechanism with ROM one
Endwith
@EndSoundFixes
; The Standard WDEF that shipped in the gybly for the Darts and DBLite had a fix which explicitely
; looked for the GSC hardware and then for a particular kind of screen. Were replacing that
; kind of thing with a Gestalt call that returns whether or not the screen sucks. We do that
; here. Since the Darts and DBLite have already shipped, we dont include them here.
;
; Note: If were on an Escher/Yeager and were docked to an Atlantis or DuoDock, then weve already
; shut the CSC down at this point, and well get a bus error if we try to talk to it. So,
; we first check to see if the CSC has been reset or not. If it hasnt, then we just skip
; all this.
;
With ProductInfo,DecoderInfo
Cmpi.w #drHwCSC,theDrHwID(A6) ; If were not using the CSC driver,
Bne @EndScreenSucks ; then just leave.
Movea.l UnivInfoPtr,A0 ; Point to the ProductInfo table.
Adda.l DecoderInfoPtr(A0),A0 ; Point to the base address table.
TestFor MSCChipBit ; If we have an MSC,
Bne.s @MSC ; then hop to it.
TestFor PrattExists ; If we have a Pratt,
Bne.s @Pratt ; then hop to it.
Bra.s @EndScreenSucks ; Otherwise, just leave.
@MSC Movea.l RBVAddr(A0),A1 ; Point to the MSCs base address.
Btst #MSCLCDReset,MSCClkCntl(A1) ; If CSC hasnt been reset,
Beq.s @EndScreenSucks ; then just leave.
Movea.l VDACAddr(A0),A1 ; Point to the CSC base address.
Move.b CSCPanelID(A1),D0 ; Read the panel ID.
Cmpi.b #isG_D_STN_640x400,D0 ; If were are using the sucky screen,
Beq.s @FixIt ; then say so.
Bra.s @EndScreenSucks ; Otherwise, just leave.
@Pratt Movea.l VDACAddr(A0),A1 ; Point to the CSC base address.
Move.b CSCPanelID(A1),D0 ; Read the panel ID.
Cmpi.b #isG_D_STN_640x480,D0 ; If we arent using the sucky screen,
Bne.s @EndScreenSucks ; then just leave.
@FixIt Moveq #0,D2 ; Assume we wont be replacing the selector.
Move.l #gestaltGraysFlicker,D0 ; Setup to load the sucky-screen selector.
_Gestalt ; If its not already loaded, then
Bne.s @AddInNew ; just add it in.
Lea OldGraysFlicker,A1 ; Point to the old-response value holder.
Move.l A0,(A1) ; Fill it up with the old response.
Moveq #1,D2 ; Remember that well be replacing.
@AddInNew Lea NewGraysFlicker,A1 ; Point to the beginning of the flicker code.
Lea EndNewGraysFlicker,A0 ; Point to its end.
Sub.l A1,A0 ; Determine the size.
Move.l A0,D0 ; Set up for _NewPtr (size in D0).
Move.l D0,D1 ; Save the size for BlockMove.
_NewPtr Sys ; Attempt to get a block in the System heap.
Bne.s @EndScreenSucks ; If failed, just go on.
Lea NewGraysFlicker,A1 ; Otherwise, point back at the code.
Exg A0,A1 ; Set up for BlockMove (A0=Src,A1=Dest).
Move.l D1,D0 ; D0 is size of block to move.
_BlockMove ; Do it.
Move.l A1,D3 ; Save System heap address for later if necessary.
Move.l #gestaltGraysFlicker,D0 ; Setup to install the new/replacement selector.
Exg A1,A0 ; Point to the code in the System heap.
Tst.l D2 ; If were supposed to be replacing,
Bne.s @ReplaceIt ; then call the replacement trap.
_NewGestalt ; Otherwise, call new.
Bra.s @ChkForErr ; See if there was an error.
@ReplaceIt _ReplaceGestalt ; Call replace.
@ChkForErr Beq.s @EndScreenSucks ; If the call worked, just go on.
Movea.l D3,A0 ; Otherwise, point to System heap code.
_DisposPtr ; And throw it away.
@EndScreenSucks
Endwith
;---------------------------------------------------------------------
;
; <H5> Call Powermanager Secondary Init. Power manager uses this entry point
; to execute code which MUST be run after patches.
;
IF hasPwrControls THEN
PowerMgr2Init
IF isUniversal THEN
TestFor hwCbPwrMgr ; check for power manager
beq.s @exitPwrMgr ; if no pmgr skip
ENDIF
With PowerDispRec,PMgrHookDispRec
moveq #((PSecondaryInit << 16) | \; secondary init selector <H8>
(PMgrHookDisp << 0)),d0 ; call pmgr hook <H8>
_PowerDispatch ; call power manager
Endwith
@exitPwrMgr
ENDIF
Unlk A6 ; Restore link.
Rts ; Go home.
_EndsSecondaryInitRec
ENDP
END