sys7.1-doc-wip/Toolbox/ResourceMgr/ResourceMgrPatches.a
2020-04-26 16:46:44 +08:00

813 lines
38 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

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

;
; Hacks to match MacOS (most recent first):
;
; <Sys7.1> 8/3/92 Reverted <SM8>: moved patches back to ResourceMgrExtensions.a
; 9/2/94 SuperMario ROM source dump (header preserved below)
;
;
; File: ResourceMgrPatches.a
;
; Contains: Fixes to the resource manager, including:
;
; x rom heap down sizing on fx/ci ———> moved to Rovr.a so 6.0 could avoid switch-launch problems
; unique id returning a better value
; getresource return an error
; SetResFileAttrs and mapReadOnly
; Clear result on failure in Get[1]IndexedResource
;
; and much, much, more
;
; Written by: Brian McGhie & Scott Boyd
;
; Copyright: © 1990-1992 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <SM8> 7/27/92 FM Move the DirID aware patches from ResourceMgrExtensions to here
; because they are implemented in ResourceMgr.a which wants to use
; ResourceMgrExtensions.a in the ROMBuild.
; <6+> 6/13/92 CS Rollin Reality changes:
; <24> 6/12/92 DTY #1032324: Add a patch to RGetResource to start searching from
; TopMapHndl. This patch is necessary because if MakeITable is
; called from inside FMSwapFont like it can be, chances are, the
; current resource map will be pointing at a font map below the
; system map, and the call to get the 'mitq' resource out of the
; system file will fail.
; <23> 5/27/92 DTY #1008888: Of course, SuitCases code has changed between
; versions. Change the code that checks for SuitCases patch to
; RsrcZoneInit to calculate a checksum of the first 8 words of
; this patch, so we can compare against different checksums for
; different versions.
; <SM5> 4/23/92 CS Apply changes from Reality <21> - <22>:
; <22> 3/30/92 DTY #1025140,<FM>: Remove GetIndexed patches. The functionality of
; these patches have been rolled into the override patches for
; these routines.
; <21> 3/16/92 DTY #1024511: Move ROZ cutback code back here from ROvr.a.
; <4> 3/11/92 stb remove forROM code. Patches.a files should never be ROMified.
; roll changed-FOND flushing code into ResourceMgr.a.
; added comments about which routines were rolled into ResourceMgr.a.
; Note that Plus patches do not need to go into ResourceMgr.a.
; <3> 3/4/92 PN Fix MyuniqueID to do ROM build
; <2> 2/13/92 PN Add conditionals for rom build. DontLetSuitcasePatchRsrcZoneInit
; needs to be rolled in. • Pre-SuperMario comments follow •
; <20> 2/3/92 DTY #1021208: Compatiblity hack for Suitcase II. The patch to
; _RsrcZoneInit in ResourceOverridePatches.a winds up in an
; infinite loop because SuitCases patch to _RsrcZoneInit makes a
; circular resource chain. Since our patch does the same thing
; that SuitCases wants to do, patch _SetTrapAddress to watch
; patches to _RsrcZoneInit. If the patch code is Suitcases patch
; code, dont install the patch. An imbedded semaphore is
; necessary so that once Suitcase has tried to apply the patch, we
; dont have to prevent any other patches.
; <19> 1/3/92 DTY Make sure the handle isnt nil in CheckCandidate.
; <18> 12/19/91 DTY #1018500: Do the same thing for _AddResource and _RmveResource.
; (This avoids any changes to the Finder on Mover invocations.)
; <17> 12/18/91 DTY Oops. My finger slipped on that last checkin. That was a bug fix
; for Radar bug number #1018500: Patch _ChangedResource to
; invalidate the 'FOND' candidate list if a 'FOND' resource in the
; candidate cache is being changed.
; <16> 12/18/91 DTY \
; <15> 12/12/91 DTY Take out the last fix. The Component Manager is being changed to
; take care of this.
; <14> 12/12/91 DTY QuickTime expects _HomeResFile to return the real file reference
; number for a resource. _HomeResFile returns 0 for system
; resources. Add a tail patch to _HomeResFile to return SysMap
; instead of 0.
; <13> 2/13/91 JSM dba,#JSM-213: Add come-from patch on _SetHandleSize inside
; ResizeMap when called from RmveName to handle resource maps with
; shared name list entries more robustly.
; <12> 1/17/91 dba (bbm & stb) fix AddResource with NIL string.
; <11> 12/14/90 bbm (djw) roll in linked comefrompatch from patchplusrom.a into
; resourcemgrpatches.a.
; <10> 12/11/90 bbm (JSM) moved the superpatch fix to ResourceMgrPatches.a, as this
; comefrom patch is now a linked patch.
; <9> 12/4/90 gbm <stb> Make a REALLY simple patch to LoadResource to always call
; StripAddress on the handle, to strip away variation codes on
; defproc handles
; <8> 11/28/90 JSM <bbm> Move come-from patches on _NewHandle and _DisposeHandle
; inside UpdateResFile here from PatchPlusROM.a.
; <7> 9/11/90 csd Rewrote the patch to Unique1ID so that it doesnt eat stack if
; it has to try more than once for a legal ID.
; <6> 8/15/90 stb Fix my typo on UniqueID
; <4> 7/30/90 stb conditionalize out some fixes for 6.0.x
; <4> 7/30/90 stb move heap down-sizing to Rovr.a
; <3> 7/12/90 stb test, debug
; <1> 7/9/90 stb first checked in
;
; To Do:
; Return ResNotFound in GetResource once GetResource come-from patches are lpchs
; ? getindexedresource in numerical order
; ? Turn AddResource into a ReplaceResource
; SetResFileAttrs and mapReadOnly; teach to actually set the bit on disk
;
load 'StandardEqu.d'
include 'fontPrivate.a'
include 'ResourceMgrPriv.a'
include 'LinkedPatchMacros.a'
AfterCreateInCreateResFile ROMBind (Plus,$137BC),(SE,$0DDB8),(II,$126F4),(Portable,$13D52),(IIci,$1AF6A)
AfterOpenRFInORFCommon ROMBind (Plus,$1379C),(SE,$0DD98),(II,$126D4),(Portable,$13D32),(IIci,$1Af4A)
AfterStdZEntryInCreateResFile ROMBind (Plus,$137AA),(SE,$0DDA6),(II,$126E2),(IIci,$1AF58),(Portable,$13D40)
ROMOpenRFPerm ROMBind (Plus,$1381A),(SE,$0DE1C),(II,$12758),(IIci,$1AFCE),(Portable,$13DB6)
StdZEntry ROMBind (Plus,$13F4E),(SE,$0E558),(II,$12E90),(IIci,$1B700),(Portable,$144E8)
Std1Entry ROMBind (Plus,$13F52),(SE,$0E55C),(II,$12E94),(IIci,$1B704),(Portable,$144EC)
RStdExit ROMBind (Plus,$1400C),(SE,$0E616),(II,$12F4E),(IIci,$1B7C4),(Portable,$145A6)
;————————————————————————————————————————————————————————————————————————————————————————————————————
; <20> Dont let Suitcases patch to _RsrcZoneInit happen.
; !!!!!!! NEVER ROLL THIS INTO ROM !!!!!!!!
kRsrcZoneInitTrapWord equ $A996 ; Suitcase patches by the trap word, not by the number.
DontLetSuitcasePatchRsrcZoneInit PatchProc _SetTrapAddress,(Plus,SE,II,Portable,IIci)
move.w PatchState,-(sp)
tst.w (sp)+ ; Has this patch already fired?
bneOld ; Yes. Let it go through.
cmpi.w #kRsrcZoneInitTrapWord,d0 ; Patching _RsrcZoneInit? (Suitcase uses the full trapword, so this might filter out other patches.)
bneOld ; No. Let it go.
movem.l d0-d1/a0-a2,-(sp) ; Save the registers were using
; Calculate a checksum of the first 8 words of this patch routine so we can make sure its
; one of several versions of SuitCase.
moveq #0,d0 ; <23>
moveq #7,d1 ; <23> Loop for 8 words
move.l a0,a2 ; <23> Use a copy of the patch routine pointer
@formChecksum
add.w (a2)+,d0 ; <23> Add a word to the checksum
dbra d1,@formChecksum ; <23>
; Compare this checksum against a list of checksums for versions we know about.
; (Or rather, versions that Dean bothered to checksum.)
lea SuitcaseChecksums,a1 ; <23> A list of checksums for different versions of SuitCase
@codeMatchLoop
move.w (a1)+,d1 ; <23> Get a checksum
bz.s @notSuitcaseCode ; <23> If were out of checksums, its not SuitCase. (At least, not one we know about)
cmp.w d1,d0 ; <23> Does this checksum match the calculated one?
bne.s @codeMatchLoop ; <23> If it doesnt, try another checksum.
; This is Suitcases code. Return instead of patching _RsrcZoneInit
lea PatchState,a0
move.w #1,(a0) ; Dont fire this patch any more
movem.l (sp)+,d0-d1/a0-a2
rts
; This wasnt Suitcases code. Apply this patch to _RsrcZoneInit
@notSuitcaseCode
movem.l (sp)+,d0-d1/a0-a2
jmpOld
PatchState
dc.w 0
SuitcaseChecksums ; SuitCase II version number:
dc.w $5A77 ; 1.2.10
dc.w $5AF9 ; 1.2.11
dc.w $5B87 ; 1.2.12
dc.w 0 ;
EndProc
;————————————————————————————————————————————————————————————————————————————————————————————————————
; <16> Flush 'FOND' candidate lists if calling _ChangedResource on a 'FOND'.
; <18> Do the same on _AddResource and _RmveResource as well.
;
; rolled in to ResourceMgr.a 3/19/92 stb
CheckForChangedFOND PatchProc _ChangedResource,(Plus,SE,II,Portable,IIci)
Import FlushChangedFONDs
move.l 4(sp),-(sp)
clr.l -(sp)
clr.w -(sp)
bsr FlushChangedFONDs
jmpOld
EndProc
CheckForAddedFOND PatchProc _AddResource,(Plus,SE,II,Portable,IIci)
Import FlushChangedFONDs
move.l 14(sp),-(sp) ; Resource handle
move.l 14(sp),-(sp) ; Resource type
move.w 16(sp),-(sp) ; Resource ID
bsr FlushChangedFONDs
jmpOld
EndProc
CheckForRemovedFOND PatchProc _RmveResource,(Plus,SE,II,Portable,IIci)
Import FlushChangedFONDs
move.l 4(sp),-(sp)
clr.l -(sp)
clr.w -(sp)
bsr FlushChangedFONDs
jmpOld
EndProc
FlushChangedFONDs Proc Export
StackFrame Record {A6Link},Decr
paramBegin equ *
resHandle ds.l 1
addResType ds.l 1 ; <18> Type for _AddResource
addResID ds.w 1 ; <18> ID for _AddResource
paramSize equ paramBegin - *
retAddr ds.l 1
A6Link ds.l 1
resID ds.w 1
resType ds.l 1
resName ds.b 256
localSize equ *
EndR
With StackFrame
link a6,#localSize
move.l d1,-(sp)
;
; Check to see if were being called from CheckForAddedFOND.
;
tst.l addResType(a6) ; <18>
bz.s @notAddResourcePatch ; <18>
move.l addResType(a6),resType(a6) ; <18>
move.w addResID(a6),resID(a6) ; <18>
bra.s @isItAFOND ; <18>
;
; Get information about the resource that was changed.
;
@notAddResourcePatch
move.l resHandle(a6),-(sp)
pea resID(a6)
pea resType(a6)
pea resName(a6)
_GetResInfo
; See if its a 'FOND' resource.
@isItAFOND
cmp.l #'FOND',resType(a6)
bne.s @notFONDResource ; Its not a FOND
;
; Its a 'FOND'. If the candidate lists have this 'FOND' cached,
; invalidate it.
;
move.l ExpandMem,a0
move.l ExpandMemRec.emSplineKey(a0),a0 ; Get handle to TrueType globals
move.l (a0),a0 ; Point to it.
lea splineKeyRec.fondCache(a0),a0 ; Point to candidate cache
move.l (a0),-(sp)
bsr CheckCandidate ; See if this candidate matches the 'FOND' ID that has changed
tst.w d1 ; Font family number was left in D0 if handle was not disposed
bne.s @notFlushed
clr.l (a0)+ ; Clear out candidate entry
@notFlushed
move.l (a0),-(sp) ; <22> Check the next one, too
bsr CheckCandidate
tst.w d1 ; Font family number was left in D0 if handle was not disposed
bne.s @notFONDResource
clr.l (a0) ; <22>
@notFONDResource
move.l (sp)+,d1
unlk a6
move.l (sp)+,a0
add.w #paramSize,sp
jmp (a0)
;
; Compare the ID of the cached FOND information. If the ID matches the resource that changed,
; invalidate the candidate entry.
;
CheckCandidate
movem.l a0/a1,-(sp)
move.l 12(sp),d0 ; Get the handle
bz.s @notSameFamily ; <19> Bail out if handle is NIL
move.l d0,a0
move.l (a0),d0 ; Get the pointer
bz.s @notSameFamily ; <19> Bail again if needed
move.l d0,a1
moveq #-1,d1 ; Assume handle is not disposed
move.w (a1),d0 ; Fetch the font family number
cmp.w resID(a6),d0 ; Compare it against the resource ID of the changed 'FOND'
bne.s @notSameFamily ; Dont invalidate if not the right ID
_DisposeHandle ; If ID matches, dispose the handle
moveq #0,d1 ; Mark as handle was disposed
@notSameFamily
movem.l (sp)+,a0/a1
move.l (sp)+,(sp)
rts
EndProc
;————————————————————————————————————————————————————————————————————————————————————————————————————
;
; ROM heap (Read-Only Zone aka ROZ) down-sizing on fx/ci
;
; For every resource in the rom that has no name, the resource manager assumes
; a length of 255 (-1 treated as unsigned). This is designed to cut the size of
; the ROZ back by the over-allocated amount. The ROZ is always a 32-bit addressed zone.
;
; Definition:
; trailer block: that invisible block at the end of heap zone which the zone header.bkLim
; points to.
;
; Steps:
; find the ROZ map
; find the ROZ
; size-down the resource map handle to match the map size value (which is correct)
; copy the trailer block to the new physical end of the resource map
; This effectively blows away any blocks between the map and the trailer
; While there shouldn't be any there, there is a free block which will be smashed
; change bkLim to point to the new trailer
; set the zone block size down to (bkLim+trailerPhysicalSize)-zoneStart
;
;
; format of a 32-bit block header
blkHeaderSize EQU 12
hdrPhysicalSize EQU 4
;————————————————————————————————————————————————————————————————————————————————————————————————————
ROZSizeCorrection InstallProc (IIci)
move.l RomMapHndl,a4 ; save handle to rom map
move.l a4,a0 ; find ROM Zone
_HandleZone
move.l a0,a3 ; save for later in a3
move.l (a4),a0 ; point at map and dereference handle
move.l MapSize(a0),d4 ; get current size and save it in d4
; this fails with -99 if the zone is marked read only
bclr #ROZ,flags(a3) ; make it not a read-only zone
move.l d4,d0 ; cut back map to actual size
move.l a4,a0
_SetHandleSize ; sizing down, so it should not fail
bset #ROZ,flags(a3) ; make it read-only again
; move trailer block to the position right after map to close the gap that
; was left after sizing the handle back down to the correct size.
move.l (a4),a1 ; get start of map
sub #blkHeaderSize,a1 ; point at block header for block containing map
add.l hdrPhysicalSize(a1),a1 ; point at end of map (start plus size)
move.l bkLim(a3),a0 ; source is the trailer block
move.l hdrPhysicalSize(a0),d0 ; move the physical block size number of bytes (is normally #$10)
_BlockMove
move.l a1,bkLim(a3) ; fix zone header.bkLim to point to new last block
clr.l zcbFree(a3) ; No free bytes left in this zone.
; cut back the heap zone block
move.l a1,d0 ; figure new zone size
add.l hdrPhysicalSize(a1),d0 ; move the physical block size number of bytes (is normally #$10)
sub.l a3,d0 ; new size = header.bkLim + trailerPhysicalSize - zoneStart
move.l a3,a0
_SetPtrSize ; chop, chop
; dont check for error, as we couldnt handle it anyway.
rts
EndProc
;————————————————————————————————————————————————————————————————————————————————————————————————————
; <24> Make RGetResource start searching from the top of the resource chain.
;
; RGetResource starts searching for resources from the current resource map.
; However, if the call to RGetResource inside of MakeITable is made when
; FMSwapFont calls MakeITable, chances are the current resource map will be
; below the system file, and the call to RGetResource to get the 'mitq' resource
; from the system file will fail.
; Inside Macintosh Volume V states that RGetResource “searches the chain of open
; resouce files (including the System Resource File) for the given resource”. Im
; taking artistic license and interpretting this to mean that it searches from the
; top of the resource chain instead of from the current resource map. Making this
; change in interpretation will allow the RGetResource call in MakeITable to always
; succeed.
StartRGetResourceSearchFromTopOfResourceChain PatchProc _RGetResource,(Plus,SE,II,Portable,IIci)
StackFrame Record {RetAddr},Decr
result ds.l 1
paramBegin equ *
type ds.l 1
ID ds.w 1
paramSize equ paramBegin - *
retAddr ds.l 1
EndR
With StackFrame
move.l type(sp),a0 ; Get the resource type to search for
move.w ID(sp),d0 ; Get the resource ID to search for
move.w CurMap,-(sp) ; Save the current resource map.
subq #4,sp ; Make room for a result
move.l a0,-(sp) ; Push the type again
move.w d0,-(sp) ; And the ID.
move.l TopMapHndl,a0 ; Get resource map at top of resource chain
move.l (a0),a0
move.w mRefNum(a0),CurMap ; Make the top map the current one
jsrOld ; Call RGetResource
move.l (sp)+,result+2(sp) ; Percolate the result back up. Need to add 2 because CurMap is on the stack.
move.w (sp)+,CurMap ; Restore the current resource map
move.l (sp)+,a0 ; Get the return address
addq #paramSize,sp ; Pop off the parameters
jmp (a0) ; Return to the caller
EndProc
;————————————————————————————————————————————————————————————————————————————————————————————————————
; UniqueID return non-system values, i.e. > 127
;
; Until this patch uniqueID would return a nonnegative value. This prevented
; applications from creating a resource in the owned resource range. This did
; not prevent creating a resource in the system range (0 to 127). This adds a
; check for that range and recurse on failure. Note stack frame maintained.
; rolled in to ResourceMgr.a 2/26/92 stb
MyUnique1ID PatchProc _Unique1ID,(Plus,SE,II,Portable,IIci)
import MyUniqueID
st ResOneDeep ; entry for one map deep call
jmp MyUniqueID ; cant fall through to a linked patch, the
; code might be rearranged.
EndProc
MyUniqueID PatchProc _UniqueID,(Plus,SE,II,Portable,IIci)
move.w D1, -(SP) ; Resource Manager preserves all but A0/D0
move.b ResOneDeep, D1 ; get OneDeep state upon entry to use for each call
@loop
move.b D1, ResOneDeep ; make OneDeep state correct every time
subq #2, SP ; room for returned ID
move.l 2+2+4(SP), -(SP) ; copy resource type
jsrOld ; call the real UniqueID
move.w (SP)+, D0 ; get the unique ID
cmp.w #128, D0 ; is it legal?
blt.s @loop ; if not, try again
move.w (SP)+, D1 ; restore
move.l (SP)+, A0 ; return address
addq #4, SP ; pop resource type parameter
move.w D0, (SP) ; ID result
jmp (A0) ; return
EndProc
;————————————————————————————————————————————————————————————————————————————————————————————————————
; AddResource nil name <12>
;
; Before this patch existed, passing a nil to AddResource would use the string starting
; at address 0. This was a common mistake, and it simplifies the Finder to not have to
; handle this case.
;
; Luckily, there at least one zero byte in low memory, which will serve for an empty
; string. We use the global OneOne, which contains $00010001, for the one zero we need.
; Also, since OneOne is a low-memory address, we only need to stuff the low word, since
; the high word is always zero when the patch triggers. If you have read this far into
; the comment, you have far too much time on your hands. Go fix a bug.
;
; rolled in to ResourceMgr.a 2/17/92 stb at AddName
AddResourceNILNameFix PatchProc _AddResource,(Plus,SE,II,Portable,IIci)
tst.l 4(sp) ; test name pointer (last parameter)
bne.s @old ; if not NIL, do the standard thing
move.w #OneOne,6(sp) ; if NIL, set up low word so pointer points at a zero byte
@old
jmpOld
EndProc
;————————————————————————————————————————————————————————————————————————————————————————————————————
; Come-from patches on _NewHandle and _DisposeHandle inside UpdateResFile <8>
;
; (Patch #29a)
;
; These patches fix the bug present in Macintosh Plus UpdateResFile which tries to
; allocate a buffer of at least 4k to do its work in. The problem is that NewHandle
; may fail to give us the desired 4k buffer. This patch handles that case by allocating 4k
; buffer on the stack. Two different patches need to take place. First is a patch to
; _NewHandle to allocate a pseudo-handle on the stack when we are called from UpdateResFile
; the memory mgr cannot come up with the 4K. Then there is a corresponding patch to
; DisposHandle to get rid of the thing; the trick to detecting this pseudo-handle is
; to compare it with sp. When the pseudo-handle is disposed we bypass the memory mgr
; entirely because the bogus handle is garbage. In both cases we can bypass the typical
; memory manager finale with d0 and MemErr since the Rsrc mgr ignores them in these
; special cases.
;
; At point of entry to NewHandle the stack is:
; rts to dispatch < A1 < D1 < D2 < A2 < junk.w < sr < rts to caller < xxx
; so 24 or $18 is the offset to rts to caller. The ReturnAddressDepth linked patch macro
; calculates this correctly.
;
; After the pseuo-handle is set up the situation is:
; rts to dispatch < A1 < D1 < D2 < A2 < junk.w < sr < rts to caller <
; < 1000 bytes taken from stack < 24 bytes of former rts/A1/D1/D2/A2/jnk/sr <
; < bogus master ptr pointing to first of 1000 bytes< xxx
;
; At point of entry to DisposHandle the stack is:
; rts to dispatch < A0 < A1 < D1 < D2 < A2 < junk.w < sr < rts to caller < xxx
; so 28 or $1C is the offset to rts to caller. The ReturnAddressDepth linked patch macro
; calculates this correctly.
AfterNewHandleInUpdateResFile ROMBIND (Plus,$139C2)
AfterDisposeHandleInUpdateResFile ROMBIND (Plus,$13A0C)
UpdateResFileNewHandleFailure ComeFromPatchProc _NewHandle,AfterNewHandleInUpdateResFile,(Plus)
jsrOld ; go do the new handle
tst.w D0 ; check error <23Apr86>
beq.s @9 ; if not, just return
lea ReturnAddressDepth(sp),A0 ; point to the return address.
move.l A0,A1 ; for my indexing
suba.w #1000,sp ; get some space for a buffer on the stack
move.l (A1),D2 ; D2 is temp variable saving our return address
move.l sp,(A1) ; this is a master pointer to our buffer
move.l D2,-(sp) ; push our return address
; Need to copy rts2disp,A1,D1,D2,A2,jnk/sr - 6 longs - to new top of stack <23Apr86>
moveq #5,D2 ; D2 will be a loop counter
@1 move.l -(A1),-(sp) ; move the valid dispatcher data down
dbra D2,@1 ;
; Now stuff a magic variable in the presumptuous rsrc mgr.
MOVEQ #64,D3 ; we will grab 1024 bytes off of the stack
ASL #4,D3 ; D3 will be the size of the buffer
@9 rts ; and return (setting neither d0 nor MemErr, mind you,
; since it seems the RsrcMgr ignores them) <23Apr86>
ENDPROC
UpdateResFileDisposeHandleCleanup ComeFromPatchProc _DisposeHandle,AfterDisposeHandleInUpdateResFile,(Plus)
cmpa.l A3,SP ; we don't need this buffer so get rid of it
bhiOld ; CC=HI means buffer is not on stack
; Must copy rts2disp,A0,A1,D1,D2,A2,jnd/sr,rts - 8 longs - to forthcoming top of stack. <23Apr86>
; By good planning, A3 in rsrc mgr points to bogus master ptr, the cell where the rts
; to caller will go, and (A3) is the long just above the block to be moved.
moveq #7,D2 ; get count+1 for loop <23Apr86>
move.l (A3),A2 ; get pointer to long before the dispatch stuff
addq #4,A3 ; point just beyond target area
@0 move.l -(A2),-(A3) ; move dispatch data down
dbra D2,@0 ; loop for entire dispatch area
move.l A3,SP ; fix sp to point at real stack, deallocating pseudo-handle
rts ; return to dispatcher&caller without setting
; d0 or MemErr <23Apr86>
ENDPROC
;————————————————————————————————————————————————————————————————————————————————————————————————————
; LoadResource - <9>
; <9>
; Always strip the handle we get, just in case it's a defproc handle and <9>
; there's some variation code bits left over. <9>
; rolled into ResourceMgr.a 2/17/92 stb
MyLoadResource PatchProc _LoadResource,(Plus,SE,II,Portable,IIci)
move.l d0, -(sp) ; save d0, because LoadResource preserves ALL registers <9>
move.l 8(sp), d0 ; get the handle (past old d0 and the return address) <9>
_StripAddress ; shave off the variation code (maybe) <9>
move.l d0, 8(sp) ; put the handle back where we got it <9>
move.l (sp)+, d0 ; restore d0 <9>
jmpOld ; jump back (probably to ROM) <9>
EndProc ; <9>
;_______________________________________________________________________________________
; Patch for openresfile superload subroutine <10>
;
; When Superloading resource files, the rom first checks the resource manager cache
; (located at HSCache). Unfortunately, the rom code used offsets into the cache as
; addresses of the cache. We fix the problem by patching MaxBlock. MaxBlock is called
; just before the spurious code. We now check the values located at the address of the
; resource manager cache added to the offsets, and return into rom.
;_______________________________________________________________________________________
FixSuperLoadEquates ComeFromAfterPatchProc _MaxBlock,AfterMaxBlockInGetMaxLoad,(Plus)
AfterMaxBlockInGetMaxLoad ROMBind (Plus, $135B8)
GetMaxLoadAfterPreLock ROMBind (Plus, $135D2)
GetMaxLoad@4 ROMBind (Plus, $135D6)
SizeFits ROMBind (Plus, $135FA)
CMP.L D7,D0 ; does compact or growheap get us more?
BLE.S @MaxInD7 ; D7 already has max value,
MOVE.L D0,D7 ; ... else D7 = amount we can grow heap.
@MaxInD7 ; D7 now has the maximum we can grow
move.l HSCache+PreExtra,D0 ; calc how much to read in for superload?
jsrROM SizeFits ; check to see if this size fits in buff
bplROM GetMaxLoad@4 ; CC=PL if this fits
move.l HSCache+PreUnlock,D0 ; check if PreUnlock fits
jsrROM SizeFits ; check to see if this size fits in buff
bplROM GetMaxLoad@4 ; CC=PL if this fits
move.l HSCache+PreLock,D0 ; check if Prelock fits
jmpROM GetMaxLoadAfterPreLock ; and return to the ROM
ENDPROC ; <10>
;————————————————————————————————————————————————————————————————————————————————————————————————————
; BadMapCheckInCheckMap
;
; If the resource file is trashed, OpenResFile should return an error when it
; tries to open the file. There is an obscure bug where the type offset in
; the map is odd, which causes the validity check (in routine CheckMap inside
; ResourceMgr.a) during openresfile to get an address error. We fix the
; problem by checking the map before the validity check checks the map. The
; last trap before the check is _Read. This patch checks to see if we just
; read in the map, and does a precheck. If the map is bad, it trashes the
; ram copy and passes control on the the rom. When the real check is called
; it fails the first test, instead of address erroring on the second check.
;————————————————————————————————————————————————————————————————————————————————————————————————————
NewMapStack Record 0
dispatcherReturn DS.L 1 ;return address to the dispatcher
dispatcherRegs DS.L 5 ;dispatcher saves five regs.
dispatcherResult DS.L 1 ;dispatcher pops this result long.
readReturn DS.L 1 ;return address for the _Read trap.
RdResgisters DS.L 4 ;four registers saved by RdData.
RdDataReturn DS.L 1 ;return address (to NewMap?)
EndR
AfterReadInRdData ROMBIND (Plus,$14250) ; address if coming from RdData call
AfterBsrReadDataInNewMap ROMBIND (Plus,$136B4) ; address if coming from NewMaps call
BadMapCheckInCheckMap ComeFromAfterPatchProc _Read,AfterReadInRdData,(Plus)
With NewMapStack
cmpROM AfterBsrReadDataInNewMap,RdDataReturn(sp) ; check if coming from the bug in rsrcmgr
bne.s @exit
move.l (A4),A1 ; A4-handle to map, A1-preserved by dispr
btst #0,mTypes+1(A1) ; check for an odd value in type offset
beq.s @exit ; ... if not odd, just exit
move.b #1,(A1) ; make sure eof for maxRFEOF is bad
move.l (A1),8(A1) ; ... so maxRFEOF returns value >= $02000000
@exit
rejoinROM
EndWith
ENDPROC
;————————————————————————————————————————————————————————————————————————————————————————————————————
; Come-from patch on _SetHandleSize inside ResizeMap when called from RmveName <13>
;
; This patch makes RmveResource and SetResInfo more robust when removing a resource name if other
; resources share the same entry in the resource name list in the resource map. While it is
; questionable whether such a resource file is valid, the fact remains that some resource files
; do share name list entries.
;
; The problem is that RmveName shrinks the resource name list and hence the resource map
; each time a resource is removed. Thus, if resources share name list entries, the map would be
; shrunk too much. This patch fixes this by setting the name list offsets to -1 (implying no name)
; for other resources that share the same name as the one being deleted.
;
; This bug became more visible in 7.0 with Mover deleting resources. Specifically, apparently
; in some versions of the Adobe font Garamond suitcase file the FONT resources share the same,
; zero length name list entry.
;
; rolled in to ResourceMgr.a 2/17/92 stb with significant rewrite (see NameUsedByOthers)
AfterSetHandleSizeInResizeMap ROMBIND (Plus,$147F4),(SE,$0EE16),(II,$13750),(Portable,$14DA8),(IIci,$1BFCC)
AfterResizeMapInRmveName ROMBIND (Plus,$1483A),(SE,$0EE5C),(II,$13796),(Portable,$14DEE),(IIci,$1C012)
GetRsrcCnt ROMBIND (Plus,$13EF2),(SE,$0E4FC),(II,$12E34),(Portable,$1448C),(IIci,$1B6A4)
At9InRmveName ROMBIND (Plus,$14858),(SE,$0EE7A),(II,$137B4),(Portable,$14E0C),(IIci,$1C030)
RmveNameNameListFix ComeFromPatchProc _SetHandleSize,AfterSetHandleSizeInResizeMap,(Plus,SE,II,Portable,IIci)
ResizeMapCallerReturnAddressDepth EQU $30
jsrOld ; always do the _SetHandleSize
cmpROM AfterResizeMapInRmveName,ResizeMapCallerReturnAddressDepth(SP) ; was ResizeMap called from RmveName?
bne.s @return ; no, just return
lea RmveNamePatch,a1 ; otherwise, make ResizeMap return to us
move.l a1,ResizeMapCallerReturnAddressDepth(SP)
@return
rts
RmveNamePatch
MOVEM.L D3-d6/A2-A3,-(SP) ; Save rest of registers. <24aug85> BBM <13>
move.w d2,d6 ; calculate offset of end of removed name in d6 <13>
sub.w d1,d6 ; subtract negative length to advance to end of name <13>
jsrROM GetRsrcCnt ; Check all entries and update name offsets. <24aug85> BBM <13>
@1
CMP.W RNameOff(A2),D2 ; is this name offset >= the removed one? <13>
bgt.s @notBlownAway ; no, so this name wasnt blown away <13>
cmp.w RNameOff(A2),d6 ; is this name offset >= the end of the removed one <13>
ble.s @notBlownAway ; yes, so this name wasnt blown away <13>
move.w #-1,RNameOff(a2) ; nuke the name offset <13>
bra.s @2 ; and advance to the next resource <13>
@notBlownAway
CMP.W RNameOff(A2),D2 ; is this name offset < the removed one? <24aug85> BBM
BGE.S @2 ; if so, skip it, else
ADD.W D1,RNameOff(A2) ; Offset shrinks by D1.
@2
ADD.W #RESize,A2 ; point to the next entry
DBRA D4,@1 ; if there are more entries loop back <24aug85> BBM
MOVEM.L (SP)+,D3-d6/A2-A3 ; Restore inner regs. <24aug85> BBM <13>
jmpROM At9InRmveName ; continue with ROM version
ENDPROC ; <13>
;————————————————————————————————————————————————————————————————————————————————————————————————————
; GetResource — return an error
;
; During MacPlus development, the resource manager started returning many
; more errors in ResErr. The programmer could then call ResError to check
; if the last resource manager call he made worked. Unfortunately, when the
; check was added to GetResource, it broke MultiPlan. Since compatability
; was the buzz word of the day, and MultiPlan was a significant player, we
; decided to delay returning an error. Times have changed. Excel is here,
; death to MultiPlan., and long live robustness. We will see if this works.
; This patch is still turned off, because we havent had a good chance to do compatibility testing
; to see which applications this affects. We wanted to do that for 7.0, but somehow it slipped
; through the cracks until it was too late.
if 0 then
MyGet1Resource PatchProc _Get1Resource,(Plus,SE,II,Portable,IIci)
import MyGetResource
st ResOneDeep ;entry for one map deep call
jmp MyGetResource ;cant fall through to a linked patch
EndProc
MyGetResource PatchProc _GetResource,(Plus,SE,II,Portable,IIci)
subq #4,sp ;room for the result
move.l 4+4+2(sp),-(sp) ;copy the type (skip the result, return addr., and id)
move.w 4+4+4(sp),-(sp) ;copy the ID (skip the type, result, and return addr.)
jsrOld ;do real GetResource
move.l (sp)+,4+2+4(sp) ;put the result down (skip the return addr., id, and type)
bne.s @success
tst.w ResErr ;check if reserr is already filled in ¿¿¿ Why ???
bne.s @success
move.w #ResNotFound,ResErr ; ...else mark as ResNotFound
@success
move.l (sp)+,a0 ;get the return address
lea 2+4(sp),sp ;remove the parameters
jmp (a0)
EndProc
endif
; moved patches back to ResourceMgrExtensions.a ex<SM8> <Sys7.1>
;————————————————————————————————————————————————————————————————————————————————————————————————————
; STILL TO DO
;————————————————————————————————————————————————————————————————————————————————————————————————————
; ? GetIndResource in numerical order
;
;————————————————————————————————————————————————————————————————————————————————————————————————————
; ? Turn AddResource into a ReplaceResource
;
; In the past AddResource would allow you to add a resource that is the same
; Type and ID and Name as a resource already present in the file. This is a
; patch that removes the old resource before adding the new one.
;
;————————————————————————————————————————————————————————————————————————————————————————————————————
; SetResFileAttrs and mapReadOnly
;
; The resource manager allows you to set the mapReadOnly bit. However, that
; doesnt do what you think it does. The mapReadOnly bit is used for internal
; housekeeping while the file is open. It signals to the resource manager
; that this file was opened read only. Upon CloseResFile or UpdateResFile the
; resource manager aborts when it sees this flag set, and writes nothing to
; disk. There is no way to set the mapReadOnly bit on disk using the normal
; resource manager calls.
;
;————————————————————————————————————————————————————————————————————————————————————————————————————
END