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

150 lines
5.6 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: PreventSwitchLaunch.a
;
; Contains: 'proc' -16495 code: Prevents switch launching from System 6 to System 7.
;
; Written by: Dean Yu
;
; Copyright: © 1990 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <3> 6/6/90 DTY Went back to using stack frame to save default directory, to get
; around bug in FixSMgrWorld which trashed D1.
; <1> 6/6/90 DTY First checked in. _InitFonts patch to prevent a switch launch
; to System 7 from older Systems. Closes the System 7 System
; file, re-opens the previous System file, re-initialise the
; system resource map, and attempt to remove patch from
; _InitFonts.
;
LOAD 'StandardEqu.d'
kInitFontsTrap equ $fe ; Trap word of _InitFonts
kJmpInstr equ $4ef9 ; JMP instruction used for unpatching
InitFontsPtch PROC EXPORT
patchVars RECORD 0,DECR
curVRefNum ds.w 1 ; Save current volume reference number
patchVarSize equ *
ENDR
;
; To reduce the amount of memory thats used we attempt to remove this patch from _InitFonts
; at the end of the patch. If we determine that someone else patched _InitFonts before we
; got called (unlikely, but it could happen), the following bra.s instruction is changed to
; a jmp, and we reduce the size of our memory block down to 6 bytes, just enough to hold the
; jmp instruction.
;
WITH patchVars
bra.s startInitFontsPatch
oldInitFont dc.l 0 ; Address of previous _InitFonts routine stored here
startInitFontsPatch
;
; This code should only be run if the switch launch is coming from Finder 6.x Check the code
; at the return address on the stack to make sure its 6.x code. If it isnt, generate a
; dsOldSystem System Error. If it is Finder 6.x, add 4 bytes to the return address, since we
; want to bypass the Finder changing the value in BootDrive, since we closed the System 7 System
; file, and re-opened the old System file, so everything is the way it was before Finder started
; switch launch, except Finder doesnt know that, so we have to fool it.
;
; (SP) (Before) ---> 31C3 0210 move.w d3,BootDrive
; (SP) (After) ---> 508f addq.l #8,sp
;
move.l (sp),a0 ; Get the return address, and check the next instruction
cmpi.l #$31c30210,(a0)+ ; to make sure its a move.w D3,BootDrive
bne.s FinderTooOld ; If not, force a System Error.
move.l a0,(sp) ; Put our modified return address back on the stack
; If were here, then we should close the System 7 System file, and re-open the System 6
; System file, and re-initialise the system resource map.
clr.w -(sp)
_CloseResFile ; Close the System file
link a6,#patchVarSize
sub.w #ioFQElSize,sp
move.l sp,a0
clr.l ioCompletion(a0)
clr.l ioNamePtr(a0)
_GetVol ; Get the current default volume
move.w ioVRefNum(a0),curVRefNum(a6) ; and save it
move.w BootDrive,ioVRefNum(a0) ; Set the volume to the previous System Folder
_SetVol
;
; _InitResources returns the reference number of the System file on the stack, but since theres a nice big
; parameter block already there, theres no REAL reason to allocate a word for the reference number, since
; the next call to _SetVol will reset that word anyway.
;
_InitResources ; _InitResources will open the System file, and rebuild the resource map
move.l sp,a0
move.w curVRefNum(a6),ioVRefNum(a0) ; Restore the default directory
_SetVol
add.w #ioFQElSize,sp ; Get rid of our parameter block
unlk a6 ; We dont need our stack frame any more
;
; Remove this patch
;
move.w #kInitFontsTrap,d0
_GetTrapAddress ; Get the address of _InitFonts routine
move.l a0,d0
_StripAddress ; Clean this guy off
move.l d0,a0 ; Save it
lea InitFontsPtch,a1 ; Get InitFontsPtchs entry point
move.l a1,d0
_StripAddress ; Cleanse ourselves of dirty bits
exg a0,d0 ; Ensure that entry point of InitFontsPtch is in A0 for _RecoverHandle later
cmp.l d0,a0 ; Make sure were the most recent patch on _InitFonts
bne.s gotPatched ; If not, we do some fancy byte saving
_RecoverHandle ,SYS
_DisposHandle ; Free up the memory were using
move.w #kInitFontsTrap,d0
move.l oldInitFont,a0
_SetTrapAddress ; Restore _InitFonts
jmp (a0) ; Continue with _InitFonts
;
; Theres a patch in front of us on _InitFont, so we cant remove ourselves,
; but we can reduce the space were taking up to 6 bytes:
; Since the address of the next _InitFonts routine is stored in bytes 2 thru 5 of this patch,
; the preceding two byte bra.s instruction can be changed to a jmp, which would then use
; oldInitFonts as the effective address to jump to. So, when this patch gets called again,
; it will jump straight to the next _InitFonts patch/routine, since InitFontsPtch has done its
; job.
gotPatched
move.w #kJmpInstr,(a0) ; Replace bra.s with jmp
_RecoverHandle ,SYS ; Handle to our block
move.l #startInitFontsPatch - InitFontsPtch,d0 ; Size of jump/bra.s instruction
_SetHandleSize ; Reduce our memory block down to size of jump.
; This needs to be changed to something safer, because the Memory Manager
; may move a block into this space when the patch gets cut back, and we
; wouldnt be here any more.
bra.s InitFontsPtch ; Since this is a jump now, we can just branch back to it to call the next routine
;
; InitFontsPtch checks specifically for code in Finder 6.x. Anything else isnt handled, and
; will generate a dsOldSystem system error.
;
FinderTooOld
moveq #dsOldSystem,d0
_SysError
ENDPROC
END