supermario/base/SuperMarioProj.1994-02-09/Tidbits/ROvr.a

217 lines
9.7 KiB
Plaintext
Raw Normal View History

2019-06-29 15:17:50 +00:00
;
; File: ROvr.a
;
; Contains: ROM resource override code -- 'ROvr' (0)
;
; Written by: Brian B. McGhie and Darin Adler
;
; Copyright: © 1986-1992 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <SM1> 4/23/92 CS Apply changes from reality:
; <8> 3/16/92 DTY #1024511:
; #1024511: Move ROZ cutback code back to ResourceMgrPatches.a
; <7> 3/4/91 dba dty: get rid of SysVers conditionals
; <6> 2/8/91 dba dty, #66370: reverting back to the old algorithm for finding
; ROv# resources; why did I ever change it?
; <5> 7/30/90 stb NEEDED FOR SIXPACK: replace ROZ cutback with another version
; <4> 6/29/90 DDG NEEDED FOR SIXPACK: Now if hasSwitchLaunchPrevention is true,
; the header is version seven and if it is false, the header is
; version three (the old version number).
; <3> 6/26/90 CCH NEEDED FOR SIXPACK: Added code to cutback size of ROM resource
; map by about 5k on $67c ROM-based machines.
; <2> 6/6/90 DTY Added a check to the ROM Override to determine if the system is
; in the process of switch-launching from an older system to
; System 7.0. If so, install a patch on _InitFonts to prevent this
; switch launch from completing, and revert back to the previous
; System file. Added additional check for value of SysVersion to
; allow network booting to work.
; <1.1> 8/30/89 dba changed to find ROv# resources by ID instead of by embedded
; version number; rewrote to fix bug with resources not in ROM
; (use one-deep calls)
; <1.0> 11/16/88 CCH Added to EASE.
;
; 'ROvr' is the resource that the Resource Mgr looks for when loading in a new
; System file. 'ROv#' is a resource type that contains which resources
; in the ROM to override. The structure for 'ROv#' is as follows:
;
; 'ROv#':
; version dc.w $0075 ; ROM version (ignored)
; count dc.w $00XX ; # of resources in list minus one
; type.0 dc.l 'WDEF' ; resource type to override
; id.0 dc.w $0000 ; resource ID
; type.1 dc.l 'PACK' ; resource type to override
; id.1 dc.w $0004 ; resource ID
; ...
; type.XX dc.l 'CURS' ; resource type to override
; id.XX dc.w $0002 ; resource ID
;
; NOTE: Previous versions of ROvr cycled through all of the 'ROv#' resources
; and obeyed any which had the proper ROM version. This version looks only at
; the 'ROv#' with the ROM version as its ID, and ignores the embedded version.
;
; The first instruction in 'ROvr' should be a bra.s past the version word
; of 'ROvr'. This will enable install programs to determine if you have
; the latest 'ROvr' resource, and replace it with a newer one.
load 'StandardEqu.d'
include 'ResourceMgrPriv.a'
macro
ResourceVersionHeader &type,&id,&version
bra.s @skipHeader
dc.l (&type)
dc.w (&id)
dc.w (&version)
@skipHeader:
endm
kBranchSize equ 2 ; Size of short branch instruction in bytes
kMinSystem equ $0700 ; Minimum System version to allow switch launching from
kpatchType equ 'proc' ; _InitFonts patch is in a 'proc' resource
kpatchID equ -16495 ; Resource ID of patch
kInitFontsTrap equ $FE ; Trap word of _InitFonts
ROvr main
ResourceVersionHeader 'ROvr',0,8 ; The Big Bang ROvr (more patches for your bucks!)
tst.w SysVersion ; At boot, SysVersion is not initialised, so we need a special
beq.s DoOverrides ; case to allow normal ROM overriding at boot.
cmpi.w #kMinSystem,SysVersion ; If SysVersion is System 7.0 or greater, allow switch launching.
bge.s DoOverrides ; (Network booting)
; If SysVersion was initialized, then were being called during a switch launch.
; Since we dont want to allow this switch launch to finish, we need to go back to the previously running
; system. In the switch launch code for Finder 6.x, _InitResources is called, then _InitFonts, then the working
; directory reference number of the new System Folder is saved in BootDrive.
; Now that weve determined that we dont want to switch launch, put a patch on _InitFonts which will close the
; System 7 (or newer) System file, re-open the old one, and rebuild the System resource map. The patch also
; bumps the return address past the instructions that stash the new WDRefNum in BootDrive, since up to this
; point, BootDrive still contains the WDRefNum of the previous System Folder. This fact makes life incredibly
; simple, and no hocus pocus has to be performed to figure out where the last System file was.
; The patch is in 'proc' -16495.
sub.w #4,sp
move.l #kPatchType,-(sp)
move.w #kPatchID,-(sp)
_GetResource ; Get a handle to our patch
tst.l (a1)
bne.s PatchInitFonts ; If the handle we got back was good, install the patch
moveq #dsBadPatch,d0 ; Generate a System Error if _GetResource returned nil
_SysError
PatchInitFonts
move.l (sp),a1
_DetachResource ; Detach it so itll stick around
move.w #kInitFontsTrap,d0
_GetTrapAddress ; Get the current _InitFonts routine
move.l (a1),a1
move.l a0,kBranchSize(a1) ; Save the address of _InitFonts
move.l a1,a0
move.w #kInitFontsTrap,d0
_SetTrapAddress ; Patch it
bra ExitROvr ; Get out of here. <3>
;————————————————————————————————————————————————————————————————————————————————————————————————————
;
DoOverrides
;
; Version 3 ROvr code starts here
;
movem.l d2/a2-a3,-(sp) ; save working registers <5><3>
move.l ROMMapHndl,a2 ; need to save ROM map attributes
move.l (a2),a0 ; dereference map handle
move.w MAttr(a0),-(sp) ; save off current ROM map attributes
clr.w MAttr(a0) ; clear all ROM map attributes for this routine
;————————————————————————————————————————————————————————————————————————————————————————————————————
; load override resources
moveq #1,d2 ; start with ROv# index of 1 <6>
ForEachOverrideList
subq #4,sp ; make space for handle
move.l #'ROv#',-(sp) ; push 'ROv#' for _Get1IxResource
move.w d2,-(sp) ; push resource index <6>
move.w #mapTrue,ROMMapInsert ; link in ROM map w/ResLoad true
_GetIndResource ; get ROv# resource (must be locked) <6>
move.l (sp)+,d0 ; save handle to the list
bz.s ROvrNOut ; no ROv#, so get out of here
move.l d0,-(sp) ; save handle for ReleaseResource later
move.l d0,a1 ; get ROv# resource handle
move.l (a1),a1 ; get ROv# resource pointer
move.l ROMBase,a0 ; get a pointer to the ROM <6>
move.w 8(a0),d0 ; get the ROM version number <6>
cmp.w (a1)+,d0 ; check if the ROv# is for this ROM <6>
bne.s NextOverrideList ; if wrong version, go on to the next ROv# resource <6>
move.w (a1)+,d1 ; count-1 of items in list
ForEachResourceInList
subq #4,sp ; make space for handle
move.l (a1)+,-(sp) ; push type onto stack
move.w (a1)+,-(sp) ; push id onto stack
move.w #mapFalse,ROMMapInsert ; link in ROM map w/ResLoad false
_Get1Resource
move.l (sp)+,d0 ; get that resource
bz.s NextResourceInList ; if no resource, advance to the next one
move.l d0,-(sp) ; push handle for RmveResource later
subq #4,sp ; make space for map entry offset
move.l d0,-(sp) ; push resource handle onto stack
move.w #mapFalse,ROMMapInsert ; link in ROM map w/ResLoad false
st ResOneDeep ; since there is no one-deep version of RsrcMapEntry
_RsrcMapEntry ; ignore errors from RsrcMapEntry
move.l (sp)+,a0 ; get map entry offset
add.l (a2),a0 ; make the map offset into a pointer
clr.b RAttr(a0) ; clear the attributes for the resource (protected, etc.)
; handle to remove is already on stack
move.w #mapFalse,ROMMapInsert ; link in ROM map w/ResLoad false
_RmveResource ; ignore errors from RmveResource
; normally, we would do a DisposHandle here, but the ROM resources are
; in their own special heap, and no-one cares about the wasted master pointer
NextResourceInList
dbra d1,ForEachResourceInList ; loop through the resources
NextOverrideList
_ReleaseResource ; handle to release is already on stack
addq.w #1,d2 ; advance to next resource index <6>
bra.s ForEachOverrideList ; go loop for the next resource <6>
;————————————————————————————————————————————————————————————————————————————————————————————————————
ROvrNOut
move.l (a2),a0 ; dereference ROM map handle
move.w (sp)+,MAttr(a0) ; restore ROM map attributes
movem.l (sp)+,d2/a2-a3 ; restore working registers <6><5><3>
ExitROvr ; Exit point after _InitFonts is patched
lea ROvr,a0 ; get pointer to this resource
_RecoverHandle ; get handle to this resource
move.l (sp),-(sp) ; put the handle below a copy of the return address
move.l a0,4(sp) ; put the handle on the stack for ReleaseResource
_ReleaseResource autoPop ; release this resource and return
endproc
;————————————————————————————————————————————————————————————————————————————————————————————————————
end