mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-28 01:29:20 +00:00
2506 lines
99 KiB
Plaintext
2506 lines
99 KiB
Plaintext
|
;
|
|||
|
; File: ResourceOverridePatches.a
|
|||
|
;
|
|||
|
; Contains: Code to handle special cases when the overrideNextMapBit, twoDeepBit,
|
|||
|
; or dontCountOrIndexDuplicatesBit is set in a resource map.
|
|||
|
;
|
|||
|
; Written by: Dean Yu
|
|||
|
;
|
|||
|
; Copyright: <09> 1991-1992 by Apple Computer, Inc., all rights reserved.
|
|||
|
;
|
|||
|
; Change History (most recent first):
|
|||
|
;
|
|||
|
; <50> 6/12/92 DTY #1032065: In SyncOverrideMap, make sure that GetMap returns a
|
|||
|
; valid resource map before continuing. In the two deep patches,
|
|||
|
; if this is not the case, bail early so that we don<6F>t set
|
|||
|
; TopMapHndl to nil in SetUpTwoDeepChain.
|
|||
|
; <49> 6/7/92 DTY #1031361: If an override map is changed (with AddResource,
|
|||
|
; RmveResource, SetResAttrs, or ChangedResource), set the
|
|||
|
; mapChanged bit on the map that is overridden to force an update
|
|||
|
; of the override map.
|
|||
|
; <48> 6/4/92 DTY Last change was for bug numbers #1031589 through 1031591.
|
|||
|
; <47> 6/4/92 DTY DoesCachedMapOverrideCurrentMap used to scan the resource chain
|
|||
|
; for duplicates until it finds a map that doesn<73>t have any
|
|||
|
; override attributes set. The theory was that a string of
|
|||
|
; resource maps with override attributes set are associated with
|
|||
|
; each other, like Gibblies and the System, or the System and font
|
|||
|
; files. This test was too generic, and fails in the case where
|
|||
|
; an application has an override map, and the map below the
|
|||
|
; application is a Gibbly or the System. In this case, resources
|
|||
|
; in the System and the application override that have the same
|
|||
|
; type and ID are considered duplicates of each other, which isn<73>t
|
|||
|
; right. Now, just look at the two deep bit on resource maps to
|
|||
|
; determine if one is associated with another. Also save and
|
|||
|
; restore D1 in that routine now that we<77>re using it to hold to
|
|||
|
; mask value we<77>re looking for.
|
|||
|
; <46> 6/2/92 DTY #1031021: Add a patch to UpdateResFile to update override maps
|
|||
|
; for a file when its resource fork is updated.
|
|||
|
; <45> 6/1/92 DTY #1031101: <43> Fixed RmveResource for override maps.
|
|||
|
; RmveResource needs to be fixed for font maps under the system
|
|||
|
; map as well. Change RemoveResourceOverride to call
|
|||
|
; IsThisASystemResourceMap to see if CurMap should be messed with
|
|||
|
; for this call.
|
|||
|
; <44> 5/27/92 DTY #1030811: People who put 1 in CurMap suck. <42> breaks the case
|
|||
|
; where CurMap is the ROM resource map, and ROMMapInsert is true.
|
|||
|
; This caused the RAM Disk portion of the Memory control panel to
|
|||
|
; not show up on Terror/Horror machines.
|
|||
|
; <43> 5/26/92 DTY #1030806: RmveResource fails if GetResource et al returns a
|
|||
|
; resource from an override map. This is because RmveResource
|
|||
|
; sucks and only lets you remove a resource from the current
|
|||
|
; resource map. Find the resource map that the handle comes from,
|
|||
|
; and see if that map overrides the current resource map.
|
|||
|
; <42> 5/5/92 DTY #1028857: Resource overriding of a resource map that is not the
|
|||
|
; system resource map does not work if ROMMapInsert is set for one
|
|||
|
; deep calls.
|
|||
|
; <41> 4/30/92 DTY #1028807: If emScanOverride is false, ignore the twoDeep bit
|
|||
|
; setting.
|
|||
|
; <40> 4/29/92 DTY #100850: Oops. Last change wasn<73>t quite done. Other parts of the
|
|||
|
; code reference a1 later, so I guess we<77>ll have to save a1.
|
|||
|
; <39> 4/27/92 DTY #100850 <gbm>: SyncTopOverrideMap is trashing A1 without saving
|
|||
|
; it. Change code to use A0 instead.
|
|||
|
; <38> 4/24/92 DTY #1028323 <pvh>: <20>BLT GetResource fails to get a ROM resource if
|
|||
|
; Gibbly exists and CurMap == SysMap. This is because the code in
|
|||
|
; SyncTopOverrideMap that sets up the chain for the insertion of
|
|||
|
; the ROM map does not change CurMap, but it should if SysMap is
|
|||
|
; CurMap.
|
|||
|
; <37> 4/21/92 DTY #1027940: Put the resource that will be returned by
|
|||
|
; GetIndexedResourceOverride into the Resource Manager HandleScan
|
|||
|
; cache in lo-mem. This is so that if GetIndResource was called
|
|||
|
; with ROMMapInsert set to true, a subsequent GetResInfo would be
|
|||
|
; able to find information about that ROM resource.
|
|||
|
; <36> 4/14/92 DTY #1026179: Bill and I had different interpretations about the
|
|||
|
; last bug. Of course, Bill<6C>s interpretation was right. Now, if
|
|||
|
; emScanOverride is off, always cache the resource without
|
|||
|
; checking the dontCountOrIndexDuplicates bit.
|
|||
|
; <35> 4/4/92 DTY #1026179: Invalidate the resource cache if the setting of
|
|||
|
; emScanOverride has changed as well.
|
|||
|
; <34> 3/30/92 DTY #1025277: Invalidate the resource cache is the value in
|
|||
|
; ROMMapInsert has changed between the calls.
|
|||
|
; <33> 3/30/92 DTY #1025140,<FM>: Made macros for common stack frame fields to
|
|||
|
; reduce chance of error when fields are added in the future. Use
|
|||
|
; labels to manipulate override bits instead of hard coded
|
|||
|
; numbers. In GetIndResourceOverride, make errorExit exit through
|
|||
|
; ExitGetIndResource instead of noROMMapToRemove since there is
|
|||
|
; one case where there will be. Removed check for presence of
|
|||
|
; ExpandMem in FlushResourceCache since it will always be there.
|
|||
|
; <32> 3/26/92 DTY #1025567: Instead of using HandleZone to determine whether or
|
|||
|
; not a handle should be cleared in RsrcZoneInit, and thus be at
|
|||
|
; the mercy of a totally flaky routine, check the resource handle
|
|||
|
; against the upper and lower bounds of the System heap ourselves.
|
|||
|
; <31> 3/23/92 DTY #1025075,<pvh>: The dontCountOrIndexDuplicates behaviour ignores
|
|||
|
; resources in the system file even if the resource is not in a
|
|||
|
; Gibbly. It should only ignore resources if it<69>s a duplicate of a
|
|||
|
; resource in an override map for that resource map. (The System
|
|||
|
; counts as an override map for fonts in the Fonts folder even
|
|||
|
; though it doesn<73>t have to overrideNextMap bit set.)
|
|||
|
; <30> 3/16/92 DTY #1024587: In StandardTwoDeepFunctionCallThrough, bail early if
|
|||
|
; no resource map handle could be found for CurMap.
|
|||
|
; <29> 3/11/92 DTY #1024405: The dontCountOrIndexDuplicates behavior is broken: the
|
|||
|
; IsDuplicate routine is using information in the cache that isn<73>t
|
|||
|
; there. Remember each resource<63>s ID in the cache so that
|
|||
|
; IsDuplicate doesn<73>t have to go unwind each cache entry.
|
|||
|
; <28> 3/3/92 DTY In the vNewMap patch that clears out the in memory attributes,
|
|||
|
; the PreventMapFromClosingBit needs to be cleared too.
|
|||
|
; <27> 2/26/92 DTY #1022942: Count1Types is still broken: ResOneDeep is set to
|
|||
|
; flag that the chain is already set up, but is not cleared before
|
|||
|
; calling _CountTypes in CountTypesOverride. This causes
|
|||
|
; _CountTypes to do a _Count1Types of the Gibbly only. Clear
|
|||
|
; ResOneDeep so that _CountTypes will count all maps marked
|
|||
|
; twoDeep.
|
|||
|
; <26> 2/24/92 DTY Erk. I<>ve got the sense of a test wrong. In CountTypesOverride,
|
|||
|
; it should branch if ResOneDeep is not zero (not if it is zero).
|
|||
|
; Add additional code at the end to take an alternate exit path if
|
|||
|
; it didn<64>t do any setup.
|
|||
|
; <25> 2/21/92 DTY curMapHandle is in the wrong place in the stack frame for
|
|||
|
; Unique2ID. This causes the machine to hang.
|
|||
|
; <24> 2/20/92 DTY Instead of calling _BlockMove to copy our parameters, call our
|
|||
|
; own byte copying routine. This prevents the caches from being
|
|||
|
; flushed on the <20>040 machines. (Not that anyone is likely to
|
|||
|
; notice, but a microsecond saved is a microsecond saved.) Also
|
|||
|
; moved StandardOverrideWordFunctionCallThrough into
|
|||
|
; CountTypesOverridePatch since that<61>s the only routine that calls
|
|||
|
; it. Set ResOneDeep on Count2Types so that SyncOverrideMap only
|
|||
|
; gets called once.
|
|||
|
; <23> 2/19/92 DTY _GetMap gets called way too much while the resource chain is
|
|||
|
; being set up to do two deep calls. Since everything calls
|
|||
|
; SyncTopOverrideMap, just remember the current map from the
|
|||
|
; _GetMap call in that routine. Also get rid of
|
|||
|
; StandardTwoDeepMapSetup since only one routine calls it.
|
|||
|
; Finally, change StandardTwoDeepLongFunctionCallThrough to change
|
|||
|
; CurMap at the bottom of the loop instead of the top.
|
|||
|
; <22> 2/11/92 DTY In RsrcZoneInitOverride, instead of checking resSysHeap to
|
|||
|
; determine whether or not to clear out a handle in a resource
|
|||
|
; entry, call _HandleZone on the resource handle. If the zone the
|
|||
|
; handle is in is not the system zone, go ahead and clear out the
|
|||
|
; resource reference. This will prevent resource handles from
|
|||
|
; being orphaned in the system heap, which should save us some
|
|||
|
; memory.
|
|||
|
; <21> 1/30/92 DTY It<49>s a slow night, so Dean<61>s doing some gratuitous engineering.
|
|||
|
; Define a new override bit, preventMapFromClosing, which causes
|
|||
|
; resource files from being closed if this bit is set. Change the
|
|||
|
; PreventOverrideMapsFromBeingClosed patch to look at this bit
|
|||
|
; instead of second guessing the uses of the other override bits.
|
|||
|
; <20> 1/29/92 DTY The mInMemoryAttr byte gets written out to disk. Patch jNewMap
|
|||
|
; to clear these bits whenever a new resource map is created.
|
|||
|
; <19> 1/28/92 DTY Allocating space on the stack for two function results doesn<73>t
|
|||
|
; help much if both functions wind up using the same word<72>
|
|||
|
; <18> 1/16/92 DTY In PreventOverrideMapsFromBeingClosed, if a resource map does
|
|||
|
; not have the twoDeepBit set, allow it to be closed.
|
|||
|
; <17> 1/16/92 DTY The Mac Plus and Mac II ROMBinds for ROMGetRsrcCnt are switched.
|
|||
|
; Someone please hit me on the head<61>
|
|||
|
; <16> 1/15/92 DTY <14> Was only half baked. Redo the RsrcZoneInitPatch to close
|
|||
|
; all files above the first system override map, then to flush all
|
|||
|
; resources from resource maps below this map to the end of the
|
|||
|
; chain.
|
|||
|
; <15> 12/20/91 DTY In the checks for preserving LastSPExtra, flush the 'FOND'
|
|||
|
; candidate list if LastSPExtra will not be preserved. Also add a
|
|||
|
; patch to _CloseResFile that does the same thing. (This may break
|
|||
|
; MacWrite II, but they<65>re revving.)
|
|||
|
; <14> 12/19/91 DTY Nail resources loaded into the application heap during boot time
|
|||
|
; in resource maps underneath the system resource map.
|
|||
|
; <13> 12/13/91 DTY The code which restores the resource chain in
|
|||
|
; GetIndResourceOverride isn<73>t quite right. It assumed that A4 was
|
|||
|
; making it through from Get2IxResource, but it wasn<73>t. Get this
|
|||
|
; value from somewhere else.
|
|||
|
; <12> 12/13/91 DTY When calling _LoadResource to load a purged, compressed resource
|
|||
|
; and ROMMapInsert is set to MapTrue, the ROM map is inserted
|
|||
|
; between the System map and its override maps. This prevents the
|
|||
|
; decompressor resource from being found. Patch _LoadResource to
|
|||
|
; jam SysMapHndl with the override map if ROMMapInsert is true.
|
|||
|
; <11> 12/9/91 DTY Sme additional checking is needed when checking the deepness of
|
|||
|
; the cached resource information. If the deepness matches, only
|
|||
|
; check CurMap for one deep calls. Also, the decompressor patch
|
|||
|
; to CheckLoad calls _Get1Resource. GetIndResourceOverride needs
|
|||
|
; to restore the resource chain before calling through the
|
|||
|
; CheckLoad vector so the decompressor can be found.
|
|||
|
; <10> 12/6/91 DTY Dean really shouldn<64>t program when he<68>s on drugs. Further
|
|||
|
; identify the contents of the cache with the file reference
|
|||
|
; number of the last cached one deep call. (This makes sequences
|
|||
|
; like _Count1Resources, _UseResFile, _Count1Resources work.)
|
|||
|
; <9> 11/27/91 DTY Don<6F>t set emLastMapOverriden until it<69>s been determined that
|
|||
|
; there is an override map for a resource map.
|
|||
|
; <8> 11/26/91 DTY Remove the FSpOpenResFile patch since it just calls
|
|||
|
; HOpenResFile. Rolled in the font cache preservation code from
|
|||
|
; 7-Up into the appropriate routines. (One less patch is one less
|
|||
|
; patch.)
|
|||
|
; <7> 11/18/91 DTY BLT#1015829: GetIndResourceOverride branches to the wrong point
|
|||
|
; if it was passed an invalid index. Also, force the resource
|
|||
|
; cache to be rebuilt if the current search depth doesn<73>t match
|
|||
|
; the depth when information was added to the cache.
|
|||
|
; <6> 11/8/91 DTY I don<6F>t know why I thought I could get away without flushing the
|
|||
|
; cache on a _CloseResFile. Add a call to FlushResourceCache in
|
|||
|
; PreventOverrideMapsFromBeingClosed.
|
|||
|
; <5> 11/6/91 DTY When _InitAllPacks is called from NewProcess, the resource chain
|
|||
|
; has been reset, but CurMap hasn<73>t been set up yet. Take this
|
|||
|
; into account in SyncTopOverrideMap.
|
|||
|
; <4> 11/6/91 DTY Add a patch to _CloseResFile which prevents override maps from
|
|||
|
; getting closed.
|
|||
|
; <3> 11/3/91 DTY Make _CountResources and _GetIndResource several orders of
|
|||
|
; magnitude faster by storing an offset from the beginning of the
|
|||
|
; resource map to the resource instead of searching by the
|
|||
|
; resource ID.
|
|||
|
; <2> 11/2/91 DTY Finished up all the patches. All override behaviours are now
|
|||
|
; implemented.
|
|||
|
; <1> 10/17/91 DTY first checked in
|
|||
|
|
|||
|
include 'Traps.a'
|
|||
|
include 'SysEqu.a'
|
|||
|
include 'SysErr.a'
|
|||
|
include 'SysPrivateEqu.a'
|
|||
|
include 'ToolEqu.a'
|
|||
|
include 'fontPrivate.a'
|
|||
|
include 'LinkedPatchMacros.a'
|
|||
|
include 'Private.a'
|
|||
|
include 'ResourceMgrPriv.a'
|
|||
|
|
|||
|
ROMGetRsrcCnt ROMBind (Plus,$13EF2),(SE,$E4FC),(II,$12E34),(IIci,$1B6A4),(Portable,$1448C)
|
|||
|
SwapROMMap ROMBind (Plus,$13F86),(SE,$E590),(II,$12EC8),(IIci,$1B73E),(Portable,$14520)
|
|||
|
|
|||
|
kInitialEntryCount equ 30 ; Make space for 30 resources at first
|
|||
|
|
|||
|
; Cache flag bits
|
|||
|
|
|||
|
kCacheIsOneDeepBit equ 0 ; Cache was formed from a one deep call
|
|||
|
kCacheHasROMResourcesBit equ 1 ; <34> Cache was formed when ROMMapInsert was set.
|
|||
|
kCacheHasOverridesBit equ 2 ; <35> Cache was formed when emScanOverrides was on
|
|||
|
|
|||
|
; Cache flag masks
|
|||
|
|
|||
|
kCacheIsOneDeepMask equ 1 ; <34>
|
|||
|
kCacheHasROMResourcesMask equ 2 ; <34>
|
|||
|
kCacheHasOverridesMask equ 4 ; <35>
|
|||
|
|
|||
|
; Cache offsets
|
|||
|
|
|||
|
kCacheFlags equ 0 ; Flags for cache
|
|||
|
kCachedMap equ 2 ; Resources cached from this resource map
|
|||
|
kResourceType equ 4 ; Resource type in cache
|
|||
|
kResourceCount equ 8 ; Number of entries cached
|
|||
|
kCacheHeaderSize equ 12 ; Offset to cached information
|
|||
|
|
|||
|
; Cache entry offsets
|
|||
|
|
|||
|
kMapHandleEntry equ 0 ; Handle to resource map this resource came from
|
|||
|
kDataOffsetEntry equ 4 ; Offset to resource data from beginning of resource map
|
|||
|
kResourceIDEntry equ 6 ; ID of this resource
|
|||
|
kCacheEntrySize equ kResourceIDEntry + 2 ; Size of each cache entry
|
|||
|
|
|||
|
; Stack Frame macros
|
|||
|
;
|
|||
|
; These macros isolate out stack frame fields common to many routines. New fields which
|
|||
|
; would affect more than one routine should be placed in these macros instead of in each
|
|||
|
; individual routine. This reduces chances for errors from placing a new field in the
|
|||
|
; wrong position, or not in one routine, etc.
|
|||
|
|
|||
|
Macro
|
|||
|
OverrideStackFrameCommon
|
|||
|
realCurMap: ds.w 1
|
|||
|
realSysMapHndl: ds.l 1
|
|||
|
curMapHandle: ds.l 1
|
|||
|
EndM
|
|||
|
|
|||
|
Macro
|
|||
|
TwoDeepStackFrameCommon
|
|||
|
OverrideStackFrameCommon
|
|||
|
realTopMap: ds.l 1
|
|||
|
realNextMap: ds.l 1
|
|||
|
EndM
|
|||
|
|
|||
|
Macro
|
|||
|
FlushResourceCacheStackFrameCommon
|
|||
|
oldSPExtra: ds.l 1
|
|||
|
oldTopMap: ds.l 1
|
|||
|
realResErr: ds.w 1
|
|||
|
EndM
|
|||
|
|
|||
|
ROMS Plus,SE,II,IIci,Portable
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; SetScanOverrideMaps
|
|||
|
;
|
|||
|
; Quick InstallProc to set emScanOverrideMaps to true.
|
|||
|
;
|
|||
|
|
|||
|
SetScanOverrideMaps InstallProc
|
|||
|
move.l ExpandMem,d0
|
|||
|
beq.s @exitInstallProc
|
|||
|
move.l d0,a0
|
|||
|
move.w #-1,ExpandMemRec.emScanOverrideMaps(a0)
|
|||
|
@exitInstallProc
|
|||
|
rts
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; <20> ClearMemoryAttributesOnNewMaps
|
|||
|
;
|
|||
|
; The mInMemoryAttrs byte of the resource map is written out to disk on an
|
|||
|
; _UpdateResFile. If _UpdateResFile is patched to clear this byte before
|
|||
|
; the resource map is written out, we<77>ll need to save and restore this byte
|
|||
|
; in memory around it. Rather than doing that, patch the NewMap vector to
|
|||
|
; clear this byte whenever a new resource map is created and read from disk.
|
|||
|
; This also prevents the override bits from being set because the resource map
|
|||
|
; on disk was corrupted.
|
|||
|
;
|
|||
|
|
|||
|
ClearMemoryAttributesOnNewMaps PatchProc jNewMap
|
|||
|
jsrOld ; Call NewMap
|
|||
|
tst.b d0 ; Check return result from NewMap
|
|||
|
beq.s @returnToCaller ; 0 means a map already exists for this resource file.
|
|||
|
bmi.s @returnToCaller ; -1 means an error occured while trying to create the map.
|
|||
|
|
|||
|
; Clear the overrideNextMapBit, twoDeepBit, and dontCountOrIndexDuplicatesBit
|
|||
|
; <28> Clear the preventMapFromClosingBit as well.
|
|||
|
|
|||
|
andi.b #kAllButOverrideAttributesMask,mInMemoryAttr(a1) ; A1 holds a pointer to the resource map on return from NewMap.
|
|||
|
@returnToCaller
|
|||
|
rts
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; <12> JamSysMapHndlOnLoadResource
|
|||
|
;
|
|||
|
; When calling _LoadResource to load a purged, compressed resource
|
|||
|
; and ROMMapInsert is set to MapTrue, the ROM map is inserted
|
|||
|
; between the System map and it<69>s override maps. This prevents the
|
|||
|
; decompressor resource from being found. Patch _LoadResource to
|
|||
|
; jam SysMapHndl with the override map if ROMMapInsert is true.
|
|||
|
;
|
|||
|
|
|||
|
JamSysMapHndlOnLoadResource PatchProc _LoadResource
|
|||
|
tst.b ROMMapInsert ; Look for resources in ROM?
|
|||
|
beqOld ; If not, don<6F>t do anything wierd
|
|||
|
|
|||
|
move.l a0,-(sp) ; Save A0
|
|||
|
move.l SysMapHndl,-(sp) ; Save real SysMapHndl
|
|||
|
|
|||
|
movem.l d0-d2/a1,-(sp) ; Save registers that get trashed by _GetOverrideMap
|
|||
|
subq #4,sp
|
|||
|
move.l SysMapHndl,-(sp)
|
|||
|
_GetOverrideMap ; Otherwise, find the system override map
|
|||
|
move.l (sp)+,a0
|
|||
|
movem.l (sp)+,d0-d2/a1 ; Restore the registers
|
|||
|
|
|||
|
move.l a0,SysMapHndl ; Use the system override map as SysMapHndl
|
|||
|
move.l (a0),a0
|
|||
|
move.w mRefNum(a0),SysMap ; Stuff SysMap with the override<64>s reference number
|
|||
|
|
|||
|
move.l 12(sp),-(sp) ; Push resource handle again
|
|||
|
jsrOld ; Call _LoadResource
|
|||
|
|
|||
|
move.l (sp)+,a0 ; Get SysMapHndl
|
|||
|
move.l a0,SysMapHndl ; Restore real SysMapHndl
|
|||
|
move.l (a0),a0
|
|||
|
move.w mRefNum(a0),SysMap ; Restore SysMap, too
|
|||
|
|
|||
|
move.l (sp)+,a0 ; Restore A0
|
|||
|
move.l (sp)+,(sp) ; Push return address up
|
|||
|
rts ; Return to caller
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; RsrcZoneInitOverride
|
|||
|
;
|
|||
|
; _RsrcZoneInit closes all resource files except the System resource file. Override
|
|||
|
; files that override System resources need to stick around also. To fake out
|
|||
|
; _RsrcZoneInit, point SysMapHndle at TopOverrideMap for the duration of the _RsrcZoneInit
|
|||
|
; call. This closes out the files above the topmost system override map. We then
|
|||
|
; take over the work from RsrcZoneInit to clear out system resources that were loaded
|
|||
|
; into the application heap. This is done for system override maps, the system file,
|
|||
|
; and files below the system. Instead of checking the sysHeap bit for each resource,
|
|||
|
; check which heap it was loaded into. If the resource was not loaded into the system
|
|||
|
; heap, nail the handle in the resource reference entry.
|
|||
|
;
|
|||
|
|
|||
|
RsrcZoneInitOverride PatchProc _RsrcZoneInit
|
|||
|
Import ExitNoRestoreNoUnlink
|
|||
|
Import FlushResourceCache
|
|||
|
|
|||
|
bsr FlushResourceCache ; Flush the cache first
|
|||
|
movem.l a1-a4/d1-d7,-(sp) ; Save all the registers the Resource Manager might use on the way
|
|||
|
move.l SysMapHndl,-(sp) ; Save handle to real System map
|
|||
|
subq #4,sp
|
|||
|
move.l SysMapHndl,-(sp)
|
|||
|
_GetOverrideMap ; Get the map to stop closing at
|
|||
|
move.l (sp),SysMapHndl ; Make _RsrcZoneInit stop closing files at the override map <22> Save copy of override map handle
|
|||
|
jsrOld ; Call _RsrcZoneInit to close all files above the system override map
|
|||
|
|
|||
|
;
|
|||
|
; Free the memory used by system resources that were loaded into the application heap.
|
|||
|
;
|
|||
|
|
|||
|
@flushFilesUnderneathSystem
|
|||
|
move.l (sp)+,d0 ; <22> Start with the override map
|
|||
|
@mapLoop
|
|||
|
move.l d0,a4
|
|||
|
jsrROM ROMGetRsrcCnt ; Skip to the entries <19jul85> BBM
|
|||
|
bmi.s @nextMap ; If no entries, no handles to zero.
|
|||
|
|
|||
|
move.l SysZone,a0 ; <32>
|
|||
|
move.l bkLim(a0),d7 ; <32> Keep upper limit of System heap
|
|||
|
move.l a0,d6 ; <32> Keep lower limit of System heap
|
|||
|
@unloadLoop
|
|||
|
move.l RHndl(a2),a0 ; <22> Get resource handle
|
|||
|
cmp.l a0,d6 ; <32> Compare against lower bound of System zone
|
|||
|
bgt.s @clearReference ; <32> If d6 > a0, handle is not in heap, so clear it
|
|||
|
cmp.l a0,d7 ; <32> Compare resource against upper limit of System zone
|
|||
|
bgt.s @entryInSysHeap ; <32> If d7 > a0, handle is in System heap, so don<6F>t clear the reference out.
|
|||
|
@clearReference
|
|||
|
clr.l RHndl(a2) ; Forget the disposed handle in app. heap.
|
|||
|
@entryInSysHeap
|
|||
|
add.w #RESize,a2 ; Otherwise skip to the next entry <19jul85> BBM
|
|||
|
dbra d4,@unloadLoop ; If there is another entry, loop back
|
|||
|
@nextMap
|
|||
|
move.l (a4),a4
|
|||
|
move.l mNext(a4),d0 ; Get the next map
|
|||
|
bnz.s @mapLoop
|
|||
|
move.l (sp)+,SysMapHndl ; Restore the real System map
|
|||
|
movem.l (sp)+,a1-a4/d1-d7
|
|||
|
|
|||
|
moveq #0,d0
|
|||
|
jmp ExitNoRestoreNoUnlink
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; PreventOverrideMapsFromBeingClosed
|
|||
|
;
|
|||
|
; This patch looks at the preventFileFromBeingClosedBit in the resource map. If
|
|||
|
; this bit is set, don<6F>t allow this file to be closed.
|
|||
|
;
|
|||
|
|
|||
|
PreventOverrideMapsFromBeingClosed PatchProc _CloseResFile
|
|||
|
Import ExitPatchedOutRoutineWithoutRestoringMap
|
|||
|
Import FlushResourceCache
|
|||
|
|
|||
|
link a6,#0
|
|||
|
movem.l a1/d1-d3,-(sp)
|
|||
|
|
|||
|
subq #4,sp ; <21> Space for resource map handle
|
|||
|
move.w 8(a6),-(sp) ; <21> Push reference number
|
|||
|
_GetMap ; <21> Get the resource map
|
|||
|
move.l (sp)+,d0 ; <21>
|
|||
|
bz.s @callRealCloseResFile ; <21> If a resource map couldn<64>t be found for this file, call _CloseResFile and let it take care of the error
|
|||
|
|
|||
|
move.l d0,a1 ; <21>
|
|||
|
move.l (a1),a1 ; <21> Pointer to resource map
|
|||
|
btst #preventFileFromBeingClosedBit,mInMemoryAttr(a1) ; <21> Can this file be closed?
|
|||
|
bnz.s @leaveWithoutClosing ; <21> No. Don<6F>t close it.
|
|||
|
|
|||
|
@callRealCloseResFile
|
|||
|
bsr FlushResourceCache ; <6> It it<69>s going to be closed, flush the cache
|
|||
|
movem.l (sp)+,a1/d1-d3
|
|||
|
unlk a6
|
|||
|
jmpOld
|
|||
|
|
|||
|
@leaveWithoutClosing
|
|||
|
clr.w ResErr
|
|||
|
movem.l (sp)+,a1/d1-d3
|
|||
|
moveq #2,d0
|
|||
|
jmp ExitPatchedOutRoutineWithoutRestoringMap
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; Map Override patches. This set of patches makes all the Resource Manager calls that
|
|||
|
; read resource information respect the Map Override behaviour. A wrapper is placed
|
|||
|
; around each of these Resource Manager routines to determine if the current resource map
|
|||
|
; has an override map. If it does, the override map is made the current map. CurMap
|
|||
|
; is restored before returning to the caller.
|
|||
|
;
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; CountTypesOverride
|
|||
|
;
|
|||
|
|
|||
|
CountTypesOverride PatchProc _CountTypes
|
|||
|
Import StandardCallThroughExit
|
|||
|
Import SyncTopOverrideMap
|
|||
|
Import CopyParameters ; <24>
|
|||
|
Import ExitWithoutRestoringMap ; <26>
|
|||
|
|
|||
|
CountTypesStack Record {A6Link},Decr
|
|||
|
numTypes ds.w 1
|
|||
|
retAddr ds.l 1
|
|||
|
A6Link ds.l 1
|
|||
|
OverrideStackFrameCommon
|
|||
|
oneDeepCall ds.w 1 ; <26> True if it<69>s _Count1Types
|
|||
|
localSize equ *
|
|||
|
EndR
|
|||
|
|
|||
|
With CountTypesStack
|
|||
|
link a6,#localSize
|
|||
|
move.w #1,oneDeepCall(a6) ; <26> Assume it<69>s one deep
|
|||
|
tst.b ResOneDeep ; <24> If one deep, maps have already been set up
|
|||
|
bnz.s @isCount1Types ; <26>
|
|||
|
clr.w oneDeepCall(a6) ; <26> It<49>s not one deep after all
|
|||
|
bsr SyncTopOverrideMap ; Set up the override maps
|
|||
|
@isCount1Types ; <24>
|
|||
|
clr.b ResOneDeep ; <27> Clear ResOneDeep so CountTypes will count all resources left in the chain.
|
|||
|
subq #2,sp ; Room for word result
|
|||
|
jsrOld ; Call through to the Resource Manager
|
|||
|
move.w (sp)+,numTypes(a6) ; Pass the result back to the caller
|
|||
|
moveq #0,d0 ; <27> CountTypes has no parameters.
|
|||
|
tst.w oneDeepCall(a6) ; <26> If this was a one deep call, we didn<64>t set up our stack frame
|
|||
|
bz.s @notOneDeep ; <26> It<49>s not one deep
|
|||
|
jmp ExitWithoutRestoringMap ; <26> so don<6F>t restore any lomems
|
|||
|
@notOneDeep ; <26>
|
|||
|
jmp StandardCallThroughExit ; And call the standard exit routine
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; GetIndexTypeOverride
|
|||
|
;
|
|||
|
|
|||
|
GetIndexedTypeOverride PatchProc _GetIndType
|
|||
|
Import StandardOverrideProcedureCallThrough
|
|||
|
|
|||
|
GetIndexedTypeStack Record {A6Link},Decr
|
|||
|
paramBegin equ *
|
|||
|
theType ds.l 1
|
|||
|
index ds.w 1
|
|||
|
paramSize equ paramBegin - *
|
|||
|
retAddr ds.l 1
|
|||
|
A6Link ds.l 1
|
|||
|
OverrideStackFrameCommon
|
|||
|
localSize equ *
|
|||
|
EndR
|
|||
|
|
|||
|
With GetIndexedTypeStack
|
|||
|
link a6,#localSize
|
|||
|
moveq #paramSize,d0
|
|||
|
leaOld a0
|
|||
|
jmp StandardOverrideProcedureCallThrough
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; GetResourceOverride
|
|||
|
;
|
|||
|
|
|||
|
GetResourceOverride PatchProc _GetResource
|
|||
|
Import StandardOverrideLongFunctionCallThrough
|
|||
|
|
|||
|
GetResourceStack Record {A6Link},Decr
|
|||
|
resHandle ds.l 1
|
|||
|
paramBegin equ *
|
|||
|
resType ds.l 1
|
|||
|
resID ds.w 1
|
|||
|
paramSize equ paramBegin - *
|
|||
|
retAddr ds.l 1
|
|||
|
A6Link ds.l 1
|
|||
|
OverrideStackFrameCommon
|
|||
|
localSize equ *
|
|||
|
EndR
|
|||
|
|
|||
|
With GetResourceStack
|
|||
|
link a6,#localSize
|
|||
|
moveq #paramSize,d0
|
|||
|
leaOld a0
|
|||
|
jmp StandardOverrideLongFunctionCallThrough
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; GetNamedResourceOverride
|
|||
|
;
|
|||
|
|
|||
|
GetNamedResourceOverride PatchProc _GetNamedResource
|
|||
|
Import StandardOverrideLongFunctionCallThrough
|
|||
|
|
|||
|
GetNamedResourceStack Record {A6Link},Decr
|
|||
|
resHandle ds.l 1
|
|||
|
paramBegin equ *
|
|||
|
resType ds.l 1
|
|||
|
resName ds.l 1
|
|||
|
paramSize equ paramBegin - *
|
|||
|
retAddr ds.l 1
|
|||
|
A6Link ds.l 1
|
|||
|
OverrideStackFrameCommon
|
|||
|
localSize equ *
|
|||
|
EndR
|
|||
|
|
|||
|
With GetNamedResourceStack
|
|||
|
link a6,#localSize
|
|||
|
moveq #paramSize,d0
|
|||
|
leaOld a0
|
|||
|
jmp StandardOverrideLongFunctionCallThrough
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; <43> RemoveResourceOverride
|
|||
|
;
|
|||
|
; RmveResource only allows resources to be removed from the current resource map.
|
|||
|
; If a resource came from an override map or a font file, RmveResource will fail
|
|||
|
; because that map<61>s file reference number will not match CurMap. Preflight
|
|||
|
; RmveResource so that CurMap will be set up with the file reference number of
|
|||
|
; an override/font map if the resource came from an override/font map.
|
|||
|
;
|
|||
|
|
|||
|
RemoveResourceOverride PatchProc _RmveResource
|
|||
|
Import FindOverriddenMap
|
|||
|
Import DoesCachedMapOverrideCurrentMap
|
|||
|
|
|||
|
RemoveResourceOverrideStack Record {A6Link},Decr
|
|||
|
paramBegin equ *
|
|||
|
resHandle ds.l 1
|
|||
|
paramSize equ paramBegin - *
|
|||
|
retAddr ds.l 1
|
|||
|
A6Link ds.l 1
|
|||
|
localSize equ *
|
|||
|
EndR
|
|||
|
|
|||
|
With RemoveResourceOverrideStack
|
|||
|
link a6,#localSize
|
|||
|
movem.l d1-d2/a2-a4,-(sp)
|
|||
|
move.l resHandle(a6),a3 ; Keep resource handle in a register
|
|||
|
|
|||
|
; First find out if CurMap needs to be changed at all
|
|||
|
|
|||
|
subq #2,sp
|
|||
|
move.l a3,-(sp)
|
|||
|
_HomeResFile ; Find out which resource file this resource came from
|
|||
|
move.w (sp)+,d0
|
|||
|
cmp.w CurMap,d0 ; Did it come from the current resource map?
|
|||
|
beq.s @curMapIsSetUp ; Yeah. Go ahead and remove it.
|
|||
|
|
|||
|
; This resource came from a map other than the current resource map. See if the map
|
|||
|
; that it came from is a system resource map, or an override map of the current map.
|
|||
|
|
|||
|
subq #4,sp
|
|||
|
move.w d0,-(sp)
|
|||
|
_GetMap ; Get a handle to the map the resource came from
|
|||
|
move.l (sp)+,d0
|
|||
|
bz.s @curMapIsSetUp ; If we couldn<64>t find the map, let RemoveResource bail for us
|
|||
|
|
|||
|
move.l d0,a4 ; Keep map handle in a safe place
|
|||
|
|
|||
|
; See if it<69>s a system resource map (Gibblies and fonts).
|
|||
|
|
|||
|
move.l SysMapHndl,a2 ; <49> Assume that this is a system override map. We<57>ll want to set the resChanged bit on the system map as well.
|
|||
|
subq #2,sp
|
|||
|
move.l a4,-(sp)
|
|||
|
_IsThisASystemResourceMap ; See if this map is a Gibble, the System file, or a font file
|
|||
|
tst.b (sp)+
|
|||
|
bnz.s @resourceIsFromAnOverrideMap ; If it<69>s one of the above, let the remove happen.
|
|||
|
|
|||
|
; It<49>s not a system resource map. See if the map the resource comes from is an override of
|
|||
|
; the current map.
|
|||
|
|
|||
|
subq #4,sp
|
|||
|
move.w CurMap,-(sp)
|
|||
|
_GetMap ; Get the map handle for the current resource map
|
|||
|
move.l (sp)+,d0
|
|||
|
bz.s @curMapIsSetUp ; Let RemoveResoruce take care of the errors
|
|||
|
|
|||
|
subq #2,sp
|
|||
|
move.l d0,-(sp)
|
|||
|
move.l a4,-(sp)
|
|||
|
move.w #kOverrideNextMapMask,-(sp) ; Scan until a non-override map is found.
|
|||
|
bsr DoesCachedMapOverrideCurrentMap ; We happen to have a routine that determines if one resource map overrides another.
|
|||
|
tst.w (sp)+
|
|||
|
bz.s @curMapIsSetUp ; The resource doesn<73>t come from an override map. Let RemoveResource fail for us.
|
|||
|
|
|||
|
; <49> The resource comes from an override map. Find the map that is being overriden so that
|
|||
|
; the resChanged bit can be set on that map. Since we know that this is an application override
|
|||
|
; map, we know that we should hit overridden map before we reach the end of the chain, so
|
|||
|
; we can skimp on a check for nil.
|
|||
|
|
|||
|
subq #4,sp ; <49>
|
|||
|
move.l a4,-(sp) ; <49> Override map
|
|||
|
bsr FindOverriddenMap ; <49> Find the map it overrides
|
|||
|
move.l (sp)+,a2 ; <49> Save the overridden map for later
|
|||
|
|
|||
|
; Set up CurMap to be that resource map so that RemoveResource will succeed.
|
|||
|
|
|||
|
@resourceIsFromAnOverrideMap
|
|||
|
move.w CurMap,-(sp) ; Save the current resource map
|
|||
|
move.l (a4),a0
|
|||
|
move.w mRefNum(a0),CurMap ; Set CurMap to be the override map
|
|||
|
move.l a3,-(sp) ; Pass resource handle again
|
|||
|
jsrOld ; Call the real RemoveResource
|
|||
|
move.w (sp)+,CurMap ; Restore current resource map
|
|||
|
|
|||
|
; <49> Set the mapChanged attribute on the overridden map if the RmveResource succeeded.
|
|||
|
|
|||
|
tst.w d0 ; <49> The Resource Manager returns ResError in D0 as well
|
|||
|
bnz.s @exitRemoveResourceOverride ; <49> Don<6F>t set the changed bit if RmveResource didn<64>t succeed
|
|||
|
move.l (a2),a0 ; <49>
|
|||
|
bset #mapChanged,mAttr(a0) ; <49> Mark the overridden map as changed.
|
|||
|
|
|||
|
; Clean up and return to the caller
|
|||
|
|
|||
|
@exitRemoveResourceOverride
|
|||
|
movem.l (sp)+,d1-d2/a2-a4
|
|||
|
unlk a6
|
|||
|
move.l (sp)+,(sp)
|
|||
|
rts ; Return without disturbing any more registers
|
|||
|
|
|||
|
; The resource map is fine, or an error came up. Pass control to the real RemoveResource to take
|
|||
|
; care of it
|
|||
|
|
|||
|
@curMapIsSetUp
|
|||
|
movem.l (sp)+,d1-d2/a2-a4
|
|||
|
unlk a6
|
|||
|
jmpOld
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; <49> AddOverrideResource
|
|||
|
;
|
|||
|
; If a resource is added to an override map, set the mapChanged bit in the map
|
|||
|
; that is overridden to ensure that the override map is updated when the original
|
|||
|
; resource map is updated.
|
|||
|
;
|
|||
|
|
|||
|
AddOverrideResource PatchProc _AddResource
|
|||
|
Import SetMapChangedBitOnOverriddenMap
|
|||
|
Import FlushResourceCache
|
|||
|
|
|||
|
movem.l d1/d2,-(sp) ; These registers are used by DispatchHelper, so they need to be saved.
|
|||
|
subq #4,sp
|
|||
|
move.w CurMap,-(sp)
|
|||
|
_GetMap ; AddResource adds to the current resource map
|
|||
|
move.l (sp)+,d0
|
|||
|
bz.s @addTheResource ; If the resource map is not in the resource chain, let AddResource fail
|
|||
|
move.l d0,-(sp)
|
|||
|
bsr SetMapChangedBitOnOverriddenMap ; If this map is an override map, set the mapChanged bit on the map it overrides
|
|||
|
@addTheResource
|
|||
|
bsr FlushResourceCache ; Got rid of seperate PatchProc to do this and moved call here.
|
|||
|
movem.l (sp)+,d1/d2
|
|||
|
jmpOld
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; <49> ChangeOverrideResource
|
|||
|
;
|
|||
|
; If a resource in an override map is changed, set the mapChanged bit in the map
|
|||
|
; that is overridden to ensure that the override map is updated when the original
|
|||
|
; resource map is updated.
|
|||
|
;
|
|||
|
|
|||
|
ChangeOverrideResource PatchProc _ChangedResource
|
|||
|
Import SetMapChangedBitOnOverriddenMap
|
|||
|
|
|||
|
move.l 4(sp),d0 ; Get the resource that has been changed
|
|||
|
movem.l d1/d2,-(sp) ; These registers are used by DispatchHelper, so they need to be saved.
|
|||
|
|
|||
|
subq #6,sp ; Space for HomeResFile and GetMap
|
|||
|
move.l d0,-(sp)
|
|||
|
_HomeResFile ; Find out which resource map this resource came from
|
|||
|
_GetMap ; And get the map handle
|
|||
|
move.l (sp)+,d0
|
|||
|
bz.s @changeTheResource ; If the resource map is not in the resource chain, let ChangedResource fail
|
|||
|
move.l d0,-(sp)
|
|||
|
bsr SetMapChangedBitOnOverriddenMap ; If this map is an override map, set the mapChanged bit on the map it overrides
|
|||
|
@changeTheResource
|
|||
|
movem.l (sp)+,d1/d2
|
|||
|
jmpOld
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; <49> SetOverrideResourceAttributes
|
|||
|
;
|
|||
|
; Normal programs call ChangedResource after calling SetResAttrs and the
|
|||
|
; ChangeOverrideResource routine would catch those. ResEdit is not a normal
|
|||
|
; program and calls SetResAttrs to set the resChanged bit, so this patch is
|
|||
|
; needed to catch that case.
|
|||
|
;
|
|||
|
|
|||
|
SetOverrideResourceAttributes PatchProc _SetResAttrs
|
|||
|
Import SetMapChangedBitOnOverriddenMap
|
|||
|
|
|||
|
move.l 6(sp),d0 ; Get the resource handle that has new attributes
|
|||
|
movem.l d1/d2,-(sp) ; These registers are used by DispatchHelper, so they need to be saved.
|
|||
|
|
|||
|
subq #6,sp ; Space for HomeResFile and GetMap
|
|||
|
move.l d0,-(sp)
|
|||
|
_HomeResFile ; Find out which resource map this resource came from
|
|||
|
_GetMap ; And get the map handle
|
|||
|
move.l (sp)+,d0
|
|||
|
bz.s @setResourceAttributes ; If the resource map is not in the resource chain, let SetResAttrs fail
|
|||
|
move.l d0,-(sp)
|
|||
|
bsr SetMapChangedBitOnOverriddenMap ; If this map is an override map, set the mapChanged bit on the map it overrides
|
|||
|
@setResourceAttributes
|
|||
|
movem.l (sp)+,d1/d2
|
|||
|
jmpOld
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; <46> UpdateResourceOverrideFile
|
|||
|
;
|
|||
|
; If a resource file has override maps on top of it, the override maps should be
|
|||
|
; updated when UpdateResFile is called in the resource file to write out any changes
|
|||
|
; to override resources.
|
|||
|
;
|
|||
|
|
|||
|
UpdateResourceOverrideFile PatchProc _UpdateResFile
|
|||
|
Import FlushResourceCache
|
|||
|
|
|||
|
move.w 4(sp),d0 ; Get file reference number to update
|
|||
|
movem.l d1/d2/a3/a4,-(sp) ; Save off needed registers
|
|||
|
|
|||
|
subq #4,sp
|
|||
|
move.w d0,-(sp)
|
|||
|
_GetMap ; Get map handle for file to update
|
|||
|
move.l (sp)+,d0 ; Make sure it<69>s in the chain
|
|||
|
bz.s @updateOriginalFile ; If it<69>s not, let UpdateResFile take care of the error
|
|||
|
|
|||
|
move.l d0,a4 ; Remember this map as the original
|
|||
|
subq #4,sp
|
|||
|
move.l d0,-(sp)
|
|||
|
_GetOverrideMap ; See if there<72>s an override map for this file
|
|||
|
move.l (sp)+,a3 ; Get the map
|
|||
|
|
|||
|
; Check to see if we<77>re updating the system file, or just another file. If we<77>re updating the
|
|||
|
; system file, then make sure we update all the font files too. If it<69>s just a generic resource map,
|
|||
|
; update just it<69>s override maps and the file itself.
|
|||
|
;
|
|||
|
; Note: I know that explicitly updating an override map of the system won<6F>t update the
|
|||
|
; font files. I think this is the right behaviour, since anyone that is referencing
|
|||
|
; the override map explicitly probably has something specific in mind.
|
|||
|
|
|||
|
cmp.l SysMapHndl,a4 ; If we<77>re updating the system file, then update the font files too
|
|||
|
bne.s @notUpdatingSystemFile ; This is done by setting a4 to nil, so that the loop won<6F>t end until
|
|||
|
moveq #0,a4 ; the end of the chain is reached
|
|||
|
bra.s @updateOverrideMaps
|
|||
|
|
|||
|
; It<49>s not the system file.
|
|||
|
|
|||
|
@notUpdatingSystemFile
|
|||
|
cmp.l a3,a4 ; If the file didn<64>t have any override maps
|
|||
|
beq.s @updateOriginalFile ; Just update the original.
|
|||
|
|
|||
|
; Update any changed override maps for this file.
|
|||
|
|
|||
|
@updateOverrideMaps
|
|||
|
move.l (a3),a0
|
|||
|
btst #mapChanged,MAttr(a0) ; See if any resources in this map were changed
|
|||
|
bz.s @nextMap
|
|||
|
move.w mRefNum(a0),-(sp) ; This override map has changed resources
|
|||
|
jsrOld ; Update it.
|
|||
|
move.l (a3),a0 ; Dereference the map handle again
|
|||
|
@nextMap
|
|||
|
move.l mNext(a0),d0 ; Get the next resource map handle
|
|||
|
cmp.l d0,a4 ; Is the next map the original map?
|
|||
|
beq.s @updateOriginalFile ; Yep. End the loop and fall through to UpdateResFile for the final time
|
|||
|
move.l d0,a3 ; Otherwise, update the next one if needed
|
|||
|
bra.s @updateOverrideMaps
|
|||
|
|
|||
|
; Update the original file
|
|||
|
|
|||
|
@updateOriginalFile
|
|||
|
bsr FlushResourceCache ; Got rid of seperate PatchProc and moved the call to FlushResourceCache into this patch.
|
|||
|
movem.l (sp)+,d1/d2/a3/a4
|
|||
|
jmpOld
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; <49> SetMapChangedBitOnOverriddenMap
|
|||
|
;
|
|||
|
; This routine determines if the resource map that contains data that is being
|
|||
|
; modified is an override map. If it is, it sets the map changed bit on the map
|
|||
|
; that is being overridden to ensure that the override map is updated.
|
|||
|
|
|||
|
SetMapChangedBitOnOverriddenMap Proc Export
|
|||
|
Import FindOverriddenMap
|
|||
|
|
|||
|
move.l (sp)+,a0 ; Return address
|
|||
|
move.l (sp)+,d0 ; Map being changed
|
|||
|
move.l a0,-(sp)
|
|||
|
movem.l a3/a4,-(sp)
|
|||
|
|
|||
|
; First determine if this map has any override attributes. If it doesn<73>t, just exit.
|
|||
|
|
|||
|
move.l d0,a3
|
|||
|
move.l (a3),a0
|
|||
|
move.b mInMemoryAttr(a0),d0 ; Get the override bits
|
|||
|
andi.b #kAllOverrideAttributesMask,d0 ; This and masks off everything but override bits. If any bits
|
|||
|
bz.s @exit ; are left in D0, then this map has some override attributes.
|
|||
|
|
|||
|
; See if this is an override map
|
|||
|
|
|||
|
btst #overrideNextMapBit,d0 ; We<57>ve still got our override attributes in D0
|
|||
|
bz.s @notAnOverrideMap ; This is an override map, but it might be a font file
|
|||
|
|
|||
|
; This is an override map. Find the map it overrides.
|
|||
|
|
|||
|
subq #4,sp
|
|||
|
move.l a3,-(sp)
|
|||
|
bsr FindOverriddenMap
|
|||
|
move.l (sp)+,a4 ; Save the handle to the overriden map
|
|||
|
bra.s @setMapChangedOnOverrideMap ; Go set the bit
|
|||
|
|
|||
|
; This isn<73>t an override map, but it might be a font map in the Fonts folder. The
|
|||
|
; easiest way to make this determination is by calling IsThisASystemResourceMap.
|
|||
|
|
|||
|
@notAnOverrideMap
|
|||
|
subq #2,sp
|
|||
|
move.l a3,-(sp)
|
|||
|
_IsThisASystemResourceMap ; See if this is a font file
|
|||
|
tst.b (sp)+ ; Well is it?
|
|||
|
bz.s @exit ; If it<69>s not, then we don<6F>t know why this map has override bits on it. Just call AddResource, and don<6F>t set the mapChanged bit anywhere else.
|
|||
|
move.l SysMapHndl,a4 ; If it is, set the mapChanged bit of the system map
|
|||
|
@setMapChangedOnOverrideMap
|
|||
|
move.l (a4),a0
|
|||
|
bset #mapChanged,mAttr(a0) ; Mark the overridden map as changed
|
|||
|
@exit
|
|||
|
movem.l (sp)+,a3/a4
|
|||
|
rts
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; <49> FindOverriddenMap
|
|||
|
;
|
|||
|
; Given a handle to a resource override map, find the map it overrides. This routine
|
|||
|
; assumes that the map passed in is an override map.
|
|||
|
;
|
|||
|
|
|||
|
FindOverriddenMap Proc Export
|
|||
|
move.l (sp)+,a0
|
|||
|
move.l (sp)+,d0 ; Get resource map handle
|
|||
|
move.l a0,-(sp)
|
|||
|
|
|||
|
@findOverriddenMapLoop
|
|||
|
move.l d0,a1
|
|||
|
move.l (a1),a0
|
|||
|
btst #overrideNextMapBit,mInMemoryAttr(a0) ; This bit says whether or not this is an override map
|
|||
|
bz.s @foundOverriddenMap ; If the bit isn<73>t set, then we<77>ve got the overridden map
|
|||
|
move.l mNext(a0),d0 ; Otherwise, look at the next map down
|
|||
|
bnz.s @findOverriddenMapLoop
|
|||
|
move.l d0,a1 ; If we didn<64>t find the overridden map before reaching the end of the chain, return nil.
|
|||
|
@foundOverriddenMap
|
|||
|
move.l a1,4(sp) ; Return result on the stack
|
|||
|
rts
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; TwoDeep patches. If a one deep Resource Manager call is made on a resource map
|
|||
|
; that has an override map in front of it, the one deep call will search the override
|
|||
|
; map and not the real resource map. If the twoDeepBit is set on a resource map, and
|
|||
|
; a one deep call is made, the map after this map will be searched for the desired
|
|||
|
; resource. This process repeats if the next map also has the twoDeepBit set.
|
|||
|
;
|
|||
|
; _________
|
|||
|
; |twoDeep| <--- TopOverrideMap: One deep resource calls start here.
|
|||
|
; | |
|
|||
|
; |_______|
|
|||
|
; |
|
|||
|
; ____v____
|
|||
|
; |twoDeep| <--- CurMap: If the requested resource was not found in the previous
|
|||
|
; | | resource map, this one is searched.
|
|||
|
; |_______|
|
|||
|
; |
|
|||
|
; ____v____
|
|||
|
; |twoDeep| Then this one<6E>
|
|||
|
; | |
|
|||
|
; |_______|
|
|||
|
; |
|
|||
|
; ____v____
|
|||
|
; | | Then this one. If, after searching this map the requested resource
|
|||
|
; | | was not found, searching stops, and resNotFound is returned.
|
|||
|
; |_______|
|
|||
|
; |
|
|||
|
; ____v____
|
|||
|
; | |
|
|||
|
; | | This map will not be searched
|
|||
|
; |_______|
|
|||
|
;
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; Get2Resource
|
|||
|
;
|
|||
|
|
|||
|
Get2Resource PatchProc _Get1Resource
|
|||
|
Import StandardTwoDeepLongFunctionCallThrough
|
|||
|
Import ExitWithoutRestoringMap
|
|||
|
|
|||
|
Get2ResourceStack Record {A6Link},Decr
|
|||
|
resHandle ds.l 1
|
|||
|
paramBegin equ *
|
|||
|
resType ds.l 1
|
|||
|
resID ds.w 1
|
|||
|
paramSize equ paramBegin - *
|
|||
|
retAddr ds.l 1
|
|||
|
A6Link ds.l 1
|
|||
|
OverrideStackFrameCommon
|
|||
|
localSize equ *
|
|||
|
EndR
|
|||
|
|
|||
|
With Get2ResourceStack
|
|||
|
move.l ExpandMem,a0 ; <41>
|
|||
|
tst.b ExpandMemRec.emScanOverrideMaps(a0) ; <41> Is overriding on?
|
|||
|
beqOld ; <41> No. Use the real Resource Manager routine.
|
|||
|
|
|||
|
tst.b ROMMapInsert
|
|||
|
bz.s @useOverrideMaps ; <42> No special case if ROMMapInsert is not set
|
|||
|
move.w CurMap,d0 ; <42>
|
|||
|
cmp.w SysMap,d0 ; <42> Is the system the current resource file?
|
|||
|
beqOld ; <42> If it is, that means the ROM map will become the current map, and the ROM map never has override bits set, so skip all this stuff.
|
|||
|
cmp.w #1,d0 ; <44> Another possibility is if someone slammed
|
|||
|
beqOld ; <44> the ROM map into CurMap
|
|||
|
|
|||
|
@useOverrideMaps
|
|||
|
link a6,#localSize
|
|||
|
clr.l resHandle(a6) ; <31> Assume no resource found.
|
|||
|
leaOld a0
|
|||
|
moveq #paramSize,d0
|
|||
|
jmp StandardTwoDeepLongFunctionCallThrough
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; Get2NamedResource
|
|||
|
;
|
|||
|
|
|||
|
Get2NamedResource PatchProc _Get1NamedResource
|
|||
|
Import StandardTwoDeepLongFunctionCallThrough
|
|||
|
Import ExitWithoutRestoringMap
|
|||
|
|
|||
|
Get2NamedResourceStack Record {A6Link},Decr
|
|||
|
resHandle ds.l 1
|
|||
|
paramBegin equ *
|
|||
|
resType ds.l 1
|
|||
|
resName ds.l 1
|
|||
|
paramSize equ paramBegin - *
|
|||
|
retAddr ds.l 1
|
|||
|
A6Link ds.l 1
|
|||
|
OverrideStackFrameCommon
|
|||
|
localSize equ *
|
|||
|
EndR
|
|||
|
|
|||
|
With Get2NamedResourceStack
|
|||
|
move.l ExpandMem,a0 ; <41>
|
|||
|
tst.b ExpandMemRec.emScanOverrideMaps(a0) ; <41> Is overriding on?
|
|||
|
beqOld ; <41> No. Use the real Resource Manager routine.
|
|||
|
|
|||
|
tst.b ROMMapInsert
|
|||
|
bz.s @useOverrideMaps ; <42> No special case if ROMMapInsert is not set
|
|||
|
move.w CurMap,d0 ; <42>
|
|||
|
cmp.w SysMap,d0 ; <42> Is the system the current resource file?
|
|||
|
beqOld ; <42> If it is, that means the ROM map will become the current map, and the ROM map never has override bits set, so skip all this stuff.
|
|||
|
cmp.w #1,d0 ; <44> Another possibility is if someone slammed
|
|||
|
beqOld ; <44> the ROM map into CurMap
|
|||
|
|
|||
|
@useOverrideMaps
|
|||
|
link a6,#localSize
|
|||
|
clr.l resHandle(a6) ; <31> Assume no resource
|
|||
|
leaOld a0
|
|||
|
moveq #paramSize,d0
|
|||
|
jmp StandardTwoDeepLongFunctionCallThrough
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; Unique2ID
|
|||
|
;
|
|||
|
|
|||
|
Unique2ID PatchProc _Unique1ID
|
|||
|
Import SyncTopOverrideMap
|
|||
|
Import SetUpTwoDeepChain
|
|||
|
Import StandardCallThroughExit
|
|||
|
|
|||
|
Unique2IDStack Record {A6Link},Decr
|
|||
|
resID ds.w 1
|
|||
|
paramBegin equ *
|
|||
|
resType ds.l 1
|
|||
|
paramSize equ paramBegin - *
|
|||
|
retAddr ds.l 1
|
|||
|
A6Link ds.l 1
|
|||
|
TwoDeepStackFrameCommon
|
|||
|
localSize equ *
|
|||
|
EndR
|
|||
|
|
|||
|
With Unique2IDStack
|
|||
|
move.l ExpandMem,a0 ; <41>
|
|||
|
tst.b ExpandMemRec.emScanOverrideMaps(a0) ; <41> Is overriding on?
|
|||
|
beqOld ; <41> No. Use the real Resource Manager routine.
|
|||
|
|
|||
|
tst.b ROMMapInsert
|
|||
|
bz.s @useOverrideMaps ; <42> No special case if ROMMapInsert is not set
|
|||
|
move.w CurMap,d0 ; <42>
|
|||
|
cmp.w SysMap,d0 ; <42> Is the system the current resource file?
|
|||
|
beqOld ; <42> If it is, that means the ROM map will become the current map, and the ROM map never has override bits set, so skip all this stuff.
|
|||
|
cmp.w #1,d0 ; <44> Another possibility is if someone slammed
|
|||
|
beqOld ; <44> the ROM map into CurMap
|
|||
|
|
|||
|
@useOverrideMaps
|
|||
|
link a6,#localSize
|
|||
|
movem.l a3/a4,-(sp)
|
|||
|
|
|||
|
bsr SyncTopOverrideMap ; Set up the override maps
|
|||
|
bz.s @noSuchResource ; <50> If CurMap was not in the resource chain, curMapHandle will be nil, and we should bail.
|
|||
|
bsr SetUpTwoDeepChain ; And cut the chain short at the right sport
|
|||
|
|
|||
|
sub.w #2,sp
|
|||
|
move.l resType(a6),-(sp)
|
|||
|
_UniqueID ; Call _UniqueID
|
|||
|
move.w (sp)+,resID(a6)
|
|||
|
|
|||
|
move.l (a4),a3
|
|||
|
move.l realNextMap(a6),mNext(a3) ; Restore the rest of the resource chain
|
|||
|
move.l realTopMap(a6),TopMapHndl ; Restore the real resource chain top
|
|||
|
@noSuchResource
|
|||
|
movem.l (sp)+,a3/a4
|
|||
|
|
|||
|
moveq #paramSize,d0
|
|||
|
jmp StandardCallThroughExit ; Get out of here.
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; Count2Types
|
|||
|
;
|
|||
|
|
|||
|
Count2Types PatchProc _Count1Types
|
|||
|
Import SyncTopOverrideMap
|
|||
|
Import SetUpTwoDeepChain
|
|||
|
Import StandardCallThroughExit
|
|||
|
Import CountTypesOverride
|
|||
|
|
|||
|
Count2TypesStack Record {A6Link},Decr
|
|||
|
typeCount ds.w 1
|
|||
|
retAddr ds.l 1
|
|||
|
A6Link ds.l 1
|
|||
|
TwoDeepStackFrameCommon
|
|||
|
localSize equ *
|
|||
|
EndR
|
|||
|
|
|||
|
With Count2TypesStack
|
|||
|
move.l ExpandMem,a0 ; <41>
|
|||
|
tst.b ExpandMemRec.emScanOverrideMaps(a0) ; <41> Is overriding on?
|
|||
|
beqOld ; <41> No. Use the real Resource Manager routine.
|
|||
|
|
|||
|
tst.b ROMMapInsert
|
|||
|
bz.s @useOverrideMaps ; <42> No special case if ROMMapInsert is not set
|
|||
|
move.w CurMap,d0 ; <42>
|
|||
|
cmp.w SysMap,d0 ; <42> Is the system the current resource file?
|
|||
|
beqOld ; <42> If it is, that means the ROM map will become the current map, and the ROM map never has override bits set, so skip all this stuff.
|
|||
|
cmp.w #1,d0 ; <44> Another possibility is if someone slammed
|
|||
|
beqOld ; <44> the ROM map into CurMap
|
|||
|
|
|||
|
@useOverrideMaps
|
|||
|
link a6,#localSize
|
|||
|
movem.l a3/a4,-(sp)
|
|||
|
|
|||
|
clr.w typeCount(a6) ; <50> Return 0 in case we bail early.
|
|||
|
bsr SyncTopOverrideMap ; Set up the override maps
|
|||
|
bz.s @noSuchResource ; <50> If CurMap was not in the resource chain, curMapHandle will be nil, and we should bail.
|
|||
|
bsr SetUpTwoDeepChain ; And cut the chain short at the right sport
|
|||
|
st ResOneDeep
|
|||
|
|
|||
|
sub.w #2,sp
|
|||
|
bsr CountTypesOverride ; Call _CountTypes
|
|||
|
move.w (sp)+,typeCount(a6)
|
|||
|
|
|||
|
move.l (a4),a3
|
|||
|
move.l realNextMap(a6),mNext(a3) ; Restore the rest of the resource chain
|
|||
|
move.l realTopMap(a6),TopMapHndl ; Restore the real resource chain top
|
|||
|
@noSuchResource
|
|||
|
movem.l (sp)+,a3/a4
|
|||
|
|
|||
|
moveq #0,d0
|
|||
|
jmp StandardCallThroughExit ; Get out of here.
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; Get2IndexedType
|
|||
|
;
|
|||
|
|
|||
|
Get2IndexedType PatchProc _Get1IxType
|
|||
|
Import SyncTopOverrideMap
|
|||
|
Import SetUpTwoDeepChain
|
|||
|
Import StandardCallThroughExit
|
|||
|
Import GetIndTypeOverride
|
|||
|
|
|||
|
Get2IndexedTypeStack Record {A6Link},Decr
|
|||
|
paramBegin equ *
|
|||
|
resType ds.l 1
|
|||
|
typeIndex ds.w 1
|
|||
|
paramSize equ paramBegin - *
|
|||
|
retAddr ds.l 1
|
|||
|
A6Link ds.l 1
|
|||
|
TwoDeepStackFrameCommon
|
|||
|
localSize equ *
|
|||
|
EndR
|
|||
|
|
|||
|
With Get2IndexedTypeStack
|
|||
|
move.l ExpandMem,a0 ; <41>
|
|||
|
tst.b ExpandMemRec.emScanOverrideMaps(a0) ; <41> Is overriding on?
|
|||
|
beqOld ; <41> No. Use the real Resource Manager routine.
|
|||
|
|
|||
|
tst.b ROMMapInsert
|
|||
|
bz.s @useOverrideMaps ; <42> No special case if ROMMapInsert is not set
|
|||
|
move.w CurMap,d0 ; <42>
|
|||
|
cmp.w SysMap,d0 ; <42> Is the system the current resource file?
|
|||
|
beqOld ; <42> If it is, that means the ROM map will become the current map, and the ROM map never has override bits set, so skip all this stuff.
|
|||
|
cmp.w #1,d0 ; <44> Another possibility is if someone slammed
|
|||
|
beqOld ; <44> the ROM map into CurMap
|
|||
|
|
|||
|
@useOverrideMaps
|
|||
|
link a6,#localSize
|
|||
|
movem.l a3/a4,-(sp)
|
|||
|
|
|||
|
move.l resType(a6),a0 ; <50>
|
|||
|
clr.l (a0) ; <50> Return a string of nulls in case we bail early
|
|||
|
bsr SyncTopOverrideMap ; Set up the override maps
|
|||
|
bz.s @noSuchResource ; <50> If CurMap was not in the resource chain, curMapHandle will be nil, and we should bail.
|
|||
|
bsr SetUpTwoDeepChain ; And cut the chain short at the right sport
|
|||
|
|
|||
|
move.l resType(a6),-(sp)
|
|||
|
move.w typeIndex(a6),-(sp)
|
|||
|
bsr GetIndexedTypeOverride ; Call _GetIndType
|
|||
|
|
|||
|
move.l (a4),a3
|
|||
|
move.l realNextMap(a6),mNext(a3) ; Restore the rest of the resource chain
|
|||
|
move.l realTopMap(a6),TopMapHndl ; Restore the real resource chain top
|
|||
|
@noSuchResource
|
|||
|
movem.l (sp)+,a3/a4
|
|||
|
|
|||
|
moveq #paramSize,d0
|
|||
|
jmp StandardCallThroughExit ; Get out of here.
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; DontCountOrIndexDuplicates patches. If a resource in an override map is of the
|
|||
|
; same type and ID of a resource in the map it overrides, _CountResources will count
|
|||
|
; both resources. If the dontCountOrIndexDuplicates bit is set in a resource map,
|
|||
|
; any resource that matches a resource that was counted earlier in the process will
|
|||
|
; not be counted. A list of the resources that are actually counted will be built and
|
|||
|
; cached in anticipation of a subsequent _GetIndResource call.
|
|||
|
;
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; CountResourcesOverride
|
|||
|
;
|
|||
|
|
|||
|
CountResourcesOverride PatchProc _CountResources
|
|||
|
Import SyncTopOverrideMap
|
|||
|
Import CacheResource
|
|||
|
Import ExitForPatchedOutRoutines
|
|||
|
Import ExitPatchedOutRoutineWithoutRestoringMap
|
|||
|
|
|||
|
CountResourcesOverrideStack Record {A6Link},Decr
|
|||
|
resourcesCount ds.w 1
|
|||
|
paramBegin equ *
|
|||
|
resType ds.l 1
|
|||
|
paramSize equ paramBegin - *
|
|||
|
retAddr ds.l 1
|
|||
|
A6Link ds.l 1
|
|||
|
OverrideStackFrameCommon
|
|||
|
localSize equ *
|
|||
|
EndR
|
|||
|
|
|||
|
With CountResourcesOverrideStack
|
|||
|
link a6,#localSize
|
|||
|
move.l d1,-(sp)
|
|||
|
clr.w resourcesCount(a6) ; Assume no resources of this type
|
|||
|
tst.b ResOneDeep ; The _Count1Resources patch already set up
|
|||
|
bne.s @overrideMapSynchronized ; the override map
|
|||
|
bsr SyncTopOverrideMap ; Sync up the top override map
|
|||
|
@overrideMapSynchronized
|
|||
|
tst.b ROMMapInsert
|
|||
|
beq.s @noROMMap
|
|||
|
moveq #0,d1
|
|||
|
jsrROM SwapROMMap ; Set up the ROM map
|
|||
|
@noROMMap
|
|||
|
clr.w ResErr ; Fresh routine, fresh start
|
|||
|
move.l resType(a6),-(sp)
|
|||
|
bsr CacheResource ; Build the resource cache
|
|||
|
move.l ExpandMem,a0
|
|||
|
move.l ExpandMemRec.emResourceCache(a0),d0
|
|||
|
beq.s @exitCountResourcesOverride
|
|||
|
move.l d0,a0
|
|||
|
move.l (a0),a0
|
|||
|
move.l kResourceCount(a0),d0 ; Get count
|
|||
|
move.w d0,resourcesCount(a6) ; And return it
|
|||
|
@exitCountResourcesOverride
|
|||
|
tst.b ROMMapInsert
|
|||
|
beq.s @noROMMapToRemove
|
|||
|
moveq #-1,d1
|
|||
|
jsrROM SwapROMMap ; Delete the ROM map
|
|||
|
@noROMMapToRemove
|
|||
|
move.l (sp)+,d1 ; Restore D1
|
|||
|
moveq #paramSize,d0
|
|||
|
tst.b ResOneDeep
|
|||
|
bne.s @oneDeepExit
|
|||
|
jmp ExitForPatchedOutRoutines ; Use the common exit code
|
|||
|
@oneDeepExit
|
|||
|
jmp ExitPatchedOutRoutineWithoutRestoringMap
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; Count2Resources
|
|||
|
;
|
|||
|
|
|||
|
Count2Resources PatchProc _Count1Resources
|
|||
|
Import SyncTopOverrideMap
|
|||
|
Import SetUpTwoDeepChain
|
|||
|
Import StandardCallThroughExit
|
|||
|
Import CountResourcesOverride
|
|||
|
|
|||
|
Count2ResourcesStack Record {A6Link},Decr
|
|||
|
resourcesCount ds.w 1
|
|||
|
paramBegin equ *
|
|||
|
resType ds.l 1
|
|||
|
paramSize equ paramBegin - *
|
|||
|
retAddr ds.l 1
|
|||
|
A6Link ds.l 1
|
|||
|
TwoDeepStackFrameCommon
|
|||
|
localSize equ *
|
|||
|
EndR
|
|||
|
|
|||
|
With Count2ResourcesStack
|
|||
|
move.l ExpandMem,a0 ; <41>
|
|||
|
tst.b ExpandMemRec.emScanOverrideMaps(a0) ; <41> Is overriding on?
|
|||
|
beqOld ; <41> No. Use the real Resource Manager routine.
|
|||
|
|
|||
|
tst.b ROMMapInsert
|
|||
|
bz.s @useOverrideMaps ; <42> No special case if ROMMapInsert is not set
|
|||
|
move.w CurMap,d0 ; <42>
|
|||
|
cmp.w SysMap,d0 ; <42> Is the system the current resource file?
|
|||
|
beqOld ; <42> If it is, that means the ROM map will become the current map, and the ROM map never has override bits set, so skip all this stuff.
|
|||
|
cmp.w #1,d0 ; <44> Another possibility is if someone slammed
|
|||
|
beqOld ; <44> the ROM map into CurMap
|
|||
|
|
|||
|
@useOverrideMaps
|
|||
|
link a6,#localSize
|
|||
|
movem.l a3/a4,-(sp)
|
|||
|
|
|||
|
clr.w resourcesCount(a6) ; <50> Return 0 in case we bail early.<2E>
|
|||
|
bsr SyncTopOverrideMap ; Set up the override maps
|
|||
|
bz.s @noSuchResource ; <50> If CurMap was not in the resource chain, curMapHandle will be nil, and we should bail.
|
|||
|
bsr SetUpTwoDeepChain ; And cut the chain short at the right sport
|
|||
|
st ResOneDeep ; Mark this so _CountResources doesn<73>t have to resync the override map
|
|||
|
subq #2,sp
|
|||
|
move.l resType(a6),-(sp)
|
|||
|
bsr CountResourcesOverride ; Call _CountResources. (The new version above will get called.)
|
|||
|
move.w (sp)+,resourcesCount(a6)
|
|||
|
|
|||
|
move.l (a4),a3
|
|||
|
move.l realNextMap(a6),mNext(a3) ; Restore the rest of the resource chain
|
|||
|
move.l realTopMap(a6),TopMapHndl ; Restore the real resource chain top
|
|||
|
@noSuchResource ; <50>
|
|||
|
movem.l (sp)+,a3/a4
|
|||
|
|
|||
|
moveq #paramSize,d0
|
|||
|
jmp StandardCallThroughExit ; Get out of here.
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; GetIndexedResourceOverride
|
|||
|
;
|
|||
|
|
|||
|
GetIndexedResourceOverride PatchProc _GetIndResource
|
|||
|
Import SyncTopOverrideMap
|
|||
|
Import CacheResource
|
|||
|
Import ExitForPatchedOutRoutines
|
|||
|
Import ExitPatchedOutRoutineWithoutRestoringMap
|
|||
|
|
|||
|
GetIndexedResourceOverrideStack Record {A6Link},Decr
|
|||
|
resHandle ds.l 1
|
|||
|
paramBegin equ *
|
|||
|
resType ds.l 1
|
|||
|
resIndex ds.w 1
|
|||
|
paramSize equ paramBegin - *
|
|||
|
retAddr ds.l 1
|
|||
|
A6Link ds.l 1
|
|||
|
TwoDeepStackFrameCommon
|
|||
|
localSize equ *
|
|||
|
EndR
|
|||
|
|
|||
|
With GetIndexedResourceOverrideStack
|
|||
|
link a6,#localSize
|
|||
|
movem.l a1-a5/d1/d2/d4-d7,-(sp) ; D2 is saved because CheckLoad trashes it
|
|||
|
move.l a4,a5 ; <13> Save handle to resource map chain was cut at.
|
|||
|
clr.l resHandle(a6) ; Assume no resource
|
|||
|
tst.w resIndex(a6)
|
|||
|
bz.s @errorExit ; <7> 0 is not a valid index
|
|||
|
bmi.s @errorExit ; <7> Negative indices aren<65>t any good either
|
|||
|
@indexOK
|
|||
|
tst.b ResOneDeep ; The _Count1Resources patch already set up
|
|||
|
bne.s @overrideMapSynchronized ; the override map
|
|||
|
bsr SyncTopOverrideMap ; Sync up the top override map
|
|||
|
@overrideMapSynchronized
|
|||
|
tst.b ROMMapInsert ; Should the ROM map be inserted?
|
|||
|
beq.s @noROMMap ; No.
|
|||
|
moveq #0,d1
|
|||
|
jsrROM SwapROMMap ; Set up the ROM map
|
|||
|
@noROMMap
|
|||
|
clr.w ResErr ; Fresh routine, fresh start
|
|||
|
move.l resType(a6),-(sp) ; Get the resource type we want
|
|||
|
bsr CacheResource ; Build the resource cache
|
|||
|
move.l ExpandMem,a0
|
|||
|
move.l ExpandMemRec.emResourceCache(a0),d0 ; Get the cache handle
|
|||
|
beq.s @errorExit ; If no handle, get out
|
|||
|
move.l d0,a0
|
|||
|
move.l (a0),a0 ; Pointer to cache
|
|||
|
moveq #0,d0
|
|||
|
move.w resIndex(a6),d0 ; Get index into cache
|
|||
|
subq #1,d0 ; Cache is zero based
|
|||
|
cmp.l kResourceCount(a0),d0 ; Check the bounds of the index
|
|||
|
blt.s @validIndex
|
|||
|
@errorExit
|
|||
|
move.w #resNotFound,ResErr ; Always return resNotFound in CountResources
|
|||
|
st ResOneDeep ; <7> Skanky way of forcing exit without restoring maps
|
|||
|
bra.s @exitGetIndResourceOverride ; <33> Exit, removing the ROM map if it<69>s there.
|
|||
|
@validIndex
|
|||
|
asl.w #3,d0 ; <31> Multiply by 8 to get offset into cache
|
|||
|
lea kCacheHeaderSize(a0,d0.w),a0 ; Point to proper entry for this index
|
|||
|
move.l (a0)+,a4 ; <31> Get the map handle (loaded into A4 for CheckLoad)
|
|||
|
moveq #0,d4 ; <31>
|
|||
|
move.w (a0),d4 ; <31> Get offset to resource reference list
|
|||
|
move.l (a4),a3 ; Dereference map handle
|
|||
|
move.w mRefNum(a3),d6 ; <31> CheckLoad in ROM needs the reference number in D6.
|
|||
|
moveq #0,d0 ; <37>
|
|||
|
move.w mTypes(a3),d0 ; <37> Get offset to type list
|
|||
|
add.w d0,d4 ; <37> Calculate offset of resource reference from beginning of type list
|
|||
|
move.l d0,HSCTOffset ; <37> Save offset to type list in the cache
|
|||
|
move.l d4,HSCROffset ; <37> Save offset to resource reference in RMgrHiVars
|
|||
|
move.l a3,a2 ; Save A3 for CheckLoad
|
|||
|
add.l d4,a2 ; Point to the resource reference
|
|||
|
move.l resType(a6),HSCRType ; <37> Save the resource type in the HandleScan cache
|
|||
|
move.l a4,HSCMapHndl ; <37> Save the map handle in RMgrHiVars
|
|||
|
move.w d6,HSCMapRNum ; <37> Save map reference number in cache
|
|||
|
|
|||
|
;
|
|||
|
; Got the correct reference list. Now see if the resource needs to be loaded. Call CheckLoad
|
|||
|
; to do this. This requires some setup, since the Resource Manager expects certain
|
|||
|
; things from itself. (Since this routine never calls the Resource Manager to set anything
|
|||
|
; up, it needs to be done now.) A3 contains a pointer to the type list, and another stack
|
|||
|
; frame is created in order to make a parameter block in the place RdData expects it. D6
|
|||
|
; needs to hold the file reference number of the current map.
|
|||
|
;
|
|||
|
; <11> The decompressor patch calls _Get1Resource from within CheckLoad to load
|
|||
|
; the decompressor. At this point, the resource chain is still set up to
|
|||
|
; do override stuff. To keep the decompressor working, restore the resource
|
|||
|
; chain at this point for _Get1IxResource calls.
|
|||
|
;
|
|||
|
|
|||
|
tst.b ResOneDeep ; <11>
|
|||
|
bz.s @notOneDeep
|
|||
|
move.l a5,a0 ; <11> Get the map we jammed into TopMapHndl
|
|||
|
move.l (a0),a0
|
|||
|
move.l (a6),a1 ; <11> Get Get2IndexedResource<63>s stack frame
|
|||
|
move.l realNextMap(a1),mNext(a0) ; <11> Restore the chain below this map
|
|||
|
move.l realTopMap(a1),TopMapHndl ; <11> Restore the real top map
|
|||
|
@notOneDeep
|
|||
|
link a6,#RMgrStack ; Create a stack frame for CheckLoad
|
|||
|
clr.w ioStkFrame+ioVRefNum(a6) ; so that it has a IOPB where it
|
|||
|
clr.w ioStkFrame+ioFileType(a6) ; expects it on the stack
|
|||
|
move.b RMgrPerm,ioStkFrame+ioPermssn(a6)
|
|||
|
move.l jCheckLoad,a0 ; Handy dandy vector to see if a resource is loaded
|
|||
|
jsr (a0) ; Go load the resource if necessary
|
|||
|
unlk a6 ; Toss the parameter block
|
|||
|
move.l a0,resHandle(a6) ; Return the handle
|
|||
|
move.l a0,HSCHandle ; <37> And save it in the cache
|
|||
|
@exitGetIndResourceOverride
|
|||
|
tst.b ROMMapInsert
|
|||
|
beq.s @noROMMapToRemove
|
|||
|
moveq #-1,d1
|
|||
|
jsrROM SwapROMMap ; Take out the ROM map
|
|||
|
@noROMMapToRemove
|
|||
|
movem.l (sp)+,a1-a5/d1/d2/d4-d7
|
|||
|
moveq #paramSize,d0
|
|||
|
tst.b ResOneDeep
|
|||
|
bne.s @oneDeepExit
|
|||
|
jmp ExitForPatchedOutRoutines ; Use the common exit code
|
|||
|
@oneDeepExit
|
|||
|
jmp ExitPatchedOutRoutineWithoutRestoringMap
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; Get2IndexedResource
|
|||
|
;
|
|||
|
|
|||
|
Get2IndexedResource PatchProc _Get1IxResource
|
|||
|
Import SyncTopOverrideMap
|
|||
|
Import SetUpTwoDeepChain
|
|||
|
Import StandardCallThroughExit
|
|||
|
Import GetIndResourceOverride
|
|||
|
|
|||
|
Get2IndexedResourceStack Record {A6Link},Decr
|
|||
|
resHandle ds.l 1
|
|||
|
paramBegin equ *
|
|||
|
resType ds.l 1
|
|||
|
resIndex ds.w 1
|
|||
|
paramSize equ paramBegin - *
|
|||
|
retAddr ds.l 1
|
|||
|
A6Link ds.l 1
|
|||
|
TwoDeepStackFrameCommon
|
|||
|
localSize equ *
|
|||
|
EndR
|
|||
|
|
|||
|
With Get2IndexedResourceStack
|
|||
|
move.l ExpandMem,a0 ; <41>
|
|||
|
tst.b ExpandMemRec.emScanOverrideMaps(a0) ; <41> Is overriding on?
|
|||
|
beqOld ; <41> No. Use the real Resource Manager routine.
|
|||
|
|
|||
|
tst.b ROMMapInsert
|
|||
|
bz.s @useOverrideMaps ; <42> No special case if ROMMapInsert is not set
|
|||
|
move.w CurMap,d0 ; <42>
|
|||
|
cmp.w SysMap,d0 ; <42> Is the system the current resource file?
|
|||
|
beqOld ; <42> If it is, that means the ROM map will become the current map, and the ROM map never has override bits set, so skip all this stuff.
|
|||
|
cmp.w #1,d0 ; <44> Another possibility is if someone slammed
|
|||
|
beqOld ; <44> the ROM map into CurMap
|
|||
|
|
|||
|
@useOverrideMaps
|
|||
|
link a6,#localSize
|
|||
|
movem.l a3/a4,-(sp)
|
|||
|
|
|||
|
clr.l resHandle(a6) ; <50> Prepare to return nil in case we bail early.
|
|||
|
bsr SyncTopOverrideMap ; Set up the override maps
|
|||
|
bz.s @noSuchResource ; <50> If CurMap was not in the resource chain, curMapHandle will be nil, and we should bail.
|
|||
|
bsr SetUpTwoDeepChain ; And cut the chain short at the right sport
|
|||
|
st ResOneDeep
|
|||
|
|
|||
|
subq #4,sp
|
|||
|
move.l resType(a6),-(sp)
|
|||
|
move.w resIndex(a6),-(sp)
|
|||
|
bsr GetIndexedResourceOverride ; Call _GetIndResource. (The new version above will get called.)
|
|||
|
move.l (sp)+,resHandle(a6)
|
|||
|
|
|||
|
move.l (a4),a3 ; A4 is a handle to the map whose next field was changed
|
|||
|
move.l realNextMap(a6),mNext(a3) ; Restore the rest of the resource chain
|
|||
|
move.l realTopMap(a6),TopMapHndl ; Restore the real resource chain top
|
|||
|
@noSuchResource ; <50>
|
|||
|
movem.l (sp)+,a3/a4
|
|||
|
|
|||
|
moveq #paramSize,d0
|
|||
|
jmp StandardCallThroughExit ; Get out of here.
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; CacheResource builds the list of resources that are actually counted or indexed. Calls
|
|||
|
; to _AddResource and _RmveResource will flush this cache. The cache contents look like
|
|||
|
; this:
|
|||
|
;
|
|||
|
; Offset Contents
|
|||
|
; 0 Cache flags
|
|||
|
; 2 File reference number
|
|||
|
; 4 Resource type in cache
|
|||
|
; 8 Number of entries in cache - 1
|
|||
|
; 12 Beginning of cache information
|
|||
|
; 0 Handle to resource map containing this resource <31>
|
|||
|
; 4 Offset from beginning of map to this resource (word) <31>
|
|||
|
; 6 ID of this resource (word) <29>
|
|||
|
;
|
|||
|
; The cache flags word is a bit field describing the state of the Resource Manager
|
|||
|
; when the cache was formed. The cache will be flushed if the current state of the
|
|||
|
; Resource Manager does not match the state when the cache was formed. The following
|
|||
|
; bits are currently defined for the cache flags:
|
|||
|
;
|
|||
|
; (0) kCacheIsOneDeepBit Cache was formed on a _Count1Resources or _Get1IxResource call.
|
|||
|
; (1) kCacheHasROMResourcesBit Cache was formed when ROMMapInsert was true.
|
|||
|
; (2) kCacheHasOverridesBit Cache was formed when emScanOverrideMaps was true.
|
|||
|
;
|
|||
|
|
|||
|
CacheResource Proc Export
|
|||
|
Import IsDuplicate
|
|||
|
|
|||
|
move.l (sp)+,a0 ; Get return address
|
|||
|
move.l (sp)+,d0 ; Get resource type
|
|||
|
move.l a0,-(sp) ; Restore return address
|
|||
|
movem.l d2-d7/a1-a4,-(sp) ; Save registers
|
|||
|
move.l d0,d7 ; Keep type in a nonvolatile place
|
|||
|
|
|||
|
move.l ExpandMem,a0
|
|||
|
move.b ExpandMemRec.emScanOverrideMaps(a0),d3 ; <35> Get scan override state
|
|||
|
bz.s @overridingNotOn ; <35> Why would anyone want to do this?
|
|||
|
move.w #kCacheHasOverridesMask,d3 ; <35> Set to a known value, since Pascal would have put a 1 in emScanOverrideMaps, whereas C would have put in -1, and who knows what Asm would have done<6E>
|
|||
|
@overridingNotOn
|
|||
|
move.l ExpandMemRec.emResourceCache(a0),d0 ; Get cached resource from expanded low mem
|
|||
|
beq.s @setupCache ; Cache doesn<73>t exist. Go build it
|
|||
|
move.l d0,a0
|
|||
|
|
|||
|
;
|
|||
|
; <7> See if the deepness of the cache matches that of ResOneDeep. If not, force the
|
|||
|
; cache to be rebuilt.
|
|||
|
; <34> Also make sure that ROMMapInsert hasn<73>t changed since the cache was formed.
|
|||
|
;
|
|||
|
|
|||
|
move.l (a0),a0
|
|||
|
move.b ResOneDeep,d1 ; Get one deep setting of current call
|
|||
|
andi.w #kCacheIsOneDeepMask,d1 ; Just keep the low bit
|
|||
|
move.b ROMMapInsert,d2 ; <34> Check ROMness of cache too
|
|||
|
andi.w #kCacheHasROMResourcesMask,d2 ; <34> Just get a bit so we can compare against the cache flags
|
|||
|
or.w d1,d2 ; <34> Merge deepness and ROMness
|
|||
|
or.w d3,d2 ; <35> Merge overrideness in with the other two
|
|||
|
cmp.w (a0)+,d2 ; Does the deepness of the cache match ResOneDeep?
|
|||
|
bne.s @deepnessDoesntMatch ; Yes.
|
|||
|
btst #kCacheIsOneDeepBit,d2 ; <11> <23> Check the deepness of the current call
|
|||
|
bz.s @mapMatches ; <11> If the call is not one deep, go ahead and use the cache
|
|||
|
move.w CurMap,d1 ; <10>
|
|||
|
cmp.w (a0)+,d1 ; <10> One deep from same map?
|
|||
|
beq.s @mapMatches ; <10> Yes
|
|||
|
move.w d1,-2(a0) ; <11> CurMap has changed. Remember the new one for next time
|
|||
|
@deepnessDoesntMatch
|
|||
|
clr.l (a0) ; Nail type to force cache to rebuild
|
|||
|
@mapMatches
|
|||
|
move.l d0,a0 ; Get handle
|
|||
|
_GetHandleSize
|
|||
|
sub.l #kCacheHeaderSize,d0 ; Don<6F>t count header information
|
|||
|
asr.l #3,d0 ; <31> Figure out how many things can fit in the existing handle
|
|||
|
move.l d0,d6 ; Save this count
|
|||
|
move.l a0,a3
|
|||
|
move.l (a3),a0
|
|||
|
move.w d2,(a0)+ ; <34> Save deepness, ROMness, and overrideness in cache flags
|
|||
|
move.w CurMap,(a0)+ ; <11> Save CurMap for one deep calls
|
|||
|
cmp.l (a0),d7 ; Does the cached type match the one requested?
|
|||
|
beq @exitCacheResource ; If so, exit
|
|||
|
move.l d7,(a0)+ ; Use existing handle for cache
|
|||
|
addq #4,a0 ; Point to first entry
|
|||
|
bra.s @buildCache
|
|||
|
|
|||
|
;
|
|||
|
; Allocate a new handle for the resource cache
|
|||
|
;
|
|||
|
|
|||
|
@setupCache
|
|||
|
move.l #(kInitialEntryCount * kCacheEntrySize) + kCacheHeaderSize,d0 ; Space for header and kInitialEntryCount entries. <29>
|
|||
|
_NewHandle ,Sys,Clear ; Get the handle
|
|||
|
bne @exitCacheResource
|
|||
|
move.l a0,a3 ; Remember the handle
|
|||
|
move.l ExpandMem,a0
|
|||
|
move.l a3,ExpandMemRec.emResourceCache(a0) ; Save it in expand mem
|
|||
|
move.l (a3),a0
|
|||
|
move.b ResOneDeep,d0
|
|||
|
andi.w #kCacheIsOneDeepMask,d0
|
|||
|
move.b ROMMapInsert,d1 ; <34> Remember ROMMapInsert in flags
|
|||
|
andi.w #kCacheHasROMResourcesMask,d1 ; <34>
|
|||
|
or.w d1,d0 ; <34> Merge the two attributes
|
|||
|
or.w d3,d0 ; <35> Merge in override setting
|
|||
|
move.w d0,(a0)+ ; Save deepness in cache flags
|
|||
|
move.w CurMap,(a0)+ ; <11> Save CurMap for one deep calls
|
|||
|
move.l d7,(a0)+ ; Save the resource type to cache
|
|||
|
addq #4,a0 ; Point to first index
|
|||
|
moveq #kInitialEntryCount,d6 ; Number of entries left before more room is needed
|
|||
|
|
|||
|
;
|
|||
|
; A0 now points to the address to begin saving resource information, and D6 contains
|
|||
|
; a zero based count of how many cache entries are still available before the handle
|
|||
|
; needs to be grown. A3 contains the cache handle.
|
|||
|
;
|
|||
|
|
|||
|
@buildCache
|
|||
|
moveq #0,d5 ; Count of entries placed in the cache so far
|
|||
|
move.l TopMapHndl,d0 ; Get handle to the first resource map
|
|||
|
beq @exitCacheResource ; Exit if there<72>s no resource map. (Most bad!)
|
|||
|
|
|||
|
@buildLoop
|
|||
|
move.l d0,a4
|
|||
|
move.l (a4),a1 ; Dereference map handle
|
|||
|
add.w mTypes(a1),a1 ; Get to type list
|
|||
|
move.l a1,a2 ; Copy top of block
|
|||
|
move.w (a2)+,d4 ; Get number of types in this map
|
|||
|
bmi.s @cacheNextMap ; If no resources in this map, go on to next map
|
|||
|
|
|||
|
;
|
|||
|
; Find the type in D7 in the resource map.
|
|||
|
;
|
|||
|
|
|||
|
@typeSearch
|
|||
|
cmp.l TType(a2),d7 ; Is this the right type?
|
|||
|
beq.s @foundTypeEntry ; Yes, go on
|
|||
|
addq #TSize,a2 ; Otherwise, check next type
|
|||
|
dbra d4,@typeSearch
|
|||
|
bra.s @cacheNextMap ; If we fall through, no resources of this type in this map
|
|||
|
|
|||
|
;
|
|||
|
; Got the type. Now determine whether or not to cache each one.
|
|||
|
;
|
|||
|
|
|||
|
@foundTypeEntry
|
|||
|
move.w tCount(a2),d4 ; Number of resources of this type
|
|||
|
moveq #0,d2
|
|||
|
move.w tOffset(a2),d2 ; Remember offset for cache
|
|||
|
add.l d2,a1 ; Get to reference list from type list
|
|||
|
move.l a1,a2 ; Keep reference pointer in A2
|
|||
|
move.l ExpandMem,a1 ; <36> If emScanOverrideMaps is false, then treat override maps
|
|||
|
tst.b ExpandMemRec.emScanOverrideMaps(a1) ; <36> as normal resource maps, and always include the overridden resources for counting and indexing
|
|||
|
bz.s @addToCache ; <36>
|
|||
|
move.l (a4),a1 ; Point to the resource map
|
|||
|
btst #dontCountOrIndexDuplicatesBit,mInMemoryAttr(a1) ; Is our magic bit set?
|
|||
|
sne d3 ; Use D3 to flag whether this bit was set
|
|||
|
@addToCacheLoop
|
|||
|
tst.b d3 ; Check to see if this entry is a duplicate?
|
|||
|
beq.s @addToCache ; If not, add the resource blindly
|
|||
|
|
|||
|
;
|
|||
|
; dontCountOrIndexDuplicatesBit is set. Determine whether this entry matches the ID
|
|||
|
; of a previous resource in the cache.
|
|||
|
;
|
|||
|
|
|||
|
bsr IsDuplicate ; See if this ID was already used
|
|||
|
bne.s @dontAddToCache ; If it is, don<6F>t add it to the cache.
|
|||
|
|
|||
|
;
|
|||
|
; Add this resource to the cache. Remember the file reference number of the map it
|
|||
|
; came from, and its ID.
|
|||
|
;
|
|||
|
|
|||
|
@addToCache
|
|||
|
subq #1,d6 ; Adding another entry
|
|||
|
bge.s @doAdd ; If there<72>s still space left in the cache, add the entry
|
|||
|
|
|||
|
;
|
|||
|
; Out of space in the cache. Double it<69>s size.
|
|||
|
;
|
|||
|
|
|||
|
move.l (a3),a1
|
|||
|
sub.l a1,a0 ; Compute current byte offset into cache
|
|||
|
exg a3,a0 ; Get handle
|
|||
|
_GetHandleSize
|
|||
|
sub.l #kCacheHeaderSize,d0 ; Don<6F>t count header info for size calculations
|
|||
|
move.l d0,d6 ; Need to recalc number of available entries in a sec
|
|||
|
asl.l #1,d0 ; Double the size of the cache
|
|||
|
add.l #kCacheHeaderSize,d0 ; And some space for the header
|
|||
|
_SetHandleSize ; Set the new size
|
|||
|
bne.s @exitCacheResource
|
|||
|
asr.l #3,d6 ; <31> Divide by 8 to get count from size
|
|||
|
subq #1,d6 ; One entry will be used up right away.
|
|||
|
move.l (a0),a1 ; Get pointer in case it moved
|
|||
|
add.l a1,a3 ; Add pointer to offset that<61>s saved in A3
|
|||
|
exg a3,a0 ; And swap the handle and the pointer
|
|||
|
@doAdd
|
|||
|
addq #1,d5 ; Increment the count
|
|||
|
move.l a4,(a0)+ ; <31> Remember the map handle
|
|||
|
move.w d2,(a0)+ ; Remember offset to resource
|
|||
|
move.w rID(a2),(a0)+ ; <29> Remember ID of this resource
|
|||
|
@dontAddToCache
|
|||
|
add.w #RESize,a2 ; Point to next entry
|
|||
|
add.w #RESize,d2 ; Update offset to next resource
|
|||
|
dbra d4,@addToCacheLoop
|
|||
|
@cacheNextMap
|
|||
|
move.l (a4),a1
|
|||
|
move.l mNext(a1),d0 ; Go until the end of the resource chain
|
|||
|
bne.s @buildLoop
|
|||
|
|
|||
|
move.l (a3),a0
|
|||
|
move.l d5,kResourceCount(a0) ; Stash the count
|
|||
|
@exitCacheResource
|
|||
|
movem.l (sp)+,d2-d7/a1-a4 ; Restore registers
|
|||
|
rts ; Return
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; IsDuplicate determines whether the resource ID pointed to be A2 is already used
|
|||
|
; by another resource entry in the cache pointed to by A3.
|
|||
|
|
|||
|
IsDuplicate Proc Export
|
|||
|
Import DoesCachedMapOverrideCurrentMap
|
|||
|
|
|||
|
moveq #1,d0 ; Assume it<69>s a duplicate
|
|||
|
move.w rID(a2),d1 ; Keep ID in a register
|
|||
|
movem.l a0/d2,-(sp) ; Save A0 & D2
|
|||
|
move.w d5,d2 ; Make a copy of the current count
|
|||
|
move.l (a3),a0
|
|||
|
add.w #kCacheHeaderSize,a0 ; Point to cached resource info
|
|||
|
bra.s @loopEnd ; Let loop fall through if the cache is empty
|
|||
|
@findDuplicates
|
|||
|
cmp.w kResourceIDEntry(a0),d1 ; Does the ID match?
|
|||
|
bne.s @notDuplicate ; No. Try the next entry
|
|||
|
|
|||
|
; <31> To make the case where a resource is in the System, an application, but not a
|
|||
|
; Gibbly work, check to see if the resource map of the cached entry is an override
|
|||
|
; map for the resource map of the resource we<77>re thinking about putting in the
|
|||
|
; cache. The handle to the second resource map is in A4, and the handle to the
|
|||
|
; first resource map is in the cache. Call the new routine, DoesCachedMapOverrideCurrentMap,
|
|||
|
; to make this determination. We might want to make this a selector off of
|
|||
|
; _ResourceDispatch one day if this type of thing needs to be determined a lot.
|
|||
|
;
|
|||
|
; <47> DoesCachedMapOverrideCurrentMap used to scan the resource chain for duplicates
|
|||
|
; until it finds a map that doesn<73>t have any override attributes set. The theory
|
|||
|
; was that a string of resource maps with override attributes set are associated
|
|||
|
; with each other, like Gibblies and the System, or the System and font files.
|
|||
|
; This test was too generic, and fails in the case where an application has an
|
|||
|
; override map, and the map below the application is a Gibbly or the System.
|
|||
|
; In this case, resources in the System and the application override that have
|
|||
|
; the same type and ID are considered duplicates of each other, which isn<73>t right.
|
|||
|
; Now, just look at the two deep bit on resource maps to determine if one is
|
|||
|
; associated with another.
|
|||
|
;
|
|||
|
|
|||
|
subq #2,sp ; <31>
|
|||
|
move.l a4,-(sp) ; <31> Resource map handle of current resource
|
|||
|
move.l kMapHandleEntry(a0),-(sp) ; <31> Resource map handle of resource in cache
|
|||
|
move.w #kTwoDeepMask,-(sp) ; <45> <47> Scan until a map without the two deep attribute is found
|
|||
|
bsr DoesCachedMapOverrideCurrentMap ; <31> Go find out if this is true
|
|||
|
tst.b (sp)+ ; <31> Check the result
|
|||
|
bnz.s @duplicateID ; <31> The cache entry comes from a resource map which overrides the current resource map, so this resource should be considered a duplicate.
|
|||
|
@notDuplicate
|
|||
|
addq #kCacheEntrySize,a0 ; Otherwise, try next cache entry
|
|||
|
@loopEnd
|
|||
|
dbra d2,@findDuplicates
|
|||
|
@idNotInCache
|
|||
|
moveq #0,d0 ; End of cache, and no duplicates
|
|||
|
@duplicateID
|
|||
|
movem.l (sp)+,a0/d2
|
|||
|
tst.w d0 ; Set up the condition codes
|
|||
|
rts ; And return
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; <31> DoesCachedMapOverrideCurrentMap. Given two resource map handles, this routine
|
|||
|
; determines if one is an override map of the other. This is done by traversing
|
|||
|
; the resource chain from the second resource map until a map is found that does
|
|||
|
; not have the overrideNextMap bit set. If any of the resource maps that are
|
|||
|
; visited during the traversal match the first resource map parameter, this routine
|
|||
|
; returns that the current map is overriden by the cached map.
|
|||
|
;
|
|||
|
; <45> Added a parameter that specifies the bit combination to test in the mInAttr field
|
|||
|
; of the resource map. Doing this allows this routine to be used by CacheResource
|
|||
|
; and RemoveResourceOverride, which require checking different bits.
|
|||
|
;
|
|||
|
|
|||
|
DoesCachedMapOverrideCurrentMap Proc Export
|
|||
|
DoesCachedMapOverrideStackFrame Record {A6Link},Decr
|
|||
|
result ds.w 1 ; Space for result
|
|||
|
paramBegin equ *
|
|||
|
currentMap ds.l 1 ; Handle to current resource map
|
|||
|
cachedMap ds.l 1 ; Handle to resource map in cache
|
|||
|
bitsToTest ds.w 1 ; <45> Bits in mInAttr to test
|
|||
|
paramSize equ paramBegin - *
|
|||
|
retAddr ds.l 1
|
|||
|
A6Link ds.l 1
|
|||
|
EndR
|
|||
|
|
|||
|
With DoesCachedMapOverrideStackFrame
|
|||
|
link a6,#0
|
|||
|
movem.l d1/a0/a1,-(sp) ; <46>
|
|||
|
move.w #-1,result(a6) ; Assume cachedMap does override currentMap
|
|||
|
move.l currentMap(a6),a0
|
|||
|
move.l cachedMap(a6),a1
|
|||
|
move.w bitsToTest(a6),d1 ; <45>
|
|||
|
@compareMap
|
|||
|
cmp.l a0,a1 ; Do the maps match?
|
|||
|
beq.s @gotMatch ; Yes. We<57>ve got an override case
|
|||
|
|
|||
|
; OK, I lied in all the comments up to now. Testing just the overrideNextMap bit isn<73>t enough,
|
|||
|
; because font resources in the Fonts folder would get counted more than once. To get
|
|||
|
; around this, if ANY override bit is set, look at the next map down.
|
|||
|
|
|||
|
move.l (a1),a1
|
|||
|
move.b mInMemoryAttr(a1),d0 ; Get override bits
|
|||
|
and.b d1,d0 ; Mask off everything but the bits of interest
|
|||
|
bz.s @noMatch ; No it<69>s not, and we should stop looking now, too.
|
|||
|
move.l mNext(a1),d0 ; It<49>s an override map. Get the next map, if there is one.
|
|||
|
bz.s @noMatch ; No more maps.
|
|||
|
move.l d0,a1
|
|||
|
bra.s @compareMap
|
|||
|
|
|||
|
; We got to the end of the resource chain or a non-override map without hitting currentMap.
|
|||
|
; Therefore, this resource should not be considered a duplicate of the current cache entry.
|
|||
|
|
|||
|
@noMatch
|
|||
|
clr.w result(a6)
|
|||
|
@gotMatch
|
|||
|
movem.l (sp)+,d1/a0/a1 ; <46> Restore used registers
|
|||
|
unlk a6
|
|||
|
move.l (sp)+,d0 ; I saved A0 for a reason, so I can<61>t use it here<72>
|
|||
|
add.w #paramSize,sp ; Pop off the parameters
|
|||
|
move.l d0,-(sp)
|
|||
|
rts
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; Resource cache patches.
|
|||
|
;
|
|||
|
; These patches flush the resource cache before going on.
|
|||
|
;
|
|||
|
; <8> Added code which preserves the font cache if the resource map does not
|
|||
|
; contain any fonts.
|
|||
|
;
|
|||
|
|
|||
|
RmveResourceFlushCache PatchProc _RmveResource
|
|||
|
Import FlushResourceCache
|
|||
|
|
|||
|
bsr FlushResourceCache
|
|||
|
jmpOld
|
|||
|
EndProc
|
|||
|
|
|||
|
WriteResourceFlushCache PatchProc _WriteResource
|
|||
|
Import FlushResourceCache
|
|||
|
|
|||
|
bsr FlushResourceCache
|
|||
|
jmpOld
|
|||
|
EndProc
|
|||
|
|
|||
|
OpenResFileFlushCache PatchProc _OpenResFile
|
|||
|
Import FlushFontsCallThrough
|
|||
|
|
|||
|
OpenResFileStack Record {A6Link},Decr
|
|||
|
result ds.w 1
|
|||
|
paramBegin equ *
|
|||
|
fileName ds.l 1
|
|||
|
paramSize equ paramBegin - *
|
|||
|
retAddr ds.l 1
|
|||
|
A6Link ds.l 1
|
|||
|
FlushResourceCacheStackFrameCommon
|
|||
|
localSize equ *
|
|||
|
EndR
|
|||
|
|
|||
|
With OpenResFileStack
|
|||
|
link a6,#localSize
|
|||
|
leaOld a0
|
|||
|
moveq #paramSize,d0
|
|||
|
jmp FlushFontsCallThrough
|
|||
|
EndProc
|
|||
|
|
|||
|
OpenRFPermFlushCache PatchProc _OpenRFPerm
|
|||
|
Import FlushFontsCallThrough
|
|||
|
|
|||
|
OpenRFPermStack Record {A6Link},Decr
|
|||
|
result ds.w 1
|
|||
|
paramBegin equ *
|
|||
|
fileNamePtr ds.l 1
|
|||
|
vRefNum ds.w 1
|
|||
|
permission ds.w 1
|
|||
|
paramSize equ paramBegin - *
|
|||
|
retAddr ds.l 1
|
|||
|
A6Link ds.l 1
|
|||
|
FlushResourceCacheStackFrameCommon
|
|||
|
localSize equ *
|
|||
|
EndR
|
|||
|
|
|||
|
With OpenRFPermStack
|
|||
|
link a6,#localSize
|
|||
|
leaOld a0
|
|||
|
moveq #paramSize,d0
|
|||
|
jmp FlushFontsCallThrough
|
|||
|
EndProc
|
|||
|
|
|||
|
HOpenResFileFlushCache PatchProc _HOpenResFile
|
|||
|
Import FlushFontsCallThrough
|
|||
|
|
|||
|
HOpenResFileStack Record {A6Link},Decr
|
|||
|
result ds.w 1
|
|||
|
paramBegin equ *
|
|||
|
vRefNum ds.w 1
|
|||
|
dirID ds.l 1
|
|||
|
fileNamePtr ds.l 1
|
|||
|
permission ds.w 1
|
|||
|
paramSize equ paramBegin - *
|
|||
|
retAddr ds.l 1
|
|||
|
A6Link ds.l 1
|
|||
|
FlushResourceCacheStackFrameCommon
|
|||
|
localSize equ *
|
|||
|
EndR
|
|||
|
|
|||
|
With HOpenResFileStack
|
|||
|
link a6,#localSize
|
|||
|
leaOld a0
|
|||
|
moveq #paramSize,d0
|
|||
|
jmp FlushFontsCallThrough
|
|||
|
EndProc
|
|||
|
|
|||
|
CloseResFileFlushCache PatchProc _CloseResFile
|
|||
|
Import FlushResourceCache
|
|||
|
Import FlushFontsCallThroughCommon
|
|||
|
Import DontFlushFonts
|
|||
|
Import MapHasFonts
|
|||
|
|
|||
|
CloseResFileStack Record {A6Link},Decr
|
|||
|
paramBegin equ *
|
|||
|
refNum ds.w 1
|
|||
|
paramSize equ paramBegin - *
|
|||
|
retAddr ds.l 1
|
|||
|
A6Link ds.l 1
|
|||
|
FlushResourceCacheStackFrameCommon
|
|||
|
localSize equ *
|
|||
|
EndR
|
|||
|
|
|||
|
With CloseResFileStack
|
|||
|
link a6,#localSize
|
|||
|
moveq #paramSize,d0 ; Remember parameter size in D0 for later
|
|||
|
movem.l d0-d2/a1-a2,-(sp)
|
|||
|
|
|||
|
move.l LastSPExtra,oldSPExtra(a6) ; Save SPExtra
|
|||
|
move.l TopMapHndl,oldTopMap(a6) ; Save top map handle
|
|||
|
bsr FlushResourceCache ; Flush the cached resources
|
|||
|
|
|||
|
moveq #0,d2
|
|||
|
subq #2,sp ; <19>
|
|||
|
_CurResFile ; Remember current resource map
|
|||
|
move.w refNum(a6),-(sp)
|
|||
|
_UseResFile ; Look for fonts in the map we<77>re going to close
|
|||
|
subq #2,sp ; <19>
|
|||
|
bsr MapHasFonts ; If the map has fonts,
|
|||
|
tst.w (sp)+ ; then flush the font cache
|
|||
|
bz.s @callCloseResFile
|
|||
|
moveq #1,d2
|
|||
|
@callCloseResFile
|
|||
|
_UseResFile ; Get back the original resource file
|
|||
|
move.w refNum(a6),-(sp)
|
|||
|
jsrOld ; Close the resource file
|
|||
|
move.w ResErr,realResErr(a6) ; Save error from _CloseResFile
|
|||
|
|
|||
|
tst.w d2 ; Were there fonts in this map?
|
|||
|
bnz.s @flushCandidateList ; Yes, flush the candidate lists
|
|||
|
jmp DontFlushFonts ; No.
|
|||
|
@flushCandidateList
|
|||
|
jmp FlushFontsCallThroughCommon ; Rejoin the common code
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; FlushFontsCallThrough <20> Preserve SPExtra around a call to OpenResFile, HOpenResFile,
|
|||
|
; or OpenRFPerm. If a new file was opened, check to see if that file has any
|
|||
|
; font resources. If it does not, restore SPExtra so the font caches don<6F>t get
|
|||
|
; flushed.
|
|||
|
;
|
|||
|
|
|||
|
FlushFontsCallThrough Proc Export
|
|||
|
Export FlushFontsCallThroughCommon
|
|||
|
Export DontFlushFonts
|
|||
|
Import MapHasFonts
|
|||
|
Import FlushResourceCache
|
|||
|
Import CopyParameters ; <24>
|
|||
|
|
|||
|
CallThroughStack Record {A6Link},Decr
|
|||
|
A6Link ds.l 1
|
|||
|
FlushResourceCacheStackFrameCommon
|
|||
|
localSize equ *
|
|||
|
EndR
|
|||
|
|
|||
|
With CallThroughStack
|
|||
|
|
|||
|
movem.l d0-d2/a1-a2,-(sp)
|
|||
|
|
|||
|
move.l LastSPExtra,oldSPExtra(a6) ; Save SPExtra
|
|||
|
move.l TopMapHndl,oldTopMap(a6) ; Save top map handle
|
|||
|
bsr FlushResourceCache ; Flush the cached resources
|
|||
|
|
|||
|
move.l a0,a2 ; Save Resource Manager routine
|
|||
|
move.l a6,a0
|
|||
|
addq #8,a0 ; Don<6F>t copy the return address
|
|||
|
subq #2,sp ; Room for word result
|
|||
|
sub.w d0,sp ; Make room for parameters on the stack
|
|||
|
move.l sp,a1
|
|||
|
bsr CopyParameters ; <24> Copy the parameters
|
|||
|
jsr (a2) ; Call through to the Resource Manager
|
|||
|
move.l 2(sp),d0 ; I<>m relying on movem saving data registers after address registers here<72>
|
|||
|
move.w (sp)+,8(a6,d0.w) ; Pass the result back to the caller
|
|||
|
move.w ResErr,realResErr(a6) ; Save ResErr
|
|||
|
|
|||
|
move.l TopMapHndl,d0
|
|||
|
cmp.l oldTopMap(a6),d0 ; Was this file just opened?
|
|||
|
beq.s DontFlushFonts ; If TopMapHndl hasn<73>t changed, the file was already open
|
|||
|
|
|||
|
subq #2,sp
|
|||
|
bsr MapHasFonts ; If the opened map has fonts,
|
|||
|
tst.w (sp)+ ; then flush the font cache
|
|||
|
bz.s DontFlushFonts
|
|||
|
|
|||
|
;
|
|||
|
; <15> In additional to letting LastSPExtra get nailed, flush the 'FOND' candidate
|
|||
|
; caches too.
|
|||
|
;
|
|||
|
|
|||
|
FlushFontsCallThroughCommon
|
|||
|
move.l ExpandMem,a1
|
|||
|
move.l ExpandMemRec.emSplineKey(a1),a1 ; Get handle to TrueType globals
|
|||
|
move.l (a1),a1 ; Point to it.
|
|||
|
lea splineKeyRec.fondCache(a1),a1 ; Point to candidate cache
|
|||
|
move.l (a1),a0
|
|||
|
_DisposeHandle ; Get rid of this cached entry
|
|||
|
clr.l (a1)+
|
|||
|
move.l (a1),a0 ; Nail the next one too
|
|||
|
_DisposeHandle
|
|||
|
clr.l (a1)
|
|||
|
bra.s Exit
|
|||
|
|
|||
|
DontFlushFonts
|
|||
|
move.l oldSPExtra(a6),LastSPExtra ; Restoring SPExtra prevents the cache flush
|
|||
|
Exit
|
|||
|
move.w realResErr(a6),ResErr ; Restore ResErr
|
|||
|
movem.l (sp)+,d0-d2/a1-a2 ; Restore the registers we used
|
|||
|
unlk a6
|
|||
|
move.l (sp)+,a0 ; Get return address
|
|||
|
add.w d0,sp ; Pop parameters
|
|||
|
move.w ResErr,d0
|
|||
|
jmp (a0) ; Return to caller
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
;
|
|||
|
; MapHasFonts determines if the current resource file has any fonts in it. There are
|
|||
|
; only two types of resource to check for. FONT is one obvious case and the
|
|||
|
; rest of the cases can be caught by checking for any FOND resources.
|
|||
|
;
|
|||
|
|
|||
|
MapHasFonts Proc Export
|
|||
|
MapHasFontsStack Record {A6Link},Decr
|
|||
|
result ds.w 1
|
|||
|
retAddr ds.l 1
|
|||
|
A6Link ds.l 1
|
|||
|
EndR
|
|||
|
|
|||
|
With MapHasFontsStack
|
|||
|
link a6,#0
|
|||
|
movem.l a4/d7,-(sp)
|
|||
|
clr.w result(a6)
|
|||
|
|
|||
|
subq #6,sp
|
|||
|
move.w CurMap,-(sp)
|
|||
|
_GetMap ; Get the resource map
|
|||
|
move.l (sp),a4 ; Rememeber the map handle
|
|||
|
_GetOverrideAttributes ; Get the attribute settings
|
|||
|
move.w (sp)+,d7 ; Remember the attributes
|
|||
|
move.w d7,d0
|
|||
|
bclr #twoDeepBit,d0 ; Make the one deep calls one deep
|
|||
|
move.l a4,-(sp)
|
|||
|
move.w d0,-(sp)
|
|||
|
_SetOverrideAttributes
|
|||
|
|
|||
|
clr.w -(sp) ;setup for Count1Resources
|
|||
|
move.l #'FONT',-(sp) ;check for any FONT resources
|
|||
|
_Count1Resources
|
|||
|
move.w (sp)+,d0 ;non-zero result means it has a font
|
|||
|
bne.s @foundFontsInMap
|
|||
|
|
|||
|
clr.w -(sp) ;setup for Count1Resources
|
|||
|
move.l #'FOND',-(sp) ;check for any FOND resources
|
|||
|
_Count1Resources
|
|||
|
move.w (sp)+,d0 ;non-zero result means it has a font
|
|||
|
|
|||
|
@foundFontsInMap
|
|||
|
move.w d0,result(a6) ; Return count as a result
|
|||
|
move.l a4,-(sp)
|
|||
|
move.w d7,-(sp)
|
|||
|
_SetOverrideAttributes ; Restore the attributes
|
|||
|
|
|||
|
movem.l (sp)+,a4/d7
|
|||
|
unlk a6
|
|||
|
rts
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; FlushResourceCache disposes the resource cache handle to force the cache to
|
|||
|
; be rebuilt next time _CountResources or _GetIndResource is called. The cache
|
|||
|
; will be flushed whenever the offset to a resource stored in the cache may become
|
|||
|
; invalid (when resources are added or removed from the map or when the map is updated or
|
|||
|
; written to disk) and when files are opened or closed which may cause the count to
|
|||
|
; become invalid.
|
|||
|
;
|
|||
|
|
|||
|
FlushResourceCache Proc Export
|
|||
|
movem.l d0/a0,-(sp)
|
|||
|
move.l ExpandMem,a0
|
|||
|
move.l ExpandMemRec.emResourceCache(a0),d0 ; Get resource cache handle
|
|||
|
beq.s @noExpandMem ; Doesn<73>t exist
|
|||
|
clr.l ExpandMemRec.emResourceCache(a0) ; Zero it out
|
|||
|
clr.w ExpandMemRec.emLastMapOverridden(a0) ; And force an override synchronization next time
|
|||
|
move.l d0,a0
|
|||
|
_DisposeHandle ; Get rid of the cache
|
|||
|
@noExpandMem
|
|||
|
movem.l (sp)+,d0/a0
|
|||
|
rts
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; SetUpTwoDeepChain
|
|||
|
;
|
|||
|
; SetUpTwoDeepChain cuts the resource chain at the end of a sequence of resource
|
|||
|
; maps with the twoDeepBit set. TopMapHndl is changed to be the current map.
|
|||
|
; The calling routine must have allocated space in a stack frame to save the
|
|||
|
; current TopMapHndl, and a nextMap field of the resource map that the chain was
|
|||
|
; cut at. On exit, A4 has the resource map handle whose nextMap field was zeroed,
|
|||
|
; and A3 points to this resource map.
|
|||
|
;
|
|||
|
|
|||
|
SetUpTwoDeepChain Proc Export
|
|||
|
TwoDeepStackStub Record {A6Link},Decr
|
|||
|
A6Link ds.l 1
|
|||
|
TwoDeepStackFrameCommon
|
|||
|
EndR
|
|||
|
|
|||
|
With TwoDeepStackStub
|
|||
|
move.l TopMapHndl,realTopMap(a6) ; Save TopMapHndl
|
|||
|
move.l curMapHandle(a6),d0 ; <23> This map was set up by SyncOverrideMap which is called before this routine was entered.
|
|||
|
move.l d0,TopMapHndl ; Start one deep search from this map
|
|||
|
@twoDeepLoop
|
|||
|
move.l d0,a4
|
|||
|
move.l (a4),a3
|
|||
|
btst #twoDeepBit,mInMemoryAttr(a3) ; Is the twoDeepBit set?
|
|||
|
beq.s @endOfTwoDeepChain ; No, bail out
|
|||
|
move.l mNext(a3),d0 ; Go to the next map
|
|||
|
bne.s @twoDeepLoop ; If one exists
|
|||
|
|
|||
|
@endOfTwoDeepChain
|
|||
|
move.l mNext(a3),realNextMap(a6) ; Save the real next map
|
|||
|
clr.l mNext(a3) ; And pretend it<69>s the end of the chain
|
|||
|
rts
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; StandardxCallThrough
|
|||
|
;
|
|||
|
; To share as much code as possible, StandardxCallThrough sets up the
|
|||
|
; parameters and calls through to the real Resource Manager routine. There are
|
|||
|
; three flavours of this routine, StandardxProcedureCallThrough, which
|
|||
|
; does not return any parameters to the caller, StandardxWordFunctionCallThrough
|
|||
|
; which returns a word to the caller, and StandardxLongFunctionCallThrough
|
|||
|
; which returns a longword to the caller. All of these routines expect a stack frame
|
|||
|
; to be set up; they fetch the parameters as offsets off of A6.
|
|||
|
;
|
|||
|
; |<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|
|
|||
|
; | parameters |
|
|||
|
; |<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|
|
|||
|
; | retAddr |
|
|||
|
; |<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|
|
|||
|
; | A6 |
|
|||
|
; |<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|
|
|||
|
; | .......... |
|
|||
|
; |<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|
|
|||
|
; | parameters | <- Copied by call StandardxCallThrough from above
|
|||
|
; |<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|
|
|||
|
;
|
|||
|
; On entry:
|
|||
|
; D0 - number of bytes of parameters to copy
|
|||
|
; A0 - address of Resource Manager routine to call through to
|
|||
|
;
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; <24> CopyParameters - Our own little BlockMove.
|
|||
|
;
|
|||
|
; An extra little perk we can use is that we<77>re always copying an even number
|
|||
|
; of bytes, so we can do word copies instead of byte copies.
|
|||
|
;
|
|||
|
; Parameters
|
|||
|
; A0 - Source
|
|||
|
; A1 - Destination
|
|||
|
; D0 - Number of bytes to copy.
|
|||
|
;
|
|||
|
|
|||
|
CopyParameters Proc Export
|
|||
|
asr.l #1,d0 ; Divide by 2 for number of words
|
|||
|
subq #1,d0 ; Zero base to loop.
|
|||
|
@copyLoopTop
|
|||
|
move.w (a0)+,(a1)+ ; Copy a word
|
|||
|
dbra d0,@copyLoopTop ; Loop through all the parameters
|
|||
|
rts
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; StandardOverrideProcedureCallThrough
|
|||
|
;
|
|||
|
|
|||
|
StandardOverrideProcedureCallThrough Proc Export
|
|||
|
Import StandardCallThroughExit
|
|||
|
Import SyncTopOverrideMap
|
|||
|
Import CopyParameters ; <24>
|
|||
|
|
|||
|
movem.l d0/a1-a2,-(sp)
|
|||
|
bsr SyncTopOverrideMap ; Set up the override maps
|
|||
|
|
|||
|
move.l a0,a2 ; Save Resource Manager routine
|
|||
|
move.l a6,a0
|
|||
|
addq #8,a0 ; Don<6F>t copy the return address
|
|||
|
sub.w d0,sp ; Make room for parameters on the stack
|
|||
|
move.l sp,a1
|
|||
|
bsr CopyParameters ; <24> Copy the parameters
|
|||
|
jsr (a2) ; Call through to the Resource Manager
|
|||
|
movem.l (sp)+,d0/a1-a2 ; Restore the registers we used
|
|||
|
jmp StandardCallThroughExit ; And call the standard exit routine
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; StandardOverrideLongFunctionCallThrough
|
|||
|
;
|
|||
|
|
|||
|
StandardOverrideLongFunctionCallThrough Proc Export
|
|||
|
Import StandardCallThroughExit
|
|||
|
Import SyncTopOverrideMap
|
|||
|
Import CopyParameters ; <24>
|
|||
|
|
|||
|
movem.l d0/a1-a2,-(sp)
|
|||
|
bsr SyncTopOverrideMap ; Set up the override maps
|
|||
|
|
|||
|
move.l a0,a2 ; Save Resource Manager routine
|
|||
|
move.l a6,a0
|
|||
|
addq #8,a0 ; Don<6F>t copy the return address
|
|||
|
subq #4,sp ; Room for long result
|
|||
|
sub.w d0,sp ; Make room for parameters on the stack
|
|||
|
move.l sp,a1
|
|||
|
bsr CopyParameters ; <24> Copy the parameters
|
|||
|
jsr (a2) ; Call through to the Resource Manager
|
|||
|
move.l 4(sp),d0 ; I<>m relying on movem saving data registers after address registers here<72>
|
|||
|
move.l (sp)+,8(a6,d0.w) ; Pass the result back to the caller
|
|||
|
movem.l (sp)+,d0/a1-a2 ; Restore the registers we used
|
|||
|
jmp StandardCallThroughExit ; And call the standard exit routine
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; StandardTwoDeepLongFunctionCallThrough
|
|||
|
;
|
|||
|
|
|||
|
StandardTwoDeepLongFunctionCallThrough Proc Export
|
|||
|
TwoDeepCallThroughStack Record {A6Link},Decr ; <23>
|
|||
|
A6Link ds.l 1 ; <23>
|
|||
|
OverrideStackFrameCommon
|
|||
|
EndR ; <23>
|
|||
|
|
|||
|
Import SyncTopOverrideMap ; <23>
|
|||
|
Import StandardCallThroughExit
|
|||
|
Import CopyParameters ; <24>
|
|||
|
|
|||
|
With TwoDeepCallThroughStack ; <23>
|
|||
|
movem.l d0-d1/a1-a4,-(sp)
|
|||
|
bsr SyncTopOverrideMap ; <23> Set up the override map
|
|||
|
move.l curMapHandle(a6),d1 ; <30>
|
|||
|
bz.s @noSuchResource ; <30> If no resource map handle for CurMap, bail out.
|
|||
|
move.l d1,a4 ; <30> Remember the map handle we<77>re searching
|
|||
|
move.l a0,a2 ; Save Resource Manager routine
|
|||
|
@twoDeepLoop
|
|||
|
move.l a6,a0
|
|||
|
addq #8,a0 ; Don<6F>t copy the return address
|
|||
|
subq #4,sp ; Room for long result
|
|||
|
sub.w d0,sp ; Make room for parameters on the stack
|
|||
|
move.l sp,a1
|
|||
|
bsr CopyParameters ; <24> Copy the parameters
|
|||
|
jsr (a2) ; Call through to the Resource Manager
|
|||
|
move.l 4(sp),d0 ; I<>m relying on movem saving data registers after address registers here<72>
|
|||
|
move.l (sp)+,d1 ; Got the resource?
|
|||
|
move.l d1,8(a6,d0.w) ; Pass the result back to the caller
|
|||
|
bne.s @gotResource ; If so, exit.
|
|||
|
|
|||
|
;
|
|||
|
; The requested resource wasn<73>t found in this map. Check if the twoDeepBit is set on this
|
|||
|
; map, and if it is, search the next map down.
|
|||
|
;
|
|||
|
|
|||
|
@didntGetResource
|
|||
|
move.l (a4),a3 ; Otherwise, try the next map, but only if this map has twoDeep set.
|
|||
|
btst #twoDeepBit,mInMemoryAttr(a3) ; Is the twoDeepBit set?
|
|||
|
beq.s @noSuchResource ; No, bail out
|
|||
|
move.l mNext(a3),d1 ; Go to the next map
|
|||
|
bz.s @noSuchResource ; <23> Exit if there are no more maps
|
|||
|
move.l d1,a4 ; <23> Start search from this map
|
|||
|
move.l (a4),a3 ; <23>
|
|||
|
move.w mRefNum(a3),CurMap ; <23> Set up CurMap for next resource manager call.
|
|||
|
st ResOneDeep ; <31> Search one map at a time
|
|||
|
bra.s @twoDeepLoop
|
|||
|
|
|||
|
@noSuchResource ; <31> Sigh. GetResource and Get1Resource aren<65>t allowed to return resFNotFound because our skanky developers don<6F>t expect it.
|
|||
|
@gotResource
|
|||
|
movem.l (sp)+,d0-d1/a1-a4 ; Restore the registers we used
|
|||
|
jmp StandardCallThroughExit ; And call the standard exit routine
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; StandardCallThroughExit
|
|||
|
;
|
|||
|
|
|||
|
StandardCallThroughExit Proc Export
|
|||
|
Entry ExitWithoutRestoringMap
|
|||
|
Entry ExitNoRestoreNoUnlink
|
|||
|
|
|||
|
StdExitStack Record {A6Link},Decr ; This stack frame is here to make
|
|||
|
A6Link ds.l 1 ; sure that Dean doesn<73>t get his
|
|||
|
OverrideStackFrameCommon
|
|||
|
EndR
|
|||
|
|
|||
|
With StdExitStack
|
|||
|
move.l realCurMap(a6),CurMap ; Restore real CurMap
|
|||
|
move.l realSysMapHndl(a6),a0
|
|||
|
move.l a0,SysMapHndl ; Restore SysMapHndl
|
|||
|
move.l (a0),a0
|
|||
|
move.w mRefNum(a0),SysMap ; Restore SysMap from the resource map
|
|||
|
|
|||
|
ExitWithoutRestoringMap
|
|||
|
unlk a6
|
|||
|
ExitNoRestoreNoUnlink ; This guy is here just for _RsrcZoneInit
|
|||
|
move.l (sp)+,a0 ; Get return address
|
|||
|
add.l d0,sp ; Pop parameters
|
|||
|
move.l a0,-(sp) ; Push return address back
|
|||
|
moveq #0,a0 ; This is some compatibility hack from the Resource Manager
|
|||
|
move.w ResErr,d0 ; Keep ResErr in D0 for compatibility
|
|||
|
rts
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; ExitForPatchedOutRoutines is the standard exit point for patches in this file
|
|||
|
; which never call the old Resource Manager routine. The Resource Manager does
|
|||
|
; some cleaning up in its exit code which needs to be done for compatibility.
|
|||
|
;
|
|||
|
|
|||
|
ExitForPatchedOutRoutines Proc Export
|
|||
|
Entry ExitPatchedOutRoutineWithoutRestoringMap
|
|||
|
|
|||
|
PatchedOutExitStack Record {A6Link},Decr ; This stack frame is here to make
|
|||
|
A6Link ds.l 1 ; sure that Dean doesn<73>t get his
|
|||
|
OverrideStackFrameCommon
|
|||
|
EndR
|
|||
|
|
|||
|
With PatchedOutExitStack
|
|||
|
move.l realCurMap(a6),CurMap ; Restore real CurMap
|
|||
|
move.l realSysMapHndl(a6),a0
|
|||
|
move.l a0,SysMapHndl ; Restore SysMapHndl
|
|||
|
move.l (a0),a0
|
|||
|
move.w mRefNum(a0),SysMap ; Restore SysMap from the resource map
|
|||
|
|
|||
|
ExitPatchedOutRoutineWithoutRestoringMap
|
|||
|
clr.b ResOneDeep ; always stop one deep calls <09jul85> BBM
|
|||
|
clr.w RomMapInsert ; always disable rom map next time <09jul85> BBM
|
|||
|
clr.b RMGRPerm ; always clear to use default next time <30oct85> BBM
|
|||
|
|
|||
|
unlk a6
|
|||
|
move.l (sp)+,a0 ; Get return address
|
|||
|
add.l d0,sp ; Pop parameters
|
|||
|
move.l a0,-(sp) ; Push return address back
|
|||
|
moveq #0,a0 ; This is some compatibility hack from the Resource Manager
|
|||
|
move.w ResErr,d0 ; Get ResErr in D0
|
|||
|
beq.s @noErr ; If equal, just return, otherwise
|
|||
|
move.l ResErrProc,-(sp) ; push error proc
|
|||
|
bne.s @noErr ; if exists, return, else,
|
|||
|
addq #4,sp ; pop off error proc address
|
|||
|
@noErr
|
|||
|
rts
|
|||
|
EndProc
|
|||
|
|
|||
|
;_______________________________________________________________________________
|
|||
|
; SyncTopOverrideMap
|
|||
|
;
|
|||
|
; SyncTopOverrideMap is a utility routine which makes sure that the override maps
|
|||
|
; are set up properly for the current resource map, then makes the top override map of
|
|||
|
; the current resource map the current resource map for subsequent Resource Manager calls.
|
|||
|
; SyncTopOverrideMap assumes that the caller has a stack frame and a location to save
|
|||
|
; the real current resource map in that stack frame.
|
|||
|
;
|
|||
|
|
|||
|
SyncTopOverrideMap Proc Export
|
|||
|
OverrideStack Record {A6Link},Decr ; This stack frame is here to make
|
|||
|
A6Link ds.l 1 ; sure that Dean doesn<73>t get his
|
|||
|
OverrideStackFrameCommon
|
|||
|
EndR
|
|||
|
|
|||
|
With OverrideStack
|
|||
|
movem.l a0/a1/a4/d0-d2,-(sp) ; Save all registers that are used (D1 sucked up by the Dispatcher)
|
|||
|
move.w CurMap,realCurMap(a6) ; Save a copy of real CurMap
|
|||
|
move.l SysMapHndl,realSysMapHndl(a6) ; Save the real system map
|
|||
|
|
|||
|
subq #4,sp ; <23>
|
|||
|
move.w CurMap,-(sp) ; <23>
|
|||
|
_GetMap ; <23> Get the current resource map handle
|
|||
|
move.l (sp)+,a4 ; <23>
|
|||
|
|
|||
|
move.l ExpandMem,a1 ; Get pointer to expandmem
|
|||
|
tst.b ExpandMemRec.emScanOverrideMaps(a1) ; See if override maps should be scanned
|
|||
|
bz.s @noOverrideMap ; It<49>s false, don<6F>t set up the override map
|
|||
|
|
|||
|
move.w ExpandMemRec.emLastMapOverridden(a1),d0 ; Get the last resource map that had to be synchronized to
|
|||
|
bz.s @synchronizeMap ; If emLastMapOverriden is 0, the maps have never been synchronized, so go do it.
|
|||
|
cmp.w CurMap,d0 ; If this map is the same as the last map read from, everything is already set up
|
|||
|
beq.s @mapsSychronized ; so skip all this work
|
|||
|
@synchronizeMap
|
|||
|
subq #4,sp ;
|
|||
|
move.l a4,-(sp) ; <23> Find override map for current resource map
|
|||
|
_GetOverrideMap ; Get an override map for it
|
|||
|
move.l (sp)+,d0 ; Get override map (it may be the map itself)
|
|||
|
bz.s @checkROMMapInsert ; Assume no override map if this map wasn<73>t found
|
|||
|
@mapInChain
|
|||
|
cmp.l a4,d0 ; <9> <23> Check override map against original
|
|||
|
beq.s @checkROMMapInsert ; <9> If they<65>re the same, there<72>s no override map
|
|||
|
|
|||
|
; We<57>ve got an override map for the current resource map. Set the override map to be the
|
|||
|
; current map for the duration of this Resource Manager call.
|
|||
|
|
|||
|
move.l d0,a0
|
|||
|
move.l (a0),a0
|
|||
|
move.w mRefNum(a0),d0 ; Get reference number of override map
|
|||
|
move.w CurMap,ExpandMemRec.emLastMapOverridden(a1) ; <9> Remember this map as the last map that we had to override.
|
|||
|
move.w d0,CurMap ; Make the Resource Manager start with an override map
|
|||
|
move.w d0,ExpandMemRec.emOverrideMapRefNum(a1) ; And save it for next time.
|
|||
|
bra.s @refreshCurMapHandle ; <23> Get the resource map handle for the override map
|
|||
|
|
|||
|
@mapsSychronized
|
|||
|
move.w ExpandMemRec.emOverrideMapRefNum(a1),CurMap ; Make the override map the current resource map
|
|||
|
@refreshCurMapHandle ; <23>
|
|||
|
subq #4,sp ; <23> An override map is now the current resource map.
|
|||
|
move.w CurMap,-(sp) ; <23> The resource map handle in A4 is no longer valid
|
|||
|
_GetMap ; <23> so call _GetMap again to get the map handle for
|
|||
|
move.l (sp)+,a4 ; <23> the override map.
|
|||
|
|
|||
|
;
|
|||
|
; Why is Brian so cynical? Because the Resource Manager sucks. SwapROMMap slams
|
|||
|
; SysMapHndl into mNext(RomMapHndl), which effectively takes override maps out of the
|
|||
|
; resource chain. To get around this (and because StdExit and StdEntry aren<65>t
|
|||
|
; vectorized on all of our existing ROMs,) put the map of the top system override map
|
|||
|
; into SysMapHndl for the duration of the call.
|
|||
|
;
|
|||
|
|
|||
|
@checkROMMapInsert
|
|||
|
tst.b ROMMapInsert ; Using the ROM map?
|
|||
|
bz.s @noOverrideMap ; No, we don<6F>t need to mess with SysMapHndl then, so go home.
|
|||
|
subq #4,sp
|
|||
|
move.l SysMapHndl,-(sp)
|
|||
|
_GetOverrideMap ; Otherwise, find the system override map
|
|||
|
move.l (sp)+,a0
|
|||
|
move.l a0,SysMapHndl ; Use the system override map as SysMapHndl
|
|||
|
move.l (a0),a0
|
|||
|
move.w mRefNum(a0),d0 ; <38> Get reference number of Gibbly into a register
|
|||
|
move.w CurMap,d1 ; <38> @#$@# 68000 won<6F>t let me compare to memory addresses
|
|||
|
cmp.w SysMap,d1 ; <38> Is the system file the current resource map?
|
|||
|
bne.s @systemFileNotCurrentMap ; <38> No. Leave CurMap alone
|
|||
|
move.w d0,CurMap ; <38> If the system file is the current resource map, the Gibbly needs to be the current resource map
|
|||
|
@systemFileNotCurrentMap
|
|||
|
move.w d0,SysMap ; <38> Make the Gibbly the system file too.
|
|||
|
@noOverrideMap
|
|||
|
move.l a4,curMapHandle(a6) ; Save the resource map handle for later use
|
|||
|
movem.l (sp)+,a0/a1/a4/d0-d2
|
|||
|
tst.l curMapHandle(a6) ; <50> Make sure we actually have a current resource map handle. The two deep patches use this condition code to bail early if the resource map for the current resource file could not be found.
|
|||
|
rts
|
|||
|
EndProc
|
|||
|
End
|