mac-rom/Toolbox/ResourceMgr/ResourceMgr.a

7653 lines
322 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.

;
; File: ResourceMgr.a
;
; Written by: Bruce Horn 22nov82 to 10sep83
;
; Copyright: © 1988-1993 by Apple Computer, Inc. All rights reserved.
;
; Change History (most recent first):
;
; <SM61> 11/7/93 SAM Roll in <MC5> from mc900ftjesus.
; <MC5> 11/7/93 SAM Fixed a couple of calls to GetMap/GetSysMap in vRMgrStdEntry
; that were checking A4 as the function result, which is wrong and
; will never indicate failure. Removed a couple of redundant loads
; of ExpandMemPtr (tons of room for improvement here...).
; <SM60> 10/27/93 rab Backed out change SM45. It fixed the bug, but caused a
; significant loss of performance (Å3x).
; <SM59> 9/16/93 SAM In RsrcZoneInit, check for the zonePtr = bufPtr before calling
; _TrashZone. The boot process calls _InitApplZone w/ApplZone =
; bufPtr as a bogus zone. The heap utils assumes the zone passed
; to it is a zone (duh!).
; <SM58> 9/13/93 SAM Added a call to _TrashZone (HeapUtils) to the start of
; RsrcZoneInit.
; <SM57> 6/22/93 kc Roll in bug fix from Ludwig.
; <LW15> 6/17/93 mal (kc) Fixed NameUsedByOthers to save A2 then restore into A3.
; <SM56> 6/6/93 BT Roll in the process manager patch on GetResource under the
; conditional compile flag 'hasRISCV0ResMgrPatches'. This is for
; speed so we don't hit mixed mode so often. Compatibility with
; old process manager is maintained, this is patch is an app
; anachronism.
; <SM55> 5/30/93 SAM Replaced several _Get/SetZone to MOVE.L A0,TheZone (etc).
; <SM54> 5/27/93 SAM Reintroduced the "is this resource from the system" check in
; checkload. Moved the definition of mapForceSysHeap into
; ResMgrPriv.a equate file.
; <SM53> 5/21/93 CSS Remove FixSMgrWorld import per P. Edberg review. Plus change
; $Axxx to _PrGlue per Cyclone review.
; <SM52> 5/14/93 PN Take out the check load roll in from ProcessMgr because we are
; now still using the old ProcessMgr therefore it applies the
; check load fix twice.
; <SM51> 4/28/93 CSS Fix Radar bugs #1079158. RmveResource had several problems: It
; was not reporting errors correctly and the check for the sysmap
; against the curmap should have been for the system override map.
; Also, in FlushResourceCache clear the expandmem
; emLastMapOverridden before the check if emResourceCache is clear
; because sometimes these two aren't set up together. If we call
; FlushResourceCache, emLastMapOverriden must be cleared.
; <SM50> 4/26/93 CSS Fix comment for <SM49>.
; <SM49> 4/26/93 CSS UseResFile doesn't work right with overrides. Because it calls
; StdTwoExit (which restores the curmap if overrides are enabled).
; Fix UseResFile to clear local override flag so that we don't write
; over curmap after we just changed it.
; <SM48> 4/16/93 kc Add AddNewRefWithoutUpdate entrypoint to AddNewRef so that
; MakeOverrideMap doesn't set the mapChanged bit. Add code to cach
; the override map refnum so that resedit doesn't corrupt the
; system file. This fixes #1069183.
; <SM47> 4/9/93 CSS Change scratch register from D0 to A0 because Eric A. did it
; that way in the shipping products.
; <SM46> 4/8/93 CSS Rollin fix to UpdateResFile to allow it to work correctly in
; multithreaded environment. (from Eric Anderson). Radar bug
; #1077394.
; <SM45> 3/24/93 CSS Try _FlushFile after SetRFEof calls to hopefully fix the various
; -39 bugs (eof errors). Add the utility RFFlush which will
; acomplish the flush. Changed a short branch to word branch.
; <SM44> 3/22/93 CSS Code to restrict the Uniqueid fuction to 128-32767 was checking
; against d0 which is how it was in the patch, but in this context
; is incorrect. In the patch d0 was pulled off the stack. In the
; current code the candidate unique id is in d2. So, I changed
; the code to reflect this. This fixes Radar bug #1063282, and
; #1062580.
; <SM43> 3/19/93 CSS In LoadResource, clear ResErr if the resource is in ROM so
; Hypercard doesn't blow its brains out when in sees lint in
; ResErr after trying to load a WDEF (which is in ROM).
; <SM42> 3/16/93 GMR Fixed the PRAM combo validity check- changed BLE.S to BLS.S to
; properly handle $80-$FF values.
; <SM41> 3/2/93 PN The rGetResource patch is only for a specific case when it
; looking for 'mitq' resource and it should not be rolled into
; ROM. So I back out the change.
; <SM40> 3/2/93 PN Fix the previous change to set current map before calling
; GetResource according to DY.
; <SM39> 2/26/93 PN Roll in a patch StartRGetResourceSearchFromTopOfResourceChain to
; rGetResource
; <SM38> 2/26/93 BT Change call in GetIndResource to call CheckLoad, not jump
; through it's vector. This breaks FlashPort and doesn't buy
; anything.
; <SM37> 2/5/93 PN Roll in a_checkload proc from ProcessMgrMisc.a into CheckLoad
; <SM36> 1/28/93 PN Fix comment to call PrGlue
; <SM35> 1/11/93 PN Fix Radar# 1059658. The AppleTalk ImageWriter and LQ AppleTalk
; ImageWriter are not 32bit clean. They set the high bit in master
; pointer block to lock the handle. Until that bug is fixed in the
; drivers. This code is used to fixed that problem and is put into
; OpenResFile.
; <SM34> 12/16/92 PN Fix LoadResource to handle NILHandle correctly
; <SM33> 12/10/92 PN Radar# 1051364 Fix LoadResource to check for purged resource and
; nil handle before doing HandleScan.
; <SM32> 12/4/92 RB In DetachResource and ReleaseResource, do not dispose of the
; handle to resources that are in ROM in the Override Map used for
; system overrides.
; <SM31> 12/4/92 SWC Moved InitRSRCMgr here from StartInit.a.
; <SM30> 12/1/92 RB Removed the GetResource hack since we have figured out a better
; way.
; <SM29> 11/20/92 RB Fixed a scrw-up in the last chekin, it'll the code will not
; really do what I wanted.
; <SM28> 11/20/92 RB In GetResource, if the type is WDEF or MDEF try looking in ROM
; first, because the Process Manager is not looking in ROM. I know
; this is gross, but it's not like it has not been done before.
; <SM27> 11/11/92 BT Add dummy entry points that FlashPort will use to attach hints
; to. Use of routine entry point was not sufficient to maintain
; offset integrity when source changes move code that is being
; hinted.
; <SM26> 11/10/92 RB Renamed CheckGrow@1 to CheckGrowAt1, since Flashport don't like
; it.
; <SM25> 10/22/92 CSS Change some branch short instructions to word branches.
; <SM24> 9/28/92 PN Take out the unneccessary save A0 and A1 around GetOverrideMap
; calls
; <SM23> 9/25/92 PN #1042784 Fix AddResource and UpdateResFile to flush the
; ResourceCache and also 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.
; <SM22> 9/17/92 kc Change Bsr to BigJsr.
; <SM21> 9/9/92 kc Fix bug in SizeResource that was corrupting TeachText.
; <SM20> 9/8/92 PN Radar#1041949. Fixed the problem in UpdateResFile where it
; should return ResFNotFound when an invalid refnum being passed
; in.
; <SM19> 8/28/92 kc Fix bug in SizeRsrc.
; <SM18> 8/12/92 PN Temporary fix the LoadResource call so that if a handle of a
; resource in ROM is passed in it will do nothing, otherwise it
; will load the resource as always.
; <SM17> 8/6/92 PN FM. Fixed the last check in so that it does not destroy chooser
; resource. It is working now, more work is still needed.
; <SM16> 8/6/92 FM Fixed bug in UpdateResFile. Needed to turn off resource
; overrides when calliing stdentry. Also need to set up a2/a3
; when calling updateresfilecommon.
; <SM15> 7/27/92 FM Fix mistake in AddResource, where I wasn't preserving
; emScanOverrides correctly!
; <SM14> 7/27/92 FM Roll in the ResourceOverrides code from reality.
; Here are the many changes I have made to the resource manager:
;
; - Fixed LoadResource. Call HandleScan BEFORE checking for purged handle or else NIL and non-resource
; handles can mess us up!É
;
; - put installproc to turn on resource overrides in InitResources(). Makes more sense here
; than in the startinit time stuffÉ
;
; - Changed permission byte and DirID handling for the OpenResFile suite of calls
; (HOpenResFile, OpenResFile, OpenRMgrPerm and CreateResFile as well). The old-style default values are
; set up in StdEntry. HFS aware calls then fill in the ioBlock in the Resource
; Managers stack frame as needed.
; This should fix some of the QuickTime 1.1 problems we were havingÉ
;
; - Removed the DirID being passed into NewMap.
;
; - Made HOpenResFile, OpenRFPerm and OpenResFile share common code in
; OpResFile common.
;
; - Added SetFileIODirID as a companion to SetFileIO since ioPosOffset and the ioDirID
; collide in a paramblock.
;
; - Changed NewMap to clear overrideBits when creating NewMaps, in case they
; were written out to disk.
;
; - Optimized the code to get often used OverrideSysMapHndl from the ResourceMgr
; stack instead of calling GetOverrideMap.The stack is set up in StdEntry.
; RsrcZoneInit now does this for example.
;
; - RsrcZoneInit no longer checks the systemmHeapBit when determining which resources to
; purge. Instead in checks the location of the resource handle to determine if it should
; be in the system heap or not.
;
; - Changed CloseAllFiles to use the OverrideSyMapHndl stack value instead
; of calling GetOverrideMap.
;
; - Got rid of ORFCommonHFS entry point since it is no longer needed.
; DirID is now set up on entry to an openrefile call. Now use OverrideSysMap to
; get string $E000 when checking for opens to the .Print driver. That way overrides
; will work correctly for this string resource.
;
; - Special cased UseResFile when the user passes in 0. This is because unlike all other calls
; using resource overrides, we want UseResFile to set to the SystemMap in this case and not
; override of the SystemMap which is what StdMapEntry would do. (Actually UseResFile has
; been defined to not respect override maps in any case, not just the case of the system map.)
; This makes some sense since when we set CurMap to equal SysMap, most ResourceMgr calls
; will end up using the System Override map anyways. This is because StdEntry will set up
; CurMap to be the override map on entry.
;
;
; - Made lots of changes to UpdateResFile to reflect the use of override maps.
;
; - Check to see if weÕre updating the system file, or just another file. If weÕre updating the
; system file, then make sure we update all the font files too. If itÕs just a generic resource map,
; update just itÕs override maps and the file itself.
;
; - from DTY->
; Note: I know that explicitly updating an override map of the system wonÕ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.
;
; - Changed CloseResFile to respect the override bit preventFileFromBeingClosedBit. Also
; added a call to CheckAndFlushFontCache which will flush the font cache if we are closing
; a file that contains 'FOND's or 'FONT's.
;
;
; - Completely rewrote Count(1)Resources to use Deans new Resource caching code. His caching
; code is smart enough to predict that someone doing a CountResources will soon be doing
; a GetIndResource. Since the results of the CountResources are cached, the GetIndResource
; calls should be much faster.p
;
;
; - Completely rewrote GetIndResource to use the new caching code. I'm not sure that
; the RMgrPerm -> ioBlock+ioPermssn(a6) is necessary but thats how Dean wrote it. I'll
; check it out with him tomorrow.
;
; - Changed Get(Cur)Map to use the OverrideSysMap instead of SysMap.
;
; - Changed NextMap to work correctly with override maps in the OneDeep case. It used to
; be that NextMap would bail when ResOneDeep was set. Now if the map has the overrideNextMap
; or twoDeepBit set then we try the next map even in OneDeep mode.
;
; - Reworked StdEntry to iomplement ResourceOverrides and HFS Aware ResourceMgr calls.
; StdEntry now seth the ioBlock to its default values. It sets up CurMap to reflect
; any override maps that exist for the old CurMap. (CurMap is restored to its previous value
; in StdExit.) I also save of the OverrideSysMapHndl and OverrideSysMap since they are
; so frequently used. After all of this is done if RomMapInsert is true StdEntry calls
; the rewritten SwapRomMap.
;
; - Rewrote SwapRomMap to respect the SystemOverrideMap.
; Now that we have overrides, we want to put the ROM map at the
; very end of the resource chain when swapping it out
; and we want to put it in front of any system override maps
;
; - Rewrote StdExit to restore all the changes necessary to make resource overrides work.
;
; - Added code to CheckLoad to set the DeanBit when loading a resource and to clear the
; Dean bit if the handle already exists. That way people can tell if they caused a resource
; to be loaded or not.
;
; - Added a new utility routine called UpdateOverriddenChangedBits. This marks the changed bits
; for any files overriden by the map in A4. This is called anywhere that the ResourceMgr
; sets MCCMask or mapChanged on a map.
;
; - Rewrote FlushChangedFonds to be register based because it is more efficient
; and because it allows us to easily call it after StdEntry which fits better with the
; existing architecture(?) of the ResourceMgr.
;
; - WriteResource now flushes the resource cache.
;
; - rolled in Phillips fix for DiskCachePurge
; <SM13> 7/10/92 PN Fix a bug in RPHook that cause the call to crash on rts. Put the
; handle on the stack again before jsr DiskCachPurgeProc
;
;
; - In AddResource Got rid of FlushChangedFONDsForAdd. I call the new register
; based FlushChangedFonds now.
;
; Also change AddResource to turn off emScanOverrides before calling StdZEntry.
; This is because AddResource is one of the few cases where we actually
; don't want to use an override map. (UseResFile is another example!)
;
; - RmveResource is documented to only allow you to remove a resource
; when it's homeresfile is in CurMap. With overrides we want to modify
; this behavior slightly to allow RmveResource calls from CurMap
; and any files that are overridden by CurMap.
;
; We also special case to allow Rmve's from system files that are below the system when
; the CurMap == SysMap. (e.g. Font Files)
;
; New Routines Added--->
;
; - New routine CacheResource from ResourceMgrExtensions.a. Made a few changes to
; work outside of its previous patch environment.
;
; - IsDuplicate - utility routine called by CacheResource. Determines whether a resource
; and ID have already been cached or not. This is how we prevent duplicates from appearing
; for maps with the dontCountOrIndexDuplicates bit.
;
; - DoesCachedMapOverrideCurrentMap - utility routine called by CacheResource. 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.
;
; - CheckAndFlushFontCache - Called By: OpenResFile, HOpenResFile, OpenRFPerm, CloseResFile.
; If the map being opened or closed contains 'FONT' or 'FOND' resource we invalidate
; the font caches.
;
; - 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.
;
; - 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.
;
;
; <SM13> 7/10/92 PN Fix a bug in RPHook that cause the call to crash on rts. Put the
; handle on the stack again before jsr DiskCachPurgeProc
; <SM13> 6/12/92 CSS Roll-in Reality Changes:
; <12> 6/11/92 FM Remove obsolete call to FixSMgrWorld.
; <SM12> 6/3/92 PN Fix the HCreateResFile to get the dirID and VRefNum correctly.
; <SM11> 6/3/92 CSS Integrate patch to RsrcZoneInit. Fix to CloseFiles to not close the override files that override
; the system resources. This is based on a patch to RsrcZoneInit
; that changes SysMapHndl to fake out closefiles to effectively do
; the same thin.
; <SM10> 5/7/92 stb roll in TrueType patch on SetResPurge for disk-based font caches
; (from DiskCachePatches.a). Rewrote to no longer need the
; TrueType global reference to the resource mgr purge proc,
; although the TrueType routine is still in place for RAM
; versions.
; <SM9> 4/24/92 PN Roll in NewCreate and NewOpenRF ValidatefileSizeInCheckGrow/
; OpenDirIDResfile/
; OpenRFPermDirIDExit/OpenresfileDirIDExit/CreateDirIDresfile/Crea
; teresfileDirIDExit from ResourceMgrExtensions.a
; <SM8> 4/18/92 kc Fix bug in GetIndResource. (Change TST.L to TST.W)
; <SM7> 4/14/92 stb Add the comments I so conveniently forgot to addÉ
; <SM6> 4/14/92 stb remove the ÔscodÕ patch on GetResource. Roll in decompression
; patches.
; <5> 3/11/92 stb fix GetIndResource and Get1IxResource so the result gets cleared
; BEFORE bailing out if the index was bogus. Flush 'FOND' candidate
; lists in AddResource, RmveResource, and ChangedResource.
; unroll <10> 'scod' patch on GetResource. Whoops, not yet.
; <4> 2/26/92 stb roll in patches for LoadResource, AddResource, GetIndResource,
; UniqueID. Fix ROZ map handle size bug in CountCombos where
; unnamed resources caused 255 bytes extra to be allocated in the
; map handle. Removed obsolete (conditionalized out) code in
; ORFCommon.
; <12> 2/14/92 stb remove support for ignored resources (conditional: hasResIgnored)
; <11> 2/14/92 stb roll in fix to RmveName so that a name doesnÕt get removed if it
; is in use by any other resource. This seems odd, but files like
; this exist, and we want them to work.
; <10> 1/20/92 PN Roll in the linkedpatch from segmentloaderpatches.a to force
; loading 'scod' resource
; <9> 1/8/92 RB Exported a few symbols so that the LinkedPatches for
; ResourceMgrExtensions can be used from ROM.
; <8> 6/12/91 LN changed #include 'HardwareEqu.a' to 'HardwarePrivateEqu.a'
; <7> 9/13/90 BG The unnamed author referred to in <6> is helping simplify things
; by removing code added for -eclipseDebug- because it is no
; longer necessary with the latest rev. of the 040. In general,
; mods <4> and <5> were removed.
; <6> 9/12/90 MSH &SWC: Fixed a bug in some eclipseDebug code in NameResource. The
; code was replacing an ADDA.W offset(Ax),Ax instruction with
; several instructions. However, the author of the replacement
; code didn't realize that that particular ADDA also does a sign
; extend of what's at offset(Ax) before, doing the add, and his
; code didn't. Very messy if the addition happens to occur with
; particular values.
; <5> 8/6/90 BG Some more EclipseNOPs were needed.
; <4> 7/17/90 BG Added EclipseNOPs for flakey 040s.
; <3> 6/27/90 CCH Fixed bug in CountCombos that increased size of ROM rsrc map by
; 255 bytes for each ROM rsrc without a name. Also removed code
; for non-combo ROM resources.
; <2> 2/1/90 CV Checking for an FPU based on the combo and HWCfgFlags. If the
; FPU is present, the combo is changed to 3 which uses the FPU
; SANE package rather than the non-FPU SANE.
; <1.6> 11/8/89 BPA Added support for ignored resources (conditional: hasResIgnored)
; <1.5> 10/2/89 BPA Catenated source files RmgrAsm1.a, RmgrAsm2.a and RmgrAsm3.a
; source files to this file.
; <1.4> 8/30/89 dba moved common equates for ResourceMgrPriv.a
; <1.3> 6/30/89 GGD NEEDED FOR AURORA: Added include of HardwareEqu.a,
; UniversalEqu.a, deleted Nequ.d
; <1.2> 6/29/89 BBM Added vectors for vRMgrStdEntry and vRMgrStdExit in RMgrAsm2.a
; <1.1> 11/10/88 CCH Fixed Header.
; <1.0> 11/9/88 CCH Adding to EASE.
; <¥1.1> 9/23/88 CCH Got rid of inc.sum.d and empty nFiles
; <1.0> 2/11/88 BBM Adding file for the first time into EASEÉ
;______ EASE Modification History for file RmgrAsm1.a ____________________________________
; <1.9> 8/30/89 dba changed MapReadError to mapReadErr
; <1.8> 7/6/89 PKE NEEDED FOR AURORA & ESPRIT: Fixed Script Mgr initialization in
; InitResources to work properly for switch launch.
; <1.7> 6/30/89 CCH Modified RedoMap to use a new field in ROM rsrc entries that
; points to rsrc data.
; <1.6> 6/30/89 GGD Added default combo selection when PRAM combo is 0, or out of
; range.
; <1.5> 6/15/89 BBM Added support in InitResources for combinational resource in
; ROM. The ROM resource map is now generated at bootime depending
; on the combination byte stored in Pram.
; <1.4> 6/12/89 dba Changed the logic that checks for old printing glue opening the
; printer file.
; <1.3> 3/3/89 CCH Now checks IntlSpec to see if Smgr has been initialized instead
; of ExpandMem.
; <1.2> 2/17/89 CSL Clean up PartRead and UpdateResFile for 32 bit clean.
; <1.1> 11/10/88 CCH Fixed Header.
; <1.0> 11/9/88 CCH Adding to EASE.
; <1.2> 10/27/88 PKE added script manager support to initresource
; <1.1> 8/26/88 BBM Example to show how to use ease.
; <1.0> 2/11/88 BBM Adding file for the first time into EASEÉ
;______ EASE Modification History for file RmgrAsm2.a ____________________________________
; <1.3> 8/30/89 dba changed MapReadError to mapReadErr
; <1.2> 6/29/89 BBM Added vectors for StdEntry and StdExit
; <1.1> 11/10/88 CCH Fixed Header.
; <1.0> 11/9/88 CCH Adding to EASE.
; <1.0> 2/11/88 BBM Adding file for the first time into EASEÉ
;______ EASE Modification History for file RmgrAsm3.a ____________________________________
; <1.2> 8/30/89 dba changed ResErrAttr to resAttrErr
; <1.1> 11/10/88 CCH Fixed Header.
; <1.0> 11/9/88 CCH Adding to EASE.
; <1.0> 2/11/88 BBM Adding file for the first time into EASEÉ
;
; To Do:
;
;_________________________________________________________________________________________
;
; Set all undefined conditionals and equates to default state
;_________________________________________________________________________________________
;_________________________________________________________________________________________
;
; Macintosh Resource Manager
;
; Written by Bruce Horn 22nov82 to 10sep83
; Modified by Brian B. McGhie 01jan85 to Present
; Modified by Bryan Atsatt 02oct89 to Present
;
; This file contains the source code for the Resource Manager. It includes files
; which contain toolbox, graftype and sysmacs equates and macro definitions.
;
; As with the OS routines, the Resource Manager routines, with one exception,
; smash A0 and D0 only; all other registers are preserved. LoadResource
; preserves ALL registers.
;
; The Mark menu lists most of the routine entry points; names preceded by an apple
; are external entries (A-Traps), those marked with a diamond are internal entries.
; All external entry points are listed in the Exports section (use Mark menu).
;
; This file is built with the following conditionals:
;
; hasComboResource: true (will always be true!)
;
;_________________________________________________________________________________________
eject
;_________________________________________________________________________________________
;
; Revision History
;_________________________________________________________________________________________
;
; 16-Dec-82 BLH Added Add/RmveResource. Massive name changing.
; 21-Jan-83 BLH Updated to new LK file system.
; 11-Feb-83 BLH Returned error codes in InitResources,
; OpenResource
; 17-Feb-83 BLH Fixed bug in CheckLoad
; 25-Apr-83 BLH Rom 3.0 overhaul:
; fixed bug in UpdateResFile, optimizing
; the writes and making it a little quicker
; to call updates.
; Changed openResFile to use the resource
; fork, and to handle more reasonably the
; already-open, not-open, and other error
; conditions.
; CloseResFile now releases all resources
; in the map before closing, compacts the
; resources in the map, and writes out the
; possibly modified map and header.
; (@@Note--CloseResFile does not compact
; yet. Due to a bug in GetHandleSize,
; this feature has been disabled. )
; The resource file starts at ZERO instead
; of 512.
; Added memory full error handling in
; OpenResFile and CheckLoad.
; Added preLoad capability to initResources
; and OpenResource.
; Added procedure WriteResource.
; Added ResAdded resource attribute.
; Added MAttr, map attributes word, in map.
; MapSize and DataSize are now LONGS.
; Resource manager routines now save
; ALL registers except A0 and D0.
; Added SetResPurge to handle the purge
; hook in the Memory Manager.
; Added CurResFile.
; 12-May-83 AJH fixed bug in InitResources -- shouldn't preload when
; you can't read the map
; 24-May-83 BLH Fixed bug in NewMap--crashes if failed due to unlink bug.
; 25-May-83 BLH Changed interface to CmpString in GetNamedResource.
; 31-May-83 BLH Added CreateResFile, fixed AddResource bugs.
; 1-Jun-83 BLH Added DetachResource.
; 6-Jun-83 BLH Fixed bug in GetNamedResource (didn't search all maps)
; 8-Jun-83 BLH Fixed bug in CloseResource (!)
; 10-Jun-83 BLH Moved compacting and mapwrite from CloseResFile to Update.
; Added routine to close maps in .
; CloseResFile closes all maps if you attempt to close
; Sys.rsrc. UpdateResFile now compacts, since GetHandleSize
; finally works.
; 13-Jun-83 BLH Made SetResAttr, SetResInfo NOT set the mapChanged bit.
; you have to explicitly call ChangedResData to make sure
; the change is written out to the map.
; 18-Jul-83 BLH Added MapCompact attribute bit to minimize resource file
; compacting. Added UniqueID to return a unique ID for a given
; type in the current map. Also, shrunk code approximately
; 60 bytes due to suggestions from Donn Denman.
; 8-Aug-83 BLH Removed BeginSubResource, EndSubResource. Added HomeResFile.
; Added ResErrProc in globals. Made UniqueID return an
; ID which is unique in all open maps. Took out SetEOF
; from UpdateResFile, to allow pre-allocation of the
; resource fork. Put in ResrvMem to reserve low locations for
; locked handles. Added file-order preload and update to
; speed up resource I/O.
; 12-Aug-83 BLH Split Resource Manager into four files: RMgr, RMgrAsm1,
; RMgrAsm2, and RMgrAsm3. Utilities in RMgrAsm2. Added
; CheckGrow to handle the DiskFull condition. CheckGrow
; called from ChangedResource, AddResource, and AddReference.
; Also Added ReallocRes, AllocRes, called from (surprise!)
; changedResource and AddResource to allocate space for
; either a new resource or a resource which has changed
; size and needs to be reallocated at the end.
; 16-Aug-83 BLH Bug fixes and space-savers.
; 29-Aug-83 BLH Fixed bug in SetResInfo, RmveResource (protect bit checked
; in RHndl instead of RAttr) and made CheckGrow handle
; memoryFull condition as well as diskFull.
; AddResource/AddReference now return ResErr=DiskFull or
; MemFull in the case that CheckGrow failed.
; 1-Sep-83 BLH InitResources shouldn't clear ResErrProc.
; Fixed NOP (branch to next instr!), folded cmn code in
; name stuff. Fixed dangling ptr problem (!) caused by
; CheckGrow. Took out dangerous LINK stuff in SetFileIO
; and just used a standard stackframe on first link in
; StdEntry. Made GetCurMap and CloseResFile handle the case
; of no maps open (set curMap to FFxx with ST). Fixed bug
; in LoadResource where errors would not get reported through
; the ResErrProc. AddResource sets the Resource bit in the
; masterPtr, RmveResource and DetachResource clear it.
; 2-Sep-83 BLH MAJOR CHANGE: threw away name ID stuff, made hard offsets
; to the names in the name block stored in the resource entry
; where the nameID was previously stored. This change
; fixed a time-bomb bug which would trash the resource file
; after repeated SetResInfo calls. Also, data lengths in
; the resource file are now LONG integers (4 bytes). Fixed
; CountTypes, GetIndType to return true counts and unique types
; for all open maps, to be consistent with CountResources
; and GetIndResource.
; 6-Sep-83 BLH Added MapReadOnly in MAttr to inhibit writing to the resource
; file and diskFull checking. Added SetResFileAttrs,
; GetResFileAttrs to allow toggling of this bit.
; 8-Sep-83 BLH Fixed bug in CheckGrow which could trash the resource map
; if the handle passed to ChangedResource or AddResource
; was purged.
; 9-Sep-83 BLH Fixed bug in CheckLoad--ResrvMem must preserve A0, so typed
; in .Word $A040 to replace _ResrvMem. Fixed bug in RmveName.
; 10-Sep-83 BLH Fixed bug having to do with protected resources; cleaned
; up usage in UpdateResFile, ChangedResource, WriteResource.
;_________________________________________________________________________________________
; Version 7.0. Last modified 10-Sep-83 by Bruce Horn. Later changes by BBM.
; All changes from this point on are part of the development of the BigROM.
;_________________________________________________________________________________________
; 22jan85 BBM started to roll in patches to the rom source.
; 29jan85 BBM Cleaned up a lot of internal tables and comments.
; 02feb85 BBM Changed InitResources to support ROM Resources. Since We
; need some of the ROM Resources (e.g. the sony drvr) at boot time
; before we have mounted (or can mount) the disk, we now call
; InitResources twice. The first time it enables just the ROM
; resources, moving both the map and the master pointers down from
; the ROM. The Second time, it sets up the system resource map from
; off of the disk as the root resource map, and moves various ptrs
; so that the system file is the root map and the ROM map is next
; in line down to ram. This enables people to lock down ROM
; resources without causeing a bus fight, Since the map and pointers
; used are not in ROM. Initresources calls BuildMap, which is new.
; 11feb85 BBM Changed CloseFiles and CloseResFile so they couldn't close ROM
; resource map. This needs to be modified later, as there should be
; a way to override ROM resources.
; 12feb85 BBM RsrcZoneInit now won't try to release rom resources. Also
; changed ReleaseResource so it wouldn't release ROM resources.
; 13feb85 BBM changed the format for the ROM resources associated code had
; to be changed. (see InitResources and BuildMap)
; 18feb85 BBM The ROM resources now work right on switch-lanching. As we
; are now using the new system equate files for the build rom
; proceedure, I had to change one equate (from resource to resourc).
; 27feb85 BBM If you call CreateResFile on a locked disk, an incorrect error
; code was being returned. Bug was that after _Create, no check for
; error was done. Fix was to stuff error code into ResErr and rtn.
; 28feb85 BBM CurResFile now returns zero if the current res file is the
; system resource file, else it returns the actual refnum.
; 03mar85 BBM CloseResfile was wasting time calling DisposeResource when it
; should call DisposHandle directly. (see note in routine's header)
; 05mar85 BBM changed BuildMap to create a read-only zone for the ROM Rsrcs.
; 07mar85 BBM Added Preload3, which is executed if ResLoad is false (in Pre-
; Load), in which case there is no need to access the disk. This
; avoids the n-squared search on the curmap for preloadable rsrcs.
; 08mar85 BBM The other problem with Preload was that it was checking
; ResPreLoad at the highest level of the loop. Added two utilities,
; FirstR2 and NextR2, which do the duplicate FirstRes and NextRes
; except they check the preload bit as they scan through the map.
; 09mar85 BBM Fixed CheckLoad. Now it only checks the size once when it is
; loading in a resource, instead of checking the size twice.
; 12mar85 BBM added a ram cache for HandleScan. Involved new low memory
; variables and modifying routines that would invalidate cache.
; Added SaveCache routine.
; 13mar85 BBM fixed a bug in release resource where it was trying to release
; the ROM resources. Fixed a stack problem in FNInit.
; 14mar85 BBM fixed preload to zero all handles of the new map, as the map
; read in may have bogus info in those fields.
; 15mar85 BBM fixed 32k limit on the size of resources.
; 19mar85 BBM SaveCache should only save words for D4-D6. FNInit should pop
; stuff off the stack using ADDQ #4,SP. Preload/2/3 should check to
; see if any rsrcs exist first. StdExit now zeros A0 for Duvall.
; 22mar85 BBM InitResources/Buildmap calculates new handles for ROMresources
; but didn't mask off high byte of the masterpointer (which could be
; locked, etc.).
; 22mar85 LAK&BAS PreLoad3 only created handles for resources that WEREN'T
; preloaded. Also, _NewEmptyHandle caused the map to move and A2
; was pointing into it, so A2 was changed to be an offset into the
; map around the _NewEmptyHandle call.
; 23mar85 BBM Calling GetMap/GetCurMap with an invalid refnum passed back an
; error but left most regs setup pointing to the system map. The old
; finder blindly used these regs without checking the error CC. So
; to be compatible in the new ROM we make the curmap, topmap.
; 25mar85 BBM the fix on 22-mar-85 only preserved A2. A3 must also live.
; 28mar85 BBM In order to access the ROM Resources nearly all the time, we
; now set the low memory variable SysMap = 1 (the ROM map refnum).
; This has implications to a majority of the RMGR routines. RMGR
; routines that check rsrc ResProtected bit or check MapReadOnly bit
; will not need added code to protect them (eg. SetResInfo)
; 29mar85 BBM Initresources(BuildMap) was hard wired to $1C which currently is
; always in MTypes. Rather than make life hard in the future, redid
; code to add in the value in MTypes and not use $1C.
; 02apr85 BBM fixed HomeResFile to return correct RefNum.
; 03apr85 BBM Finished work of 29-mar-85. DetachResource and
; ReleaseResource now set ResErr (ResChngBit = -198) if ResChanged
; bit is set. AddResource and AddReference would not allow you to
; add to the system map.
; 09apr85 BBM made FirstR2/NextR2 more general. These routines now use D1
; to determine which bit of RAttr to test on the lowest level. This
; fix enables both UpdateResource and Preload to use FirstR2/NextR2.
; 10apr85 BBM Added a fix that was from Bud Tribble to ORFCommon. This is a
; fix for some print drivers. Fixed GetResInfo so that if a pointer
; is passed which is nill, it doesn't attempt to write out that var.
; Added new routine DoRomEntry to recover handles in the ROMZone,
; also had to save off ROMZone when created and made ReleaseResource
; work in the RomZone
; 11apr85 BBM Change DoRomEntry to support a new interface with the Memory
; manager. Added routine CheckMap, which does some minimal error
; checking on rsrc maps.
; 16apr85 BBM GetResource and GetNamedResource now return an error if they
; couldn't find the resource. _NewHandle in routine NewMap didn't
; set ResErr if it returned an error, now it does. UpdateResFile
; didn't set ResErr if MapReadOnly is set, now it does. GetIndResource
; sets ResErr if input index is zero or negative. ChangedResource
; and SetResInfo now return error condition if ResProtected is set.
; WriteResource now sets ResErr if Map is ReadOnly or Res not changed.
; CloseResFile returns error code if UpdateResFile fails as well.
; 18apr85 BBM now Preload, if ResLoad is false, doesn't call NewEmptyHandle.
; SetResPurge now points to the correct Zone.
; 22apr85 BBM Finished the one map deep calls. Added Seven new entry points:
; Get1Resource, Get1IndResource, Get1NamedResource, Get1IndType,
; Count1Types, Count1Resources, Unique1ID. (added Std1Entry).
; 23apr85 BBM Fixed the checks in GetResInfo which see if the pointers to
; var parameters are nill. Started to remove references from RMGR.
; Also fixed the switcher, to keep all RMGR files open & circumvent
; the RMGR Andy H. did a MOVE.L SysMapHndl,TopMapHndl and called
; RsrcZoneInit. Most likely he is not the only one doing it, so we
; added an error check in closefiles, which corrects TopMapHndl if
; it is pointing below the ROMMapHndl.
; 29apr85 BBM Fixed bug in Preload (it would only load in one rsrc). Fixed
; bug in CheckMap.
; 30apr85 BBM GetIndResource, GetResource and GetNamedResource all save the
; HandleScan cache. Sped up GetIndResource and CountResources by
; not dealing with system references.
; 01may85 BBM Sped up HandleScan by a whole lot!!!!! Added a new exit for
; routines called SubA2Found, to speedup IDScan and TypeScan. Sped
; up DoRomEntry and CountITypes.
; 02may85 BBM Added new trap GetMaxSize. Fixed a bug and (while there) sped
; up GetIndResource.
; 06may85 BBM Preload could save a word by preload calling GetMap. Andy H
; looked at code and suggested some cleanups in SaveCache, SizeRsrc,
; RdRsrc, RdData, GetHS, HomeResFile, CloseResFile, MoveNames, and
; added some stuff for the font manager.
; 07may85 BBM Started speed up on Preload, added SuperLoad & GetMaxSize.
; 08may85 BBM fixed a bug in CheckMap (death occured if there were no named
; resources).
; 09may85 BBM finished the first whack at SuperPreload.
; 10may85 BBM Added new routine GetRsrcCnt which can be used in conjunction
; with a DBRA D4, instead of GetEntries/NextEntries (forSpeed).
; Modified FirstR2, NextR2, Preload accordingly.
; 13may85 BBM Sped up FirstRes/NextRes and combined with FirstR2/NextR2 for
; Space as well as speed.
; 14may85 BBM Fix ORFCommon to use less stack & be a little faster.
; 16may85 BBM made SysMap = RomMap = 2 to fix a bug in Lotus where they were
; trying to do file IO with the bogus ROM map refnum.
; 17may85 BBM patched out superload, since it was superslow.
; 20may85 BBM fixed bug in SpaceAt to setup D1 before call to NextRes. Also
; fixed bug in HandleScan (an off by one bug). Also made the check
; in AddResource less strict, to fix a bug in "Printer Installer".
; Stuffed the MRefNum in the ROM Map with 2, not 1 (see BuildMap).
; 21may85 BBM Backed out change (20may85) to AddResource, in favor of a fix
; in DoRomEntry. Fixed SkipToEntry to handle an offset of 64k.
; 22may85 BBM CloseResFile didn't shut down system right. DetachResource,
; when passed a nill handle went ahead and munged random memory. I
; put the fix into StdResEntry to fix similar problems elsewhere.
; 30may85 BBM made A2/A3 offsets for every IO call. (see WrData2/RDData2).
; 31may85 BBM ReallocRes assumed D1 preserved across SpaceAt. Fixed same.
; 03jun85 BBM Fixed a bug in IO calls by forcing A4 to be even on entry.
; 07jun85 - 13jun85
; BBM made a new entry Called 'OddSize', which gets four bytes out
; of memory and stuffs it into D0. Finished first massive pass at
; UpdateResFile. Eliminated use of one low memory variable.
; 18jun85 BBM GetIndResource sped up and fixed (wrong value in D4 cache).
; 19jun85 BBM fixed bug related to ResOneDeep stuff (in nextmap).
; 20jun85 - 24jun85
; BBM rewrote superpreload and various stuff to accomodate different
; loading sequence on preload. (speed improvement).
; 26jun85 BBM made onedeep flag a byte instead of a word. Remaining byte is
; used for RomMapInsert. Note on clearing ResOneDeep we still clear
; the whole word, as RomMapInsert still needs to be cleared.
; 27jun85 BBM finished pulling ROM Resources.
; 29jun85 BBM _MaxBlock/_NewHandle may move memory (resource map) so need to
; keep A2 valid in _UpdateResFile.
; 30jun85 BBM optimised RLocnNew. Fixed CmpFrmDsk.
; 01jul85 BBM fixed UpdateResFile (again?!).
; 02jul85 BBM start code thought that ResErrProc is already setup. Added new
; entries into FirstRes/NextRes which zero D1 on entry.
; 03jul85 BBM cleaned up UpdateResFile.
; 08jul85 BBM Fixed some subtle wierd cases in UpdateResFile routines.
; 09jul85 BBM changed lowmem defs, pulled out new updateresfile for now, made
; powerup code work right with the ROM resource pullout.
; 10jul85 BBM tried a fix in OpenRF in conjunction with the new file system.
; Fixed a bug swapping rom map in and out, which involved curmap.
; Finally fixed UpdateResFile - its about as fast as it can be.
; 11jul85 BBM fixed up superload to work with the new ROM insert stuff.
; 15jul85 BBM backed out enhancement to CurResFile (which returned zero if
; CurMap = SysMap). F/DA Mover was walking through FCB Queue using
; zero as a valid refnum.
; 18jul85 BBM added some more error checking on the handlescan cache. Three
; calls mess with the map after setting up the cache (AddResource,
; RmveResource, and SetResInfo) so fixed them as well.
; 19jul85 BBM Sped up RsrcZoneInit.
; 22jul85 BBM Fixed bugs connected with CloseResFile (assumed SysMap <= 2).
; Removed the MaxSizeRsrc call to make room in ROM.
; 12aug85 BBM Sped up CloseResFile. Cleaned up most of the special code for
; the ROM map, and did house cleaning.
; 13aug85 BBM Compacted some code.
; 14aug85 BBM RMGR should work with the map in the front, so fixed SpaceAt,
; CheckMap and SetRFEOF.
; 20aug85 BBM started a new format for getting address of a rom rsrc.
; 21aug85 BBM fixed and adjusted SizeResource and MaxSizeRsrc, and added new
; trap called RsrcMapEntry.
; 22aug85 BBM made a standard entry and exit for utility routines called
; SaveRegs and RestRegs. Fixed SetResInfo.
; 24aug85 BBM fixed RmveName.
; 26aug85 BBM cleaned up more, Replaced SpaceAt to work with map at front.
; Added OpenRFPerm. Removed a lot of SetEOF Calls.
; 27aug85 BBM made massive changes to InitResources and BuildMap. Added new
; routines. This version of RMGR depends on new format of ROM Rsrc's.
; 28aug85 BBM made RomRsrcStart an offset, not hardwired to $40001A.
; 29aug85 BBM fixed two bugs during InitResoruces.
; 04sep85 BBM added routine SizeFits to help in SuperLoad.
; 05sep85 BBM made OpenRFPerm work right.
; 09sep85 BBM fixed bug in AllocRes/ReallocRes.
; 11sep85 BBM fixed bug in MaxRFEOF (wrong if data before and after map).
; 12sep85 BBM fixed bug in updateresfile.
; 14sep85 BBM AddResource inserts rsrc entry at end of rsrc entries for that type.
; 17sep85 BBM Fixed NewMap to check whether map exists if ResFile is open.
; 19sep85 BBM Fixed NewMap to really check if this is a new format preload file.
; 09oct85 BBM fixed UpdateResFile (file's first rsrc needed compaction).
; 10oct85 BBM didn't fix right on 09oct85, but now UpdateResFile is great!
; (But AllocRes wasn't. forgot to subtract resdataoffset from file loc)
;________________________________________________________________________________________
; BETA ROMS LAUREL & HARDY (all changes from this point are witnessed by two
; people, the second person in lowercase)
;________________________________________________________________________________________
; 17oct85 BBM/jtc MacWrite 2.2 uses AddReference and RmveReference. The fix
; will be to keep the traps but strip the parameters off the stack
; and return with ResError set as an error. This makes these two
; traps equivalent to nop routines.
; BBM/jtc UpdateResFile could be passed a bad map and get caught in
; an infinite loop. Now it cann't get caught in an infinite loop.
; 21oct85 BBM/jtc In UpdateResFile mark ResErr with error if we abort.
; 27oct85 BBM Added some vectors for the low level routines. (True Paranoia!)
; Changed NewMap to return error if no map found.
; 30oct85 BBM Changed the way that OpenResFile and OpenRFPerm worked with the
; permission in order to accomidate the segment loader.
;; 04nov85 BBM RmveResource of a ROM resource tried to do SetEOF on ROM RefNum, which is an
; illegal file call. This fix skips the eof call if it is the rom refnum.
; This change is needed if we want ROM Override to work correctly.
; 06nov85 BBM MicroSoft's Word was going behind the font manager's back, which
; caused the font cache to become invalid. So I now invalidate the
; Font Manager's cache if I release a resource of type 'FONT'.
;_________________________________________________________________________________________
; POST LONELY HEIFER FIXES
;_________________________________________________________________________________________
; <06jan86> BBM Took out three lines that shouldn't have been in the routine
; CmpFrmDsk. This fixes a bug in UpdateResFile.
; <08jan86> BBM If UpdateResFile cann't get at least 4k for a buffer it dies.
; Fixed UpdateResFile so it can use a 1k buffer off of the stack.
; <09jan86> BBM cleaned up the way it found space on the stack for UpdateRes.
; <13jan86> BBM Fixed GetMaxLoad to get the right data. (PreLock, etc., were not
; addresses, they were offsets.) This fixes superpreload.
; <19feb86> BBM Made some modifications to work under MPW
; <13may86> BBM Fixed a bug in updateresfile. The bug manifested itself when
; compacting from disk and slideing the resource forward in the buffer
; from one to three bytes. This caused the resource size to overwrite
; itself. Thus some resources could be several meg long.
;<C169/24Sep86> JTC Changes in all 1,2,3 files for 32-bit support. Trick change
; to DoROMEntry presumes that rel handles in mem mgr block headers
; have only 24 bits, as in the Leung/Fung 32-bit memory manager.
;<C206/09oct86> bbm added support for mpw includes.
;<C238/17oct86> bbm font manager wanted its cache invalidated on opening and
; closing resource files. Helps new font manager be compatible with
; some old applications.
;<C249/20oct86> bbm made the check for a bad map more robust (rmgrasm2(checkmap)).
;<C268/27oct86> bbm one of the macplus patches to updateResFile did not get rolled
; in. UpdateResFile now finds buffer space more intelligently.
;<A291/29oct86> bbm memory manager is now long word aligned, which changes ROZinti.
;<A340/03nov86> bbm fixed dumb mistake in patch that was rolled in (see C268).
;<C396/26nov86> agh 32 Bit address Fixes. Removed dozens of asm bra size warnings.
; UNIX 8 byte master pointer mods to ROZInit.
;<C628/14jan87> bbm added rGetResource trap to rmgrasm3.a. This trap reverses the
; order of the system and rom map when doing a GetResource. (In reality,
; _GetResource is called with romMapInsert false. If that fails
; _GetResource is called with romMapInsert true.)
;<C669/22jan87> bbm fixed rGetResource trap to rmgrasm3.a. (stack cleanup problem)
;_________________________________________________________________________________________
;
; Files Combined
;_________________________________________________________________________________________
;
; <02oct89 bpa> Combined ResourceMgr.a, RmgrAsm1.a, RmgrAsm2.a & RmgrAsm3.a into one
; file: ResourceMgr.a.
; <03oct89 bpa> Modified ZFirstRes/ZNextRes/FirstRes/NextRes so can be called with
; D1 = resIgnored (0). Made two copies of Get1IndResource/GetIndResource,
; one if hasResIgnored and the other if not; modified the one for
; hasResIgnored so manages ResIgnored attribute.
; <04oct89 bpa> Modified PreLoad and UpdateResFile so will clear ResIgnored attribute bits
; in all entries in map. Added new routine ClearIgnore.
; <05oct89 bpa> Added new routine ChkTypeIgnored which checks to see if all entries for a
; given type are ignored; modified CountITypes and TypeScan to call it.
; Modified CountResources/Count1Resources so doesn't count ignored
; resources. Modified IDScan so skips any matching ID whose ignore bit is
; set.
; <06oct89 bpa> Added new routine TypeScanAll which does not ignore types; modified
; AddNewRef and RmveResource to call it rather than TypeScan. Modified
; IDScan so skips any entries whose ignore bit is set. Added new routine
; IDScanAll which does not ignore types; modified UniqueID/Unique1ID to call
; it (& TypeScanAll) rather than IDScan. Modified GetResAttrs and
; SetResAttrs to force ResIgnored bit clear. Modified GetNamedResource and
; Get1NamedResource so skips any entries whose ignore bit is set.
; <07nov89 bpa> Added support for undefined conditionals (sets them to default state).
;_________________________________________________________________________________________
LOAD 'StandardEqu.d'
include 'HardwarePrivateEqu.a'
include 'UniversalEqu.a' ; <1.3>
include 'ResourceMgrPriv.a'
include 'FontPrivate.a' ; <sm5>stb<sm10>stb
include 'Decompression.a' ; <sm6>stb
include 'InternalOnlyEqu.a' ; <PN>
include 'SysPrivateEqu.a' ; <sm10>stb
include 'PrintTrapsEqu.a' ; <SM56> BT
string asis
;_________________________________________________________________________________________
;
; Export all external entry points
;_________________________________________________________________________________________
RMgr PROC EXPORT
EXPORT AddResource ; Add a resource to the resFile.
EXPORT AddReference ; a nop routine added back in for MacWrite 2.2 <17oct85> BBM
EXPORT ChangedResource ; Called to mark resource to be written
EXPORT CloseResFile ; Given refnum, closes the resource
EXPORT Count1Resources ; $A81A (26) OneMapDeep version of CountResources
EXPORT Count1Types ; $A81C (28) OneMapDeep version of CountTypes
EXPORT CountResources ; Given type, return number of resources
EXPORT CountTypes ; Returns number of types in current rsrc
EXPORT CreateResFile ; Given filename, create a null res file
EXPORT CurResFile ; Returns the current resource file refnum
EXPORT DetachResource ; Given handle, detaches it from resources.
EXPORT Get1IndResource ; $A81B (27) OneMapDeep version of GetIndResource
EXPORT Get1IndType ; $A81D (29) OneMapDeep version of GetIndType
EXPORT Get1NamedResource ; $A820 (32) OneMapDeep version of GetNamedResource
EXPORT Get1Resource ; $A81F (31) OneMapDeep version of GetResource
EXPORT GetIndResource ; Given index and type, returns handle
EXPORT GetIndType ; Given index, returns type
EXPORT GetNamedResource ; Given name and type, return handle
EXPORT GetResAttrs ; Given handle, get the attributes of a resource
EXPORT GetResFileAttrs ; Given refnum, return resfile attributes.
EXPORT GetResInfo ; Given handle, get the info of a resource
EXPORT GetResource ; Given an ID and type, give handle back
EXPORT HomeResFile ; Returns refnum of an object's home resfile
EXPORT InitResources ; One-time call, initializes resource manager
; and opens Sys.resource (!refnum)
EXPORT InitRSRCMgr ; initializes the Resource Manager, called from StartInit
EXPORT LoadResource ; Given handle, loads resource from source
EXPORT MaxSizeRsrc ; $A821 (33) size of rsrc without hitting disk
EXPORT OpenResFile ; Given filename, opens and returns refnum
EXPORT OpenRFPerm ; Given filename, permissions, and volrefnum,
; ... do OpenResfile
EXPORT ReleaseResource ; Given handle, releases resource.
EXPORT ResError ; Returns error code, 0 if no error.
EXPORT rGetResource ; $A80C (12) getresource/reverse sys & rom map. <14jan87> BBM
EXPORT RmveResource ; Remove a resource from the resFile
EXPORT RmveReference ; a nop routine added back in for MacWrite 2.2 <17oct85> BBM
EXPORT RsrcMapEntry ; given handle, return offset to rsrc entry
EXPORT RsrcZoneInit ; Zero all handles in the system map
; ... which point to application heap zone
EXPORT SetResAttrs ; Given handle, set the attributes of a resource
EXPORT SetResFileAttrs ; Given refnum, set resfile attributes.
EXPORT SetResInfo ; Given handle, set the info
EXPORT SetResLoad ; Auto-Load on get?
EXPORT SetResPurge ; Write resources when purging?
EXPORT SizeResource ; Returns 4 byte resource size (may go to disk!!)
EXPORT Unique1ID ; $A81E (30) OneMapDeep version of UniqueID
EXPORT UniqueID ; Given type, return a unique ID for that type
EXPORT UpdateResFile ; Given refnum, update resource file
EXPORT UseResFile ; Given refnum, sets current res file.
EXPORT WriteResource ; Given handle, writes resource to file
EXPORT vSuperLoad ; vector to routine superload <27oct85> BBM
EXPORT vCmpFrm ; vector to inside UpdateResFile <27oct85> BBM
EXPORT vNewMap ; vector to routine NewMap <27oct85> BBM
EXPORT vCheckLoad ; vector to the checkload routine. <27oct85> BBM
EXPORT vRMgrStdEntry ; vector to the StdEntry routine. <1.2> BBM
EXPORT vRMgrStdExit ; vector to the StdExit routine. <1.2> BBM
EXPORT StdZEntry ; <9> rb
EXPORT Std1Entry ; <9> rb
EXPORT RStdExit ; <9> rb
EXPORT RdData ; <9> rb
EXPORT WrData ; <9> rb
EXPORT SaveRegs ; <9> rb
EXPORT SpaceAt ; <9> rb
EXPORT CheckGrowAt1 ; <9> rb <SM26> rb
EXPORT RefHandle ; <9> rb
EXPORT AddNewRef ; <9> rb
EXPORT AddNewRefWithoutUpdate ; <SM48> kc
EXPORT AddName ; <9> rb
EXPORT RRentry6 ; <9> rb
EXPORT ROMOpenRFPerm ; <9> rb
EXPORT HCreateResFile,HOpenResFile ;<SM9> <PN>
EXPORT FPCallROvr ; <SM27> bt
EXPORT FPCallCacheFlush ; <SM27> bt
EXPORT FPCallDonnDecompress ; <SM27> bt
EXPORT FPCallGreggyPrepare ; <SM27> bt
EXPORT FPCallGreggyDecomp ; <SM27> bt
EXPORT FPCallGreggyDone ; <SM27> bt
EXPORT FPCallResErrProc ; <SM27> bt
EXPORT FPCallCountIExit ; <SM27> bt
EXPORT FPvCmpFrm ; <SM38> bt
EXPORT SuperLoad ; <SM38> bt
EXPORT NewMap ; <SM38> bt
EXPORT CheckLoad ; <SM38> bt
;_______________________________________________________________________________
; Register conventions throughout the Resource Manager:
;
; A0, D0, D1, D2, D7 scratch.
;
; A1 is the handle to the resource
; A2 points to an entry in the map
; A3 points to the beginning of a sub-block
; A4 is the map handle
;
; D3 is the resource type, if any
; D4 is the number of resource entries (-1) for looping
; D5 is the number of types (-1) for looping
; D6 is the resource map reference number
;
; A6 is always LINKed, through StdEntry. There is only 1 local variable,
; an IOStackFrame. A0 also always points to 8(A6) when returning from StdEntry.
;_______________________________________________________________________________
;_______________________________________________________________________________
;
; NullRF the null resource file.
; NullStr just points to the word 0.
; RMGRVersion the resource manager version number
;_______________________________________________________________________________
BLANKS ON
STRING ASIS
MACHINE MC68020
NullRMSize EQU 30 ; number of bytes in a null map
NullStr ; Null String (pascal string 1st byte 0)
NullRF ; Null Resource map
DC.W 0, DataFirstRes ; ResDataOffset
DC.W 0, DataFirstRes ; ResMapOffset (no data!)
DC.W 0, 0 ; DataSize
DC.W 0, NullRMSize ; MapSize
DC.W 0, 0 ; MNext <1.1>
DC.W 0 ; MRefNum
DC.W 0 ; MAttr
DC.W MTyps-NullRF ; MTypes
DC.W MNams-NullRF ; MNames
MTyps DC.W -1 ; no types listed
MNams DC.W 0 ; null string
RMGRVersion DC.W 1 ; Resource Manager version number
;_______________________________________________________________________________
;
; Routine: InitRSRCMgr
;
; Arguments: none
;
; Called By: system initialization sequence in StartInit
; Calls: InitResources
; Destroys: D0-D2/A0-A1
;
; Function: Call the Resource Manager to load ROM rsrcs and set up his
; indefatigable world.
;_______________________________________________________________________________
InitRSRCMgr ST SysMap ; flag that resources are not inited
CLR.L TopMapHndl ; tell the res mgr that it's start time
move.l ExpandMem,a0 ; init override flags <SM48> kc
clr.b ExpandMemRec.emScanOverrideMaps(a0) ; turn off ScanOverrideMaps <SM48> kc
clr.w ExpandMemRec.emLastMapOverridden(a0) ; flush override cache. <SM48> kc
clr.w ExpandMemRec.emOverrideMapRefNum(a0) ; flush override cache. <SM48> kc
; <SM48> kc
CLR.W -(SP) ; Save room for function result
_InitResources ; Init ROM resource file
ADDQ #2, SP ; Assume success
RTS
;_______________________________________________________________________________
;
; Routine: FUNCTION InitResources: INTEGER;
;
; Arguments: 8(A6) (output.W) Refnum of Sys.rsrc map
;
; Called By: A-trap through Dispatcher
; Calls: StdEntry, NewMap, PreLoad, StdZeroExit, BuildMap
;
; Function: Now a Two-time call, in order to support ROM Resources. First,
; it sets up the ROM resources as the Current and System (& only)
; Map in memory. Second call initializes resource manager & opens
; Sys.rsrc switching pointers to make it the System map and the
; Rom map and the current map.
; Returns the reference number of the Sys.rsrc map.
; Sets ResLoad to TRUE initially, in PreLoad.
;_______________________________________________________________________________
IMPORT SmgrInitialize ;
InitResources
; deleted the stuff here that called FixSMgrWorld: was never executed <07/02/89 pke>
CLR.L HSCHandle ; Invalidate cache <12mar85> BBM
BSR StdZEntry ; Save regs <11jul85> BBM
TST.L TopMapHndl ; are the ROM resources "loaded in"? <31jan85> BBM
BGT.S @skipROM ; CC=LE means to build rom map from scratch <27aug85> BBM
CLR.L ResErrProc ; clear for start code <27aug85> BBM
BSR ROZInit ; initialize a Read-Only-Zone
MOVE.L A0,TopMapHndl ; Save handle as top map
MOVE.L A0,SysMapHndl ; and as system map
MOVE.L OneOne,SysMap ; Make SysMap & Curmap refnum = 1
BSR ReDoMap ; set up map from rom image (Returns A1 Ptr)
CLR.L MNext(A1) ; Zero next map handle
BRA.S @exit ; and exit through StdExit
@skipROM
LEA theZone, A3 ; ... else do full load,Point to theZone.
MOVE.L (A3), -(SP) ; Save the current zone
MOVE.L SysZone, (A3) ; Set system heap for system resource map.
LEA SysResName, A1 ; Point to name of system resource.
MOVEQ #$00,D0 ; nil dir id <SM9> <PN>
BSR NewMap ; Load in map, refnum in D6, result in D0.
MOVE.L (SP)+, (A3) ; Restore the zone
MOVE.W D6, 8(A6) ; Return result/error code.
TST.L D0 ; Test newMap result in D0.
BLE.S @exit ; if <=0, error or already open.
MOVE.L A4,TopMapHndl ; Save handle as top map <05sep85> BBM
MOVE.L A4,SysMapHndl ; Save handle as sys map <05sep85> BBM
MOVE.W D6,CurMap ; set up curmap <09jul85> BBM
MOVE.W D6,SysMap ; set up sysmap <10jul85> BBM
BSR PreLoad ; Preload required resources... <31jan85> BBM
BSR ReDoMap ; restore the ROM map (Returns A1 pointer)
MOVE.L SysMapHndl,MNext(A1) ; next map in link from rom is system
MOVE.L SysMapHndl,A1 ; get handle to system map
MOVE.L (A1),A1 ; and dereference system handle
CLR.L MNext(A1) ; sysmap is last link in chain
BSR.S RomOverRide ; check which rom rsrc's to override
move.l IntlSpec,D0 ; if IntlSpec is not set up, <1.2><1.3>
addq #1,D0 ; go set it up. <1.2><1.3>
BigJsr SmgrInitialize,a0 ; <SM22>
@exit
; Rolled in InstallProc rolled in to set emScanOverrideMaps to true here.
move.l ExpandMem,d0
beq.s @noExpandMem
move.l d0,a0
move.w #-1,ExpandMemRec.emScanOverrideMaps(a0)
@noExpandMem
BRA StdZeroExit ; ...and exit.
;_______________________________________________________________________________
;
; Routine: RomOverRide 65446 (utility)
;
; Arguments: None
;
; Called By: InitResources
; Calls: _GetResource
;
; Function: Checks to see if there is a override resource in the new file
; opened. If there is, it executes that resource.
;
; NOTE: The override resource must be preloaded, locked, & nonpurgable.
;_______________________________________________________________________________
ROVR EQU $524F7672 ; ROVR = 'ROvr' (type of override rsrc)
RomOverRide ; new routine <27aug85> BBM
SUBQ #4,SP ; Save room on stack for handle
PEA ROVR ; rsrc type for override
MOVE.W #0,-(SP) ; rsrc ID of 0
MOVE #-1,RomMapInsert
_GetResource ; get the override rsrc
SUBQ #4,SP ; Save room on stack for handle
PEA ROVR ; rsrc type for override
MOVE.W #0,-(SP) ; rsrc ID of 0
_GetResource ; get the override rsrc
MOVEQ.L #0,D1
MOVE.L (SP)+,D0 ; Check to see if it exists
BEQ.S @Lx
MOVE.L D0,A0 ; get ready to execute this resource
MOVE.L (A0),A0 ; dereference handle
Move $8(A0), D1
@Lx MoveA.L (SP)+, A1
Move.L A1, D2
BEQ.S @L0
MoveA.L (A1), A0
Move $8(A0), D2
@L0 Cmp D2, D1
BHI.S @L2
Tst.L D0
BEQ.S @L1
Cmp.L A1, D0
BEQ.S @L1
Move.L A1, -(SP)
Move.L D0, -(SP)
_ReleaseResource
MoveA.L (SP)+, A1
@L1 Move.L A1, D0
BEQ.S ROvrOut
@L2 MoveA.L D0, A0
MoveA.L (A0), A0
FPCallROvr ; FlashPort hint attachment point <bt>
JSR (A0) ; and execute handle
ROvrOut RTS ; and return
; <1.5> Equates
ComBFSz EQU 5 ; combo bitfield size
MemHeadSz EQU 8 ; size of memory header
MaxComInd EQU 4 ; maximum valid combo field index
RNmOff EQU $F ; offset from past the combo field to the name size <3>
;_______________________________________________________________________________
;
; Routine: ROZInit (utility)
;
; Arguments: A0 (output.L) Handle to the Map in the ROZ
; A2 (output.L) Pointer to the Map up in the ROM
; RomMapHndl (output.L) Handle to the Map in the ROZ
;
; unchanged: A3-A7,D1-D7
; trashes: A1-A2,D0
;
; Called By: InitResources
; Calls: _BlockMove, _InitZone, _NewHandle, _NewPtr
;
; Function: Builds a new zone in the system heap. This zone is a Read Only
; Zone. The size of the new zone can be calculated by the fomula:
;
;<A291/29oct86> bbm memory manager is now long word aligned, which changes ROZinit.
;<C396/4dec86> agh Make master pointer size 8 bytes for use with UNIX 32 bit
; memory mgr.
;
;_______________________________________________________________________________
;
; Size = zoneheader + zonefooter + longwordalignbias + slop
; + (12 + block of 4 master pointers)
; + (12 + size of master pointer block) + (12 + size of map)
; Size = 52 + 12 + 12 + (12 + 32) + (12 + sizempb) + (12 + sizemap) + slop <c396>
; Size = 144 + sizebmp + sizemap + slop <c396>
; Size = $90 + 8*X + Y+slop ; (where X = number of rsrc's <c396>
; Size = 8*(#$18 + X) + Y ; and Y = size the map) <c396>
;
;The old stucture of the ROM is as follows:
; ROMRsrcStart: (long) ; offset to Rom Rsrc stuff
; Rom Rsrc Stuff
; X: (2) number of rsrc's in rom
; Y: (2) size of rom rsrc map in rom
; Map: (Y) the rom map
; rsrc's: (x) the rsrc's
;
;The new stucture of the ROM is as follows:
; RomBase
; 1A (4) offset to Rom Resource Structure Table
;
; Rom Resource Structure Table
; 0 (4) offset to first Resource Entry
; 4 (1) maximum valid index in parameter ram [v]
; 5 (1) Size of Combo Bit Field (v)
; 6 (2) Version
; 8 (2) Size of memory block header
;
; Hiram Resource Entry (all are offsets from base of rom)
; 0 (v) combo bits
; v (4) link to next Resource
; v+4 (4) offset to data for this rsrc
; v+8 (4) Resource Type
; v+C (2) Resource ID
; v+E (1) Resource Attributes
; v+F (1) length of Resource name [n]
; v+$10 (n) Resource name
; v+$10+n (0-3) align 4
; g(v+$10+n) (8/12) memory block header
; g(v+$10+n)+8 (y) Resource Data [or g(v+C+n) + 12, depending on which mem mgr]
; x+y (0-3) align 4
;
; where g(w) = w + ((4 - (w mod 4)) mod 4)
;
;_______________________________________________________________________________
ROZInit ; new routine <27aug85> BBM <1.5>
bsr CountCombos ; to determine the sizes <1.5>
move.l d0,d5 ; save count in D5
move.l d1,d6 ; save map size in d6
moveq #$18,d0 ; clear high word (D0 will be size of ROZ) <1.5>
add.w d5,d0 ; add in number of MP's
asl.l #3,d0 ; multiply by 8 (the size of a MP)
add.w d6,d0 ; Add in size of map [D0 = 8*(#$10 + X) + Y]
; Note to accomodate Figment, we make the ROZ larger. -JC
add.l #1000,d0
move.l d0,a1 ; Save off Zone size for later
_NewPtr ,SYS ; no error checking. If failure, system dead.
MOVE.L theZone,-(SP) ; save current zone till after map build
CLR.L -(SP) ; pGrowZone = 0
MOVE.W #4,-(SP) ; cMoreMasters = 4
ADDA.L A0,A1 ; limitPtr = startPtr + Size
MOVE.L A1,-(SP) ; ... and storing to parameter block
MOVE.L A0,-(SP) ; setting up parameter block for _InitZone
MOVE.L A0,A1 ; save pointer to zone for later
MOVE.L SP,A0 ; Point A0 to the paramter
_InitZone ; finally get to set up zone
BSET #ROZ,flags(A1) ; make this zone a read-only zone
MOVE.L A1,theZone ; we want ROM Rsrcs in this new zone
ADD.W #$E,SP ; pop off parameter block from stack
move.l d5,D0 ; get number of MP's <1.5>
ASL.L #3,D0 ; Get the size (size = 8*X) <c396>
_NewPtr ; get MPB in ROZ. (If failure, system dead.)
MOVE.W d6,D0 ; get the size of the map <1.5>
_NewHandle ; get map in ROZ. (If failure, system dead.)
_HLock ; itÕs always there, so lock it <C169>
MOVE.L A0,RomMapHndl ; Save this handle.
MOVE.L (Sp)+,theZone ; restore current zone
RTS
;_______________________________________________________________________________
;
; Routine: ReDoMap (utility)
;
; Arguments: A1 (output.L) pointer to the map in the ROZ
;
; unchanged: A5-A7,D6-D7
; trashes: A0,A2-A4,D0-D5
;
; Called By: InitResources
; Calls: _SetHandleSize, _BlockMove, GetRsrcCnt, SetPL
;
; Function: This routine builds Rom map in the ROZ. ReDoMap assumes that
; the ROZ is already built, and ignores all previous data in ROZ.
;_______________________________________________________________________________
ReDoMap ; new routine
bsr CountCombos ; to determine the sizes
move.l d1,d0 ; get approximate size of map into d0
move.l RomMapHndl,A0 ; Get the handle to the ROM Map in ROZ
move.l A0,A4 ; Save for later
_SetHandleSize ; Old resource map could have overrides
moveq #$20,d0 ; size of null map
lea NullRF,a0 ; get null map from rom
move.l (A4),A1 ; Dereference handle to destination
_BlockMoveData ; move map down
move.w #1,MRefNum(a1) ; and stuff the rom map refnum (so getcurmap works)
clr.w -(sp) ; get a buffer on the stack to read in index
move.l sp,a0 ; point to stack
move.l #$000100AE,d0 ; get selected resource combo index
_ReadXPram ;
move.b (a0),d3 ; save index in d1
addq #2,sp ; dispose of buffer
; add all the resources, set up the regs to look like:
; a2.l pointer to resource header
; d2.l combo field size
; d3.b index
; d4.w size of memory block header (in bytes)
move.l RomBase,a2 ; get pointer to romstart
adda.l RomRsrcStart(a2),a2 ; add in offset to Rom Rsrc Stuff
moveq #0,d2 ; zero combo bitfield size
move.b ComBFSz(a2),d2 ; get combo bitfield size
move.w MemHeadSz(a2),d4 ; get size of memory header
tst.b d3 ; combo zero means use default (PRAM init'ed) <1.6>
beq.s @default ; if invalid PRAM, use machine specific default <1.6>
cmp.b MaxComInd(a2),d3 ; check if d3 too big
bls.s @good ; <SM42>
@default ; if out of range, or invalid, use default <1.6>
movea.l UnivInfoPtr,a0 ; point to the universal ProductInfo record <1.6>
move.b ProductInfo.DefaultRSRCs(a0),d3 ; get the default combo <1.6>
@good ;
; Test for an optional FPU. Combos 3 and 4 are identical except 3 inludes FPU <2>
; Combos are defined in Rom.r. **** If combos change, make sure test is valid !!!*** <2>
cmpi.b #4,d3 ; combo with optional FPU? <2>
bne.s nochange ; branch if not combo with optional FPU <2>
btst.b #hwCbFPU-8,HWCfgFlags ; FPU installed on board? <2>
beq.s nochange ; branch if no FPU installed <2>
moveq #3,d3 ; change to combo with FPU <2>
nochange ; <2>
move.l (a2),a2 ; offset to the first resource.
add.l RomBase,a2 ; make offset a pointer
@loop
;first check if this combo is valid
move.l a2,a0 ; get combo field pointer
moveq #0,d0 ; clear upper bytes
move.b d3,d0 ; get index
lsr.b #3,d0 ; div by 8
add.w d0,a0 ; bump a0 to the right byte
move.b d3,d0 ; get index into this byte (index is 0-7)
eori.b #$FF,d0 ; reverse index
andi.b #7,d0 ; make index correct (index is now 7-0)
btst.b d0,(a0) ; check if this resource should be included
add d2,a2 ; point at link to next entry (no ccÕs set)
beq.s @bypass ; this resource not in current combo, so skip
;add this resource
move.l 4(a2),a3 ; get ptr to resource data
adda.l RomBase,a3 ; make offset a pointer (cc's not changed)
; set up master pointer
move.l RomMapHndl,A0 ; get a pointer to the start of ROZ Zone
_HandleZone ;
move.l -4(A3),D0 ; Rel handle may have useful hi byte
_StripAddress ; Restrict to 24MB range off header
adda.l D0,A0 ; Add in offset to MP [-4(A1) is the RelHandle]
move.l A3,(A0) ; stuff MP with pointer to rsrc in ROM
move.l a0,-(sp) ; push the handle
move.l $8(a2),-(sp) ; push the Resource Type
move.w $C(a2),-(sp) ; push the Resource ID
pea $F(a2) ; push pointer to Resource name
IF 0 THEN
move.l RomMapHndl,A0 ; get a handle to the map
move.l (a0),a0 ; point to the map
moveq #0,d7 ; zero high byte
move.w $1c(a0),d7 ; save number of types across call
ENDIF
bsr.s addRomRsrc ; add the resource
IF 0 THEN
move.l RomMapHndl,A0 ; get a handle to the map
move.l (a0),a0 ; point to the map
sub.w $1c(a0),d7 ; subtract new number of types
lsl.w #3,d7 ; mult by 8 for new map size delta (new type entry)
add.w #12,d7 ; for new resource entry
add.l d7,MapSize(a0) ; fix map size
move.l -8(A3),D0 ; get the size in d0
_StripAddress ; since in 24 bit world size may have flags in upper byte
addq #4,d0 ; for size in data
add.l d0,ResMapOffset(a0) ; adjust map offset (although all this is bogus)
add.l d0,DataSize(a0) ; adjust data size (really bogus, but looks nice)
ENDIF
@bypass ;
move.l (a2),a2 ; offset to next resource header
move.l a2,d0 ; check if no more in the list
adda.l RomBase,a2 ; make offset a pointer (cc's not changed)
bne.s @loop ; go find next link
move.w #1,MRefNum(A1) ; save the refnum of the rom file in map
rts ; and return
;_______________________________________________________________________________
;
; Routine: CountCombos (utility)
;
; Arguments: D0 (output.W) number of resources in the rom.
; D1 (output.L) Approximate Size of Rom Resource Map
;
; unchanged: A0-A7,D2-D7
; Trashed: d0-d1 (upper word trashed, lower word is output)
;
; Called By: ReDoMap, ROZInit
; Calls: not a soul.
;
; Function: Go Through the linked list and count the number in the list and
; get the total size of all the names.
;_______________________________________________________________________________
CountCombos ; new routine <1.5>
movem.l d2-d4/a2,-(sp) ; save d0-d1/a0 across call
move.l RomBase,a2 ; get pointer to romstart
adda.l RomRsrcStart(a2),a2 ; add in offset to Rom Rsrc Stuff
moveq #0,d2 ; zero combo bitfield size
move.b ComBFSz(a2),d2 ; save combo bitfield size
move.l (a2),a2 ; offset to the first resource.
add.l RomBase,a2 ; make offset a pointer
moveq #0,d0 ; clear count
moveq #0,d1 ; clear total name size
moveq #0,d3 ; clear temp name size
@loop
addq #1,d0 ; add one to the count of the resources
add d2,a2 ; jump past the combo bit field
move.b RNmOff(a2),d3 ; get the name size (only get one byte!)
bmi.s @resourceNotNamed ; donÕt add the name size if not named <13> stb
add.l d3,d1 ; add into total name size <3> <13> stb
@resourceNotNamed ; <13> stb
move.l (a2),a2 ; offset to next resource header
move.l a2,d4 ; check if no more in the list
add.l RomBase,a2 ; make offset a pointer
bne.s @loop ; go find next link
; to get approx size of map
; use headersize + 8*n + 12*n + namesize
; 28 + (20)*n + d1
; where n is number of resources and d1 has the size of names.
move.l d0,d2 ; get number of resources
mulu #$14,d2 ; multiply by size of type entry and resource entry
addi.l #$1c,d2 ; add in map header
add.l d2,d1 ; add into the size of names
movem.l (sp)+,d2-d4/a2 ; restore registers
rts ; and return
;_______________________________________________________________________________
;
; Routine: PROCEDURE AddRomRsrc(theResource:Handle; theType:LONGINT;
; theID:INTEGER; name:Str255);
;
; Arguments: 18(A6) (input.L) handle to the resource
; 14(A6) (input.W) theType
; 12(A6) (input.W) theID
; 8(A6) (input.L) pointer to pascal string
;
; Called By: ReDoMap
; Calls: StdEntry, GetCurMap, AddNewRef, AddName, StdExit
;
; Function: Add a reference to the given resource in the rom map.
;_______________________________________________________________________________
RomAttrs EQU $58 ; the default rom resource attributes
; (protected, locked, sysheap)
AddRomRsrc
move.w #MapTrue,RomMapInsert ; don't insert ROM Map
bsr StdEntry ; Link A6, save regs
move.l 18(a6),a1 ; Get handle in A1 (has to be valid!)
bsr GetCurMap ; Get the current map for diskFull check
move.l 14(a6),d3 ; Put type of resource to add in D3
bsr AddNewRef ; Set up a new reference to the resource
; Returns A2-->reference location.
move.w 12(a6),RID(a2) ; Set ID of reference
move.w #-1,RNameOff(a2) ; Assume no name yet
move.l 8(A6), A0 ; Get pointer to reference name
bsr AddName ; Name set in RNameOff(A2).
; A2, A3 preserved and are correct.
move.l 18(a6),a0 ; get the handle to the resource
move.l A0,RHndl(a2) ; set handle.
move.l (a0),a0 ; point at the resource
sub.l rombase,a0 ; make a0 an offset into rom
move.l a0,RLocn(a2) ; store offset into map
move.b #RomAttrs,RAttr(a2) ; set rom resource attributes
@9 moveq #14, D0 ; Pop off 14 bytes of parameter
bra StdExit ; Restore regs, unlink A6
;_______________________________________________________________________________
;
; Routine: PreLoad (Utility)
;
; Arguments: There are no input arguments.
; The world is left in a weird state on exit (no regs dependable).
;
; Called by: (Preload): InitResources
; (Preload2): OpenResFile
; Calls: GetMap, FirstRes, CheckLoad, NextRes
;
; Function: Clear the handle locations for all local (i.e. non-resSysRef)
; resource entries, and load in all resources in the current map
; which have the resPreload bit set.
;
; PreLoad walks through the map in file order. This was done to
; optimize the file I/O and buffer hits.
;_______________________________________________________________________________
Preload
ST ResLoad ; Set ResLoad to True (byte operation)
Preload2 ; alternate entry for OpenResFile
BSR GetMap ; Get the current map <06may85> BBM
BMI.S @9 ; if can't find map then exit
BSR GetRsrcCnt ; get the first resource entry <10may85> BBM
BMI.S @9 ; if no entries just exit
@1 ADDQ #RHndl,A2 ; point at the resource entry handle
CLR.L (A2)+ ; clear it and point and next rsrc entry
DBRA D4,@1 ; if more, loop back, else fall through
TST.B ResLoad ; if (ResLoad = False) just return <22apr85> BBM
BEQ.S @9 ; ... sure enough resload is false (CC=EQ)
BSR.S SuperLoad ; if we can do fast load then this does it <24jun85> BBM
BEQ.S @9 ; CC=EQ means that we have loaded in rsrcs
@2 MOVEQ #ResPreLoad,D1 ; Which bit to test on the lowest level <09apr85> BBM
BSR FirstRes ; Point A2 to 1st preload file-order entry <08mar85> BBM
BMI.S @9 ; if none, exit.
@3 BSR CheckLoad ; load in the resource.
MOVEQ #ResPreLoad,D1 ; Which bit to test on the lowest level <29apr85> BBM
BSR NextRes ; Skip to next preload entry in file order. <08mar85> BBM
BEQ.S @3 ; If there are more, loop back
@9 RTS ; ...and return.
;_______________________________________________________________________________
;
; Routine: SuperLoad (internal) <06may85> BBM
;
; Arguments: A4 (i/o.L) Handle to the new map
;
; Unchanged: A4-A7,D6
; Trashed: A0-A3,D0-D5,D7
;
; Called By: Preload/Preload2
; Calls: _BlockMove, _DisposHandle, GetEntries, GetMaxLoad, _NewEmptyHandle,
; _NewHandle, _NewPtr, NextEntry, NotFound, SetPL, SetupInBuff
;
; Function: Try to load all of the resources you can in a more intelligent
; fashion. If you cann't then exit with CC=MI. This means you'll
; have to do the old stupid preload. GetMaxLoad determines if
; this is a new format, how much of the file to read in, and reads
; the data into a buffer.
;
; future note - Try taking advantage of all the information in the cache.
;_______________________________________________________________________________
SuperLoad
MOVE.L jSuperLoad,A0 ; get the vector from the OSJumptable <27oct85> BBM
JMP (A0) ; and go to the routine <27oct85> BBM
vSuperLoad ; Def to build dispatch entry <27oct85> BBM
BSR GetMaxLoad ; load in as much as we can for super load <24jun85> BBM
BMI NotFound ; if nothing to SuperLoad return (old format)
BSR GetEntries ; get the first resource entry <07may85> BBM
MOVE.L (A4),A1 ; dereference map handle
@1 MOVE.L RLocn(A2),D0 ; check if this rsrc is in the buffer <24jun85> BBM
AND.L Lo3Bytes,D0 ; mask off attributes
CMP.L HSCache,D0 ; offset to end of buffer
BGE @7 ; skip to the next one <SM25> CSS
MOVE.L theZone,-(SP) ; save theZone for later <08may85> BBM
BTST #ResSysHeap,RAttr(A2) ; which zone do we put this rsrc?
BEQ.S @2 ; skip if default zone.
MOVE.L SysZone,theZone ; else force system heap
@2 MOVE.L RLocn(A2),D2 ; Get offset into file
AND.L Lo3Bytes,D2 ; clear high bits.
BSR SetupInBuff ; setup D0=size; A0=Ptr2Rsrc <SM25> CSS
BTST #ResLocked,RAttr(A2) ; if locked do NewPtr ...
SUBA.L (A4),A2 ; (Make A2 an Offset)
SUBA.L (A4),A3 ; (Make A3 an Offset)
BEQ.S @3 ; ... else do NewHandle <15may85> BBM
; We have a locked resource. Do contortions to <c396>
; get the resource loaded low (NewPtr style). <c396>
MOVE.L D0, D1 ; Save Resource Size. <c396>
_NewEmptyHandle ; NewEmptyHandle / DisposeHandle pair insures <c396>
BMI @9 ; that a master pointer will be available <c396> <SM25> CSS
_DisposHandle ; without allocating a new master pointer blk <c396>
BMI @9 ; when we do the for-real _NewHandle. <c396> <SM25> CSS
MOVE.L D1, D0 ; Grab block size. <c396>
_NewPtr ; NewPtr allocates block of desired size low <c396>
BMI @9 ; and leave roving allocate ptr set to it. <c396> <SM25> CSS
_DisposPtr ; DisposPtr leaves the perfect free block <c396>
BMI.S @9 ; for subsequent NewHandle to allocate. <c396>
MOVE.L D1, D0 ; Restore block size into D0 <c396>
@3 _NewHandle ; Get a handle for this rsrc (D0 already setup)
BMI.S @9 ; any error go do regular preload stuff
MOVE.L A0,D1 ; save off Handle to stuff into map
MOVE.L (A0),A1 ; Get Destination into A1 for BlockMove
@6 BSR.S SetupInBuff ; note destination already has A1
_BlockMove
ADDA.L (A4),A2 ; Make A2 a pointer again
ADDA.L (A4),A3 ; Make A3 a pointer again
MOVE.L D1,RHndl(A2) ; and tell RMGR resource is loaded in.
MOVE.L D1,A0 ; get handle into A0 to setup purge/lock bits
MOVE.B RAttr(A2),D1 ; get attrs into D1 to setup purge/lock bits
BSR SetPL ; setup purge/lock bits
MOVE.L (SP)+,theZone ; restore theZone
@7 BSR NextEntry ; go get the next entry to clear handle
BPL.S @1 ; if more entries, loop back
MOVE.L D7,A0 ; get handle to InBuff into A0
_DisposHandle ; free up the memory
@8 MOVEQ #0,D0 ; set completion flag (CC=EQ)
RTS ; ... and return no error
@9 MOVE.L (SP)+,theZone ; restore theZone
@5 MOVE.L D7,A0 ; get handle to InBuff into A0
_DisposHandle ; free up the memory
BRA NotFound ; return with error.
SetupInBuff
MOVE.L D7,A0 ; get handle to Input Buffer (buff may have moved)
MOVE.L (A0),A0 ; dereference it
ADDA.L D2,A0 ; add in offset (D2 can be odd, Byte stuff follows)
OddSize ; added new entry for UpdateResFile <07jun85> BBM
MOVE.B (A0)+,D0 ; X.X.X.0 - We want '0.1.2.3' byte order <09may85> BBM
LSL.W #8,D0 ; X.X.0.X
MOVE.B (A0)+,D0 ; X.X.0.1
SWAP D0 ; 0.1.X.X
MOVE.B (A0)+,D0 ; 0.1.X.2
LSL.W #8,D0 ; 0.1.2.X
MOVE.B (A0)+,D0 ; 0.1.2.3 - Size=D0, rsrc=A0
RTS ;
;_______________________________________________________________________________
;
; Routine: GetMaxLoad (internal)
;
; Arguments: D0 (output.L) -1 on error; size of data on good rts
; D7 (output.L) Handle to input buffer
;
; Unchanged: A1-A7,D3-D6
; Trashed: A0,D0-D2
;
; Called By: SuperLoad
; Calls: _DisposHandle, _MaxBlock, _NewHandle, NotFound, RdData
;
; Function: Four step process. First, find out how much space is available
; in the application zone without moving anything, or purging
; anything. Second, find out size of resources to be read in.
; Third, get a NewHandle of twice the size to get us some room to
; work in, and toss it away. (This forces the heap to grow as much
; as we will need.) Fourth, get a NewHandle of the size we need
; and read in data. Return with CC=MI or D7=handle of input buff.
;_______________________________________________________________________________
GetMaxLoad ; READ IN MAX AMOUNT TO DISECT IN SUPERLOAD <24jun85> BBM
TST.L HSCache ; is there a valid key?
BEQ @9 ; wrong format for superload <SM25> CSS
MOVEQ #0,D7 ; D7 is the amount we can grow heap.
MOVE.L SP,D0 ; Get top of Stack.
_StripAddress ; Want clean arithmetic. <C169>
SUB.L MinStack,D0 ; Allow some stack margin.
CMP.L ApplLimit,D0 ; if ApplLimit is greater then use ...
BCS.S @1 ; ... use ApplLimit instead.
MOVE.L ApplLimit,D0 ; D0 now has the maximum limit
@1 SUB.L HeapEnd,D0 ; if D0 <= HeapEnd
BLE.S @2 ; ... then can't grow heap
CMP.L #MinFree,D0 ; can the zone grow by the minimum size
BLS.S @2 ; ... if not, can't grow heap.
MOVE.L D0,D7 ; Stuff D7 with the amount to grow heap.
@2 _MaxBlock ; D0 has max space after a compact.
CMP.L D7,D0 ; does compact or growheap get us more?
BLE.S @3 ; D7 already has max value,
MOVE.L D0,D7 ; ... else D7 = amount we can grow heap.
@3 MOVE.L HSCache+PreExtra,D0 ; calc how much to read in for superload? <13jan86> BBM
BSR.S SizeFits ; check to see if this size fits in buff <04sep85> BBM
BPL.S @4 ; CC=PL if this fits
MOVE.L HSCache+PreUnlock,D0 ; check if PreUnlock fits <13jan86> BBM
BSR.S SizeFits ; check to see if this size fits in buff
BPL.S @4 ; CC=PL if this fits
MOVE.L HSCache+PreLock,D0 ; check if Prelock fits <13jan86> BBM
BSR.S SizeFits ; check to see if this size fits in buff <04sep85> BBM
BMI.S @9 ; not even this fits, so exit with error
@4 _NewHandle ; by allocating some room <15may85> BBM
BMI.S @9 ; if cann't even do this exit
_DisposHandle ; else dispose of space to get us some room <15may85> BBM
MOVE.L D1,D0 ; need to know size for newhandle <07may85> BBM
_NewHandle ; get some space to read in the Rsrcs
BMI.S @9 ; and return to preload with error
MOVE.L D1,D0 ; get size into D0 for read
MOVE.L A0,D7 ; Save off handle of PreLoad input Buffer
MOVE.L (A0),D1 ; set up pointer to this buffer
MOVE.L (A4),A0 ; Dereference map handle to get offset
MOVE.L ResDataOffset(A0),D2 ; get start position in file
BSR RdData ; massive read of data into Buff (D6 good)
BEQ.S @8 ; if read good return
MOVE.L D7,A0 ; get handle to buffer into A0
_DisposHandle ; else dispose of space to get us some room <11jul85> BBM
@9 MOVEQ #-1,D0 ; ELSE ERROR RETURN
@8 RTS ;
SizeFits ; new routine <04sep85> BBM
MOVE.L D0,HSCache ; save off for SuperLoad
BEQ NotFound ; if nothing to load, set CC's to MI
BMI.S @9 ; If CC=MI, just return
MOVE.L D0,D1 ; Save off for later
ADD.L D0,D0 ; double D0
MOVE.L (A4),A0 ; Dereference map handle
ADD.L MapSize(A0),D0 ; add in size of map
CMP.L D0,D7 ; Set CC's and return
@9 RTS ;
;_______________________________________________________________________________
;
; Routine: NewMap (Utility)
;
; Arguments: A1 (input.L) pointer to filename
; A1 (output.L) pointer to map
; A2 (output.L) handle to map
; D0 (output.L) result code
; D6 (output.L) file reference number
;
; Called by: InitResources, OpenResFile
; Calls: _Close, _DisposHandle, _GetEOF, _NewHandle, ORFCommon, RdData,
; SetFileIO, _SetHandlesize
;
; Function: Create a new resource map in the RMGR map chain for the given
; resource file. Sets up regs A1/A2/D0/D6 with values for input
; filename. Three possible returns:
; D0 = 0; D6 = MRefNum Map already exists
; D0 = 1; D6 = refnum New map created
; D0 = D6 = -1 Error return
;_______________________________________________________________________________
NewMap
MOVE.L jNewMap,A0 ; get the vector from the OSJumptable <27oct85> BBM
JMP (A0) ; and go to the routine <27oct85> BBM
vNewMap ; Def to build dispatch entry <27oct85> BBM
CLR.L HSCache ; invalidate cache always <20jun85> BBM
CLR.L HSCHandle ; invalidate cache
MOVEQ #HdrSize+PreSize,D0 ; Set length = header size <11jul85> BBM
_NewHandle
MOVE.W D0, ResErr ; return the error code in ResErr <16apr85> BBM
BMI NMNoHandle ; If failed this little newHandle, exit,
MOVE.L A0,A4 ; else save handle in A4 <05sep85> BBM
BSR SetFileIODirID ; Set up the file IO frame A0 -->
BSR ORFCommon ; Open the resource file with name in A1 <SM9> <PN>
BEQ.S @1 ; If open was successful, go on
CMP.W #OpWrErr, D0 ; Already open?
BNE NMNoFile ; If not open, can't handle, else
MOVEM.L A2-A4/D6,-(SP) ; save regs across call <17sep85> BBM
BSR GetMap ; check to see if map exists <17sep85> BBM
MOVEM.L (SP)+,A2-A4/D6 ; restore regs <17sep85> BBM
BNE NMNoFile ; If no map then exit with error <27oct85> BBM
CLR.W ResErr ; Clear the error flag if open
MOVE.L A4, A0 ; Get the map handle <05sep85> BBM
_DisposHandle ; and deallocate it. Map already exists.
; DisposHandle returns D0=0, signal already open.
RTS ; D6=refnum of already opened file
; The file exists.
; Check size; if not null, load map & set up handles.
@1 _GetEOF ; Get the EOF of the resource fork.
MOVE.W #EOFErr, ResErr ; Assume EOF error (null fork)
TST.L IOLEOF(A0) ; Is it a null fork?
BEQ NMFail ; If so, close and fail--no map to load. <SM25> CSS
MOVEQ #HdrSize+PreSize,D0 ; byte count=HdrSize <11jul85> BBM
MOVE.L (A4), A1 ; dereference map handle to ptr. <05sep85> BBM
MOVE.L A1, D1 ; Copy to D1 for RdData
MOVEQ #0, D2 ; Start at beginning of file
BSR RdData ; Read data, set new ResErr result.
BMI NMFail ; If failed, return error+close file. <SM25> CSS
MOVEA.L A1,A0 ; Source for blockmove <20jun85> BBM
ADDA.L #HdrSize,A0 ; ... finish calc for source
LEA HSCache,A1 ; Destination for blockmove
MOVE.L #PreSize,D0 ; size for blockmove <11jul85> BBM
_BlockMoveData ; move the key data to the stack
MOVEA.L A0,A1 ; restore A1
SUBA.L #HdrSize,A1 ; ... finish restoring A1
BSR PreFormat ; check the preload format of this file <SM25> CSS
MOVEQ #HdrSize-4, D1 ; Get header size - 4 in D1 <19sep85> BBM
MOVE.L ResMapOffset(A1), D2 ; Get offset to resource map,
ADD.L D1, D2 ; but skip header
MOVE.L MapSize(A1), D4 ; Get mapsize
MOVE.L D4, D0 ; Get map size in D0
MOVE.L A4, A0 ; Get handle in A0 for size set <05sep85> BBM
_SetHandleSize ; Set size to mapsize
MOVE.W D0, ResErr ; return the error code in ResErr
BNE.S NMFail ; If mem full, return error+close file.
MOVE.L (A4), A1 ; Dereference new map <05sep85> BBM
; we are about to read in the extended attributes
CLR.B mInMemoryAttr(a1) ; clear run-time-only attributes <sm6>stb
MOVE.L D4, D0 ; Get mapsize in D0 to calc bytes to read
SUB.L D1, D0 ; MapSize-HeaderSize=bytes to read
ADD.L A1, D1 ; skip header in buffer too
BSR RdData ; Read in the bytes!
BMI.S NMFail ; if IO err, return and close file.
TST.L HSCache ; if already zero, then old format <19sep85> BBM
BEQ.S @2 ; so skip check for new format <19sep85> BBM
MOVE.L MapSize(A1),HSCache ; get second key (stored in mapsize) <19sep85> BBM
BSR.S PreFormat ; check if new format <19sep85> BBM
@2 MOVE.L D4,MapSize(A1) ; restore true map size <19sep85> BBM
BSR CheckMap ; is the map in a consistent state <29apr85> BBM
BMI.S NMFail ; ... if not, return and close file.
; Clear the overrideNextMapBit, twoDeepBit, and dontCountOrIndexDuplicatesBit
; Clear the preventMapFromClosingBit as well. These bits should be cleared when
; a new map is first created and only set after the appropriate Resource overrides
; calls have been made.
andi.b #kDecompressionPasswordMask,mInMemoryAttr(a1)
; Successful load. Return with D6=refnum of file and D0=1 for "newmap" flag
CLR.L MNext(A1) ; Zero nextMap handle
MOVE.W D6, MRefNum(A1) ; Save refnum of file in map
MOVEQ #1, D0 ; Return 1 for "new resource" flag
RTS ; ...and return, successful open.
; error results: close the opened file, if necessary, dispose of the map
; handle if necessary, and return with D6=D0=-1.
NMFail
BSR SetFileIO ; Set up file frame again. D3=iorefnum.
_Close ; Close the file
NMNoFile
MOVE.L A4, A0 ; Get the map handle <05sep85> BBM
_DisposHandle ; ...and dispose of it.
NMNoHandle
CLR.L HSCache ; invalidate superpreload <20jun85> BBM
CLR.L HSCHandle ; invalidate cache <20jun85> BBM
MOVEQ #-1, D6 ; set D6=-1 for failure
MOVEQ #-1, D0 ; Return -1 for failed open flag
RTS ; return to InitResources or OpenResource.
;_______________________________________________________________________________
;
; Routine: PreFormat (Utility)
;
; Arguments: HSCache (io.L) input = value to test; output = zero or key
;
; Preserved: A0-A7,D1-D7
; Trashes: D0
;
; Called by: NewMap
; Calls: NONE
;
; Function: Check to see if the key info agrees with the map header info. <21jun85> BBM
; This is done by checking if HSCache=$20B7A185. If not, clear
; HSCache, as that invalidates superpreload.
;_______________________________________________________________________________
PreFormat
MOVE.L HSCache,D0 ; get the current key <21jun85> BBM
SUB.L #PreKey,D0 ; check to see if key is present
BEQ.S @9 ; key valid, jump to return
CLR.L HSCache ; invalidate superpreload
@9 CLR.L HSCHandle ; invalidate cache and clear out version# <11jul85> BBM
RTS
;_______________________________________________________________________________
;
; Routine: PROCEDURE RsrcZoneInit;
;
; Arguments: NONE
;
; Called By: A-trap through Dispatcher
; Calls: StdEntry, CloseFiles, GetEntries, StdZeroExit
;
; Function: Zeroes all handles in the system map which point to the
; application zone, and closes all other maps. This routine is
; called from the Memory Manager when an application zone is
; initialized.
;_______________________________________________________________________________
RsrcZoneInit
BSR StdZEntry ; Link A6, save regs <09jul85> BBM
TST.W SysMap ; Is there at least the system map?
BMI.S @9 ; If not, just return, otherwise
movem.l a0-a2/d0-d2,-(sp) ; help the compiler out a litle <SM58>
move.l ApplZone,a0 ; the zone in question
cmp.l bufPtr,a0 ; Does this zonePtr = bufPtr? (Special Boot3.a case)<SM59>
beq.s @noTrash ; -> Yes, do not call TrashZone on the bogus zone <SM59>
move.w #10,d0 ; TrashZone
;_FigmentDispatch ; let everyone know this zone is gone
dc.w $a0a4
@noTrash movem.l (sp)+,a0-a2/d0-d2
bsr FlushResourceCache ; <SM11> CSS Flush the cache first
; Now make the system map forget about resources it has loaded into the
; application heap by clearing their handle locations.
BSR.S CloseFiles ; Close all res files except system.
move.l ResourceMgrStack.OverrideSysMapHndl(a6),d0 ; Start with the override map
@mapLoop
MOVE.L D0,A4
JSR GetRsrcCnt ; 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Õ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
@9
BRA StdZeroExit ; ...and exit.
;_______________________________________________________________________________
;
; Routine: CloseFiles (Utility)
;
; Arguments: None?
;
; Called by: RsrcZoneInit, CloseResFiles
; Calls: _CloseResFile
;
; Function: Closes all maps except the system [override] map.
;_______________________________________________________________________________
CloseFiles
movem.l a0-a1/d0-d2,-(sp) ; save reg's cause GetOverrideMap destroys d1 & d2
@1 MOVE.L TopMapHndl, A0 ; Get the top map
CMPA.L ResourceMgrStack.OverrideSysMapHndl(a6), A0 ; Is the current map the SYS map? <SM11> CSS
BEQ.S @9 ; if so, just exit
; eliminated special checks for rom map here <22jul85> BBM
MOVE.L (A0), A0 ; Dereference map handle
MOVE.W MRefNum(A0), -(SP) ; Push the map refnum
_CloseResFile ; Close the resource file.
BRA.S @1 ; and loop back. <SM11> CSS
@9 movem.l (sp)+,a0-a1/d0-d2
RTS ;
;_______________________________________________________________________________
;
; Routine: ORFCommon (Utility)
;
; Arguments: A1 (input.L) pointer to resource file name
; A0 (input.L) pointer to the I/O block
; D0 (output.W) Error code
; D6 (output.W) IORefnum of File
;
; Called by: NewMap, CreateResFile
; Calls: _OpenRF
;
; Function: Open the resource fork whose name is in A1. A0 must point to
; the I/O block, usually allocated by SetFileIO. Returns Error
; code in D0/ResErr, and IORefNum in D6.
;
; First check to see if it is coming from the old .print driver.
; If it is, set the IOVRefNum to the BootDrive.
;_______________________________________________________________________________
ORFCommon ; rewritten for OpenRFPerm <05sep85> BBM
; This old code checked for the .Print driver open case by turning the pointer into a
; handle with RecoverHandle and subsequently calling GetResInfo to see if it was STR
; $E000. This causes a crash when passing pointers to strings in resouce handles. To
; avoid this, the new code checks for the .Print driver by getting the STR $E000
; resource (with SetResLoad(false)) and comparing it with the file name pointer that
; was passed.
move.l a0,-(sp) ; save pointer to parameter block
move.w CurMap,-(sp) ; save the current map
move.b ResLoad,-(sp) ; save the old value for whether to load resources
move.w ResourceMgrStack.OverrideSysMap(a6),CurMap ; get the resource from the system file
sf ResLoad ; donÕt load the resource
subq #4,sp ; make room for resource handle
move.w #$E000,-(sp) ; get that resource handle
_GetString ; got the string now!
move.l (sp)+,d0 ; get the string into a register
move.b (sp)+,ResLoad ; restore ResLoad
move.w (sp)+,CurMap ; restore CurMap
move.l (sp)+,a0 ; get back the parameter block pointer
tst.l d0 ; check if the handle is nil
bz.s @notPrint ; nope, it is not the printer driver name
exg d0,a1 ; move to address register for dereference
move.l (a1),a1 ; dereference to get the pointer
exg d0,a1 ; move file name pointer back to A1
cmp.l d0,a1 ; check and see if it is the printer name
bne.s @notPrint ; nope, it is not the printer driver
; Note that we can get here if there is a STR $E000 that has not yet been
; loaded and the file name pointer in A1 is NIL! This is not a problem,
; since a NIL file name pointer is illegal anyway, and changing the vRefNum
; in the parameter block for OpenRF shouldnÕt have any effect.
move.w BootDrive,ioVRefNum(a0) ; always open the printer driver on the boot drive
@notPrint
MOVE.L A1,IOFileName(A0) ; Set filename pointer
CLR.L IOOwnBuf(A0) ; No buffer
_OpenRF ,newHFS ; HFSOpen the file's resource fork <SM9> <PN>
MOVE.W IORefNum(A0),D6 ; set D6=file refnum.
MOVE.W D0, ResErr ; and set ResErr
RTS
;_______________________________________________________________________________
;
; Routine: PROCEDURE HCreateResFile(vRefNum: INTEGER; dirID: LONGINT; fileName: Str255); <SM9> <PN>
;
; Called By: A-trap through dispatcher.
;
; Function:
; Initialize a null resource fork for the given filename
; In the specified directory and volume.
;
; From ResourceMgrPatches.a
;_______________________________________________________________________________
;
MyStkFrame Record 0
A6Link ds.l 1
Return ds.l 1
filename ds.l 1
dirID ds.l 1
vRefNum ds.w 1
EndR
HCreateResFile
With MyStkFrame
BSR StdZEntry ; Link and save regs
MOVE.L $00(A0), A1 ; Get filename pointer
BSR SetFileIODirID ; Set up the file IO frame A0 -->
move.w vRefNum(a6),ioVRefNum(a0) ; stuff vRefNum into parameter block <SM9> <PN>
move.l dirID(a6),ioDirID(a0) ; stuff the ioDirID into parameter block <SM9> <PN>
ENDWITH
BSR.S ORFCommon ; Attempt to open the resource fork. <SM9> <PN>
; D6 := refnum of file.
BEQ.S @1 ; If successful, see if the fork is null.
CMP.W #FNFErr, D0 ; Was the error "file not found"?
BNE.S @9 ; If a different error, can't handle, else
;Roll in NewCreate from ResourceMgrExtensions.a
_Create ,newHFS ; HFScreate a new file with null D+R forks <SM9> <PN>
MOVE.W D0,ResErr ; ... else (A0) points to parameter block <27feb85> BBM
BMI.S @9 ; ... and error exit
BSR.S ORFCommon ; and attempt to open again. D6=refnum.<SM9> <PN>
BMI.S @9 ; If open failed, can't do anything.
@1 _GetEOF ; Get EOF of rsrc fork. (file exists!)
MOVE.W #DupFNErr, ResErr ; Assume error, fork already exists
TST.L IOLEOF(A0) ; Is it a null fork, ready to initialize?
BNE.S @7 ; If not, leave DupFNErr and exit, else
MOVEQ #HdrSize, D0 ; Write header only at 0.
LEA NullRF, A1
MOVE.L A1, D1 ; Set buffer address to null map
BSR WrDataSt ; Write out initial map @0. Set ResErr.
MOVEQ #NullRMSize, D0 ; Set number of bytes
MOVEQ #64, D2 ; Get 64 for offset...
ASL.W #2, D2 ; left shift 2 for 256=FirstResData.
BSR WrData ; Write out initial map. Set ResErr.
@7 _Close ; Close the file. Error code in D0 ignored...
; WrData, WrDataSt preserved A0.
@9 jmp StdTenExit ; clear the dirID and exit (done by StdExit on newer ROMs) <SM9> <PN>
;_______________________________________________________________________________
;
; Routine: PROCEDURE CreateResFile(fileName: Str255);
;
; Arguments: 8(A6), A0 pointer to filename
;
; Called By: A-trap through dispatcher.
; Calls: StdEntry, SetFileIO, ORFCommon, _Create, _GetEOF, WrDataSt,
; WrData, _Close, StdFourExit
; Function:
; Initialize a null resource fork for the given filename.
; If the file does not exist at all, create it.
; note:
; <27feb85> BBM added check to see if file
;_______________________________________________________________________________
CreateResFile
BSR StdZEntry ; Link and save regs <09jul85> BBM
MOVE.L (A0), A1 ; Get filename pointer
BSR SetFileIODirID ; Set up the file IO frame A0 -->
BSR.S ORFCommon ; Attempt to open the resource fork.
; D6 := refnum of file.
BEQ.S @1 ; If successful, see if the fork is null.
CMP.W #FNFErr, D0 ; Was the error "file not found"?
BNE.S @9 ; If a different error, can't handle, else
_Create ; create a new file with null D+R forks
MOVE.W D0,ResErr ; ... else (A0) points to parameter block <27feb85> BBM
BMI.S @9 ; ... and error exit
BSR.S ORFCommon ; and attempt to open again. D6=refnum.
BMI.S @9 ; If open failed, can't do anything.
@1 _GetEOF ; Get EOF of rsrc fork. (file exists!)
MOVE.W #DupFNErr, ResErr ; Assume error, fork already exists
TST.L IOLEOF(A0) ; Is it a null fork, ready to initialize?
BNE.S @7 ; If not, leave DupFNErr and exit, else
MOVEQ #HdrSize, D0 ; Write header only at 0.
LEA NullRF, A1
MOVE.L A1, D1 ; Set buffer address to null map
BSR WrDataSt ; Write out initial map @0. Set ResErr.
MOVEQ #NullRMSize, D0 ; Set number of bytes
MOVEQ #64, D2 ; Get 64 for offset...
ASL.W #2, D2 ; left shift 2 for 256=FirstResData.
BSR WrData ; Write out initial map. Set ResErr.
@7 _Close ; Close the file. Error code in D0 ignored...
; WrData, WrDataSt preserved A0.
@9 BRA StdFourExit ; pop 4 bytes and exit
;_______________________________________________________________________________
;
; Routine: FUNCTION HOpenResFile(vRefNum: INTEGER; dirID: LONGINT; fileName:
; Str255; permission: SignedByte): INTEGER;
;
; Function: Given filename, opens this resource. Returns resource file
; reference number. If the file was already open, returns the
; current refnum of the file. If negative, an error occurred and
; the code can be noted in ResErr. InitResources must be called
; before OpenResFile. Sets ResLoad to TRUE initially.
; From ResourceMgrPatches.a
;_______________________________________________________________________________
WITH ResourceMgrStack
HOpenResFile
BSR StdZEntry ; Link and save regs
MOVE.W $0a(a0),ioBlock+IOVRefNum(A6) ; stuff vRefNum into ioParmBlk
MOVE.L $06(a0),ioBlock+ioDirID(A6) ; Stuff dirID into ioParmBlk
MOVE.L $02(a0),A1 ; Get fileName in A1 for call to NewMap
MOVE.B $00(a0),ioBlock+ioPermssn(a6) ; set up permission byte <SM9> <PN>
BSR OPResFileCommon ; go open the file.
MOVE.W D6,20(a6) ; output refNumÉ
@9 BRA StdTwelveExit ; clear the dirID and exit (done by StdExit on newer ROMs)<SM9> <PN>
ENDWITH
;_______________________________________________________________________________
;
; Routine: FUNCTION OpenResFile(fileName: Str255): INTEGER;
;
; Arguments: 8(A6),A0 (input) pointer to filename
; 12(A6) (output.x) Resource file refnum.
;
; Called By: (OpenResFile): A-trap through Dispatcher
; (OPResFile): OpenRFPerm
; Calls: StdEntry, NewMap, PreLoad2, StdFourExit
;
; Function: Given filename, opens this resource. Returns resource file
; reference number. If the file was already open, returns the
; current refnum of the file. If negative, an error occurred and
; the code can be noted in ResErr. InitResources must be called
; before OpenResFile. Sets ResLoad to TRUE initially.
; note:
; <22Jan85> BBM We want to call PreLoad, but we don't want to set ResLoad flag,
; so we call PreLoad2. This fix was part of the ram patches to
; the version 7.0 ROM.
;_______________________________________________________________________________
OpenResFile
;¥¥¥¥ Fix for the old AppleTalk ImageWriter and LQ AppleTalk ImageWriter until these drivers are fixed <SM35>
move.b ResLoad,-(sp) ; save the old value for whether to load resources <SM35>
sf ResLoad ; donÕt load the resource <SM35>
subq #4,sp ; make room for resource handle <SM35>
move.w #$E000,-(sp) ; get that resource handle <SM35>
_GetString ; got the string now! <SM35>
move.l (sp)+,d0 ; get the string into a register <SM35>
move.b (sp)+,ResLoad ; restore ResLoad <SM35>
tst.l d0 ; check if the handle is nil <SM35>
bz.s NotForPrinting ; nope, it is not the printer driver name <SM35>
exg d0,a0 ; move to address register for dereference <SM35>
move.l (a0),a0 ; dereference to get the pointer <SM35>
exg d0,a0 ; move file name pointer back to A1 <SM35>
cmp.l 4(sp), d0 ; check and see if it is the printer name <SM35>
bne.s NotForPrinting ; nope, it is not the printer driver <SM35>
movem.l d1-d2/a1,-(sp) ; Resource Mgr calls shouldnÕt touch these <SM35>
move.l #$D8000000,-(SP) ; PrLoadDriver <SM35>
_PrGlue ; Call PrGlue <SM53> CSS
movem.l (sp)+,d1-d2/a1 ; restore registers <SM35> <4>
move.w D0, ResErr ; copy the error result into ResErr <SM35>
move.w $952, D0 ; copy the printing refnum into the function result <SM35>
; This will be the error from HOpenResFile if it didn't work. <SM35>
move.l (sp)+, a0 ; save return address <SM35>
add.l #4, sp ; strip the parameter <SM35>
move.w d0, (sp) ; set the function result <SM35>
jmp (a0) ; out of here <SM35>
NotForPrinting ; <SM35>
;¥¥¥ end fix
BSR StdZEntry ; Link A6, save regs <30oct85> BBM
MOVE.L (A0), A1 ; Get name pointer in A1
BSR OPResFileCommon ; go open the file.
move.w d6,12(a6) ; output refNumÉ
BRA StdFourExit ; ...and exit
;_______________________________________________________________________________
;
; Routine: FUNCTION OpenRFPerm(fileName:Str255, VRefNum: INTEGER,
; Permission: Byte): INTEGER;
; Arguments: ????????
;
; Called By: A-trap through Dispatcher
; Calls: StdZEntry, OPResFile
;
; Function: Given filename, volume reference number and permissions, open
; this resource. Returns resource file reference number. If the
; file was already open, returns the current refnum of the file.
; If negative, an error occurred and the code can be noted in
; ResErr. InitResources must be called before OpenResFile.
;_______________________________________________________________________________
ROMOpenRFPerm
OpenRFPerm ; new routine
BSR StdZEntry ; Save regs etc. (D0 saved across call)
WITH ResourceMgrStack
MOVE.W $02(a0),ioBlock+IOVRefNum(A6) ; stuff vRefNum into ioParmBlk
MOVE.L $04(a0),A1 ; Get fileName in A1 for call to NewMap
MOVE.B $00(a0),ioBlock+ioPermssn(a6) ; set up permission byte <SM9> <PN>
BSR OPResFileCommon ; go open the file.
ENDWITH
move.w d6,16(a6) ; output refNumÉ
BRA StdEightExit ; and go to common code <05sep85> BBM
;_______________________________________________________________________________
;
; Routine: OPResFileCommon
; Arguments: A1 - Ptr to file name of resource fork to openÉ
;
; Called By: HOpenResFile, OpenResFile, and OpenRFPerm
; Calls: NewMap, PreLoad2
;
; A1 points to name to open at this point and permissions and DirID are set
; in the pb on the stack.
;
; return refNum in D6
OPResFileCommon
MOVE.L MinusOne,LastSPExtra ; invalidate font cache
BSR NewMap ; D0=dirID, D3=refnum, A1=map ptr, A2 is map handle
MOVE.W D6,-(sp) ; Return refnum of map, or -1 for error. (save refNum on the stack)
BMI.S @9 ; If I/O error, return.
MOVE.W D6, curMap ; Save it as current map.
TST.W D0 ; Was it a newly-created map?
BEQ.S @9 ; No, it was already there, don't relink.
MOVE.L TopMapHndl, MNext(A1) ; If new, link. Store old top as next map
MOVE.L A4,TopMapHndl ; Set new map as top map <05sep85> BBM
BSR PreLoad2 ; Preload required resources... <22Jan85> BBM
BSR CheckAndFlushFontCache ; If this new file has fonts we should flush the font cacheÉ
@9
move.w (sp)+,d6 ; get the ref num to return
rts ; exit
;_______________________________________________________________________________
;
; Routine: PROCEDURE UseResFile(RefNum: INTEGER);
;
; Arguments: 4(SP) (input) resource file refnum
;
; Called By: A-trap through dispatcher
; Calls: StdMapEntry, StdTwoExit
;
; Function: Given refnum, sets current resource to use. If there isn't any
; such map, ignores the request.
;_______________________________________________________________________________
UseResFile
; We have to check for UseResFile(0) first because this is the one case where
; we don't want the override of the system to come back in d6 but instead we want
; to have the real SysMap in d6.
BSR StdZEntry ; Link and save regs <12aug85> BBM
MOVE.W (A0), D6 ; Get the resource map refnum
bne.s @notSystemMap
move.w SysMap,d6 ; 0 means use SysMap
bra.s @exit
@notSystemMap
BSR GetMap ; Scan for it
BMI.S @err ; If not found, exit, otherwise
@exit
MOVE.W D6, CurMap ; Set this refnum as the current map
CLR.W ResourceMgrStack.doOverrides(a6); Turn off overrides so that the CurMap doesn't get overwritten. <SM49> CSS
BRA StdTwoExit ; and exit.
@err
MOVE.W #ResFNotFound, ResErr ; set error code, and
BRA StdTwoExit ; and exit.
;_______________________________________________________________________________
;
; Routine: FUNCTION GetResFileAttrs(refnum: INTEGER): INTEGER;
;
; Arguments: 8(A6) (input.W) Resource file refnum
; 10(A6) (output.B) Attribute byte
;
; Called By: A-trap through dispatcher
; Calls: StdMapEntry, StdTwoExit
;
; Function: Given a resource file, return its attribute byte in low order.
; high order is trash.
;_______________________________________________________________________________
GetResFileAttrs
BSR.S StdMapEntry ; Look for the file. If not there, exit
MOVE.B MAttr(A3),11(A6) ; Return the byte in low order
BRA StdTwoExit ; and exit.
;_______________________________________________________________________________
;
; Routine: PROCEDURE SetResFileAttrs(refnum: INTEGER; attrs: INTEGER);
;
; Arguments: 10(A6) (input.W) resource file refnum
; 8(A6) (input.W) Resource attribute byte)
;
; Called By: A-trap through dispatcher
; Calls: StdEntry, GetMap, StdFourExit
;
; Function: Given a resource file, set its attribute byte.
; note:
; there is no error checking!! The attribute bytes could be wrong
; and this procedure will still write them out.
;_______________________________________________________________________________
SetResFileAttrs
BSR StdZEntry ; Look for the file. If not there, exit <12aug85> BBM
MOVE.W 10(A6), D6 ; Get the refnum
BSR GetMap ; Get the corresponding map
BMI.S @1 ; if can't find, just exit.
MOVE.B 9(A6), MAttr(A3) ; Set attributes word
@1 BRA StdFourExit ; and exit.
;_______________________________________________________________________________
;
; Routine: StdMapEntry (utility)
;
; Arguments: 8(A6) (input.W) Map refnum
; D6 (output.W) Map refnum
;
; Called By: UseResFile, UpdateResFile, CloseResFile
; Calls: StdEntry, GetMap, StdTwoExit
;
; Function: Given the map refnum 8(A6), scans for the map and exits if not
; found. StdEntry returns A0=8(A6), so the refnum is copied from
; (A0). Callers must have a two-byte argument.
;_______________________________________________________________________________
StdMapEntry
MOVE.L (SP)+, D0 ; Save return address in D0
BSR StdZEntry ; Link and save regs <12aug85> BBM
MOVE.L D0, -(SP) ; Restore return address
MOVE.W (A0), D6 ; Get the resource map refnum
BSR GetMap ; Scan for it
BMI.S @1 ; If not found, exit, otherwise
RTS ; just return.
@1 ADDQ #4, SP ; pop return address,
MOVE.W #ResFNotFound, ResErr ; set error code, and
BRA StdTwoExit ; and exit.
;_______________________________________________________________________________
;
; Routine: FirstRes, NextRes, ZfirstRes, ZnextRes (utilities)
;
; Arguments: A2 (input.L) Pointer to last rsrc (used by NextRes)
; A4 (input.L) map handle
; D1 (input.L) which bit to test in RAttr(A2)
; A2 (output.L) Pointer to the resource entry
; D0 (output.L) Next file Location
;
; Unchanged: A0-A1,A3-A7,D1-D7
; Trashed: None
;
; Called By: (FirstRes): PreLoad, PreLoad2,UpdateResFile
; (NextRes): PreLoad, PreLoad2,UpdateResFile
; Calls: GetRsrcCnt
;
; Function: FirstRes and NextResÊare File-Order routines. They are used to
; find the first/next resource in file order. D1 determines what
; kind of search to do. If (D1.W < 0) then FirstRes/NextRes will
; find the first/next resource in file order. If (D1.W > 0) then
; FirstRes/NextRes will test RAttr(A2) with bit referenced in D1.
; In other words if (D1.W > 0) then FirstRes/NextRes will find
; the first/next resource in file order with that bit set.
; FirstRes/NextRes point A2 to the entry found and sets CC=EQ. If
; no entry was found A2 is garbage, and CC=MI. Alternate entries
; ZfirstRes and ZnextRes force search through all rsrcs.
;_______________________________________________________________________________
ZfirstRes
MOVEQ #-1,D1 ; get the first resource in file order <03oct89 bpa>
FirstRes
MOVEQ #-1, D0 ; prime with -1 for first resource
BRA.S FNCmn ; and jump to common code
ZnextRes
MOVEQ #-1,D1 ; get the very next resource <03oct89 bpa>
NextRes
MOVE.L RLocn(A2), D0 ; Get the location
AND.L Lo3Bytes,D0 ; and mask off the high byte.
FNCmn ; (only FirstRes uses this label)
MOVEM.L A3/D2-D7,-(SP) ; Save regs
MOVE.L D0, D2 ; Copy location to find successor of
BSR GetRsrcCnt ; Point to the first entry <10may85> BBM
BMI.S @9 ; If none, exit
LEA MinusOne,A3 ; Point to MinusOne, but <26aug85> BBM
SUBQ.L #RLocn,A3 ; skip back RLocn. (RLocn(A2)=MinusOne).
MOVE.L A3,D6 ; D6=new candidate. valid A2 will replace.
MOVEQ #-1, D7 ; D7:=FFFFFFFF
LSR.L #1, D7 ; shift rt by 1 = 7FFFFFFF, +ve infinity.
TST.W D1 ; if (D1 < 0) then get next in file order <03oct89 bpa>
BMI.S @3 ; ... else fall through to test bit loop <03oct89 bpa>
@1 BTST D1,RAttr(A2) ; if you don't want to preload this one, <10may85> BBM
BEQ.S @2 ; ... then don't look at it.
MOVE.L RLocn(A2), D0 ; Get the resource location
AND.L Lo3Bytes,D0 ; AND off high order 8 bits
CMP.L D0, D2 ; is this location greater than given?
BGE.S @2 ; No, try next
CMP.L D0, D7 ; is it less than the last candidate?
BLE.S @2 ; no, old candidate is still good
MOVE.L D0, D7 ; else replace old candidate with new
MOVE.L A2, D6 ; Save A2 candidate also in D6
@2 ADD.W #RESize,A2 ; point to the next entry
DBRA D4,@1 ; if there was one, loop back
BRA.S @8 ; ... else goto exit code.
@3 MOVE.L RLocn(A2), D0 ; Get the resource location <13may85> BBM
AND.L Lo3Bytes,D0 ; AND off high order 8 bits
CMP.L D0, D2 ; is this location greater than given?
BGE.S @4 ; No, try next
CMP.L D0, D7 ; is it less than the last candidate?
BLE.S @4 ; no, old candidate is still good
MOVE.L D0, D7 ; else replace old candidate with new
MOVE.L A2, D6 ; Save A2 candidate also in D6
@4 ADD.W #RESize,A2 ; point to the next entry
DBRA D4,@3 ; if more loop back, else fall into exit code
@8 MOVE.L D6,A2 ; return A2 as the next resource entry
MOVE.L D7,D0 ; Return D0 as the next file Location
MOVE.L RLocn(A2),D7 ; Get this entry's location.
AND.L Lo3Bytes,D7 ; and off high bits.
CMP.L D0,D7 ; Set CC's. EQ=valid entry, MI=end of list.
@9 MOVEM.L (SP)+,A3/D2-D7 ; Restore regs
RTS ; ...and return.
;_______________________________________________________________________________
;
; Routine: PROCEDURE UpdateResFile(refNum: INTEGER);
;
; Arguments: 8(A6) (input.W) resource file refnum
;
; Called By: A-trap through dispatcher
; Calls: StdMapEntry, ResRW, StdTwoExit, SetRFEOF, FirstRes, WrRsrc,
; NextRes, CheckLoad, _ReleaseResource, SizeRes, WrData, WrDataSt
; ClearIgnore
; Labels: UpdateResFile, UpDateCompact, WriteMap
;
; Function: Given refnum, writes out new resources and updates map. If
; refnum=0, use system file. CloseResFile calls UpdateResFile,
; so on exit from an application all resource files which are
; marked dirty have thier maps writen out and are compacted.
;
; The new UpdateResFile (July 85) uses one buffer to do all the
; reads and writes. When compacting the file the regester usage
; is as follows:
; A1 end of the region already compacted and still in buffer.
; A2 pointer to Resource entry.
; A3 handle to the start of locked update buffer.
; A4 handle to resource map.
; D3 pointer to the end of the update buffer.
; D5 current Read position in the file less ResDataOffset.
; D6 current resource file refnum.
; D7 current Write position in the file less ResDataOffset.
;_______________________________________________________________________________
UpdateResFile
WITH ResourceMgrStack
move.l ExpandMem,a0 ;
move.b ExpandMemRec.emScanOverrideMaps(a0),D0 ; save override state. (StdZEntry must preserve d0)
clr.b ExpandMemRec.emScanOverrideMaps(a0) ; turn it off for StdEntry
BSR StdZEntry ; Link and save regs <12aug85> BBM
MOVE.W (A0), D6 ; Get the resource map refnum
move.l ExpandMem,a0 ;
move.b d0,ExpandMemRec.emScanOverrideMaps(a0) ; restore override state
BSR GetMap ; Scan for it
BMI.S @ErrExit ; If not found, exit, otherwise
clr.w ResErr ; start out freshÉ
BSR UpdateResFileCommon ; first try updating this resfileÉ
tst.w ResErr ; Did we get the first file?
bra.s @exit ; no wayÉ get outta here!
subq #4,sp
move.l a4,-(sp)
_GetOverrideMap ; See if thereÕs an override map for this file
move.l (sp)+,a3 ; Get the map
; Check to see if weÕre updating the system file, or just another file. If weÕre updating the
; system file, then make sure we update all the font files too. If itÕs just a generic resource map,
; update just itÕs override maps and the file itself.
;
; Note: I know that explicitly updating an override map of the system wonÕ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 SysMap(a6),a4 ; If weÕ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Õt end until
moveq #0,a4 ; the end of the chain is reached
bra.s @updateOverrideMaps
; ItÕs not the system file.
@notUpdatingSystemFile
cmp.l a3,a4 ; If the file didnÕt have any override maps
beq.s @exit ; Just update the original.
; Update any changed override maps for this file.
@updateOverrideMaps
move.l a4,-(sp) ; save a4
move.l a3,a4 ; get map to try in a4
bsr UpdateResFileCommon ; Try updating this mapÉ
move.l (sp)+,a4 ; restore a4
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 @exit ; 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
@ErrExit
MOVE.W #ResFNotFound,ResErr ; resource file not found error <PN>
@exit
bsr FlushResourceCache ; from UpdateResourceOverrideFile <PN>
bra StdTwoExit
ENDWITH
; UpdateResFileCommon takes a map in A4 and tries to update itÉ
; it preserves a0-a4/d0-d1
UpdateResFileCommon
movem.l a0-a4/d0-d1,-(sp) ; save regs
BSR ResRW ; Read/write allowed for this resFile?
BEQ.S @1 ; yes, go on <16apr85> BBM
MOVE.W #mapReadErr,ResErr ; ... else don't allow write, mark as error
BRA UpdateResExit ; ... and exit always <03jul85> BBM
@1 BTST #MapChanged,MAttr(A0) ; Map changed? (***Hack!, should be MapUpdate)
BEQ UpdateResExit ; if not don't bother to update
BSR SetRFEOF ; Check disk full even though might compact <28jan85> BBM
BMI UpdateResExit ; if failed return error
BCLR #MapCompact, MAttr(A3) ; Do I need to compact? <12jun85> BBM
BNE.S UpdateCompact ; If so, skip to compact stuff
MOVEQ #ResChanged,D1 ; which bit to check in FirstRes/NextRes <09apr85> BBM
BSR FirstRes ; first resource in file order that changed <13may85> BBM
BMI.S @4 ; If none, go on. <03jul85> BBM
@0 BSR WrRsrc ; otherwise write out the changed resource. <09apr85> BBM
BSR NextRes ; next in file order (NOTE D1=ResChanged still) <13may85> BBM
BEQ.S @0 ; and loop back, if any left.
@4 BRA WriteMap ; and go write map if necc. <12jun85> BBM
UpDateCompact ; this section does a buffer update <12jun85> BBM
BSR ZfirstRes ; get the first resource in file order <04jun85> BBM
BMI WriteMap ; if none, go on. <12jun85> BBM
MOVE.L (A4),A0 ; Dereference map handle <10oct85> BBM
MOVE.L ResDataOffset(A0),D7 ; D7 will point to current write position <09oct85> BBM
SUB.L ResMapOffset(A0),D7 ; Do we need to compress this file? <09oct85> BBM
BCS.S @2 ; Compact to ResDataOffset <10oct85> BBM
BSR GetRsrcCnt ; set up indexing for looping <10oct85> BBM
@1 ADD.L D7,RLocn(A2) ; Add in new resDataOffset <10oct85> BBM
ADD.W #RESize,A2 ; point to the next resource <10oct85> BBM
DBRA D4,@1 ; loop back through entire map <10oct85> BBM
MOVE.L ResMapOffset(A0),ResDataOffset(A0) ; make new resDataOffset <10oct85> BBM
BSR ZfirstRes ; get the first resource in file order <10oct85> BBM
@2 MOVEQ #0,D7 ; compact to the beginning of ResDataOffset <10oct85> BBM
BRA.S stFindGap ; Check to see if first rsrc needs compaction <10oct85> BBM
findGap
BTST #ResChanged,RAttr(A2) ; Does this resource need to be written?
BEQ.S @1 ; ... No, go get its size
BSR WrRsrc ; ... else write out resource
MOVE.L RHndl(A2),A0 ; What is the size of this resource?
_GetHandleSize ;
BRA.S @2 ; go check if time to start compact
@1 BSR SizeRsrc ; Get the size of this resource
@2 ADDQ.L #LenWdLen,D0 ; add in length size to size of resource (.L) <01jul85> BBM
MOVE.L RLocn(A2),D7 ; D7 points to current position in file
ADD.L D0,D7 ; point past this resource
AND.L Lo3Bytes,D7 ; mask off RAttrs <13jun85> BBM
BSR ZnextRes ; Get the next resource <02jul85> BBM
BMI wrDtSize ; maybe only map needs to be moved up <09jan86> BBM
stFindGap ; new label <10oct85> BBM
MOVE.L D7,D0 ; need a 24 bit compare of RLocn(A2) & D7 <09oct85> BBM
SUB.L RLocn(A2),D0 ; Compare this with the next file offset
AND.L Lo3Bytes,D0 ; result is a 24 bit compare if EQ
BEQ.S findGap ; don't start compact yet
SUB.L (A4),A2 ; we make A2 an offset since map may move <29jun85> BBM
BSR MaxRFEOF ; find how much space we need to use <09jan86> BBM
MOVE.L D0,D3 ; Calculate how big this file is <09jan86> BBM
_MaxBlock ; how much can we get? <09jan86> BBM
CMP.L D3,D0 ; Get minimum of (filesize, maxblock) into D3 <C268>
BGE.S @0 ; D3 already has the minimum <C268>
EXG D3,D0 ; only if D0 and D3 are backwards <C268>
@0
MOVEQ #64,D0 ; make sure we have a buffer size >= 1k <09jan86> BBM
ASL.W #4,D0 ; D0 = $400 (or 1K) <09jan86> BBM
CMP.L D0,D3 ; Is it greater than 1k? <09jan86> BBM
BGE.S @1 ; CC=GE means we can get buffer in Zone <09jan86> BBM
MOVE.L D0,D3 ; D3 will be a buffer of 1024k size <09jan86> BBM
LINK A3,#-1024 ; Get 1k buffer and set up bogus MP for A3 <08jan86> BBM
MOVE.L SP,(A3) ; A3 now points to a good MP <08jan86> BBM
BRA.S @2 ; and don't try to lock down the stack <08jan86> BBM
@1 MOVE.L D3,D0 ; D3 is size of update buffer <09jan86> BBM
_NewHandle ; Get a handle to my update buffer <09jan86> BBM
_Hlock ; Don't allow it to move and ruin my ptrs <08jan86> BBM
MOVE.L A0,A3 ; A3 is our handle to update buffer <A340>
@2 ADD.L (A4),A2 ; restore A2 to a pointer <08jan86> BBM
MOVE.L (A3),D0 ; D0 now points to the beginning of buffer
_StripAddress ; make sure no garbage in high byte <c396>
ADD.L D0,D3 ; D3 now points to end of update buffer
MOVE.L D0,A1 ; A1 is our compacted region pointer
MOVE.L A1,D4 ; nothing is read in yet, so D4 = A1 <01jul85> BBM
MOVE.L D7,D5 ; D5 = file read pos; D7 = file write pos
FPvCmpFrm
MOVE.L jCmpFrm,A0 ; get the vector from the OSJumptable <27oct85> BBM
JMP (A0) ; and go to the routine <27oct85> BBM
vCmpFrm ; Def to build dispatch entry <27oct85> BBM
@3 BTST #ResChanged,RAttr(A2) ; is the rsrc in mem (and needs to be written)
BEQ.S @4 ; CC=EQ means ResChanged bit not set
BSR.S CmpFrmMem ; else get rsrc from memory and compact
BPL.S @5 ; go get next resource <02jul85> BBM
@4 BSR CmpFrmDsk ; read rsrc from disk and compact
@5 BSR ZnextRes ; go get the next resource
BEQ.S @3 ; if more resources loop back
@6 MOVE.L A1,D0 ; empty the buffer of the remaining stuff
SUB.L (A3),D0 ; ... now D0 has size left to write <10jul85> BBM
_StripAddress ; ... just to be on the safe side <v1.2>
MOVE.L (A3),D1 ; start of buffer address for write <10jul85> BBM
MOVE.L (A4),A0 ; get current file write position
MOVE.L D7,D2 ; ... get biased position
ADD.L ResDataOffset(A0),D2 ; ... and take away the bias
BSR WrData ; and write out the data left in buffer
ADD.L D0,D7 ; point current write position past last rsrc
MOVE.L (A3),A0 ; we don't need this buffer so get rid of it <SM47> CSS
CMPA.L SP,A0 ; <SM47> CSS
BEQ.S @7 ; CC=EQ means buffer is on stack <SM46> CSS
; <SM46> CSS This works because (A3) contains the SP at the
; time of creation if we created the buffer on the stack,
; AND the stack is the same depth here and at the time
; of creation.
MOVE.L A3,A0 ; Else buffer is in memory <08jan86> BBM
_DisposHandle ; get rid of it <08jan86> BBM
BRA.S @8 ; and skip by stack code <08jan86> BBM
@7 UNLK A3 ; Dispose of buffer on stack <08jan86> BBM
@8 MOVE.L (A4),A3 ; Derefernce map to write out <08jan86> BBM
wrDtSize ; New lable <10oct875> BBM
MOVE.L D7,DataSize(A3) ; update current size for the data
WriteMap
BCLR #MapChanged, MAttr(A3) ; Clear the map-changed bit before write.
BEQ.S UpdateResExit ; If the map didn't change either, exit.
MOVE.L DataSize(A3), D2 ; Get updated data size
ADD.L ResDataOffset(A3), D2 ; Add data offset to get new map offset
MOVE.L D2, ResMapOffset(A3) ; Save new map offset from D2
MOVE.L MapSize(A3), D0 ; byte count=size of map
MOVE.L A3, D1 ; Address of map in memory. D2=map offset.
BSR WrData ; Write the map out!
MOVEQ #HdrSize, D0 ; byte count=HdrSize (write new header!) <12jun85> BBM
BSR WrDataSt ; ...and do it!
BSR SetRFEOF ; Set new EOF
UpdateResExit
@9
movem.l (sp)+,a0-a4/d0-d1
rts
;_______________________________________________________________________________
;
; Routine: CmpFrmMem (utility)
;
; Arguments: A1 (i/o.l) pointer to the end of compacted region
; A3 (input.l) Handle to start of update buffer
; A4 (input.l) current map handle
; D3 (input.l) pointer to end of update buffer
; D4 (i/o.l) pointer in buffer (end of stuff read in)
; D5 (i/o.l) current file read position - ResDataOffset
; D6 (input.w) the current file refnum
; D7 (i/o.l) current file write position - ResDataOffset
; RLocn(A2) (output.l) the new file offset for this rsrc
;
; Unchanged: A2-A7,D1,D3,D6
; Trashed: A0,D0-D2
;
; Called By: UpdateResFile
; Calls: _BlockMove, CmpctRead, _GetHandleSize, NotFound, PartWrite,
; Ptr1Exit, RLocnNew, WriteSize
;
; Function: Compacts resource from Memory (because the ResChanged bit set).
; Just does compact of one resource. If cann't read in all of
; resource into update buffer, writes out compacted stuff and
; continues until all is done. Also updates RLocn(A2) as well.
;_______________________________________________________________________________
CmpFrmMem
BSR PartWrite ; make sure we have some room to play in
MOVE.L RHndl(A2),A0 ; get info about resource
_GetHandleSize ;
TST.L D0 ; check to see if purged or zero length <02jul85> BBM
BMI NotFound ; if purged exit with CC=MI or CC=EQ <10jul85> BBM
BSR.S RLocnNew ; update new file position for this rsrc
BSR.S WriteSize ; write size of this resource into buff <08jul85> BBM
MOVE.L D0,D2 ; check to see if enough room in buff
ADD.L A1,D2 ; ... D2 now points to proposed end
CMP.L D2,D4 ; Does it fit inside read buffer?
MOVE.L (A0),A0 ; dereference handle to rsrc for calc <10jul85> BBM
BGE.S Ptr1Exit ; CC=GE means it fits so transfer and exit <10jul85> BBM
MOVE.L D0,D2 ; D2 will be the number of bytes left in rsrc
MOVEQ #0,D1 ; D1 will be offset into resource <02jul85> BBM
@1 MOVE.L RHndl(A2),A0 ; set up A0 to be pointer into resource
MOVE.L (A0),A0 ; ... dereference handle
ADD.L D1,A0 ; ... and add in offset <02jul85> BBM
MOVE.L D3,D0 ; How much room in update buffer?
SUB.L A1,D0 ; ... D0 has free byte count in buffer
CMP.L D2,D0 ; is there room in buffer?
BGE.S @7 ; CC=GE means enough room <02jul85> BBM
ADD.L D0,D1 ; update offset into resource <02jul85> BBM
SUB.L D0,D2 ; Update number of bytes left
BSR.S @8 ; Transfer what we can <02jul85> BBM
BSR PartWrite ; write out what we can
BRA.S @1 ; and loop back for the rest of rsrc
@7 MOVE.L D2,D0 ; D2 has number of bytes left in rsrc
@8 MOVE.L A1,D4 ; update buffer end read pointer <02jul85> BBM
; BRA.S Ptr1Exit ; and exit with block move stuff <10jul85> BBM
; *!*!*!* Heads Up - Falling Through ; BRA commented out for warning free assembly. <c396>
;_______________________________________________________________________________
;
; Routine: Ptr1Exit, Ptr2Exit, Ptr3Exit (utilities) <10jul85> BBM
;
; Arguments: A0 (input.l) pointer to source of blockmove (Ptr1Exit)
; A1 (i/o.l) compacted region pointer
; D0 (input.l) size of blockmove or offset to add to D5/A1
; D4 (output.l) end of region read into buffer
; D5 (i/o.l) current file read position
;
; Unchanged: A0,A1-A7,D0-D3,D5-D7
; Trashed: none
;
; Called By: CmpFrmMem
; Calls: none
;
; Function: standard exit code for several routines. Saves a few bytes and
; makes sure a few tests are done.
;
; Warning: Entered by falling through from previous function (CmpFrmMem) <c396>
;_______________________________________________________________________________
Ptr1Exit
CMP.L A0,A1 ; is the block move necessary? <10jul85> BBM
BEQ.S Ptr2Exit ; ... no, then skip it
MOVE.L D0,-(SP) ; save D0 across Blockmove call
_BlockMove ;
MOVE.L (SP)+,D0 ; restore the size
Ptr2Exit
ADD.L D0,D5 ; update file read pointer
ADD.L D0,A1 ; update compated region pointer
Ptr3Exit
CMP.L A1,D4 ; if A1 > D4 then D4 gets A1
BGE.S @1 ; else just exit
MOVE.L A1,D4 ; text is true
@1 RTS ;
;_______________________________________________________________________________
;
; Routine: RLocnNew (utility)
;
; Arguments: A1 (input.l) pointer to the end of compacted region
; A3 (input.l) Handle to start of update buffer
; D7 (input.l) the current file write position
; RLocn(A2) (i/o.l) the new file offset for this rsrc
;
; Unchanged: A0-A7,D0-D7
; Trashed: none
;
; Called By: CmpFrmDsk, CmpFrmMem
; Calls: none
;
; Function: Updates resource map entry to the new file offset.
;_______________________________________________________________________________
RLocnNew
MOVEM.L D0-D1/A0,-(SP) ; save D0-D1/a0 across call <10jul85> BBM
MOVEQ #-3,D1 ; get ResChanged mask (-3 = $FD = RCBMask) <30jun85> BBM
LEA RAttr(A2),A0 ; address of RAttr and RLocn <10jul85> BBM
AND.B (A0),D1 ; save old Attr in D1
MOVE.L A1,D0 ; calc file position for this rsrc
SUB.L (A3),D0 ; ... by calc how much stuff still in buff
ADD.L D7,D0 ; ... and adding to current write position
MOVE.L D0,(A0) ; write out new location
MOVE.B D1,(A0) ; restore Attributes
MOVEM.L (SP)+,D0-D1/A0 ; restore registers
RTS ; and go back to caller
;_______________________________________________________________________________
;
; Routine: WriteSize, WriteZero (utility) <08jul85> BBM
;
; Arguments: A1 (i/o.l) pointer to the end of compacted region
; D0 (input.l) the size to write into the buffer (WriteZero)
; D5 (i/o.l) the current read pointer
;
; Unchanged: A0,A2-A7,D0-D4,D6-D7
; Trashed: none
;
; Called By: CmpFrmDsk, CmpFrmMem
; Calls: none
;
; Function: Writes D0 into update buffer. Updates the two pointers A1 & D5.
; The size is maintained across call in D0.
;_______________________________________________________________________________
WriteZero
MOVEQ #0,D0 ; write out a zero resource size into buff
WriteSize ;
MOVE.L D1,-(SP) ; save D1 across call
MOVEQ #3,D1 ; write D0 (size) into update buffer
@0 ROL.L #8,D0 ; write size into buffer
MOVE.B D0,(A1)+ ; ... still writing
DBRA D1,@0 ; ... loop back until done
ADDQ.L #4,D5 ; update file read pointer
MOVE.L (SP)+,D1 ; restore D0-D1
BRA.S Ptr3Exit ; and go back to caller
;_______________________________________________________________________________
;
; Routine: CmpFrmDsk (utility)
;
; Arguments: A1 (i/o.l) pointer to the end of compacted region
; A2 (input.l) pointer to resource entry
; A3 (input.l) Handle to start of update buffer
; A4 (input.l) current map handle
; D3 (input.l) end of the update buffer
; D4 (i/o.l) pointer in buffer (end of stuff read in)
; D5 (i/o.l) the current file read position
; D6 (input.w) the current file refnum
; D7 (i/o.l) the current file write position
; RLocn(A2) (output.l) the new file offset for this rsrc
;
; Unchanged: A2-A7,D1,D3,D6
; Trashed: A0,D0,D2
;
; Called By: UpdateResFile
; Calls: _BlockMove, CmpctRead, PartRead, PartWrite, Ptr1Exit, Ptr2Exit,
; RLocnNew, WriteZero
;
; Function: Compacts resource from disk (because the ResChanged bit not set).
; Just does read and compact of one resource. If cann't read in
; all of resource into update buffer, writes out compacted stuff
; and continues until all is done. Also updates RLocn(A2) as well.
; Also, D4 is limited as a lower bound by A1.
;_______________________________________________________________________________
CmpFrmDsk
MOVE.L RLocn(A2),D0 ; point to next resource in file
AND.L Lo3Bytes,D0 ; make sure high byte cleared for compare <08jul85> BBM
SUB.L D5,D0 ; check to see if this RLocn is resonable
BGE.S @4 ; CC=GE offset seems good (past stuff written)
BSR PartWrite ; make sure we have some room to work in
BSR.S RLocnNew ; update rsrc location in map
BRA.S WriteZero ; write out zero for size of rsrc & return <08jul85> BBM
;;;RTS ; we really return though WriteZero
@4 ADD.L A1,D0 ; add offset to end of compact region
ADDQ.L #4,D0 ; add in the size of the rsrc size <03jul85> BBM
CMP.L D0,D4 ; is all of the size in memory???
BGE.S @1 ; if it is all in memory go read in size <10jul85> BBM
BSR PartWrite ; else get some room to work with
MOVE.L RLocn(A2),D0 ; get current position of this resource
AND.L Lo3Bytes,D0 ; get rid of the resource attributes
MOVE.L D0,D5 ; set up read pointer for next read
BSR.S PartRead ; and read in the size
@1 MOVE.L RLocn(A2),D0 ; point A0 to Size of resouce
BSR.S RLocnNew ; update new position in the map <02jul85> BBM
SUB.L D5,D0 ; ... D0 now has delta from D5 to size
AND.L Lo3Bytes,D0 ; ... make sure no garbage in high byte
MOVE.L A1,A0 ; ... get pointer into buffer
ADD.L D0,A0 ; ... A0 now points to the size in memory
BSR OddSize ; D0 gets Size of Rsrc; A0 points to Rsrc
ADDQ.L #4,D0 ; Also include the size of the resource <13may86> BBM
SUBQ.L #4,A0 ; and point A0 to the size of the resource <13may86> BBM
MOVE.L D0,D2 ; save size for later
ADD.L A0,D2 ; Check to see if all of rsrc is in buffer
CMP.L D2,D4 ; is all of rsrc in buffer?
BGE Ptr1Exit ; if all in buffer exit by compacting
ADD.L A0,D5 ; bump D5 pointer by A0-A1 to É <C268>
SUB.L A1,D5 ; É keep D5 correct for large files <C268>
AND.L Lo3Bytes,D5 ; É and make sure no garbage in high byte <C268>
MOVE.L D0,D2 ; D2 will be count of stuff left to read in <01jan86> BBM
MOVE.L D4,D0 ; get the end of the stuff read in
SUB.L A0,D0 ; calc the amount of rsrc in update buffer
BSR Ptr1Exit ; move it down to compacted space
MOVE.L A1,D4 ; since there is no more valid data in buff <10jul85> BBM
@2 BSR.S PartWrite ; write out what we have
BSR.S PartRead ; Read in more of the resource
BEQ.S @9 ; abort if zero bytes read in <17oct85> BBM
SUB.L D0,D2 ; update amount of this resource to read
MOVE.L A1,A0 ; calc how much of rsrc we just loaded
ADD.L D2,A0 ; ... A0 now points to end of rsrc
CMP.L A0,D4 ; does rest of rsrc lie in buffer?
BGE.S @3 ; ... CC=GE means the rest is in mem
MOVE.L D4,D0 ; compact and write what we have
SUB.L A1,D0 ; ... by calc how much we have
BSR Ptr2Exit ; ... updateing pointers and ...
BRA.S @2 ; ... looping back
@3 MOVE.L A0,D0 ; calc size of the rest of this rsrc
SUB.L A1,D0 ; ... D0 now is size
BRA Ptr2Exit ; and exit!!!!
@9 MOVE.W #mapReadErr,ResErr ; mark as error for exit <21oct85> BBM
BRA Ptr3Exit ; and exit back to update <21oct85> BBM
;_______________________________________________________________________________
;
; Routine: PartRead (utility)
;
; Arguments: A1 (input.l) pointer to the end of compacted region
; A3 (input.l) Handle to start of update buffer
; A4 (input.l) current map handle
; D3 (input.l) end of input buffer
; D4 (output.l) pointer in buffer (end of stuff read in)
; D5 (input.l) the current file read position
; D6 (input.w) the current file refnum
;
; Unchanged: A0-A7,D0-D3,D5-D7
; Trashed: none
;
; Called By: CmpFrmDsk
; Calls: RdData
;
; Function: Reads in as much as it can from the file into the update buffer.
; Note that if you haven't used all you read in before, this will
; read in the unused stuff again. Make sure you compact as much
; as possible and call PartWrite before you call this routine.
;_______________________________________________________________________________
PartRead
MOVEM.L D0-D2/A0,-(SP) ; save these across call
BSR MaxRFEOF ; get EOF in D0 <12sep85> BBM
MOVE.L (A4),A0 ; dereference map handle
SUB.L D5,D0 ; D0 = amount left to read in.
SUB.L ResDataOffset(A0),D0 ; take out bias for D5
AND.L Lo3Bytes,D0 ; make sure no garbage in top byte
MOVE.L D3,D1 ; get end of buffer <12sep85> BBM
SUB.L A1,D1 ; D1 = amount left in buffer
CMP.L D1,D0 ; get minimum of D0/D1
BLE.S @0 ; CC=LE means D0 is already minimum
MOVE.L D1,D0 ; else D1 is minimum
@0 MOVE.L A1,D1 ; set up destination address
MOVE.L D5,D2 ; set up file position
ADD.L ResDataOffset(A0),D2 ; take out bias for D5
MOVE.L A1,D4 ; set up new end of read region
ADD.L D0,D4 ; update read buffer pointer
; this should never be needed for 24 bit and 32 bit addressing <v1.2>
; AND.L Lo3Bytes,D4 ; make sure high byte cleared <v1.2>
BSR RdData ; read data into update buffer (D0 good across call)
TST.L D0 ; check if zero byte read call issued <17oct85> BBM
MOVEM.L (SP)+,D0-D2/A0 ; restore working registers
RTS ;
;_______________________________________________________________________________
;
; Routine: PartWrite (utility)
;
; Arguments: A1 (i/o.l) pointer to end of data compacted in buff
; A3 (input.l) Handle to beginning of data buffer
; A4 (input.l) Handle to the resource map
; D4 (i/o.l) pointer to end of data read in
; D6 (input.w) the current file refnum
; D7 (i/o.l) file write position - ResDataOffset
;
; Unchanged: A2-A7,D0-D3,D5-D6
; Trashed: A0
;
; Called By: CmpFrmDsk
; Calls: _BlockMove, WrData
;
; Function: Writes what has been compacted in the buffer pointed to by (A3),
; and slides the rest forward updating the correct vars.
;_______________________________________________________________________________
PartWrite
MOVEM.L D0-D2,-(SP) ; save working registers
MOVE.L A1,D0 ; check if anything is ready to be written <01jul85> BBM
SUB.L (A3),D0 ; ... get amount already compacted
AND.L Lo3Bytes,D0 ; if zero nothing in buffer
BEQ.S @9 ; ... if nothing then just return
MOVE.L (A4),A0 ; Dereference map for D7 bias correction
MOVE.L D7,D2 ; ... D2 will be actual file position
ADD.L ResDataOffset(A0),D2 ; ... now D2 is unbiased file write position
ADD.L D2,D0 ; force size to be on a 512 byte boundry
AND.W #$FE00,D0 ; ... round down to 512 byte boundry
SUB.L D2,D0 ; restore D0 to be size to write out
BLE.S @9 ; not enough to write out <01jul85> BBM
MOVE.L (A3),D1 ; Set up Buff address for write
BSR WrData ; do write (NOTE D0 saved across call)
ADD.L D0,D7 ; update file write pointer
SUB.L D0,A1 ; update end of compact region in buffer
SUB.L D0,D4 ; update end of valid data read in
MOVE.L A1,-(SP) ; save A0/A1 across blockmove call
MOVE.L (A3),A1 ; set up destination for blockmove
MOVE.L (A3),A0 ; set up source for blockmove
ADD.L D0,A0 ; ... add in offset to source
ADD.L D4,D0 ; set up block count for blockmove
SUB.L A0,D0 ; ... subtract end pointer
AND.L Lo3Bytes,D0 ; ... make sure A0 didn't have garbage <01jul85> BBM
_BlockMove ;
MOVE.L (SP)+,A1 ; restore A1 to be compact pointer
@9 MOVEM.L (SP)+,D0-D2 ; restore working registers
RTS ;
;_______________________________________________________________________________
;
; Routine: PROCEDURE CloseResFile(refNum: INTEGER);
;
; Arguments: 4(SP) (input.L) File refnum
;
; Called By: A-trap through dispatcher, CloseFiles
; Calls: CloseFiles, StdMapEntry, _UpdateResFile, GetEntries,
; _ReleaseResource, GetMap, SetFileIO, _Close,
; _DisposHandle, StdTwoExit
;
; Function:
; Updates, compacts, and closes the given resource file.
; Writes out the possibly changed map and header. Disposes of all
; resources referred to in the map. Unlinks the map from the
; linked list of resource maps, and disposes of the map handle.
; If the refnum given is 0, closes ALL resource files.
;_______________________________________________________________________________
CloseResFile
MOVE.L MinusOne,LastSPExtra ; invalidate font cache for font manager <C238>
MOVE.W HSCMapRNum,D0 ; if the HandleScan cache map refnum... <06may85> BBM
CMP.W 4(SP),D0 ; ... equals this maps refnum then ...
BNE.S @1 ; ... blitz the cache else skip next ins.
CLR.L HSCHandle ; Invalidate cache <12mar85> BBM
@1 TST.W 4(SP) ; is it the system resource file?
BNE.S ClsRFile ; if not, go on, else
BSR CloseFiles ; Close all files other than system
ClsRFile
BSR StdMapEntry ; Link A6, save regs, get map, exit if none
; Check preventFileFromBeingClosedBit in the resource map. If
; this bit is set, donÕt allow this file to be closed.
move.l (a4),a1 ; Pointer to resource map
btst #preventFileFromBeingClosedBit,mInMemoryAttr(a1) ; Can this file be closed?
bnz @leaveWithoutClosing ; No. DonÕt close it.
@doClose
BSR CheckAndFlushFontCache ; If we are closing a file w/ fonts we should invalidate the cache
@temp
; Attempt an update, writing out all resources with the ResChanged bit set,
; updating the map, and compacting the resource file.
MOVE.W D6, -(SP) ; Push the refnum
_UpdateResFile ; Update the file.
; Release all the resources
; This section used to call DisposeResource which checked three things: <03mar85> BBM
; handle nil, system reference, and resource marked to be updated. Since
; UpdateResFile was just called there is no point in checking changed bit
; This loop already checks handle nil and system reference, so why not
; call DisposHandle directly. In fact, why not save more time by getting
; trap address and avoiding the dispatcher. (comment part of <3mar85> BBM)
MOVE.L #$23,D0 ; calling dispose handle a lot so ... <03mar85> BBM
_GetTrapAddress ; ... for speed bypass dispatcher.
BSR GetRsrcCnt ; Get to the entries list. <12aug85> BBM
BMI.S @3 ; if no entries, don't release resources <28Jan85> BBM
MOVE.L A0,A4 ; (A4) = _DisposeHandle. Restored in GetMap <06may85> BBM
ADDQ #RHndl,A2 ; Bias A2 in the loop (for speed) <12aug85> BBM
@1 MOVE.L (A2)+,D0 ; Get the handle <12aug85> BBM
BEQ.S @2 ; if nil, don't attempt a release, else
MOVE.L D0,A0 ; get the handle <03mar85> BBM
JSR (A4) ; and release it. (_DisposHandle) <06may85> BBM
@2 ADDQ.W #RESize-4,A2 ; point at the next entry <12aug85> BBM
DBRA D4,@1 ; if more exist, loop back <12aug85> BBM
; Unlink the map from the map list. <28Jan85> BBM
@3 BSR GetMap ; Get this map, and previous in D0 <12aug85> BBM
MOVE.L MNext(A3), A0 ; Get my next link
TST.L D0 ; Did I have a previous map? (i.e. <>top?)
BNE.S @4 ; If so, leave topMapHndl the same
MOVE.L A0, TopMapHndl ; Otherwise save my next as top map
BRA.S @5 ; ...and handle refnum stuff.
@4 MOVE.L D0, A1 ; Get previous map in AReg
MOVE.L (A1), A1 ; Dereference
MOVE.L A0, MNext(A1) ; set previous next as my next
@5 CMP.L SysMapHndl, A4 ; Am I removing the system map?
BNE.S @6 ; If not, handle normally.
LEA TopMapHndl,A0 ; initialize world as in powerup <22jul85> BBM
MOVE.L ROMMapHndl,(A0)+ ; make rom map top map <22jul85> BBM
MOVE.L ROMMapHndl,(A0)+ ; make rom map system map <22jul85> BBM
MOVE.L OneOne,(A0)+ ; set SysMap & curMap to Rom Map RefNum <22jul85> BBM
MOVE.L ROMMapHndl,A0 ; zero next map link <22jul85> BBM
MOVE.L (A0),A0 ; ... dereference rom map handle <22jul85> BBM
CLR.L MNext(A0) ; ... Zero nextMap handle <22jul85> BBM
BRA.S @9 ; and close.
@6 CMP.W CurMap, D6 ; Am I the current map?
BNE.S @9 ; No, everything's ok. If I actually am,
MOVE.L (A0), A0 ; Dereference my next (which exists)
MOVE.W MRefNum(A0), CurMap ; and save its refnum in CurMap.
@9 BSR SetFileIO ; Set up a file block
_Close ; And close it.
BEQ.S @7 ; if no error use ResErr from UpdateResFile <16apr85> BBM
MOVE.W D0, ResErr ; ... else store this code into ResError <16apr85> BBM
@7 MOVE.L A4, A0 ; get handle into A0 for dispose
_DisposHandle ; Kill map even if error (not recoverable)
bra.s @8
@leaveWithoutClosing
clr.w ResErr
@8
BRA StdTwoExit ; and exit.
;_______________________________________________________________________________
;
; Routine: FUNCTION CountResources(theType: ResType): INTEGER;
;
; Arguments: 8(A6) (input.L) resource type
; 12(A6) (output.W) number of resources with that type
;
; Called By: A-trap through dispatcher
; Calls: StdEntry, GetTopMap, TypeScan, NextMap, StdFourExit
;
; Function: Given the type, return the number of resources of that type
; accessable in ALL open maps.
;_______________________________________________________________________________
Count1Resources
ST ResOneDeep ; entry for one map deep call <22apr85> BBM
CountResources
BSR StdEntry ; Link A6, save regs
CLR.W 12(a6) ; None of this type found so far
move.l (a0),-(sp) ; Pust the typeÉ
bsr CacheResource ; Build the resource cache for that type
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),d1 ; Get count
MOVE.W D1,12(A6) ; Save Result
@exitCountResourcesOverride
BRA StdFourExit ; else, lets exit.
;_______________________________________________________________________________
;
; Routine: FUNCTION GetIndResource(theType:ResType; index:INTEGER): Handle;
;
; Arguments: 10(A6) (input.L) resource type
; 8(A6),A0(input.W) index
; 14(A6) (output.L) resource handle
;
; Called By: A-trap through dispatcher
; Calls: CheckLoad, GetTopMap, NextMap, SaveCache, SkipToEntry,
; StdEndtry, StdSixExit, TypeScan
;
; Function: Given the type and the index, return the resource handle.
;_______________________________________________________________________________
Get1IndResource
ST ResOneDeep ; entry for one map deep call <22apr85> BBM
GetIndResource
BSR StdEntry ; Link A6, save regs
MOVE.W (A0)+, D7 ; Get index in D7
MOVE.L (A0)+, D3 ; and type into D3.
CLR.L (A0)+ ; Assume not found.
TST.W D7 ; the index<=0 and return not found) <sm 5> stb<SM8>
BLE get1IndErrExit ; <sm 5> stb
move.l D3,-(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 get1IndErrExit ; If no handle, get out
move.l d0,a0
move.l (a0),a0 ; Pointer to cache
moveq #0,d0
move.w d7,d0 ; Get index into cache
subq #1,d0 ; Cache is zero based
cmp.l kResourceCount(a0),d0 ; Check the bounds of the index
bge.s get1IndErrExit
@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 D3,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.
;
@notOneDeep
WITH ResourceMgrStack
clr.w ioBlock+ioVRefNum(a6) ; so that it has a IOPB where it
clr.w ioBlock+ioFileType(a6) ; expects it on the stack
move.b RMgrPerm,ioBlock+ioPermssn(a6)
jsr CheckLoad ; Go load the resource if necessary
move.l a0,14(a6) ; Return the handle
move.l a0,HSCHandle ; <37> And save it in the cache
bra.s get1IndOut
ENDWITH
get1IndErrExit
MOVE.W #ResNotFound,ResErr ; ... else mark as an error.
get1IndOut
BRA StdSixExit ; pop 6 bytes and exit
;_______________________________________________________________________________
;
; Routine: FUNCTION CountTypes: INTEGER;
;
; Arguments: 8(A6) (output.W) number of types
;
; Called By: A-trap through dispatcher
; Calls: StdEntry, CountITypes, StdZeroExit
;
; Function: Return the number of types in open resource files.
;_______________________________________________________________________________
Count1Types
ST ResOneDeep ; entry for one map deep call <22apr85> BBM
CountTypes
BSR StdEntry ; Link A6, save regs
BSR.S CountITypes ; Stack up unique types, D7=count
UNLK A6 ; Pop off the types
MOVE.W D7, 8(A6) ; Set function result
BRA StdZeroExit ; Unlink A6, restore regs
;_______________________________________________________________________________
;
; Routine: CountITypes (utility)
;
; Arguments: D7.W (output.W) number of unique types
;
; Called By: CountTypes, GetIndType, Count1Types, Get1IndType
; Calls: GetTopMap, GetTypes, NextMap, ChkTypeIgnored
;
; Function: Return a list of unique types on the stack, and D7 = the count.
;_______________________________________________________________________________
CountITypes
MOVE.L (SP)+, A0 ; Get return address in A0
LINK A6, #0 ; Link A6 for quick unlk of types
MOVEQ #0, D7 ; No types yet
BSR GetTopMap ; Get the top map
@0 BSR GetTypes ; Get the type list
BMI.S @5 ; If no types, go to next map
@1 MOVE.L TType(A2), D3 ; Get candidate type in D3
MOVE.L SP, A1 ; Set up climber register
MOVE D7, D0 ; Get current count
SUBQ #1, D0 ; Zero based for DBRA
BMI.S @3 ; if none yet, just add
@2 CMP.L (A1)+, D3 ; is this type already represented?
DBEQ D0,@2 ; loop back for count of types <01may85> BBM
BEQ.S @4 ; If so, go to next type in map
@3 MOVE.L D3, -(SP) ; Push the new type on the stack
ADDQ #1, D7 ; Increment type count
@4 ADDQ.L #TSize, A2 ; Skip to next type entry
DBRA D5, @1 ; and loop back.
@5 BSR NextMap ; Link to next map
BEQ.S @0 ; If there are more, loop back.
FPCallCountIExit ; FlashPort hint attachment point <bt>
JMP (A0) ; and return. D7=one's based count,
; stack has the types.
;_______________________________________________________________________________
;
; Routine: PROCEDURE GetIndType(VAR theType: ResType; index: INTEGER);
;
; Arguments: 10(A6) (input.L) resource type
; 8(A6),A0(input.W) resource ID
; 14(A6) (output.L) resource handle
;
; Called By: A-trap through dispatcher
; Calls: StdEntry, CountITypes, StdSixExit
;
; Function: Given the index, return indexed type in the current resource map.
;_______________________________________________________________________________
Get1IndType
ST ResOneDeep ; entry for one map deep call <22apr85> BBM
GetIndType
BSR StdEntry ; Link A6, save regs
MOVE.W (A0)+, D2 ; Get index number in D2,
MOVE.L (A0), D1 ; and VAR address in D1.
BSR.S CountITypes ; Make type list on stack
MOVE.L D1, A0 ; Get VAR address in AReg
CLR.L (A0) ; Assume failure
SUBQ.W #1, D2 ; Make count zero based
BMI.S @9 ; if count was <=0, exit with error.
CMP.W D2, D7 ; is it > max?
BLE.S @9 ; if so, use error result.
ASL.W #2, D2 ; (count-1)*4 for offset
MOVE.L 0(SP, D2), (A0) ; Set function result
@9 UNLK A6 ; Pop off the types (linked in CountITypes)
BRA StdSixExit ; and exit
;_______________________________________________________________________________
;
; Routine: FUNCTION UniqueID(theType: ResType): INTEGER;
;
; Arguments: 8(A6) (input.L) resource type
; 12(A6) (output.W) Unique ID
;
; Called By: A-trap through dispatcher
; Calls: StdEntry, GetTopMap, _Random, TypeScan, SkipToEntry, IDScan,
; IDScanAll, NextMap, StdFourExit
;
; Function: Return a unique ID for a given type. The ID is unique across
; ALL maps that are currently open. The ID is always > 127. <13> stb
;_______________________________________________________________________________
Unique1ID
ST ResOneDeep ; entry for one map deep call <22apr85> BBM
UniqueID
BSR StdEntry ; Link A6, save regs
MOVE.W Ticks+2, D7 ; Get low ticks for initial ID guess
@0 BSR GetTopMap ; Get the top map
SUBQ #2, SP ; Make room for result
_Random ; Get Bill's random number
ADD.W (SP)+, D7 ; Increment ticks by a random amount.
AND.W #$7FFF, D7 ; Force it positive for no good reason
MOVE.L 8(A6), D3 ; Get type in D3
MOVE.W D7, D2 ; Copy ID candidate to D2.
CMP.W #128, D2 ; is it legal? <13> stb <SM44> CSS
BLT.S @0 ; if not, try again <13> stb
@1 BSR TypeScan ; Try to find the type.
BMI.S @2 ; if MI, no such type
BSR SkipToEntry ; Skip to the first entry of that type
BSR IDScan ; Now try to find the ID
BEQ.S @0 ; if found, need a new random ID.
@2 BSR NextMap ; follow link to next map
BEQ.S @1 ; If there is another map, scan it,
MOVE.W D2, 12(A6) ; else, Return the unique ID
BRA StdFourExit ; and exit.
;_______________________________________________________________________________
;
; Routine: FUNCTION GetResource(theType: ResType; theID: INTEGER): Handle;
;
; Arguments: 10(A6) (input.L) resource type
; 8(A6),A0(input.W) resource ID
; 14(A6) (output.L) resource handle
;
; Called By: A-trap through dispatcher
; Calls: StdEntry, GetCurMap, TypeScan, SkipToEntry, IDScan, NextMap,
; CheckLoad, StdSixExit, GetTopMap, SaveCache
;
; Function: Given a type and ID, return the handle to the resource. Searches
; all maps starting with the current map and ending with the system
; map.
; NOTE:
; May not search all open maps, depending which the current map is.
;_______________________________________________________________________________
Get1Resource
returnAddress EQU 0
theResID EQU returnAddress+4
theResType EQU theResID+2
ST ResOneDeep ; entry for one map deep call <22apr85> BBM
IF hasRISCV0ResMgrPatches THEN
BRA realGetRes
GetResource
; <SM56> BT
; first do GetResource ProcessManager patch if the process manager is around
MOVE.L ExpandMem,A0 ; get ExpandMem
TST.W ExpandMemRec.emProcessMgrExists(A0) ; is the process manager here?
BEQ.S realGetRes ; nope, blow the patch
; the patch checks to see if we have old PrintMgr.o glue trying to print
; by loading the resource and calling it directly. If so, we need to deal
; with the local/global printer scheme for the glue, since _PROpenDriver isn't
; going to be there to cover for us
moveq.l #0,d0
move.l 6(sp),a0 ; get res type
cmp.l #'PDEF',a0 ; is this a potential print entry point?
bne.s realGetRes ; if not, branch
move.w 4(sp),d0 ; get res id (whole word)
cmp.w #7+1,d0 ; is it 0-7?
bcc.s realGetRes ; if not, branch to real call
movem.l d1-d2/a1,-(sp) ; save work regs
lea -10(sp),sp ; room for 2 pointers + return value (on bottom)
pea 6(sp) ; push ptr to one ptr
pea 6(sp) ; push ptr to the other ptr
_MFGetPrTypeStrings ; get local and global ref nums
moveq.l #0,d0 ; assume pr types the same
tst.b (sp)+ ; is pr type locked for this guy?
beq.s @sameString ; if so, branch (treat as strings equal)
move.l 0(sp),a0 ; get first string in a0
move.l 4(sp),a1 ; get second string in a1
moveq.l #0,d0 ; clear out d0
move.b (a0)+,d0 ; d0.w <- length of first string
swap d0
move.b (a1)+,d0 ; d0.w <- length of second string
_RelString ; call it
move.l 4(sp),d2 ; save local name
; get here with condition codes saying whether the types are the same
@sameString
addq.w #8,sp ; get rid of the 2 string ptrs
tst.w d0 ; are they the same?
beq.s @GotoPDEF ; if equal, branch
; Set the printer type for the current process, give a _Close call to the .Print driver, and
; then give it an _Open call. If the driver is not in yet, _Close will return an error which
; we ignore. If it is in, it simple passes it along to the appropriate .XPrint.
subq.w #2,sp ; room for return result
move.l d2,-(sp) ; push local name
move.w BootDrive,-(sp) ; has to be in sys folder
move.b #fsCurPerm,-(sp) ; default arg (need to r/w probably)
_OpenRFPerm ; bring to front (already opened)
move.w (sp)+,d2 ; save the refnum
_PrDrvrOpen ; Open new driver, thus closing old one
move.w d2,-(sp) ; push refnum of (old) local pr type name
_CloseResFile ; close old driver's res file
move.l TopMapHndl,a0 ; get top map
move.l (a0),a0 ; hdl -> ptr
move.l MRefNum(a0),CurMap ; force new guy (who is at top) to be current
@GotoPDEF
movem.l (sp)+,d1-d2/a1 ; restore work regs
; <SM56> BT end of patch, do the real thing
ELSE
GetResource
ENDIF
realGetRes BSR StdEntry ; Link A6, save regs
BSR GetCurMap ; Get handle to current map
BPL.S @2 ; fix an old finder bug with new roms <25mar85> BBM
BSR GetTopMap ; ... when get resource passed bad RefNum
@2 MOVE.W (A0)+, D2 ; Get resource ID in D2
MOVE.L (A0)+, D3 ; and type in D3
CLR.L (A0) ; Assume not found
@0 BSR TypeScan ; Try to find the type
BMI.S @1 ; if MI, no such type, get next map
BSR SkipToEntry ; Skip to the first entry of that type
BSR IDScan ; Now try to find the ID
BEQ.S @8 ; If EQ, found it! Otherwise try next map
@1 BSR NextMap ; follow link to new map
BEQ.S @0 ; If there is another map, try again,
;<17jun85> BBM MOVE.W #ResNotFound,ResErr ; ...else mark as error <16apr85> BBM
BRA.S @9 ; else not found.
@8 BSR SaveCache ; valid most of cache for handle scan <30apr85> BBM
BSR CheckLoad ; Check handle, init/load it if needed
MOVE.L A0, 14(A6) ; Save result--fall through to exit.
MOVE.L A0,HSCHandle ; finish validating cache <30apr85> BBM
@9 BRA StdSixExit ; else not found.
;_______________________________________________________________________________
;
; Routine: FUNCTION GetNamedResource(theType:ResType;theName:Str255):Handle;
;
; Arguments: 12(A6) (input.L) resource type
; 8(A6) (input.L) pointer to resource name
; 16(A6) (output.L) resource handle
;
; Called By: A-trap through dispatcher
; Calls: StdEntry, GetCurMap, TypeScan, SkipToEntry, NamedResource,
; _CmpString, NextEntry, NextMap, CheckLoad, StdExit, SaveCache
;
; Function: Given a type and name, return the handle to the resource.
; Searches all maps starting with the current map and ending with
; the system map.
; NOTE:
; May not search all open maps, depending which the current map is.
;_______________________________________________________________________________
Get1NamedResource
ST ResOneDeep ; entry for one map deep call <22apr85> BBM
GetNamedResource
BSR StdEntry ; Link A6, save regs
BSR GetCurMap ; Get the current map
MOVE.L (A0), A1 ; Get name pointer in A1.
CLR.L 16(A6) ; Assume the resource was not found
@1 MOVE.L 12(A6), D3 ; Get type of resource in D3 for scan.
BSR TypeScan ; Look for the type
BMI.S @4 ; If no such type found, get next map
BSR SkipToEntry ; Walk through the entries of this type.
@2 BSR NameResource ; Given RNameOff(A2), return name in A0.
BMI.S @3 ; if CC=MI, didn't find name (A1=target string)
MOVEQ #0, D0 ; Clear out high bits
MOVE.B (A0)+, D0 ; Get length (trash A0!)
SWAP D0 ; and put it in high order
MOVE.B (A1)+, D0 ; Get length of second string in low order
_CmpString ; Check equality of strings in A0 and A1
SUBQ #1, A1 ; Point back to the Pascal string in A1
BEQ.S @8 ; If equal, load it in!
@3 BSR NextEntry ; Skip to next entry
BEQ.S @2 ; If not changed type, get next res
@4 BSR NextMap ; Link to next map
BEQ.S @1 ; if one exists, go search it,
MOVE.W #ResNotFound,ResErr ; ...else mark as error <16apr85> BBM
BRA.S @9 ; ...and exit.
@8 BSR SaveCache ; valid most of cache for handle scan <30apr85> BBM
BSR CheckLoad ; otherwise load it in, if necessary.
MOVE.L A0,16(A6) ; Save the handle as function result
MOVE.L A0,HSCHandle ; finish validating cache <30apr85> BBM
@9 MOVEQ #8, D0 ; pop off eight bytes of parameter
BRA StdExit ; and exit.
;=== RmgrAsm2.a Starts Here =============================================================
;_______________________________________________________________________________
;
; The following routines are all of the same form: GET*.
; Given a parameter, point registers to *.
;_______________________________________________________________________________
;_______________________________________________________________________________
;
; Routine: GetTopMap (utility)
;
; Arguments:: A4 (input.L) handle top map
; A2 (output.L) pointer top map
; A3 (output.L) pointer top map (same as A2)
; A4 (output.L) handle top map
; D0 (output.L) handle previous map (if BNE GetCurMap)
; D6 (output.W) top map refnum
;
; Called By: CountResources, GetIndResource, CountITypes, UniqueID,
; GetResource, HandleScan
; Calls: GetCurMap
;
; Function: Set up regs for the current topmost resource map.
;_______________________________________________________________________________
GetTopMap
BLANKS ON
STRING ASIS
TST.B ResOneDeep ; if one is set get current map instead <26jun85> BBM
BNE.S GetCurMap ; ... else fall through to GetTopMap.
MOVE.L TopMapHndl, A4 ; Get topMap handle
MOVE.L (A4), A3 ; Dereference it
MOVE.W MRefNum(A3), D6 ; Get reference number
MOVE.L A3, A2 ; Copy it in A2
RTS ; Block handle in A4, ptr in A3 and A2
;_______________________________________________________________________________
;
; Routine: GetCurMap, GetMap (utilities)
;
; Arguments: D6 (input.W) map refnum
; A4 (output.L) handle to new map
; A3 (output.L) pointer to new map
; A2 (output.L) pointer to new map
; D0 (output.L) handle of previous map
;
; Called By: (GetCurMap): PreLoad, PreLoad2, RsrcZoneInit, GetResource,
; GetNamedResource, AddResource
; (GetMap): SetResFileAttrs, StdMapEntry, CloseResFile
; Calls: NONE
;
; Function: Set up registers for resource map specified by refnum in D6.
; GetCurMap sets D6 to the current map refnum & calls get map.
; D0 = 0 if no previous Map.
;_______________________________________________________________________________
GetCurMap
MOVE.W CurMap, D6 ; Get current resFile refnum.
GetMap
TST.W D6 ; Test refnum (system special, or none)
BMI NotFound ; if -ve, no maps open--exit with error.
BNE.S @1 ; If not zero, use standard resource
MOVE.W ResourceMgrStack.OverrideSysMap(a6),D6 ; Otherwise use refnum of system map
@1 MOVE.L TopMapHndl, A4 ; Get top map handle
MOVEQ #0, D0 ; Initialize prev map handle
BRA.S @3 ; Get next map (jump into loop)
@2 MOVE.L MNext(A3),D0 ; Get handle to the next map.
BEQ NotFound ; If the handle was nil, not found
EXG A4,D0 ; set A4, and last map handle in D0.
@3 MOVE.L (A4),A3 ; Dereference
CMP.W MRefNum(A3),D6 ; Is it the right resource map?
BNE.S @2 ; no, skip to the next one
MOVE.L A3, A2 ; Copy it in A2
RTS ; Block handle in A4, ptr in A3 and A2
;_______________________________________________________________________________
;
; Routine: NextMap (utility)
;
; Arguments: A4 (input.L) resource map handle
; A3 (output.L) pointer to next map
; A4 (output.L) handle to next map
; D6 (output.L) refnum to next map
;
; Called By: HandleScan, CountIResources, CountITypes, UniqueID, GetResource,
; GetNamedResource
; Calls: NONE
;
; Function: Given map handle in A4 Set up map handle, pointer, refnum of
; next map. Returns EQ if found, MI if not
;_______________________________________________________________________________
NextMap
move.l a0,-(sp) ; save off a0
TST.B ResOneDeep ; if one deep set, don't get next map <26jun85> BBM
BEQ.S @1 ; ... else do normal stuff
move.l ExpandMem,a0 ; <41>
tst.b ExpandMemRec.emScanOverrideMaps(a0) ; <41> Is overriding on?
beq.s @3 ; <41> No. don't check the 2 deep bit.
; The requested resource wasnÕt found in the map in A4. Check if the twoDeepBit is set on this
; map, and if it is, search the next map down.
move.l (a4),a3 ; Try the next map, but only if this map has twoDeep set.
btst #twoDeepBit,mInMemoryAttr(a3) ; Is the twoDeepBit set?
BNE.S @1 ; ... yes ignore oneDeep, so don't zero handle
@3 SUBA.L A4,A4 ; Zero Handle and error exit.
BRA.S @2 ; ... and return <19jun85> BBM
@1 MOVE.L (A4), A3 ; Dereference map handle
MOVE.L MNext(A3), A4 ; Get next handle
@2 move.l (sp)+,a0 ; restore a0
MOVE.L A4, D0 ; Was the handle zero?
BEQ NotFound ; If no more maps
MOVE.L (A4), A3 ; Otherwise dereference
MOVE.W MRefNum(A3), D6 ; Get new refnum also
BRA Found ; Say it was found
;_______________________________________________________________________________
;
; Routine: GetTypes (utility)
;
; Arguments: A4 (input.L) map handle
; A2 (output.L) pointer to first type
; A3 (output.L) pointer to type block in map
; D5 (output.W) Type count
;
; Unchanged: A0-A1,A4-A7,D0-D4,D6-D7
; Trashed: NONE
;
; Called By: AddNewRef, CountITypes, GetEntries, TypeScan
; Calls: NONE
;
; Function: Given map handle in A4, Returns A2 pointing to the first type.
; A3 points to type block. D5 is type count.
;_______________________________________________________________________________
GetTypes
MOVE.L (A4), A3 ; Dereference map handle
ADDA.W MTypes(A3), A3 ; Add offset to type list
MOVE.L A3, A2 ; Copy top of block
MOVE.W (A2)+, D5 ; Get type count, point to first type
RTS
;_______________________________________________________________________________
;
; Routine: GetRsrcCnt (utility) <10may85> BBM
;
; Arguments: A4 (input.L) map handle
; A2 (output.L) pointer to first rsrc entry
; A3 (output.L) trashed
; D3 (output.W) the first type
; D4 (output.W) number of rsrc entries in map (minus one)
; D5 (output.W) D5 = $FFFF (always)
;
; Unchanged: A0-A1,A4-A7,D0-D2,D6-D7
; Trashed: A3,D3,D5
;
; Called By: Preload/Preload2, RomMapEntry, ReDoMap
; Calls: GetEntries
;
; Function: Set up D4 for looping through resource entries in map. If you
; need to go through every rsrc in the map call this routine, and
; do the following loop:
;
; @1 ...Code ; put your code here
; ADD.W #RESize,A2 ; point to next entry
; DBRA D4,@1 ; loop back if more entries
;
;_______________________________________________________________________________
GetRsrcCnt
BSR.S GetEntries ; set up regs for the count
BMI.S @9 ; if no entries just return with CC=MI
ADDQ #TCount+2,A3 ; point to 1st count (+2 is for TypeCount)
ADD.W D5,D4 ; D4 already has first count (Getentries)
BRA.S @1 ; jump into loop check
@0 ADDQ #TSize,A3 ; skip to count in the next type
ADD.W (A3),D4 ; Add this count into D4
@1 DBRA D5,@0 ; if more types loop back
@9 RTS ; else return with CC= error state
;_______________________________________________________________________________
;
; Routine: GetEntries (utility)
;
; Arguments: A4 (input.L) map handle
; A2 (output.L) pointer to the first ID
; A3 (output.L) points to type block
; D3 (output.W) the first type
; D4 (output.W) entry count (of the first type)
; D5 (output.W) type count
;
; Unchanged: A0-A1,A4-A7,D0-D2,D6-D7
; Trashed: none
;
; Called By: HandleScan, RsrcZoneInit, CloseResFile, RmveName
; Calls: GetTypes, SkipToEntry
;
; Function: set up regs from map handle for entry munging.
;_______________________________________________________________________________
GetEntries
BSR.S GetTypes ; A2 points to first type, D5 is NTypes
MOVE.L TType(A2), D3 ; Set the type
BSR.S SkipToEntry ; Skip to the first entry of that type
TST.W D5 ; Set CC's
RTS ; ...and return.
;_______________________________________________________________________________
;
; The following routines are all of the same form: *Scan.
; Scan for * within the map. If found, return CC=EQ. If not found, return
; CC=MI. A2 points to the correct entry.
;_______________________________________________________________________________
;_______________________________________________________________________________
;
; Routine: IDScan (utility)
;
; Arguments: A2 (input.L) pointer to first entry of given type
; D2 (input.W) ID of desired entry
; D4 (input.W) Entry count
; A2 (output.L) pointer to correct entry (if found)
;
; Unchanged: A0-A1,A3-A7,D1-D3,D5-D7
; Trashed: D0,D4
;
; Called By: GetResource
; Calls: NotFound, SubA2Found
;
; Function: Searches for desired entry. If found, return CC=EQ, else CC=MI.
;_______________________________________________________________________________
IDScan
MOVEQ #RESize,D0 ; Set up D0 with Rsrc Size for loop <01may85> BBM
@1 CMP.W RID(A2), D2 ; Is it the right ID? (note: RID=0)
ADDA.W D0,A2 ; Skip to next ID, if any
DBEQ D4,@1 ; Loop back, unless no more or found ID <01may85> BBM
BEQ.S SubA2Found ; if found, exit by adjusting A2
BRA.S NotFound ; If made it to here, not found
;_______________________________________________________________________________
;
; Routine: TypeScan (utility)
;
; Arguments: A4 (input.L) map handle
; D3 (input.L) resource type
; A2 (output.L) pointer to type entry
; D4 (output.W) entry count
; D5 (output.W) type count remaining
;
; Called By: CountIResources, UniqueID, GetResource, AddNewRef,
; GetNamedResource, RmveCmn
; Calls: GetTypes, ChkTypeIgnored
;
; Function: Set up returned registers from map handle. CC=MI if no types in
; map or entry type not found.
;_______________________________________________________________________________
TypeScan
BSR.S GetTypes ; A2 -->first type, D5 is type count
BMI.S NotFound ; No types listed!
MOVEQ #TSize,D0 ; Delta to next type <01may85> BBM
@1 CMP.L TType(A2), D3 ; Is it the right type? (note TType=0)
ADDA.W D0,A2 ; Skip to next type
DBEQ D5,@1 ; Decrement and try again, unless found <01may85> BBM
BEQ.S SubA2Found ; if found, exit by adjusting A2
BRA.S NotFound ; If made it to here, not found
;_______________________________________________________________________________
;
; Routine: SkipToEntry
;
; Arguments: A2 (input.L) pointer to type entry
; A2 (output.L) ptr to first res of input type (or NIL)
; D4 (output.W) entry count
; D5 (output.W) type count remaining
;
; Called By: GetEntries, CountIResources, UniqueID, GetResource,
; GetNamedResource, AddNewRef
; Calls: NONE
;
; Function: Set up registers from input type entry pointer. Returns pointing
; to the first resource entry of that type, or nil.
; (21may85 - now can handle 64k offsets correctly.)
;_______________________________________________________________________________
SkipToEntry
MOVE.W TCount(A2), D4 ; Copy entry count of first type into D4
MOVE.L D0,-(SP) ; make sure to preserve D0 <21may85> BBM
MOVEQ #0,D0 ; clear top half of D4 for 64k offset
MOVE.W TOffset(A2), D0 ; Copy offset to first entry
MOVE.L D0,A2 ; move to address reg.
MOVE.L (SP)+,D0 ; make sure to restore D0 <21may85> BBM
ADD.L A3, A2 ; Adding in block address gives entry address
RTS ; ...and return
;_______________________________________________________________________________
;
; Routine: Found, NotFound, SubA2Found
;
; Arguments: D0 (output.L) CC=EQ is found, CC=MI is Not found
;
; Called By: (found): nearly everyone
; (SubA2Found): IDScan
; (NotFound): nearly everyone
; Calls: NONE
;
; Function: these routines set up D0 and the condition codes for proper rts.
; SubA2Found also adjusts A2 to point at the 'right' entry.
;_______________________________________________________________________________
SubA2Found
SUBA.W D0,A2 ; adjust A2 and fall into found. <01may85> BBM
Found
MOVEQ #0, D0 ; Set CC=EQ
RTS
NotFound
MOVEQ #-1,D0 ; Set CC=MI
RTS
;_______________________________________________________________________________
;
; Routine: StdZEntry, Std1Entry, StdEntry (utilities)
;
; Arguments: A0 (output.L)
;
; Called By: everyone (well, almost)
; Calls: NONE
;
; Function: Links A6, saves ALL regs except A0 and D0. A0 is returned
; pointing to the last parameter, for (A0)+ traversals.
;
; WARNING: Currently this routine preserves D0. OpenRFPerm depends on D0
; not changing across the call. DO NOT MODIFY.
; Add Resource also depends on this!!
;_______________________________________________________________________________
StdZEntry
CLR.W RomMapInsert ; don't insert ROM Map <09jul85> BBM
Std1Entry
CLR.B ResOneDeep ; disable one deep stuff <26jun85> BBM
StdEntry
MOVE.L JRMgrStdEntry,A0 ; get the vector from the OSJumptable <1.2> BBM
JMP (A0) ; and go to the routine <1.2> BBM
vRMgrStdEntry ; Def to build dispatch entry <1.2> BBM
WITH ResourceMgrStack, ExpandMemRec
CLR.W ResErr ; Clear the error flag
MOVE.L (SP)+, A0 ; Get return address in A0
LINK A6, #localSize ; Link A6 for IOStkFrame <sm6>stb
CLR.W ioBlock+IOVRefNum(A6) ; always default to default volume and ... <05sep85> BBM<sm6>stb
CLR.W ioBlock+IOFileType(A6) ; File type Zero etc. <05sep85> BBM<sm6>stb
CLR.L ioBlock+ioDirID(A6) ; zero out the dir ID
CLR.B ioBlock+ioPermssn(A6) ; zero out the permissions byte
MOVEM.L A1-A4/D1-D7, -(SP) ; Save registers
SUBA.L A4,A4 ; since IO calls sub (A4) make sure even <03jun85> BBM
MOVE.L A0, -(SP) ; Push A0 back on as return
LEA 8(A6), A0 ; Point A0 at last parameter
movem.l a0-a5/d0-d5,-(sp) ; Save work registers for override setup
move.w CurMap,realCurMap(a6) ; Save a copy of real CurMap
clr.w doOverrides(a6) ; assume no overrides for nowÉ
clr.w overrideCurMap(a6) ; assume no overrides for nowÉ
; Save default values for SysMap and SysMapHndl
move.l SysMapHndl,OverrideSysMapHndl(a6) ; save the handle
move.w SysMap,OverrideSysMap(a6) ; Get reference number for SysMap
; As far as I can tell, CurMap is only negative before InitResources is called.
; If this is the case, we certainly don't want to save and restore curmap
; to a negative oneÉ
tst.w CurMap ; Special system case, bailÉ
bmi @noOverrideMap ; no overrides ( changed short branch to long ) <SM48> kc
move.l ExpandMem,a0 ; Get the expandmem rec ptr
tst.b emScanOverrideMaps(a0) ; Is overriding on?
beq.s @noOverrideMap ; No. Use the old resource mgr stuff.
move.w #1,doOverrides(a6) ; overrides are on.
bsr GetCurMap ; Get the Current Map in A4(Handle) and A3 (Ptr)
bmi.s @getSystemMap ; -> failed. Use the system map. <MC5>
move.w emLastMapOverridden(a0),d0 ; Get the last map that was overriden <MC5>
bz.s @GetOverrideMap ; If refnum is 0, then go get the override map. <SM48> kc
cmp.w CurMap,d0 ; If the refnum is the same as last time, <SM48> kc
beq.s @UseCachedMap ; skip all the work <SM48> kc
@GetOverrideMap ; <SM48> kc
; <SM48> kc
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 @getSystemMap ; Assume no override map if this map wasnÕt found
cmp.l a4,d0 ; did we get an override map?
beq.s @getSystemMap ; no they're the sameÉ
; WeÕ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,a1
move.l (a1),a0
move.w mRefNum(a0),d0 ; Get reference number of override map
move.l ExpandMem,a0 ; Cache override and overridden refnums <SM48> kc
move.w CurMap,emLastMapOverridden(a0) ; Remember the last map we overrode. <SM48> kc
move.w d0,emOverrideMapRefNum(a0) ; Remember the override map refnum. <SM48> kc
; <SM48> kc
@UseCachedMap ; <SM48> kc
move.w emOverrideMapRefNum(a0),d0 ; Get override refnum from the cache <SM48> kc
; <SM48> kc
move.w d0,CurMap ; Make the Resource Manager start with an override map
move.w d0,overrideCurMap(a6) ; store the override map.
@getSystemMap
move.w SysMap,D6
BSR GetMap ; Get the System Map in A4(Handle) and A3 (Ptr)
bmi.s @noOverrideMap ; -> Couldn't find the map. <MC5>
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 @noOverrideMap ; Assume no override map if this map wasnÕt found
move.l d0,OverrideSysMapHndl(a6) ; save the handle
move.l d0,a1
move.l (a1),a0
move.w mRefNum(a0),OverrideSysMap(a6) ; Get reference number of override map
@noOverrideMap
TST.B RomMapInsert ; do I need to insert ROM Map <26jun85> BBM
BEQ.S @done ; if zero don't add
MOVEQ #0,D1 ; tell SwapRomMap to add
BSR.S SwapRomMap ; else go add ROM map
@done
movem.l (sp)+,a0-a5/d0-d5
RTS ; and return.
ENDWITH
;_______________________________________________________________________________
;
; Routine: SwapRomMap (utility) <26jun85> BBM
;
; Arguments: D1 (input.w) 0 means add map; -1 means remove map
;
; Unchanged: A0-A7,D0-D7
; Trashed: NONE
;
; Called By: StdEntry, StdExit
; Calls: NONE
;
; Function: called by standard entry and exit to either add in the rommap to
; the map chain, or delete the rommap from the map chain.
;
; Now that we have overrides, we want to put the ROM map at the
; very end of the resource chain when swapping it out
; and we want to put it in front of any system override maps
; when swapping inÉ
;_______________________________________________________________________________
SwapRomMap ;
MOVEM.L A0-A3/D0-D2,-(SP) ; Save all regs used
move.l d1,-(sp) ; save d1 trashed by GetOverrideMap
MOVEA.L ResourceMgrStack.OverrideSysMapHndl(a6),A3 ; Hold the override map in a3 the link we're looking for
move.l (sp)+,d1 ; restore d1 trashed by GetOverrideMap
MOVEA.L ROMMapHndl,A2 ; A2 has the ROM Map
CMPA.L A3,A2 ; if A3=A2 then only ROM map around so...
BEQ @9 ; ... just return
;
; If we are swapping inÉ
; if CurMap == SysMap then make CurMap= ROMMap (1)
; else if we are swapping outÉ
; if CurMap == ROMMap then make CurMap SysMap
;
TST.L D1 ; determine if we are inserting or removing the rommap
BNE.S @removing ; -1 means removing ROM Map
MOVE.W CurMap,D0 ; for check if curmap needs changing <10jul85> BBM
@0 CMP.W ResourceMgrStack.OverrideSysMap(a6),D0 ; if SysMap=CurMap <10jul85> BBM
BNE.S @1 ;
MOVE.W #1,CurMap ; ... then CurMap gets RomMap
;InsertingÉ Put the rom resource map above the System Override fileÉ
@1 MOVEA.L TopMapHndl,A0 ; start at top and find map before A0
@2 MOVE.L (A0),A0 ; dereference it to get pointer
MOVE.L MNext(A0),D0 ; get the next map handle into A0
BEQ.S @4 ;;;;;;; error!!!
CMP.L A3,D0 ; is this the map we want
BEQ.S @3 ; found the right map
MOVE.L D0,A0 ; Make A0 a handle to the next map
BRA.S @2 ; and loop back for next check
@3 MOVE.L A2,MNext(A0) ; put in right link
BRA.S @5 ; skip to exit code
@4 CMP.L TopMapHndl,A3 ; if (topmaphndl <> A1) then ...
BNE.S @5 ; ... don't change topmaphndl
MOVE.L A2,TopMapHndl ; topmap is now the right link
@5 MOVE.L ROMMapHndl,A0 ; Point ROM to sysmap
MOVE.L (A0),A0 ; ... Dereference map handle to pointer
MOVE.L A3,MNext(A0) ; ... and point ROM to sysmap (possibly overidden)
bra.s @exit
@removing
MOVE.W CurMap,D0 ; for check if curmap needs changing <10jul85> BBM
CMP.W #1,D0 ; is RomMap=CurMap
BNE.S @begin ;
MOVE.W ResourceMgrStack.OverrideSysMap(a6),CurMap ; ... then make the system the current map
; Find the map that is above the ROM Map so we can point it around the
; ROM Map
@begin
MOVEA.L TopMapHndl,A0 ; start at top and find map before A0
@loop MOVE.L (A0),A0 ; dereference it to get pointer
MOVE.L MNext(A0),D0 ; get the next map handle into A0
BEQ.S @6 ;;;;;;; error!!!
CMP.L A2,D0 ; is this the map we want
BEQ.S @7 ; found the right map
MOVE.L D0,A0 ; Make A0 a handle to the next map
BRA.S @loop ; and loop back for next check
@6 CMP.L TopMapHndl,A2 ; if (topmaphndl <> Rom Map) then ...
BNE.S @7 ; ... don't change topmaphndl
MOVE.L A3,TopMapHndl ; topmap is now the system map (or its override)
bra.s @exit
@7 move.l (A2),A1 ; Ptr to ROM Map is now in A1
move.l MNext(A1),MNext(A0) ; Cut ROM out of the loopÉ MapBeforeROMMap->next = ROMMap->next
@exit
MOVE.B ResLoad,D0 ; Swap ResLoad and TmpResLoad
MOVE.B TmpResLoad,ResLoad ; ... Swap continued
MOVE.B D0,TmpResLoad ; ... Swap continued
@9 MOVEM.L (SP)+,A0-A3/D0-D2 ; Save all regs used
RTS ;
;_______________________________________________________________________________
;
; Routine: StdExit,StdZeroExit,StdTwoExit,StdFourExit,StdSixExit(utilities)
;
; Arguments: D0 (input.L) # of bytes to pop off stack before exit
; A6 (input.L) LINKed register
;
; Called By: everyone
; Calls: NONE
;
; Function: Unlinks A6, restores ALL regs except A0, D0. Call ResErrHook if
; ResErr<>0. ResErrProc called with error in D0 and return
; address of caller on stack. The hook can therefore filter
; errors and return to caller.
;_______________________________________________________________________________
StdTwelveExit
MOVEQ #12,D0 ; standard eight byte exit <SM9> <PN>
BRA.S StdExit ; and exit <SM9> <PN>
StdTenExit ;
MOVEQ #10,D0 ; standard six byte exit <SM9> <PN>
BRA.S StdExit ; and exit <SM9> <PN>
StdEightExit ;
MOVEQ #8,D0 ; standard six byte exit <SM9> <PN>
BRA.S StdExit ; and exit <SM9> <PN>
StdSixExit ;
MOVEQ #6,D0 ; standard six byte exit
BRA.S StdExit ; and exit
StdFourExit ;
MOVEQ #4,D0 ; standard four byte exit
BRA.S StdExit ; and exit
StdTwoExit ;
MOVEQ #2,D0 ; standard two byte exit
BRA.S StdExit ; and exit
StdZeroExit ;
MOVEQ #0,D0 ; standard Zero byte exit
RStdExit ; <9> rb
StdExit
MOVE.L JRMgrStdExit,A1 ; get the vector from the OSJumptable <1.2> BBM
JMP (A1) ; and go to the routine <1.2> BBM
vRMgrStdExit ; Def to build dispatch entry <1.2> BBM
tst.w ResourceMgrStack.doOverrides(a6)
beq.s @noOverrides
move.w ResourceMgrStack.overrideCurMap(a6),d1 ; did the resource manager change the CurMap?
beq.s @noOverrides
cmp.w CurMap,d1
bne.s @noOverrides ; yes, so leave it alone
move.w ResourceMgrStack.realCurMap(a6),CurMap ; Restore real CurMap
@noOverrides
TST.B RomMapInsert ; do I need to insert ROM Map <26jun85> BBM
BEQ.S @1 ; if zero don't add
MOVEQ #-1,D1 ; tell SwapRomMap to Delete ROM map
BSR SwapRomMap ; else go add ROM map
@1 CLR.B ResOneDeep ; always stop one deep calls <09jul85> BBM
CLR.W RomMapInsert ; always disable rom map next time <09jul85> BBM
MOVEM.L (SP)+, A1-A4/D1-D7 ; Restore registers
UNLK A6 ; Unlink A6
MOVE.L (SP)+, A0 ; Get return address in A0
ADD.L D0, SP ; Pop off parameter
MOVE.L A0, -(SP) ; Push return back
SUBA.L A0,A0 ; Zero A0 for Duvall's Edit? <19mar85> BBM
MOVE.W ResErr, D0 ; Get ResErr in D0
BEQ.S StdExitOut ; If equal, just return, otherwise
FPCallResErrProc ; FlashPort hint attachment point <bt>
MOVE.L ResErrProc, -(SP) ; push error proc
BNE.S StdExitOut ; if exists, return, else,
ADDQ #4, SP ; pop off error proc address
StdExitOut
RTS ; ...and return
;_______________________________________________________________________________
;
; Routine: HandleScan (utility)
; RestoreCache (utility
;
; Arguments: A1 (input.L) resource handle
; A2 (output.L) ptr to entry with correct handle (or nil)
; A3/A4/D3-D6 Normal setup into map where handle found
;
; Called By: (HandleScan): LoadResource, StdResEntry, RefHandle, AddResource
; (RestoreCache): GetIndResource
; Calls: GetTopMap, GetEntries, NextMap, SaveCache
;
; Function: Returns A2 pointing to entry with the correct handle, or nil if
; not found. Scans all maps.
;_______________________________________________________________________________
HandleScan
MOVE.L A1, D0 ; Check for zero handle
BEQ NotFound ; Can't have a zero handle, say not found
CMPA.L HSCHandle,A1 ; is this handle in the cache? <12mar85> BBM
BEQ.S RestoreCache ; if yes, go set regs and return
HndlScan ; alternate entry for RestoreCache <18jul85> BBM
BSR GetTopMap ; Point to the topmost map first
MOVE.L A0,-(SP) ; save A0 across HandleScan Call <01may85> BBM
@0 BSR GetEntries ; Point to the resource entries
BMI.S @3 ; If no entries, link to next map.
MOVE.L A3,A0 ; Keep A0 around as a pointer to types
ADDQ #TSize,A0 ; point at the next type entry <20may85> BBM
@2 ADDQ #2,A0 ; ... point to the next type <02may85> BBM
@1 ADDQ #RHndl,A2 ; adjust A2 for speed
CMPA.L (A2)+,A1 ; Is this the handle we want?
DBEQ D4,@1 ; If more of this type continue <01MAY85> BBM/LAK
BEQ.S @4 ; ... yes, exit with save. <01MAY85> BBM/LAK
MOVE.L (A0)+,D3 ; get the type into D3 <20may85> BBM
MOVE.W (A0)+,D4 ; get the total of this type into D4 <20may85> BBM
DBRA D5,@2 ; if this type exists loop back else <20may85> BBM
@3 BSR NextMap ; Try to link to next map
BEQ.S @0 ; If there is one, scan it, otherwise
MOVE.L (SP)+,A0 ; Restore A0 <01may85> BBM
BRA NotFound ; the handle wasn't found.
@4 SUBA #RESize,A2 ; Because A2 points to the next Rsrc entry <01may85> BBM
BSR.S SaveCache ; save this entry in the cache <12mar85> BBM
MOVE.L (SP)+,A0 ; Restore A0 <01may85> BBM
BRA Found ; Exit with condition code = EQ
RestoreCache
MOVEM.L HSCache,D3/A1-A4 ; restore the long regs from cache <12mar85> BBM
MOVEM.W HSCEntryCnt,D4-D6 ; restore the word regs from cache
ADD.L (A4),A2 ; Make A2 a pointer
ADD.L (A4),A3 ; Make A3 a pointer
CMPA.L RHndl(A2),A1 ; Is this really the handle in the map? <18jul85> BBM
BEQ Found ; good data means finish restoring cache <18jul85> BBM
CLR.L HSCHandle ; bad data in cache so invalidate it <18jul85> BBM
BRA.S HndlScan ; and go look for the real thing <18jul85> BBM
;_______________________________________________________________________________
;
; Routine: SaveCache (utility)
;
; Arguments: A1 (input.L) handle to resource
; A2 (input.L) pointer to resource entry
; A3 (input.L) pointer to resource name
; A4 (input.L) map handle
; D3 (input.L) resource type
; D4 (input.W) current entry count (this map)
; D5 (input.W) Total count (-1) of this type
; D6 (input.W) Map/file reference number
; D0 (output.W) Gets trashed
;
; Called By: (SaveCache): GetNamedResource, GetResource, HandleScan
; (SaveIndCache): GetIndResource
; Calls: NONE
;
; Function: Saves the current resource reg world into HSCache.
;_______________________________________________________________________________
SaveCache ;
MOVE.W MinusOne,GIRIndex ; invalidate GetIndResource cache <27jun85> BBM
SaveIndCache ; alternate entry for GetIndResource
MOVE.L (A4),D0 ; for speed get make D0 a pointer <06may85> BBM
SUB.L D0,A2 ; make A2 an offset as map may move
SUB.L D0,A3 ; make A3 an offset as map may move
MOVEM.L D3/A1-A4,HSCache ; save long regs into the cache <12mar85> BBM
MOVEM.W D4-D6,HSCEntryCnt ; save word regs into the cache <19mar85> BBM
ADD.L D0,A2 ; restore A2 as a pointer
ADD.L D0,A3 ; restore A3 as a pointer
RTS
;_______________________________________________________________________________
;
; Routine: NameResource (utility)
;
; Arguments: A2 (input.L) pointer to resource entry
; A0 (output.L) pointer to resource name
;
; Called By: CheckLoad, GetNamedResource, GetResInfo
; Calls: NONE
;
; Function: Returns A0 pointing to the resource name (or CC=MI if not found).
;_______________________________________________________________________________
NameResource
MOVE.W RNameOff(A2), D0 ; Get the name offset
BMI.S @9 ; if negative, return empty string.
MOVE.L (A4), A0 ; Dereference map handle
ADDA.W MNames(A0), A0 ; Jump to names block
ADD.W D0, A0 ; and offset to the name
BRA Found ; say found.
; if here, named resource failed.
@9 LEA NullStr, A0 ; Get address of an empty string,
BRA NotFound ; and say not found
;_______________________________________________________________________________
;
; Routine: NextEntry (utility)
;
; Arguments: A2 (input.L) pointer to resource entry
; D4 (input.W) Resource entry count
; D5 (input.W) Type entry count
; A2 (output.L) pointer to next ID resource entry
; D3 (output.L) resource type (if changed)
; D4 (output.W) number of item types (if changed)
;
; Called By: CountIResources, GetNamedResource, RmveName
; Calls: NONE
;
; Function: Set up A2 as pointer to the next ID resource entry. Returns
; CC=MI if not found, CC=EQ if found, and CC=GT if changed type.
;
;_______________________________________________________________________________
NextEntry
ADD.W #RESize, A2 ; Point to the next entry (sign extended)
SUBQ.W #1, D4 ; Decrement resource entry count
BPL Found ; Return if still more entries left
SUBQ.W #1, D5 ; Decrement type entry count
BMI NotFound ; If negative, hit end of map
MOVE.W TypeCount(A3), D0 ; Get number of types
SUB.W D5, D0 ; Get type index
ASL.W #TypeShift, D0 ; *8 gives offset to the type
MOVE.L TType+2(A3, D0), D3 ; Get the type in D3
MOVE.W TCount+2(A3, D0), D4 ; Get number of items in D4
MOVEQ #1, D0 ; Set CC=GT, for "typeChanged" flag
RTS ; and return
;_______________________________________________________________________________
;
; Routine: DoRomEntry (utility) <11apr85> BBM
;
; Arguments: A2 (input.L) pointer to resource entry
; A0 (output.L) handle to resource
; A1 (output.L) trashed
; D0 (output.L) trashed
;
; Called By: CheckLoad
; Calls: _HandleZone, SetPL
;
; Function: If the ROM resource has been released, "load it" back in. This
; code really just recovers what has always been there.
;_______________________________________________________________________________
DoRomEntry ; All new routine <20aug85> BBM
MOVE.L A1,-(SP) ; need to preserve this regs
MOVE.L RLocn(A2),D0 ; Get the offset to the ROM rsrc
AND.L Lo3Bytes,D0 ; Get rid of the Attrs
ADD.L RomBase,D0 ; D0 now points to the ROM Rsrc
MOVE.L D0,A1 ; Save off for later
MOVE.L RomMapHndl,A0 ; get a pointer to the start of ROZ Zone
_HandleZone ;
MOVE.L -4(A1),D0 ; Rel handle may have useful hi byte <C169>
AND.L Lo3Bytes,D0 ; Restrict to 24MB range off header <C169>
ADDA.L D0,A0 ; Add in offset to MP [-4(A1) is the RelHandle] <C169>
MOVE.L A0,RHndl(A2) ; map gets handle to the rsrc
TST.B ResLoad ; test if we want to stuff MP
BEQ.S @9 ; CC=EQ means just allocate handle
MOVE.L A1,(A0) ; stuff MP with pointer to rsrc in ROM <29aug85> BBM
BSR SetPL ; set the Purgable/Lock bits in MP
@9 MOVE.L (SP)+,A1 ; restore regs <29aug85> BBM
RTS ; and exit
********************************************************************************************
; Rolled in decompression stuff from DecompressorPatch.a 4/14/92 <sm6>stb
;
; To Do: Rewrite this stuff entirely, because it is showing its organic growth and the
; logic is less clear than it could be.
DecompressionLocals RECORD {a6Link},decr ;<17>
return DS.L 1
a6Link DS.L 1
ResHeaderBuffer DS.B ResourceTemplate.ResTemplateSize ; room for a ExtResRecord
DoDonnDecompress DS.B 1 ; boolean set if we're doing "old" decompression
extra DS.B 1 ; and a little padding
DefProcHandle DS.L 1 ; handy place to keep the current decompressor <sm6>stb
localSize EQU *
ENDR ;<17>
********************************************************************************************
*
* CheckLoad for decompression
*
* Description: If we are reading in a packed resource, then unpack the
* data as it is loaded.
*
* New
* Operation: If the resource is not compressed,
* or if the handle has data then Jump PlainOldCheckLoad.
* Remember ResLoad, Clear ResLoad.
* Call PlainOldCheckLoad to allocate the data handle.
* Restore ResLoad, if False then exit.
* Allocate the data handle (in the right heap), with a
* little extra slop (using resrvemem if locked).
* Unpack the data in place.
* Trim away the extra slop.
* Exit.
*
* Input: A2: pointer to resource list entry
* A4: resource map handle
*
* ResLoad: true if load, false if no load
*
* Output: A0: handle to resource
* A1: trashed
* A2-A7: unchanged
* D0-D2: trashed
* D3-D7: unchanged
*
* Called by: Resource Manager
*
* Register usage: D2 - offset of raw data in this resource.
* D3 - handle's zone.
* D4 - resource attributes.
* D5 - unpacked size.
* D6 - offset to this resource's data, then the var table handle.
* D7 - original resLoad state.
* A2/A3/A4 - as the Resource Manager needs them.
* A5 - the resource handle.
* A6 - LINKed locals <17>
*
********************************************************************************************
CheckLoad ; moved the vectored jump up from the original checkload
MOVE.L jCheckLoad,A0 ; get the vector from the OSJumptable
JMP (A0) ; and go to the routine
vCheckLoad ; Def to build dispatch entry
; Force all system resources into the system heap by setting the ResSysHeap bit. <SM37> PN.start <SM54>
subq #2,sp
move.l a4,-(sp)
_IsThisASystemResourceMap ; Is this the system map or system override?
tst.b (sp)+
bne.s @system_rsrc ; if so, branch
move.l (a4),a0 ; a0 <- ptr to map
btst.b #overrideNextMapBit,MAttr(a0) ; should all entries in map go in system heap?
beq.s @GoOnCheckLoad ; if not, branch
@system_rsrc
bset #ResSysHeap,RAttr(a2) ; get into the system heap (and stay there!)
bne.s @GoOnCheckLoad ; branch if was already set
bset #ResSysRef,RAttr(a2) ; mark that shouldn't be permanent
@GoOnCheckLoad ; <SM37> PN.end
; This snippet checks to see if the resource reference entry already contains a handle
; or not. If it does, DeanBit is cleared. If there is no handle (ie, the resource will
; be loaded this time) set DeanBit. This allows people to determine whether they loaded
; a resource, or if someone else did.
;
tst.l RHndl(a2) ; See if a master pointer has already been allocated
bz.s @setDeanBit
bclr #kDeanBit,kBrianBits ; A master pointer has already been allocated
bra.s @goLoadTheResource
@setDeanBit
bset #kDeanBit,kBrianBits ; WeÕll be loading the resource right now
@goLoadTheResource
;is it compressed? Flag that it isn't in case it gets modified and written.
BTst.B #resExtended,RAttr(A2)
BNZ.S TestResHandle
BRA PlainOldCheckLoad ;no, then just do the old checkload stuff.
; if there is already data in the handle, then just call old checkload.
TestResHandle
Move.L RHndl(A2),D0 ;is the handle loaded already?
BZ.S DeCompressor ;no, then we will try to load it.
Move.L D0,A0
Move.L (A0),D0 ;check if the master pointer is nil
BNZ PlainOldCheckLoad ; it has data, so no need to load, or decompress.
DeCompressor
WITH DecompressionLocals, ExtResRecord
LINK A6, #localSize ; save space for a read buffer and stuff <17>
MoveM.L D3-D7/A4-A5,-(SP) ;save some regs.
; Remember ResLoad, Set ResLoad False.
Move.B ResLoad,D7 ;remember ResLoad. ?Should I use _GetResLoad and SetResLoad?
Clr.B ResLoad ;don't load the data in old checkLoad.
; The resource is compressed but not loaded yet. Make sure the handle gets created.
BSr PlainOldCheckLoad ;create the handle for the data.
Move.B D7,ResLoad ;restore ResLoad.
BZ.S @IfZExit2
Move.L A0,A5 ;remember the handle.
Move.L A0,D0 ;is the handle allocated now?
@IfZExit2
BZ Exit2 ; no, then we can't do any more.
Move.B RAttr(A2),D4 ;remember the attribute flags.
; read in the resource data header. This gives us decompressed size.
MoveQ #ExtResRecord.ResHeaderSize,D0 ;amount we wish to read.
Move.L RLocn(A2),D6 ;get the relative data location.
And.L Lo3Bytes,D6 ;mask off the resource attributes.
Move.L D6,D1 ;this is where we want to start reading from.
Bsr ReadResBuffer ;read in the resource data.
; do a robustness check to see if the handle really seems to be compacted.
Cmp.L #RobustnessData,ExtResRecord.ResHeader.signature(A0) ;is it really an extended resource?
BEQ.S @TestHeaderVersion
MoveM.L (SP)+,D3-D7/A4-A5 ;restore the regs, but don't pop them yet.
UNLK A6 ; <17>
Bra PlainOldCheckLoad ;read in the data, now that resLoad is restored.
@TestHeaderVersion
Move.W #CantDecompress,D2 ;assume bad extended resource.
lea DoDonnDecompress(a6), A1 ;get flag location <17>
sf (a1) ;set the flag, assuming that's what we want
Cmp.B #CurHeaderVersion,ResHeader.headerVersion(A0) ;is this DonnBits?
BEQ @headerVersionOK ;yep, okay
st (a1) ;nope, clear the flag
cmp.b #greggyHeaderVersion, ResHeader.headerVersion(a0) ;is this GreggyBits?
bne ErrorExit ;no, bail
@headerVersionOK ;move along
; Make the pointers into the Map relative offsets, so we can rebuild them after a heap shuffle.
Sub.L (A4),A2 ; pointer to map entry becomes an offset.
Sub.L (A4),A3 ; some callers have a block pointer here.
; assume it's just a non-compressed extended resource, compute data size and offset.
MoveQ #ExtendedResource.extendedData,D2 ;offset to start of data for a normal extended attribute resource
Move.L ResSize(A0),D5 ;get the size, including header.
Sub.L D2,D5 ;actual amount of data to read.
BTst #resCompressed,ResHeader.extendedAttributes(A0)
BZ HaveSizeAndOffset ;not compressed, then we have the size and offset.
; check which def proc to unpack it with. We use a simple robust caching scheme to avoid _GetResource calls.
Move.W #badExtResource,D2 ;assume an error if it was the wrong version!
btst #0, DoDonnDecompress(a6) ; are we doing DonnBits <17>
bne.s @notDonn ; no, get ID from revised general header format
Move.W ResHeader.decompressID(A0),D5 ;get the Donn ID this resource needs
bra.s @gotID ; ...and keep going
@notDonn
move.w ResHeader.defprocID(a0), d5 ; get defProc
@gotID
; here, we look for decompression defprocs in all files below the current one
Move.W #CantDecompress,D2 ;assume bad extended resource
move.l a4,a1 ;get a handle to the first file to look in
@tryMap
move.l a1,d0 ;are we done?
bz ErrorExit ;yes, we looked and didnÕt find anything
move.l (a1),a0 ;get map pointer
btst #decompressionPasswordBit,mInMemoryAttr(a0)
bz.s @nextFile
move.w CurMap,-(sp)
Move.B ResOneDeep,-(SP) ;preserve the depth setting
move.w ROMMapInsert,-(sp) ;save the value of ROMMapInsert <15>
move.l ResErrProc,-(sp) ;remember the ResErrProc <15>
move.w mRefNum(a0),CurMap ;get resource from this file
clr.w ROMMapInsert ;donÕt even think about ROM map <15>
clr.l ResErrProc ;and donÕt call the app. <15>
SubQ #4,SP
Move.L #DeCompressDefType,-(SP) ;'dcmp'
Move.W D5,-(SP)
_Get1Resource ;get the decompress def. proc.
Move.L (SP)+,A0
move.l (sp)+,ResErrProc ;back to normal <15>
move.w (sp)+,ROMMapInsert ;restore ROM guy too <15>
Move.B (SP)+,ResOneDeep ;restore depth
move.w (sp)+,CurMap
Move.L A0,D0
bne @gotDecompressor ;if we got the decompressor, then use it
move.w ResErr,d0 ;if there was no dcmp, go on
beq.s @nextFile
cmp.w #resNotFound,d0 ;if there was an error, quit with the error
bne ErrorExit
@nextFile
move.l (a1),a1 ;get map pointer
move.l mNext(a1),a1 ;go on to the next file in the chain
bra.s @tryMap
@gotDecompressor
; remember the defproc handle. (mostly 'cause we don't have any registers left...)
Lea DefProcHandle(A6),A1 ;stuff away the defproc <sm6>stb
Move.L A0,(A1) ;stuff away the defproc handle into DefProc
; it is a compressed resource, make sure we can handle it, and get its size from the header.
@HaveDefProc
Lea ResHeaderBuffer(a6),A0 ;point into our frame. <17>
btst #0, DoDonnDecompress(a6) ; are we DonnBits? <17>
bne.s @cTableDontCare ; no, then cTables are not used
Tst.W ResHeader.cTableID(A0) ;is the built in table to be used?
Bne ErrorExit ; for now, we don't load decompression tables.
@cTableDontCare
MoveQ #ExtendedResource.compressedData,D2 ;offset to start reading from.
Move.L ResHeader.actualSize(A0),D5 ;get the unpacked size.
MoveQ #0,D0 ;overRun indicates the amount of extra room we need to
btst #0, DoDonnDecompress(a6) ; are we DonnBits? <17>
bne.s @getWordSizedSlop ; no, then slop size is a word
Move.B ResHeader.overRun(A0),D0 ; avoid the input and output pointers crossing during decompression.
bra.s @addOverRun ;
@getWordSizedSlop ;
move.w ResHeader.decompressSlop(a0), d0 ; get word sized slop size
@addOverRun ;
Add.L D0,D5 ; block size must include overRun.
HaveSizeAndOffset
; Remember the current heap zone, and switch to the zone of the compressed handle.
MOVE.L TheZone,A0 ;get the current heap zone. <SM55>
Move.L A0,D3 ;remember current heap.
Cmp.L RomMapHndl,A4 ; is it in the ROM map?
Bne.S @NotROMMap ; then go recover information
; Break 'RomMapHndl Zone'
Move.L A4,A0
_HandleZone ; use the zone that the ROM Map comes from.
Bra.S @SetRightZone
@NotROMMap
BTst.L #ResSysHeap,D4 ; Is it in the system heap?
BZ.S @SetRightZone ; No, use same heap
Move.L SysZone,A0 ; otherwise set the system zone for now
@SetRightZone
MOVE.L A0,TheZone ; and use it, for now. <SM55>
; If the handle was locked, then we reserve low memory for the bigger unpacked handle.
BTst.L #resLocked,D4 ;should the handle be locked?
BZ.S @DoneReserve
Move.L D5,D0 ;amount of space we will need.
_ResrvMem ;reserve room in locked space for the handle.
@DoneReserve
; Reallocate the handle.
Move.L A5,A0
Move.L D5,D7 ;remember new size.
Move.L D5,D0
_ReallocHandle ;set up the unpacked handle's size.
Move.W D0,D1
BZ.S @GotHandle ;did it get allocated without an error?
; Break 'Error from _ReallocHandle'
Move.W D1,ResErr
Suba.l A5, A5 ; return NIL since we donÕt have enough memory <10>
Bra ExitCLPastHSetState ;exit if an error happened. Skip HSetState <10>
@GotHandle
; compute the amount of data to be read.
Move.L ResHeaderBuffer+ExtResRecord.ResSize(a6),D0 ;amount of raw resource data. <17>
Sub.L D2,D0 ;subtract the (offset of data from the header) from size.
; compute where the data should go.
Move.L (A5),A0 ;point to the handle base.
Sub.L D0,D7 ;subtract the data size from the block size.
Add.L D7,A0 ;point to the last place where the data will fit.
; Read the data into the end part of the handle.
Move.L D6,D1 ;where the size and resource header start.
AddQ.L #ResHeader-ResSize,D1 ; point past the size.
Add.L D2,D1 ; we want to read from beyond the header.
Bsr ReadResData ;read the data into the block.
BZ.S @NoReadError ; do an error check.
Move.W D0,ResErr ;set up res error from I/O error.
; Break 'error during read'
Bra ExitCheckLoad
@NoReadError
; if it is not a compressed resource, then we are done.
BTst #resCompressed,ResHeaderBuffer+ExtResRecord.ResHeader.extendedAttributes(a6) ;compressed resource? <17>
Beq ExitCheckLoad
; create the room for the variable table. It is a percentage of the unpacked size.
btst #0, DoDonnDecompress(a6); DonnBits? <17>
bne.s dontCallDonn ; no, call defProc via new and improved interface
MoveQ #0,D0 ;get the ratio of var table to unpacked size.
Move.B ResHeaderBuffer+ResHeader.varTableRatio(a6),D0 ;<17>
Beq.S @HaveVarSize
AddQ.L #1,D0 ;round up.
Move.L D5,D1 ;unpacked size - is it a long?
Swap D1
Mulu D0,D1 ;in case it is, scale the high word too.
Swap D1
Clr.W D1 ;clear out the overflow.
Mulu D5,D0
Add.L D1,D0
Lsr.L #8,D0
@HaveVarSize
AddQ.L #VarTableRec.VarRecSize,D0 ;add enough room for at least one record.
Move.L D0,D1 ;save var table size.
_NewHandle ;get the table. Used to be a _NewPtr, but that moves the Realloc'ed handle
Bne ErrorExitBlowoffHandle ;blow off the handle and return a nil handle
_HLock ;donÕt let it move
Move.L A0,D6 ;save var table ptr.
; Finally we are ready to decompress the data in the clone into our larger handle.
Move.L (A5),A0
Add.L D7,A0 ;point to the data.
Move.L A0,-(SP) ;source ptr
Move.L (A5),-(SP) ;destination ptr.
Move.L D6,A0 ;var table handle
Move.L (A0),-(SP) ;pass var table ptr.
Move.L D1,-(SP) ;pass var table size
Move.L DefProcHandle(A6),A0 ;get the defproc handle. <sm6>stb
Move.L (A0),A0
FPCallDonnDecompress ; FlashPort hint attachment point <bt>
Jsr (A0) ;call the defproc. Note: the defProc can't move memory!
; dispose of the var table handle.
Move.L D6,A0
_DisposHandle ;dispose of the var table handle.
bra.s cutBackCLHandle
dontCallDonn
pea ResHeaderBuffer+ExtResRecord.ResHeader(a6) ; header ptr <17>
Move.L DefProcHandle(A6),A0 ; get the defproc handle. <sm6>stb
move.l (a0), a0 ;
adda.w 0(a0), a0 ; move to offset of "Prepare" routine
FPCallGreggyPrepare ; FlashPort hint attachment point <bt>
jsr (a0) ; call defProc "Prepare" routine
move.l (a5), a0 ; get start of block
add.l d7, a0 ; point to the start of the data
move.l a0, -(sp) ; source
move.l (a5), -(sp) ; destination
pea ResHeaderBuffer+ExtResRecord.ResHeader(a6) ; header ptr <17>
Move.L DefProcHandle(A6),A0 ; get the defproc handle. <sm6>stb
move.l (a0), a0 ;
adda.w 2(a0), a0 ; move to offset of "Decompress" routine
FPCallGreggyDecomp ; FlashPort hint attachment point <bt>
jsr (a0) ; call defProc "Decompress" routine
pea ResHeaderBuffer+ExtResRecord.ResHeader(a6) ; header ptr <17>
move.l DefProcHandle(A6), a0 ; <sm6>stb
move.l (a0), a0 ;
adda.w 4(a0), a0 ; move to offset of "Done" routine
FPCallGreggyDone ; FlashPort hint attachment point <bt>
jsr (a0) ; call defProc "Done" routine
cutBackCLHandle ; cut back the handle to get rid of the slop.
Move.L ResHeaderBuffer+ExtResRecord.ResHeader.actualSize(a6),D0 ;final size. <17>
Move.L A5,A0
_SetHandleSize ;shrink the handle to it's correct size.
; restore the handle state, and restore the zone.
ExitCheckLoad
Move.L A5,A0 ; Black magic code Donn stole from the resource manager.
LSL.B #3,D4 ; Shift over lock to bit 7 in D4, purge bit to X .
RoL.B #1,D4 ; Rotate Lock to bit 0
RoXR.B #2,D4 ; Rotate L & P to bits 7 & 6
Or.B #$20,D4 ; Set Resource Flag bit of D4.B
And.B #$E0,D4 ; lear all but LPR bits of D4.B
_HGetState ; D0 <- LPR bits Is this needed?
AND.B #$1F,D0 ; Clear LPR bits only
OR.B D4,D0 ; Set up new LPR bits
_HSetState ; MemMgr bits <- D0
ExitCLPastHSetState ; <10>
Move.L D3,TheZone ; restore the zone. <SM55>
; Make the offsets into the Map pointers again, so they will be valid after a heap shuffle.
Add.L (A4),A2 ; pointer to map entry.
Add.L (A4),A3 ; some callers have a block pointer here.
Move.L A5,A0 ;return the handle.
MACHINE MC68040 ; (should we cache flush on all cpus?) <18>
; (if we do then make sure to save D1 since trashed by '030 flush routine) <18>
cmp.b #cpu68040,CPUFlag ; check if we are on a 68040 <18>
bne.s flushNot040 ; If we are then <18>
FPCallCacheFlush ; FlashPort hint attachment point <bt>
jsr ([jCacheFlush]) ; flush data cache for consistency! <18>
; we should really do this cache line by line for speed... maybe later <18>
flushNot040
MACHINE MC68000
Exit2
MoveM.L (SP)+,D3-D7/A4-A5
UNLK A6 ; <17>
Rts
; We got an error cloning the handle, or creating the unpacked handle. Toss the clone (even if Nil).
ErrorExitBlowoffHandle
Move.W #MemFullErr,D2 ;not enough to allocate var table
Move.L A5,A0
_DisposeHandle
ErrorExit
;*** Break 'DeCompressor - not enough RAM - set up the error code for the Resource Man'
Move.W D2,ResErr ;set up the error code for the Resource Man.
Sub.L A0,A0 ;return with nil.
Bra.S Exit2
ENDWITH
******************** end of <sm6>stb rollin ************************************
;_______________________________________________________________________________
;
; Routine: PlainOldCheckLoad (utility) renamed <sm6>stb
;
; Arguments: A2 (input.L) pointer to resource entry
; A0 (output.L) handle to resource
; A1 (output.L) trashed
; D0 (output.L) trashed
; D1 (output.L) trashed
; D2 (output.L) trashed
;
; Called By: Preload, Preload2, UpdateResFile, GetIndResource, GetResource,
; GetNamedResource, LoadResource
; Calls: RdRsrc, SetPL, _NewHandle, _NewEmptyHandle, SizeRsrc,
; _ResrvMem, _ReallocHandle
;
; Function: Initializes the handle, first-time if needed, and loads in if
; ResLoad is true.
;
; In the case of a reference being loaded, branch to CheckRefLoad.
;
; In the non-reference case, A2 & A3 are made offsets and restored
; after the call -- therefore they are preserved and correct.
;_______________________________________________________________________________
;
; LoadIt, PrepHandle, GotHandle, LoadRes, ErrLoad, NoResLoad, EndLoad, EndLoad2
; are really local labels, but the code is so twisted it is hard to tell that
; these are all part of CheckLoad.
;_______________________________________________________________________________
PlainOldCheckLoad
MOVE.B RAttr(A2), D1 ; Get resource info from RAttr
CMP.L RomMapHndl,A4 ; is it in the ROM map? <10apr85> BBM
BEQ.S DoRomEntry ; then go recover information
MOVE.L theZone, -(SP) ; Save old zone
BTST #ResSysHeap, D1 ; Is it in the system heap?
BEQ.S @1 ; No, use same heap
MOVE.L SysZone, theZone ; otherwise set the system zone for now
@1 MOVE.L RHndl(A2), A0 ; Get the handle in A0, if any.
SUB.L (A4), A3 ; Make A3 an offset
TST.B ResLoad ; should the resource be loaded, if nec.?
BEQ.S NoResLoad ; no, just create empty handle, if needed.
MOVE.L A0, D0 ; Is there a handle yet?
BNE.S GotHandle ; If so, go on
BSR.S PrepHandle ; Set up size, reserve mem if necessary.
_NewHandle ; create a handle of the right size
BEQ.S LoadRes ; if successful, load it, else
BRA.S ErrLoad ; exit with error.
PrepHandle
BSR SizeRsrc ; get the size of the resource in D0.
MOVE.L D0, D2 ; Save D0=length for routine RdRsrc. <09mar85> BBM
SUB.L (A4), A2 ; Make A2 an offset.
BTST #ResLocked, D1 ; Is this going to be a locked handle?
BEQ.S @2 ; No, allocate as usual, floating in heap.
_ResrvMem ; reserve low memory for the locked handle
; (Save/restore A0 across call! .WORD $A040)
@2 MOVE.L D2, D0 ; restore D0 for memory mgr call <09mar85> BBM
RTS ; and return.
GotHandle
TST.L (A0) ; is resource already in?
BNE.S EndLoad ; if so, just return, otherwise
BSR.S PrepHandle ; Set up size, reserve mem if necessary,
_ReallocHandle ; and reallocate it to correct size.
BMI.S ErrLoad ; if unsuccessful, don't try to load.
; RELOAD the resource, or possibly LOAD it for the first time.
LoadRes
ADD.L (A4), A2 ; Restore A2
MOVE.L A0, RHndl(A2) ; Set RHndl(A2) for RdRsrc
BSR RdRsrc ; read the resource.
BSR.S SetPL ; set purgable, lock bits in MP
MOVE.W ResErr, D0 ; was there a read error? (D0 for errLoad)
BEQ.S EndLoad ; If not, everything is ok. A2 correct.
SUB.L (A4), A2 ; Make A2 an offset again for ErrLoad
ErrLoad
MOVE.W D0, ResErr ; Report error
SUB.L A0, A0 ; Zero handle
BRA.S EndLoadA2 ; and restore A2.
; ResLoad is FALSE. If there is already a handle, return,
; ... else allocate new.
NoResLoad
MOVE.L A0, D0 ; Otherwise test the handle
BNE.S EndLoad ; If there is one, just return. A2 correct.
SUB.L (A4), A2 ; Make A2 an offset for NewHandle call.
_NewEmptyHandle ; Create a handle for load next time <07mar85> BBM
EndLoadA2
ADD.L (A4), A2 ; Finally restore A2.
EndLoad
MOVE.L A0, D0 ; Is there a good handle?
BEQ.S @1 ; If not, don't write in map
MOVE.L A0, RHndl(A2) ; otherwise copy it in Hndl location
@1 ADD.L (A4), A3 ; Restore A3 for caller
MOVE.L (SP)+, theZone ; Restore the zone
RTS ; ...and return
;_______________________________________________________________________________
;
; Routine: SetPL (utility)
;
; Arguments: A0 (input.L) handle to resource in memory
; D1 (input.B) Resource Attribute Byte <C396>
; D1 (output.B) purgeable, lock bits
;
; Called By: CheckLoad, DoROMEntry <C169>
; Calls: NONE
;
; Function: Set purgeable, lock, and resource bits in master pointer. D0 is
; trashed, high 3 bits of Òmaster pointerÓ are set. <C169>
;_______________________________________________________________________________
SetPL
LSL.B #3, D1 ; Shift over lock to bit 7 in D1,
; purge bit to X . <C396>
ROL.B #1, D1 ; Rotate Lock to bit 0 <C396>
ROXR.B #2, D1 ; Rotate L & P to bits 7 & 6
OR.B #$20, D1 ; Set Resource Flag bit of D1.B <C396>
AND.B #$E0, D1 ; lear all but LPR bits of D1.B <C396>
_HGetState ; D0 <- LPR bits <C169>
AND.B #$1F,D0 ; Clear LPR bits only <C169>
OR.B D1,D0 ; Set up new LPR bits <C169>
_HSetState ; MemMgr bits <- D0 <C169>
RTS ; finally return.
;_______________________________________________________________________________
;
; Routine: SizeRsrcDecomp (utility) <sm21>kc
;
; Arguments: A2 (input.L) pointer to resource entry
; D0 (output.L) size of resource
;
; Called By: SizeResource <sm21>kc
; Calls: RREntry, ReadRsrcLength <sm21>kc
;
; Function: Returns the size of the resource in D0 by reading the size word
; from the resource file. If memory manager error, sets ResErr.
;
; If the resource is marked in the map as compressed, <sm6>stb
; then
; check the extended header.
; If it has a valid header
; then
; read the actual length from the header.
;_______________________________________________________________________________
SizeRsrcDecomp ; <sm21>kc
; start of <sm6>stb rollin from DecompressorPatch.a
WITH DecompressionLocals, ExtResRecord
MOVEM.L D1-D2/A0-A1, -(SP) ; Save regs
BSR RREntry ; Smashes changed, added bits.
BTst.B #resExtended,RAttr(A2) ; is this an extended resource?
Bz.S ReadRsrcLength ; nope, treat it normally. <sm21>kc
@CompressedRead
; make sure this is really a compressed resource by reading in the header data, and testing for our signature.
LINK A6, #localSize ; allow for reentrancy
MoveM.L D1/A0,-(SP) ; save some scratch regs
MoveQ #ExtResRecord.ResHeaderSize,D0 ; amount we wish to read.
Move.L RLocn(A2),D1 ; get the relative data location.
And.L Lo3Bytes,D1 ; mask off the resource attributes.
Bsr ReadResBuffer ; read in the resource data.
; do a robustness check to see if the handle really seems to be compacted.
Cmp.L #RobustnessData,ResHeader.signature(A0) ;is it really an extended resource?
MoveM.L (SP)+,D1/A0
UNLK A6
BNE.S ReadRsrcLength ;didn't match, then just do old sizersrc. <sm21>kc
; adjust the position offset to point within the header to the actual length.
MoveQ #ExtResRecord.ResHeader.actualSize,D0 ;get delta to the new position.
Add.L D0,d2 ;bump the offset by our header and a long. <SM19>
bra.s ReadRsrcLength ; <sm21>kc
; end of <sm6>stb rollin
ENDWITH
;_______________________________________________________________________________
;
; Routine: SizeRsrc (utility)
;
; Arguments: A2 (input.L) pointer to resource entry
; D0 (output.L) size of resource
;
; Called By: CheckLoad, RdRsrc, UpdateResFile, SizeResource
; Calls: RREntry, RdData
;
; Function: Returns the size of the resource in D0 by reading the size word
; from the resource file. If memory manager error, sets ResErr.
;_______________________________________________________________________________
SizeRsrc
MOVEM.L D1-D2/A0-A1, -(SP) ; Save regs
BSR.S RREntry ; Smashes changed, added bits.
ReadRsrcLength ; <sm21>kc
SUBQ.L #LenWdLen, SP ; Save space for length longword
MOVE.L SP, D1 ; Point buffer to stack
MOVEQ #LenWdLen, D0 ; Read 4 bytes
BSR RdData ; and read the bytes in! <<RdData2 06may85>> <30may85> BBM
MOVE.L (SP)+, D0 ; Get length in D0
MOVEM.L (SP)+, D1-D2/A0-A1 ; Restore regs
RTS ; ...and return.
;_______________________________________________________________________________
;
; Routine: ReadResBuffer, ReadResData (utility)
;
; Entry: D0 - number of bytes to read.
; D1 - relative data location within the resource data block.
; A0 - pointer to the data buffer [ReadResData only].
; A4 - resource map handle.
; A6 - LINKed locals for decompression
; Exit: D0 - result code.
; A0 - pointer to the header data.
; all other registers saved.
;
; Called By: SizeRsrc: ReadResBuffer
; ??? : ReadResData
; Calls: _Read
;
; Function: Read resource data for D0 bytes into the buffer (A0).
; ReadResBuffer uses a buffer on the stack in the A6 link.
;
; Rolled in from DecompressorPatch.a <sm6>stb
;_______________________________________________________________________________
With ExtendedResource, ExtResRecord, VarTableRec, ResourceTemplate, DecompressionLocals
ReadResBuffer
Lea ResHeaderBuffer(a6),A0 ; <17>
ReadResData
MoveM.L D1-D2/A0-A3,-(SP)
MoveQ #ioQElSize,D2 ;create a param block on the stack.
Sub.L D2,SP
Move.L A0,ioBuffer(SP) ;place to put the data.
Move.L SP,A0 ;for the read call.
Move.L (A4),A1 ;deref the map handle.
Move.W MRefNum(A1),ioRefNum(A0) ;refNum from the resource map.
Move.L D0,ioReqCount(A0) ;number of bytes to read.
Move.W #1,ioPosMode(A0) ;read from start of file.
Add.L ResDataOffset(A1),D1 ;add the base data offset in the file.
Move.L D1,ioPosOffset(A0) ;computed offset from file start.
_Read ;read the resource data.
Add.L D2,SP ;strip the ioParam block.
MoveM.L (SP)+,D1-D2/A0-A3
Rts
;_______________________________________________________________________________
;
; Routine: RdRsrc, RRExit (utility)
;
; Arguments: A2 (input.L) pointer to resource entry
; D2 (input.L) Size of Resource
;
; Called By: (RdRsrc): CheckLoad
; (RRExit): WrRsrc
; Calls: RREntry, SizeRsrc, RdData
;
; Function: Loads the resource into the handle specified in RHndl(A2). The
; handle MUST be the correct size.
;_______________________________________________________________________________
RdRsrc
MOVEM.L D0-D2/A0-A1, -(SP) ; Save regs
MOVE.L D2,D0 ; get rsrc size into D0 for RdData <09mar85> BBM
BSR.S RREntry ; Set up the regs for read/write
ADDQ.L #LenWdLen, D2 ; Skip over the length longword
MOVE.L (A1), D1 ; Set buffer address
BSR RdData ; and read the bytes in! <<RdData2 06may85>> <30may85> BBM <SM25> CSS
RRExit
MOVEM.L (SP)+, D0-D2/A0-A1 ; Restore registers ...
RTS ; ...and return!
;_______________________________________________________________________________
;
; Routine: RREntry (utility)
;
; Arguments: A2 (input.L) pointer to resource entry
; A4 (input.L) handle to resource map
; A0 (output.L) pointer to resource map
; A1 (output.L) handle to resource
; D2 (output.L) location of entry in file
;
; Called By: SizeRsrc, RdRsrc, WrRsrc
; Calls: NONE
;
; Function: Given a resource entry pointer, set up registers for read/write
;_______________________________________________________________________________
RREntry
ANDI.B #RCBMask, RAttr(A2) ; Clear resChanged on read/write.
RREntry6 ; <9> rb
MOVE.L (A4), A0 ; Dereference map handle again
MOVE.L RLocn(A2), D2 ; Get location long word
AND.L Lo3Bytes,D2 ; Clear high 8 bits.
ADD.L ResDataOffset(A0), D2 ; Add in the data offset
MOVE.L RHndl(A2), A1 ; Get the handle in A1
RTS ; ...and return.
;_______________________________________________________________________________
;
; Routine: WrRsrc (utility)
;
; Arguments: D2
; A2 (input.L) pointer to resource entry
; A4 (input.L) handle to map
;
; Called By: UpdateResFile, WrRsrc
; Calls: RREntry, _GetHandleSize, WrData, RRExit
;
; Function: Writes resource specified in RHndl(A2) out to the resource file
;_______________________________________________________________________________
WrRsrc
MOVEM.L D0-D2/A0-A1, -(SP) ; Save regs
BSR.S RREntry ; Set up the regs for read/write
MOVE.L A1, A0
_GetHandleSize ; Get the size to write out
TST.L D0 ; for sizes bigger than 32k <15mar85> BBM
BPL.S @1 ; if good size, go on, else
MOVEQ #0, D0 ; force zero length (purged!)
@1 MOVE.L D0, -(SP) ; Push size on the stack
MOVE.L SP, D1 ; Write the size out (buffer addr.=stack)
MOVEQ #LenWdLen, D0 ; Write 4 bytes
BSR.S WrData ; Write out length word data (was WrData2) <30may85> BBM
ADDQ.L #LenWdLen, D2 ; Skip over length longword
MOVE.L (A1), D1 ; Read bytes from handle
MOVE.L (SP)+, D0 ; Restore the size to D0 for write
BSR.S WrData ; ...and do it! (was WrData2) <30may85> BBM
BRA.S RRExit ; Restore regs and exit.
;_______________________________________________________________________________
;
; Routine: SetFileIO (utility)
;
; Arguments: A6 (input.L) LINK'ed for file I/O
; D0 (input.L) number of bytes to read/write
; D1 (input.L) IO buffer address
; D2 (input.L) IO position offset
; D6 (input.W) IORefnum
; A0 (output.L) pointer to IO stack frame
;
; Called By: RdData, WrData, SetRFEOF, CheckGrow, NewMap, CreateResFile,
; CloseResFile
; Calls: NONE
;
; Function: Points A0 to the I/O Stack Frame, and fills out the Param Block
; from imput registers.
;_______________________________________________________________________________
SetFileIO
WITH ResourceMgrStack ; <sm6>stb
LEA ioBlock+IORefNum(A6), A0 ; Point to frame at IORefNum <sm6>stb
MOVE.W D6, (A0)+ ; Set IORefnum
ADDQ #6, A0 ; Skip over unused stuff
MOVE.L D1, (A0)+ ; Set IOBuffer
MOVE.L D0, (A0)+ ; Set IOByteCount
ADDQ #4, A0 ; Skip actual byte count
MOVE.W #1, (A0)+ ; Set IOPosMode=absolute (fsFromStart)
MOVE.L D2, (A0)+ ; and finally set IOPosOffset.
LEA ioBlock(A6), A0 ; Reset A0 for stack frame
RTS ; and return.
ENDWITH ; <sm6>stb
;_______________________________________________________________________________
;
; Routine: SetFileIODirID (utility)
;
; Arguments: A6 (input.L) LINK'ed for file I/O
; D0 (input.L) number of bytes to read/write
; D1 (input.L) IO buffer address
; D6 (input.W) IORefnum
; A0 (output.L) pointer to IO stack frame
;
; Called By: RdData, WrData, SetRFEOF, CheckGrow, NewMap, CreateResFile,
; CloseResFile
; Calls: NONE
;
; Function: Just like SetFileIO except don't trash ioDirID w/ a posOffsetÉ
;_______________________________________________________________________________
SetFileIODirID
WITH ResourceMgrStack ; <sm6>stb
LEA ioBlock+IORefNum(A6), A0 ; Point to frame at IORefNum <sm6>stb
MOVE.W D6, (A0)+ ; Set IORefnum
ADDQ #6, A0 ; Skip over unused stuff
MOVE.L D1, (A0)+ ; Set IOBuffer
MOVE.L D0, (A0)+ ; Set IOByteCount
ADDQ #4, A0 ; Skip actual byte count
MOVE.W #1, (A0)+ ; Set IOPosMode=absolute (fsFromStart)
LEA ioBlock(A6), A0 ; Reset A0 for stack frame
RTS ; and return.
ENDWITH ; <sm6>stb
;_______________________________________________________________________________
;
; Routine: RdData (utility)
;
; Arguments: A6 (input.L) LINK'ed for file I/O
; D0 (input.L) number of bytes to read/write
; D1 (input.L) IO buffer address
; D2 (input.L) IO position offset
; D6 (input.W) IORefnum
; A0 (output.L) pointer to IO stack frame ??
;
; Called By: SizeRsrc, RdRsrc, NewMap
; Calls: SetFileIO, _Read, IOExit
;
; Function: Read data according to input registers. Note A2/A3 made offsets
; across this call and resored in IOExit
;_______________________________________________________________________________
RdData
BSR.S SaveRegs ; Saves A1/A0/D1/D0 and makes A2/A3 offsets <22aug85> BBM
; so their handles can move across _Read <sm6>stb
BSR.S SetFileIO ; Set up a file frame
_Read ; Read the bytes
BRA.S IOExit ; sets reserr and restores all
;_______________________________________________________________________________
;
; Routine: WrData, WrDataSt (utilities)
;
; Arguments: A2,A3 (not used) May get blitzed!! (see Warning below)
; A4 (not used) handle to Map
; A6 (input.L) LINK'ed for file I/O
; D0 (input.L) number of bytes to read/write
; D1 (input.L) IO buffer address
; D2 (input.L) IO position offset
; D6 (input.W) IORefnum
; A0 (output.L) pointer to IO stack frame
;
; Called By: (WrData): WrRsrc, UpdateResFile, UpdateResFile, CreateResFile
; (WrDataSt): CreateResFile
; (IOExit): WrData, RdData, SetRFEOF
; (RestRegs): SetRFEOF
; Calls: SetFileIO, _Write, WrData
;
; Function: Write Data to file according to input registers. This write
; may move map around in the heap, so A2/A3 pointers are always
; saved across this call (by making them offsets).
;
; NOTE: IOExit and RestRegs are the standard returns for RdData, WrData,
; and SetRFEOF. Also note that IOExit stuffs result in ResErr.
;_______________________________________________________________________________
WrDataSt
MOVEQ #0, D2 ; PosOffset=0
WrData
BSR.S SaveRegs ; Saves A1/A0/D1/D0 and makes A2/A3 offsets <22aug85> BBM
BSR.S SetFileIO ; Set up a file frame
_Write ; Write the bytes
IOExit
MOVE.W D0, ResErr ; Save file I/O result in ResErr
RestRegs
ADDA.L (A4),A3 ; restore A3 to a pointer <30may85> BBM
ADDA.L (A4),A2 ; restore A2 to a pointer <30may85> BBM
MOVEM.L (SP)+, A0-A1/D0-D1 ; Restore regs <22aug85> BBM
RTS ; ...and return
;_______________________________________________________________________________
;
; Routine: SaveRegs (utility)
;
; Arguments: A4 (input.L) handle to a map
;
; Called By: RdData, WrData, WrDataSt, SetRFEOF, CheckGrow
; Calls: NONE
;
; Function: Standard entry routine that saves A0/A1/D0/D1, and makes A2/A3
; into offsets. The reverse operation is RestRegs. Note that A4
; must be even else an address error occurs.
;_______________________________________________________________________________
SaveRegs
MOVEM.L A0/D0/D1,-(SP) ; Stack now has return address and A0/D1/D0 <22aug85> BBM
MOVE.L 12(SP),A0 ; Get return address into A0 for return.
MOVE.L A1,12(SP) ; Stack now has A1/A0/D1/D0.
SUBA.L (A4),A3 ; make A3 an offset
SUBA.L (A4),A2 ; make A2 an offset
JMP (A0) ; ... and return
;_______________________________________________________________________________
;
; Routine: SetRFEOF (utility)
;
; Arguments: A4 (input.L) handle to a map
;
; Called By: UpdateResFile, ResizeMap, AllocRes, ReallocRes
; Calls: ResRW, SetFileIO, _SetEOF
;
; Function: Set the resource file EOF, and now (14aug85) checks if map is in
; front or in back of the data.
;_______________________________________________________________________________
SetRFEOF
BSR.S SaveRegs ; Saves A1/A0/D1/D0 and makes A2/A3 offsets <22aug85> BBM
SetEOF2
BSR ResRW ; Read/write allowed?
BNE.S RestRegs ; if not, just exit! <22aug85> BBM
BSR.S SetFileIO ; Set up a file block
BSR.S MaxRFEOF ; get the end of the file <14aug85> BBM
MOVE.L D0,IOLEOF(A0) ; Set EOF in parameter block
_SetEOF ; call the FS
BRA.S IOExit ; and exit through common code
MaxRFEOF
MOVEM.L A1/D1,-(SP) ; save A1/D1 across call <11sep85> BBM
MOVE.L (A4),A1 ; Dereference map handle <14aug85> BBM
MOVE.L (A1)+,D0 ; Get ResDataOffset into D0 <11sep85> BBM
MOVE.L (A1)+,D1 ; Get ResMapOffset into D1
ADD.L (A1)+,D0 ; add in the DataSize to D0
ADD.L (A1)+,D1 ; add in the MapSize to D1
CMP.L D1,D0 ; which is greater??
BPL.S @9 ; CC=PL means ResDataOffset + DataSize = EOF
MOVE.L D1,D0 ; ... else ResMapOffset + MapSize = EOF
@9 MOVEM.L (SP)+,A1/D1 ; restore A1/D1
RTS ; and return
;_______________________________________________________________________________
;
; Routine: GetHS (utility)
;
; Arguments: A2 (input.L) pointer to entry
; D0 (output.L) size of resource entry + 4
;
; Called By: ReallocRes, AllocRes
; Calls: _GetHandleSize
;
; Function: Get ResourceSize+4 in D1
;_______________________________________________________________________________
GetHS
MOVE.L RHndl(A2), A0 ; Get the resource handle from A2
_GetHandleSize ; Get the size of the handle.
ADDQ.L #LenWdLen, D0 ; add 4 for length longword <06may85> BBM
MOVE.L D0, D1 ; Copy to D1 for caller.
RTS
;_______________________________________________________________________________
;
; Routine: SpaceAt (utility)
;
; Arguments: A2 (input.L) pointer to resource entry
; D0 (output.L) space available for map
; CCR (output) BMI for last resource or just before map
;
; Called By: (SpaceAt): ReallocRes
; (SpaceAt2): MaxSizeRsrc
; Calls: NextRes
;
; Function: Given A2 pointing to a resource entry, return space available in
; the map for the resource in D0. Does not include space for a
; length longword.
; If last resource, returns MI with D0=space available before map.
; Otherwise returns PL with D0=space avail before next resource.
;_______________________________________________________________________________
SpaceAt ; completely redid routine <27aug85> BBM
MOVEM.L A0-A2/D1/D7,-(SP) ; Save regs
MOVE.L RLocn(A2),D7 ; Get the location longword
AND.L Lo3Bytes,D7 ; AND off high 8 bits.
MOVE.L (A4),A0 ; dereference map to get at offsets
MOVE.L ResMapOffset(A0),D0 ; check to see who is in front
SUB.L ResDataOffset(A0),D0 ; ... and get delta in D0/A1 with CC's
MOVE.L D0,A1 ; ... Save for later
BMI.S @2 ; CC=MI means map is in front of all RSRCs
CMP.L D7,A1 ; Is current resource past the map?
BMI.S @2 ; CC=MI means first resource past map
; RSRC is before the map . ..
BSR ZNextRes ; Get following resource--D0 is location.
BMI.S @1 ; If no next resource go get size before map
CMPA.L D0,A1 ; If next resource before map ...
BPL.S satNotLast ; ... CC=PL means it is before map
@1 MOVE.L A1,D0 ; Else get biased offset to map in D0
BRA.S satLast ; and exit though satLast
; we come here if RSRC is past map . . .
@2 BSR ZNextRes ; Get following resource--D0 is location.
BPL.S satNotLast ; CC=PL means next resource exists
BSR.S MaxRFEOF ; get EOF in D0 and exit through satLast
SUB.L ResDataOffset(A0),D0 ; make D0 an offset into the data segment <28oct85> BBM
satLast ; last RSRC before Map or EOF
SUB.L D7,D0 ; Get the space available into D0
MOVEQ #-1,D7 ; Set CC's to MI to tag as 'last' b4 map or LEOF
BRA.S satReturn ; and exit though satReturn
satNotLast
SUB.L D7,D0 ; Get the space available into D0
satReturn
MOVEM.L (SP)+,A0-A2/D1/D7 ; Restore regs
RTS
;_______________________________________________________________________________
;
; Routine: ReallocRes, AllocRes (utilities)
;
; Arguments: A2 (input.L) pointer to source entry
; A0 (output.L) Blitzed
; D0 (output.L) Blitzed
; D1 (output.L) Blitzed
;
; Called By: (ReallocRes): ChangedResource
; (AllocRes): AddResource
; Calls: GetHS, SpaceAt, SetRFEOF, MaxRFEOF
;
; Function: Allocate a space for the resource in the resource file. If the
; current location is ok, just return. If the current location is
; too small, allocate the resource on the end, updating the
; ResMapOffset and DataSize. WARNING!! THE RESOURCE MUST BE IN
; MEMORY. The resfile may be trashed if not.
;
; AllocRes just bypasses the SpaceAt check, and automatically
; allocates the resource at the end. Does not grow the resource
; file--assumes a previous call to CheckGrow.
;_______________________________________________________________________________
ReallocRes
BSR.S GetHS ; Get handleSize+4 in D1
BSR.S SpaceAt ; How much space available here?
CMP.L D0, D1 ; If space exists at end ... <27aug85> BBM
BLE SetRFEOF ; ... just exit through SetRFEOF
AllocRes
BSR.S GetHS ; Get handleSize+2 in D1
BSR.S MaxRFEOF ; get end of rsrc file in D0 <27aug85> BBM
MOVE.L (A4),A0 ; Dereference map handle <10oct85> BBM
SUB.L ResDataOffset(A0),D0 ; get new data size in D0 <10oct85> BBM
MOVE.B RLocn(A2),-(SP) ; save off attrs <10oct85> BBM
MOVE.L D0,RLocn(A2) ; get new address <10oct85> BBM
MOVE.B (SP)+,RLocn(A2) ; restore attrs <10oct85> BBM
ADD.L D1,D0 ; Get new end of file <10oct85> BBM
MOVE.L D0,DataSize(A0) ; ... and save it <10oct85> BBM
ORI.B #MCCMask,MAttr(A0) ; Set mapChanged and MapCompact bits
BSR UpdateOverriddenChangedBits ; set the changed bit for any files that may be overridden by the map in A4
BRA SetRFEOF ; exit through SetRFEOF.
;_______________________________________________________________________________
;
; Routine: ResRW (utility)
;
; Arguments: A4 (input.L) map handle
;
; Called By: SetRFEOF, CheckGrow, UpdateResFile, WriteResource
; Calls: NONE
;
; Function: Check the read-only bit (in map attribute byte) and return CC.
;_______________________________________________________________________________
ResRW
MOVE.L (A4), A0 ; Dereference map handle
BTST #MapReadOnly, MAttr(A0) ; Set CC's
RTS ; and return.
;_______________________________________________________________________________
;
; Routine: CheckGrow (utility)
;
; Arguments: D6 (input.W) resource file refnum
; A1 (input.L) handle to resource to be added to the
; resource file
;
; Called By: ChangedResource, SetResInfo, AddResource
; Calls: _GetHandleSize, _SetHandleSize, ResRW, SetFileIO, _GetEOF,
; _SetEOF
;
; Function: CheckGrow checks for the DiskFull and MemFull conditions. It
; assumes the maximum overhead for adding the information to the
; map, as well as adding the data to the resource file. 256 bytes
; for max name size, 12 for the resource entry, and 6 for the type
; entry for a maximum delta of 274 bytes for the map. If the
; resource is added to the end of the resource file, the amount
; that the resource file may need to grow, worst case, will be
; 4+sizeOfResource+274 bytes. For convenience, 280+sizeOfResource
; will be used.
;
; If the resource file in question is read-only, the diskFull test
; will not be performed. Be aware of this feature.
;
; If it is safe to grow both the map handle in memory and the
; resource file on disk, CheckGrow will return with CC=EQ, and
; ResErr=0. If either the memFull or DiskFull conditions occur,
; CheckGrow will return with CC=MI and ResErr=the error code.
;
; Keeps A2,A3 correct ptrs (calculates and restores with offsets).
; Other registers, if pointing inside the map block, may become
; invalid due to the SetHandleSize moving the block.
;_______________________________________________________________________________
CheckGrow
BSR SaveRegs ; Saves A1/A0/D1/D0 and makes A2/A3 offsets <22aug85> BBM
MOVE.L D2,-(SP) ; Save D2 <22aug85> BBM
MOVEQ #70, D1 ; Get D1=70, then
ASL.W #2, D1 ; *4=280, max overhead possible.
MOVE.L A4, A0 ; Get map handle in A0
_GetHandleSize ; Get the size
MOVE.L D0, D2 ; Save size in D2
ADD.L D1, D0 ; Increase by max overhead
_SetHandleSize ; Grow it
EXG D0, D2 ; Get old size, save error code in D2
_SetHandleSize ; and shrink it back.
MOVE.W D2,D0 ; Was there an error by first SetHandleSize <26aug85> BBM
BMI.S CG9 ; if so, set resErr on exit, D2=code. <9> rb
BSR.S ResRW ; Read/write allowed?
BNE.S CG9 ; if not, exit without doing diskFull check. <9> rb
MOVE.L A1, D0 ; is there a handle to account for?
BEQ.S CG1 ; if not, don't add length... <9> rb
MOVE.L A1, A0 ; Copy to A0 for GetHandleSize call
_GetHandleSize ; get the handle size in D0
MOVE.L D0,D2 ; Test long word for error
BMI.S CG9 ; if so, report error <9> rb
ADD.L D0, D1 ; otherwise add length to other overhead
CheckGrowAt1 ; <9> rb <SM26> rb
CG1 BSR SetFileIO ; Set up the file frame <9> rb
LEA IOLEOF(A0), A1 ; A1 points to EOF loc'n
_GetEOF ; Get the current EOF
MOVE.L (A1), D2 ; Copy it to D2.
ADD.L D1, (A1) ; increment it by maximum grow value
; and set it back. was it successful?
; Roll in ValidateFileSizeInCheckGrow from ResourceMgrExtensions.a <SM9><PN>
TST.B (A1) ; get new size of file set up by CheckGrow (a1 points to ioLEOF inside param block)
; note: 16 meg = $01000000, so if any bits are set in first byte itÕs >= 16 meg
BNE CheckGrowErr ; it's ³ 16Meg so return an error SM9><PN>
_SetEOF ; set it back
CG9 ; <9> rb
MOVE.L (SP)+,D2 ; restore D2 <26aug85> BBM
BRA IOExit ; exit by setting CC's and ResErr <26aug85> BBM
CheckGrowErr
MOVE.W #EOFERR,D0 ; not really an eofErr, but it is the end of the resource fork <SM9><PN>
BRA CG9 ; SM9><PN>
;_______________________________________________________________________________
;
; Routine: CheckMap (utility)
;
; Arguments: A4 (input.L) map handle
; D0 (output.L) Error result
; CC's (output.CC) MI=error; EQ=good
;
; Called By: OpenResFile
; Calls: NONE
;
; Function: Check the consistency of the map. This is some simple error
; checking for resource files. It preserves all regs except D0,
; and returns the error result in D0 and CC's.
; note:
; test1: Check to see if the EOF is unreasonable.
; test2: Checks to see if offset to Types is odd. (If so, map is bad.) <C249>
; test3: Checks to see if MNames starts right after all the rsrc entries.
;_______________________________________________________________________________
CheckMap
MOVEM.L A0-A1/D0-D1,-(SP) ; save regs
MOVE.L (A4), A0 ; Dereference map handle <05sep85> BBM
;test1
BSR MaxRFEOF ; get what map thinks to be EOF (trashes A1) <14aug85> BBM
CMP.L Lo3Bytes,D0 ; Shouldn't have a file longer than $FFFFFF <21aug85> BBM
BGE.S @8 ; ... If EOF is bigger than we're in trouble.
;test2
BTST.B #0,MTypes+1(A0) ; check for an odd offset <C249>
BNE.S @8 ; if there is an odd offset, map is bad <C249>
;test3
MOVEA.L A0,A1 ; now both A0 & A1 point to map.
ADDA.W MTypes(A0),A1 ; A1 now points to type stuff
MOVE.W (A1)+,D0 ; D0 = # of types minus one (TypeCount) <08may85> BBM
BMI.S @1 ; if TypeCount is minus no entries
MOVEQ #0,D1 ; D1 used to sum counts of types
@0 ADD.W TCount(A1),D1 ; add count for this type
ADDQ #1,D1 ; since TCount is really (n-1)
ADDQ #TSize,A1 ; point to next type
DBRA D0,@0 ; loop back for all types
; note A1 already points to first rsrc entry
MULU #RESize,D1 ; make offset to end of rsrc entries
ADDA.L D1,A1 ; A1 points just past rsrc entries
@1 MOVE.W MNames(A0),D1 ; get name offset into D1 <08may85> BBM
BGT.S @2 ; if name offset exists go test it
SUBA.L A0,A1 ; else see if A1 points past end of map
MOVE.L A1,D1 ; need to and off high byte
AND.L Lo3Bytes,D1 ; this size should be less than mapsize
CMP.L MapSize(A0),D1 ; if CC=GT then ERROR
BGT.S @8 ; Goto error
BRA.S @7 ; else map is good.
@2 ADDA.W D1,A0 ; point A0 where names begin
CMPA.L A1,A0 ; if CC=MI then error
BMI.S @8 ; BMI to error, fall through to Good
;endtests
@7 MOVEQ #0,D0 ; No Error
BRA.S @9 ; ... and skip next instruction
@8 MOVE.W #mapReadErr,ResErr ; Error return
@9 MOVEM.L (SP)+,A0-A1/D0-D1 ; restore regs
RTS ; and return
;=== RmgrAsm3.a Starts Here =============================================================
;_______________________________________________________________________________
;
; Routine: PROCEDURE LoadResource(theResource: Handle);
;
; Arguments: 20(A6) (input.L) handle to resource
;
; Called By: A-trap through dispatcher
; Calls: StdEntry, HandleScan, CheckLoad, StdZeroExit
;
; Function: Given the handle, loads the resource from its resource file,
; if necessary. Saves all registers INCLUDING A0 and D0.
; theResource is 20(A6), over fake return+A0/D0+actual return.
;_______________________________________________________________________________
LoadResource
BLANKS ON
STRING ASIS
MOVEM.L A0-A1/D0, -(SP) ; Save extra registers
;¥¥¥ begin temp fix
;check if resource is in ROM or not
MOVE.L 16(SP),D0 ; get resource handle
BEQ.S @NilHandle ; Is the handle nil <SM33> PN
_StripAddress ; shave off the variation code (in case its a defproc) <13> stb
MOVE.L D0,A0 ; handle in A0
MOVE.L ROMBASE,A1
CMP.L (A0),A1 ; resource in ROM
BHI.S @2 ; Nope
CLR.W ResErr ; since we found a ROM resource, and we assume it is ok. <SM43> CSS
BRA.S @9 ; yes, done
@2
;¥¥¥ end fix
PEA @9 ; Fake out stdExit to return here
BSR Std1Entry ; Do standard entry <22apr85> BBM
MOVE.L D0,A1 ; put stripped handle in a1 <13> stb
TST.L (A1) ; Was it purged? <SM33> PN
BNE.S @8 ; No, don't load <SM33> PN
BSR HandleScan ; Otherwise set up A2 to point to the entry
BEQ.S @1 ; if found, go on, else
MOVE.W #ResNotFound,ResErr ; Set ResErr
BRA.S @8 ; and exit.
@1
MOVE.B ResLoad,-(SP) ; Save current value of ResLoad
ST ResLoad ; Set TRUE temporarily, forcing a load.
BSR CheckLoad ; load the resource in, if needed
MOVE.B (SP)+,ResLoad ; and restore the value of ResLoad
@8
BRA StdZeroExit ; Fake out stdExit to not pop params.
@NilHandle
MOVE.W #ResNotFound,ResErr ; set ResError <SM34> PN
@9 ; returns here actually...
MOVEM.L (SP)+,A0-A1/D0 ; Gotta restore my regs first
MOVE.L (SP)+,(SP) ; Pop off handle, preserving retaddr
RTS ; ...and return.
;_______________________________________________________________________________
;
; Routine: ReleaseResource(theResource: Handle);
;
; Arguments: 8(A6) (input.L) handle to resource
;
; Called By: A-trap through dispatcher
; Calls: StdResEntry
;
; Function: Given handle, releases the resource and disposes of the handle.
; Any GetResource to the released resource will then cause a disk
; access and return a new handle. Error condition handled in
; StdResEntry.
; Do not release system override resources from ROM, since there is <SM32> rb
; no way to get the back in the resource map. <SM32> rb
;_______________________________________________________________________________
ReleaseResource
BSR StdResEntry ; Link, save regs, scan for handle.
CMPI.W #kFakeResourceOverrideMapRefNum,D6 ; is this a ROM resource ? <SM32> rb
BEQ.S RelExt2 ; exit if so <SM32> rb
BTST #ResChanged, RAttr(A2) ; is it marked to be written?
BNE.S RelExt2 ; if so, can't release! So exit. <12aug85> BBM
MOVE.L A1, A0 ; Copy handle to A0
_DisposHandle ; Dispose of handle
RelExit ; common exit for DetachResource <12aug85> BBM
CMP.L #'FONT',D3 ; Check if we should invalidate font cache <06nov85> BBM
BNE.S @0 ; CC=NE means this is not a font, so skip <06nov85> BBM
MOVE.L MinusOne,LastSPExtra ; ...else invalidate font cache <06nov85> BBM
@0 ;
CLR.L RHndl(A2) ; Clear the handle location in map only
CLR.L HSCHandle ; Invalidate cache <12mar85> BBM
RelExt2 ; common exit for DetachResource <12aug85> BBM
BRA StdFourExit ; and exit.
;_______________________________________________________________________________
;
; Routine: PROCEDURE DetachResource(theResource: Handle);
;
; Arguments: 8(A6) (input.L) handle to the resource
;
; Called By: A-trap through dispatcher
; Calls: StdResEntry
;
; Function: Given the handle, releases the resource only. Does NOT dispose
; of the handle. Any GetResource to the released resource will
; then cause a disk access and return a new handle. Error
; condition handled in StdResEntry.
; Do not detach system override resources from ROM, since there is <SM32> rb
; no way to get the back in the resource map. <SM32> rb
;_______________________________________________________________________________
DetachResource
BSR StdResEntry ; Link, save regs, scan for handle. <SM32> rb
CMPI.W #kFakeResourceOverrideMapRefNum,D6 ; is this a ROM resource ? <SM32> rb
BEQ.S RelExt2 ; exit if so <SM32> rb
BTST #ResChanged, RAttr(A2) ; is it marked to be written?
BNE.S @5 ; if so, can't detach! <03apr85> BBM
MOVEA.L A1,A0 ; GentlemanÕs way to say Ònot an rsrcÓ <C169>
_HClrRBit ; <C169>
BRA.S RelExit ; Common exit code <12aug85> BBM
@5 MOVE.W #resAttrErr,ResErr ; mark it as an error <03apr85> BBM
BRA.S RelExt2 ; and exit <12aug85> BBM
;_______________________________________________________________________________
;
; Routine: PROCEDURE ChangedResource(theResource: Handle);
;
; Arguments: 8(A6) (input.L) handle to the resource
;
; Called By: A-trap through dispatcher
; Calls: StdResEntry, CheckGrow, ReallocRes
;
; Function: Mark the resource to be written out into the resource file.
; If protected, won't allow change to occur. If read-only flag
; set, won't do the diskFull check, though if at a later time the
; read-only flag is cleared, it will be written. Be careful!
; DiskFull may occur at that time, which will destroy your
; resource file! ResNotFound condition handled in StdResEntry.
;_______________________________________________________________________________
ChangedResource
BSR.S StdResEntry ; Link, save regs, scan for handle.
bsr FlushChangedFONDs ; flush 'FOND' candidate list if this is a FOND <sm 5> stb
MOVEA.L A1,A0 ; Save state of lock/purge/res bits in D7 <C169>
_HGetState ; D0 <- LPR bits <C169>
MOVE.B D0,D7 ; <C169>
_HNoPurge ; donÕt allow purge here (CheckGrow) <C169>
BTST #ResProtected, RAttr(A2); Is it protected? (also checks if ROM)
BNE.S @5 ; if so, don't allow change. <16apr85> BBM
BSR CheckGrow ; Can it grow resource file + map?
BMI.S @9 ; if not, just exit with error, otherwise
BSET #ResChanged, RAttr(A2) ; Set the changed bit for this resource.
BSR ReallocRes ; and allocate it in-place or at end.
MOVE.L (A4),A0 ; dreference map handle <28jan85> BBM
BSET #mapChanged,MAttr(A0) ; ***Hack! really want MapUpdate <29jan85> BBM
BSR UpdateOverriddenChangedBits ; set the changed bit for any files that may be overridden by the map in A4
BRA.S @9 ; and exit <16apr85> BBM
@5 MOVE.W #resAttrErr,ResErr ; mark it as an error return <16apr85> BBM
@9
MOVEA.L A1,A0 ; A0 <- handle <C169>
MOVE.B D7,D0 ; D0 <- saved LPR bits <C169>
_HSetState ; <C169>
BRA StdFourExit ; exit
;_______________________________________________________________________________
;
; Routine: PROCEDURE WriteResource(theResource: Handle);
;
; Arguments: 8(A6) (input.L) handle to the resource
;
; Called By: A-trap through dispatcher
; Calls: StdResEntry, ResRW, WrRsrc
;
; Function: Given the handle, writes out the resource back to the resource
; file. ResChanged is checked, and the resource not written
; unless TRUE. Error condition handled in StdResEntry.
;_______________________________________________________________________________
WriteResource
BSR.S StdResEntry ; Link, save regs, scan for handle.
bsr FlushResourceCache
BSR ResRW ; Read/write allowed on this file?
BNE.S @9 ; if not, don't allow the write!
BTST #ResChanged, RAttr(A2) ; test resChanged attribute
BEQ.S @9 ; Don't write if not changed.
BSR WrRsrc ; Else write out the changed resource
; and exit without error <12aug85> BBM
@9 BRA StdFourExit ; pop 4 bytes and exit.
;_______________________________________________________________________________
;
; Routine: StdResEntry (utility)
;
; Arguments: 8(A6) (input.L) handle to the resource
; xx (output.x) output from HandleScan
;
; Called By: ReleaseResource, DetachResource, WriteResource, HomeResFile,
; ChangedResource, SizeResource, MaxSizeRsrc, RsrcMapEntry
; Calls: Std1Entry, HandleScan, StdFourExit
;
; Function: Given the handle 8(A6), scans for the handle and exits if not
; found. StdEntry returns with A0 pointing to the last argument
; (the handle). Callers should exit through StdFourExit.
;_______________________________________________________________________________
Std2ResEntry
MOVE.L MinusOne,12(SP) ; Assume it can't be found <21aug85> BBM
StdResEntry
MOVE.L (SP)+, D0 ; Get return address
BSR Std1Entry ; Link A6, save regs <22apr85> BBM
MOVE.L D0, -(SP) ; Push return back.
MOVE.L A0,D0 ; Check for nil handle <22may85> BBM
BEQ.S @5 ; if nil return with error <22may85> BBM
MOVE.L (A0), A1 ; Get the resource handle
BSR RefHandle ; Scan for it <26aug85> BBM
BEQ.S @9 ; If found, just return
@5 ADDQ #4, SP ; Otherwise, pop the return address
BRA StdFourExit ; and exit.
@9 RTS ; ... else return
;_______________________________________________________________________________
;
; Routine: FUNCTION HomeResFile(theResource: Handle): INTEGER;
;
; Arguments: 8(SP) (input.L) handle to the resource
; 12(A6) (output.W) refnum of resource file that has handle
;
; Called By: A-trap through dispatcher
; Calls: StdResEntry, StdFourExit
;
; Function: Given a handle, returns the refnum of the resource file that the
; resource lives in. If the resource is not found, returns -1.
; Error condition handled in StdResEntry.
;_______________________________________________________________________________
HomeResFile
MOVE.W #-1,8(SP) ; Assume failure. <06may85> BBM
BSR.S StdResEntry ; Get the resource, and return if NIL.
CMP.W SysMap, D6 ; Is it the system or rom map? <16may85> BBM
BNE.S @1 ; No, leave refnum,
@0 MOVEQ #0, D6 ; else return 0 for homeResFile value.
@1 MOVE.W D6, 12(A6) ; Return map refnum as function result
BRA StdFourExit ; and exit.
;_______________________________________________________________________________
;
; Routine: PROCEDURE SetResPurge(install: BOOLEAN);
;
; Arguments: 8(A6) (input.W) Install flag
;
; Called By: A-trap through dispatcher
; Calls: _WriteResource (later in purge proc) if a resource gets purged
; and has been marked changed
;
; Function: Install or remove the resource manager purge hook in the
; current zone.
;
; Clearing now means leaving the disk cache purge proc in place.
; Setting now means putting RPHook into the purge proc, and it
; calls through to the the TrueType disk cache purge proc. <sm10>stb
;_______________________________________________________________________________
IMPORT DiskCachePurgeProcedure
;------ start of the resource mgr purge proc
; The actual purge hook code. Assumes the handle is pushed on stack.
; Smashes A0, A1 and D0 always.
RPHook
move.l 4(sp),-(sp)
jsr DiskCachePurgeProcedure ; Give TrueType a crack at flushing this block <sm10>stb
; to disk if itÕs a font cache block <sm10>stb
MOVE.L (SP)+, A1 ; Get the return address in A1
MOVE.L (SP)+, A0 ; and the handle in A0.
_HGetState ; D0 <- Lock/Purge/Res bits <C169>
BTST #Resource,D0 ; NE => itÕs indeed a rsrc <C169>
BEQ.S @1 ; If not resource, just return,
MOVE.L A0, -(SP) ; otherwise push the handle
_WriteResource ; Attempt a write (ResChanged checked)
@1 JMP (A1) ; and return to memory manager
;------ end of the resource mgr purge proc
SetResPurge
MOVE.L (SP)+, D0 ; Get return address in D0
TST.B (SP)+ ; Install or remove the hook?
BNE.S @install ; install
@clear ; clearing means leaving the font disk cache purge proc in place <sm10>stb
lea DiskCachePurgeProcedure,a1 ; the TrueType purge procedure <sm10>stb
BRA.S @continue
@install ; installing. Put the resource mgr purge proc into the zoneÕs purgeProc
lea RPHook,a1 ; <sm10>stb
@continue
MOVE.L theZone,A0 ; Get the application zone <18apr85> BBM<sm10>stb
move.l a1,purgeProc(a0) ; Set or clear the purge hook <sm10>stb
MOVE.L D0, -(SP) ; Push return address back
RsClrEx ; rts from SetResLoad, ResError & CurResFile <13aug85> BBM
CLR.B ResOneDeep ; disable one deep calls <13aug85> BBM
CLR.W RomMapInsert ; disable rom map next time <13aug85> BBM
RTS ; and return.
;_______________________________________________________________________________
;
; Routine: PROCEDURE SetResLoad(autoLoad: BOOLEAN);
;
; Arguments: 4(SP) (input.B) autoload flag
;
; Called By: A-trap through dispatcher
; Calls: NONE
;
; Function: Set automatic-loading true or false. If autoLoad=TRUE, then the
; resource manager will load resources from the disk if necessary.
; If FALSE, returns the handle, which may be empty.
;_______________________________________________________________________________
SetResLoad
MOVE.L (SP)+,A0 ; Get return address
MOVE.B (SP)+,ResLoad ; Set ResLoad from proc parameter
MOVE.L A0,-(SP) ; Get return address <13aug85> BBM
BRA.S RsClrEx ; and return <13aug85> BBM
;_______________________________________________________________________________
;
; Routine: FUNCTION CurResFile: INTEGER;
;
; Arguments: 4(SP) (output.W) refnum of current resource file
;
; Called By: A-trap through dispatcher
; Calls: NONE
;
; Function: Returns the reference number of the current resource file.
;_______________________________________________________________________________
CurResFile
MOVE.W CurMap, 4(SP) ; else Set the function result as current map <15jul85> BBM
BRA.S RsClrEx ; and return <13aug85> BBM
;_______________________________________________________________________________
;
; Routine: FUNCTION ResError: INTEGER;
;
; Arguments: 4(SP) (input.L) place to store ResError code
; 4(SP) (output.L) ResError code
;
; Called By: A-trap through dispatcher
; Calls: NONE
;
; Function: Return a resource error code. Usually the code will be an I/O
; error, but there are several resource-only errors which are
; reported through this call.
;_______________________________________________________________________________
ResError
MOVE.W ResErr,4(SP) ; Set error code as function result
BRA.S RsClrEx ; and return <13aug85> BBM
;_______________________________________________________________________________
;
; Routine: PROCEEDURE AddReference(theResource: Handle; theID: INTEGER;
; name: Str255);
;
; Arguments: (output.W) ResError code
;
; Called By: A-trap through dispatcher
; Calls: RsClrEx
;
; Function: Return a resource error code of AddRefFailed.
;_______________________________________________________________________________
AddReference
MOVE.L (SP)+,A0 ; get return address into A0 <17oct85> BBM
ADDA.W #$A,SP ; strip ten bytes off stack (parameters) <17oct85> BBM
MOVE.L A0,-(SP) ; push return address <17oct85> BBM
MOVE.W #AddRefFailed,ResErr ; Set error code as failed <17oct85> BBM
BRA.S RsClrEx ; and return <17oct85> BBM
;_______________________________________________________________________________
;
; Routine: PROCEEDURE RmveReference(theResource: Handle);
;
; Arguments: (output.W) ResError code
;
; Called By: A-trap through dispatcher
; Calls: RsClrEx
;
; Function: Return a resource error code of AddRefFailed.
;_______________________________________________________________________________
RmveReference
MOVE.L (SP)+,(SP) ; strip parameter with return address <17oct85> BBM
MOVE.W #RmvRefFailed,ResErr ; Set error code as failed <17oct85> BBM
BRA.S RsClrEx ; and return <17oct85> BBM
;_______________________________________________________________________________
;
; Routine: FUNCTION GetResAttrs(theResource:Handle): INTEGER;
;
; Arguments: 8(A6) (input.L) handle to the resource
; (A0) (input.L) same as 8(A6)
; 12(A6) (output.W) resource attributes in low order byte
;
; Called By: A-trap through dispatcher
; Calls: StdEntry, RefHandle, StdFourExit
;
; Function: Given a resource, return the resource attributes in the low order
; byte of the integer result. If a reference to the resource exists
; in the current resFile, returns attributes of that reference.
;_______________________________________________________________________________
GetResAttrs
BSR Std1Entry ; Link A6, save regs <22apr85> BBM
MOVE.L (A0), A1 ; Get the resource handle
BSR.S RefHandle ; Scan for reference or handle
BMI.S @9 ; if not found, resErr set, just exit.
MOVE.B RAttr(A2), 13(A6) ; Set function result in low byte of result
@9 BRA StdFourExit ; and branch to standard exit
;_______________________________________________________________________________
;
; Routine: PROCEDURE SetResAttrs(theResource: Handle; attrs: INTEGER);
;
; Arguments: 10(A6) (input.L) handle to the resource
; 8(A6) (input.W) new attributes
;
; Called By: A-trap through dispatcher
; Calls: StdEntry, RefHandle, StdSixExit
;
; Function: Given a resource, set the resource attributes which are in the low
; order byte of the integer parameter. These new attributes will only
; be in effect the next time the resource is loaded, except for SysHeap,
; which will be ignored. If a reference to the resource exists in the
; current resource file, the attributes of the reference will be set.
; <28jan85> BBM ram patches added in.
;_______________________________________________________________________________
SetResAttrs
BSR Std1Entry ; Link A6, save regs <22apr85> BBM
MOVE.L 10(A6), A1 ; Get the resource handle
BSR.S RefHandle ; Look for a reference or the resource
BMI.S @9 ; if not found, ResErr set, just exit.
CMP.L RomMapHndl, A4 ; is it in the ROM map? <28mar85> BBM
BEQ.S @9 ; then exit here too (just a nop) <28mar85> BBM
MOVE.B 9(A6), RAttr(A2) ; Set attr byte in the location longword
MOVE.L (A4),A0 ; Dereference map handle <28jan85> BBM
BSET #MapChanged,MAttr(A0) ; Set the map changed bit
BSR UpdateOverriddenChangedBits ; set the changed bit for any files that may be overridden by the map in A4
@9 BRA StdSixExit ; pop 6 bytes and exit
;_______________________________________________________________________________
;
; Routine: RefHandle (utility)
;
; Arguments: A1 (input.L) handle to the resource.
; Ax (input.L) assumes regs setup as per StdEntry
;
; Called By: GetResAttrs, SetResAttrs, GetResInfo, SetResInfo
; Calls: HandleScan
;
; Function: Scans for reference, then handle. Returns MI if neither found,
; and sets ResErr to ResNotFound.
;_______________________________________________________________________________
RefHandle
BSR HandleScan ; Otherwise find the resource itself
BEQ.S @9 ; if resource found, exit, else
MOVE.W #ResNotFound, ResErr ; Set ResErr, CC's
@9 RTS ; ...and return
;_______________________________________________________________________________
;
; Routine: PROCEDURE GetResInfo(theResource:Handle; VAR theID:INTEGER;
; VAR theType:LONGINT; VAR name:Str255);
;
; Arguments: 20(A6) (input.L) handle to res
; 16(A6) (input.W) Resource ID
; 12(A6) (input.L) Resource type
; 8(A6) (input.L) pointer to pascal string
;
; Called By: A-trap through dispatcher
; Calls: StdEntry, RefHandle, NameResource, CopyStr, StdExit
;
; Function: Given a resource, return the information about the resource in
; the VAR parameters. If a reference to the resource exists in the
; current resFile, the information will be returned about the
; reference.
;_______________________________________________________________________________
GetResInfo
BSR Std1Entry ; Link A6, save regs <22apr85> BBM
MOVE.L 20(A6),A1 ; Get the resource handle
BSR.S RefHandle ; Look for a reference to this resource
BEQ.S @1 ; If OK, go on, else ResErr set,
LEA MinusOne,A2 ; point to -1, -1,
MOVEQ #0, D3 ; and set type to null type.
@1 LEA 16(A6),A0 ; Get top parameter address
MOVE.L (A0),A1 ; Get address of the ID variable
MOVE.L A1,D0 ; If pointer to var parameter is nil <06may85> BBM
BEQ.S @2 ; ... then don't write out.
MOVE.W RID(A2),(A1) ; Store it
@2 MOVE.L -(A0),A1 ; Get address of the type variable
MOVE.L A1,D0 ; If pointer to var parameter is nil <06may85> BBM
BEQ.S @3 ; ... then don't write out.
MOVE.L D3,(A1) ; Store it
@3 MOVE.L -(A0),A1 ; Get address of the name variable
MOVE.L A1,D0 ; If pointer to var parameter is nil <06may85> BBM
BEQ.S @9 ; ... then don't write out.
CLR.B (A1) ; Store first byte zero, for null string
BSR NameResource ; Given RNameOff(A2), point A0 to the name.
BMI.S @9 ; If can't find the name, no go
BSR.S CopyStr ; Copy string in A0 to A1.
@9
MOVEQ #16,D0 ; Pop off 16 bytes of parameter
BRA StdExit ; and exit.
;_______________________________________________________________________________
;
; Routine: CopyStr (utility)
;
; Arguments: A0 (input.L) pascal String pointer
; A1 (input.L) pointer to new location
;
; Called By: GetResInfo, AddName
; Calls: _BlockMove
;
; Function: Given a Pascal string in A0 and an address in A1, copies the
; string including the length byte to A1 using blockMove.
;_______________________________________________________________________________
CopyStr
MOVEQ #0, D0 ; Zero high order bits.
MOVE.B (A0), D0 ; Get length of string
ADDQ.W #1, D0 ; include length byte. <14jun85> BBM
_BlockMoveData ; Copy the string to A1
RTS ; and return.
;_______________________________________________________________________________
;
; Routine: PROCEDURE SetResInfo(theResource:Handle; theID:INTEGER;
; theName:Str255);
;
; Arguments: 14(A6) (input.L) handle to the resource
; 12(A6) (input.W) resource ID
; 8(A6) (input.L) pointer to pascal string
;
; Called By: A-trap through dispatcher
; Calls: StdEntry, RefHandle, CheckGrow, RmveName, AddName, StdExit
;
; Function: Given a resource, Set the information about the resource. If the
; name pointer is NIL, doesn't change the name. If the protect bit
; is on, returns without doing anything. If a reference to the
; resource exists in the current resFile, the information about the
; reference will be set.
;_______________________________________________________________________________
SetResInfo
BSR Std1Entry ; Link A6, save regs <22apr85> BBM
MOVE.L 14(A6), A1 ; Get the resource handle
BSR.S RefHandle ; Look for a reference to this resource
BMI.S @9 ; Couldn't find it, or reference!
BTST #ResProtected,RAttr(A2) ; Is it protected from being changed?
BNE.S @5 ; Yes, return immediately, otherwise <16apr85> BBM
MOVE.L 8(A6),D0 ; Check for a nil name pointer <22aug85> BBM
BEQ.S @1 ; if no name just change RID
SUB.L A1, A1 ; (no handle)
BSR CheckGrow ; can the resfile + map grow? (sets ResErr)
BMI.S @9 ; if failed, can't set. Bad boundary condition.
MOVE.L D0, A0 ; Get name pointer in A0
BSR RmveName ; Remove old name, if it exists
BSR AddName ; Add the new one back, Sets in RNameOff(A2)
BSR SetRFEOF ; set new end of file <26aug85> BBM
@1 MOVE.L (A4),A0 ; Dereference map handle <22aug85> BBM
BSET #MapChanged,MAttr(A0) ; set the mapchanged bit
BSR UpdateOverriddenChangedBits ; set the changed bit for any files that may be overridden by the map in A4
MOVE.W 12(A6), RID(A2) ; Get new ID and store it
BRA.S @9 ; skip over error
@5 MOVE.W #resAttrErr,ResErr ; ... else mark it as error <16apr85> BBM
@9 MOVEQ #10, D0 ; pop off 10 bytes of parameters
BRA StdExit ; Restore regs, unlink A6
;_______________________________________________________________________________
;
; Routine: PROCEDURE AddResource(theResource:Handle; theType:LONGINT;
; theID:INTEGER; name:Str255);
;
; Arguments: 18(A6) (input.L) handle to the resource
; 14(A6) (input.W) theType
; 12(A6) (input.W) theID
; 8(A6) (input.L) pointer to pascal string
;
; Called By: A-trap through dispatcher
; Calls: StdEntry, HandleScan, GetCurMap, CheckGrow, AddNewRef, AddName,
; AllocRes, StdExit
;
; Function: Add a reference to the given resource in the current map. Set ID
; and name in the reference. Mark the resource to be written out
; into the correct resource map data section.
;_______________________________________________________________________________
AddResource
move.l ExpandMem,a0 ;
move.b ExpandMemRec.emScanOverrideMaps(a0),D0 ; save override state. (StdZEntry must preserve d0)
clr.b ExpandMemRec.emScanOverrideMaps(a0) ; turn it off for StdEntry
BSR StdZEntry ; Link A6, save regs <12aug85> BBM
bsr FlushResourceCache ; <PN> need to flush the resource cache
move.l ExpandMem,a0 ;
move.b d0,ExpandMemRec.emScanOverrideMaps(a0) ; restore override state
MOVE.W #AddResFailed,ResErr ; Assume error. CheckGrow resets ResErr.
MOVE.L 18(A6), A1 ; Get handle in A1
MOVE.L A1, D0 ; Set CC's
BEQ.S @9 ; if NIL handle, can't add!
BSR HandleScan ; Is the data already a resource?
BEQ.S @9 ; cann't add another <21may85> BBM
BSR GetCurMap ; Get the current map for diskFull check
BSR CheckGrow ; Room for resource + map overhead?
; CheckGrow calls ResRW which tests MapReadOnly <28mar85> BBM
BMI.S @9 ; if not, can't add the resource.
; Return with error from CheckGrow.
; If successful, ResErr := 0.
MOVE.L 14(A6), D3 ; Put type of resource to add in D3
BSR.S AddNewRef ; Set up a new reference to the resource
; Returns A2-->reference location.
MOVE.W 12(A6),(A2)+ ; Set ID of reference
MOVE.W #-1,(A2)+ ; Assume no name yet
MOVE.L #$02000000,(A2)+ ; ResChanged set
MOVE.L 18(A6), A0 ; Get the handle
_HSetRBit ; Mark it like a gentleman <C169>
MOVE.L A0, (A2) ; Finally, set handle.
SUBQ.L #8, A2 ; Back up for AddName, AllocRes.
MOVE.L 8(A6), A0 ; Get pointer to reference name
BSR AddName ; Name set in RNameOff(A2).
; A2, A3 preserved + correct.
BSR AllocRes ; Allocate new resource loc'n.
bsr FlushChangedFONDs ; flush 'FOND' candidate list if this is a FOND <sm 5> stb
@9 MOVEQ #14, D0 ; Pop off 14 bytes of parameter
BRA StdExit ; Restore regs, unlink A6
;_______________________________________________________________________________
;
; Routine: AddNewRef (utility)
;
; Arguments: A4 (input.L) handle to map
; A3 (input.L) pointer into map
; D3 (input.L type of resource to add
; A2 (output.L) pointer to loc of new reference
;
; Called By: AddResource
; Calls: TypeScan, TypeScanAll, ShiftBlock, MoveNames, GetTypes,
; SkipToEntry
;
; Function: add a new reference in the map (of type specified in D3)
;_______________________________________________________________________________
AddNewRef
BSET #MapChanged, MAttr(A3) ; Set mapChanged bit
BSR UpdateOverriddenChangedBits ; set the changed bit for any files that may be overridden by the map in A4
AddNewRefWithoutUpdate ; EntryPoint for MakeOverrideMap that doesn't set mapChanged bit. <SM48> kc
BSR TypeScan ; Scan for type of referent (D3) in cur map
BEQ.S @2 ; If found, type exists, otherwise
; Add both a new type and a new entry.
MOVEQ #RESize+TSize, D0 ; Move names up by RE+TE size to leave
BSR MoveNames ; room in handle for type and res entry.
BSR GetTypes ; Point to first type, if any.
BMI.S @1 ; If none, skip SkipToentry (adding 1st one!)
BSR SkipToEntry ; ... skip to res entry. A2-->first res entry.
@1 ; start adding type here (A2 should point at loc where to add new type)
MOVE.L A2, A3 ; A3 is location of new type entry.
MOVE.L (A4), A2 ; Dereference map handle.
ADD.W MNames(A2), A2 ; A2 points to new res entry loc'n.
SUB.W #RESize+TSize, A2 ; (name block already moved.)
MOVEQ #TSize, D0 ; Now shift all entries up by TSize
MOVE.L A3, A0 ; (A3=first entry loc)
MOVE.L A2, A1 ; new res entry locn is high bounds of block.
BSR ShiftBlock ; Made room for type entry now.
MOVE.L (A4), A0 ; Dereference map handle
ADD.W MTypes(A0), A0 ; Point to type block
ADDQ.W #1, (A0) ; Increment type count.
MOVE.L D3, (A3)+ ; Set the new type
CLR.W (A3)+ ; Set TCount to 0 (1 entry)
SUB.L A0, A1 ; Subtract first entry loc from block start
MOVE.W A1, (A3) ; to get the offset (new entry needs +TSize too).
ADDQ.L #TSize, A2 ; add offset to returned loc'n
MOVE.W (A0)+, D5 ; Get number of types
BRA.S UTOffsets ; update ALL type offsets by TSize and exit.
; The type already exists. Just add a new entry.
; This part only adds the new entry
@2
MOVEQ #RESize, D0 ; Move names up by entry size only.
BSR MoveNames ; Move names up for room
MOVE.L (A4), A1 ; Dereference map handle.
ADD.W MNames(A1), A1 ; end of block to move is beginning of names.
SUB.W D0, A1 ; names moved already--skip back to old val.
BSR TypeScan ; Scan for type of referent (D3) in cur map
MOVE.L A2, -(SP) ; Save type entry location for offset updating
ADDQ.W #1,TCount(A2) ; Increment entry count for this type
MOVEQ #RESize,D0 ; get offset to last Rsrc entry in D0 <14sep85> BBM
MULU TCount(A2),D0 ; D0 has offset past the first entry <14sep85> BBM
MOVE.W TOffset(A2),A2 ; Skip to the first entry of that type
ADD.L A3,A2 ; add in block address gives absolute addr.
ADD.W D0,A2 ; point to the last entry <14sep85> BBM
MOVE.L A2,A0 ; Start moving entries from here to names.
MOVEQ #RESize,D0 ; Move entries up by entry size only.
BSR ShiftBlock ; shift block up by RESize.
MOVE.L (SP)+, A0 ; Restore type entry location, and update
; following types by RESize.
BRA.S UTInLoop ; jump in lp to skip type entry
;_______________________________________________________________________________
;
; Routine: UTOffsets, UTInLoop (utilities)
;
; Arguments: D0 (input.W) Delta offset for this type
; D5 (input.L) types-1 remaining
; A0 (input.L) points to first entry
;
; Called By: (UTOffsets): AddNewRef, RmveCmn
; (UTInLoop): AddNewRef
; Calls: NONE
;
; Function: Update type offsets
;_______________________________________________________________________________
UTOffsets
ADD.W D0, TOffset(A0) ; Increment by D0
UTInLoop
ADDQ.W #TSize, A0 ; bump address
DBRA D5, UTOffsets ; Update each name offset
RTS
;_______________________________________________________________________________
;
; Routine: PROCEDURE RmveResource(theResource: Handle);
; RmveCmn (utility)
;
; Arguments: 8(A6) (input.L) handle to the resource
; (A0) (input.L) handle to the resource
;
; Called By: (RmveResource): A-trap through dispatcher
; (RmveCmn): RmveResource (by falling through)
; Calls: (RmveResource): StdEntry, HandleScan, RmveExit
; (RmveCmn): RmveName, TypeScan, TypeScanALl, ShiftBlock, UTOffsets,
; MoveNames, StdFourExit
;
; Function: Remove a resource from the map, and from the data section of the
; resource file when UpdateResFile/CloseResFile is called. May
; only be removed if it is in current map and is not protected.
;_______________________________________________________________________________
RmveResource
BSR Std1Entry ; Link A6, save regs <22apr85> BBM
bsr FlushResourceCache ; preserves a0
MOVE.L (A0), A1 ; Get the handle in A1
BSR HandleScan ; Find the handle, wherever it is.
BMI RmveErr ; Can't find it, so can't remove it. <SM51> CSS
bsr FlushChangedFONDs ; flush 'FOND' candidate list if this is a FOND <sm 5> stb
BTST #ResProtected, RAttr(A2); Is it protected?
BNE RmveErr ; Yes, return immediately <SM51> CSS
; RmveResource is documented to only allow you to remove a resource
; when it's homeresfile is in CurMap. With overrides we want to modify
; this behavior slightly to allow RmveResource calls from CurMap
; and any files that are overridden by CurMap.
CMP.W CurMap, D6 ; Is it in the current map?
BEQ.S RmveIt ; If so, go ahead and remove itÉ
subq #4,sp
move.l a4,-(sp)
_GetOverrideMap ; Get the override map for the map we found the resource in.
MOVEA.L (sp)+,A3 ; Hold the override map in a3 the link we're looking for
move.w CurMap,d1 ; Get CurMap
move.l (a3),a3 ; Get Override map ptr in a3
cmp.w mRefNum(a3),d1 ; were we removing from an overridden file?
beq.s RmveIt
; It wasn't an overridden file so we should check for "two deep bit" and other
; system files if the current map is the override of the system map.
; <SM51> CSS changed to look at the override map to the system not SysMap!
subq #4,sp
move.l SysMapHndl,-(sp)
_GetOverrideMap ; Get the override map for the system
movea.l (sp)+,a3 ; hold the override map in a3 of the system
move.w CurMap,d1 ; Get CurMap
move.l (a3),a3 ; get override ptr in a3
cmp.w mRefNum(a3),d1 ; is the system override map the curmap?
bne RmveErr ; no - bail out
subq #2,sp
move.l a4,-(sp)
_IsThisASystemResourceMap ; See if this map is a font file or other two deep bit fileÉ
tst.b (sp)+
beq.s RmveErr ; error outÉ <SM51> CSS
RmveIt
MOVEA.L A1,A0 ; Mark it no longer a rsrc <C169>
_HClrRBit ; <C169>
MOVEQ #MCCMask, D0 ; MapChanged+MapCompact to be set in RmveCMn
BSR UpdateOverriddenChangedBits ; set the changed bit for any files that may be overridden by the map in A4
; Common code for remove reference/remove resource.
; A2 points to the resource entry.
RmveCmn
CLR.L HSCHandle ; invalidate cache always <18jul85> BBM
MOVE.L (A4), A0 ;
OR.B D0, MAttr(A0) ; Set mapChanged and possibly mapCompact.
BSR RmveName ; Remove RNameOff(A2)'s name, if any.
MOVEQ #-RESize, D7 ; Get -(resource entry size)
MOVE.L A2, A0 ; Remember address of
SUB D7, A0 ; NEXT entry, in A0.
BSR TypeScan ; Scan for type of referent (D3) in cur map
MOVE.L (A4), A1 ; Dereference map handle
ADDA.W MNames(A1), A1 ; A1 points to the name block
MOVE.L D7, D0 ; Copy (-RESize) in D0
BSR ShiftBlock ; Shift the block down
MOVE.L A2, A0 ; Copy type entry address to A0
ADDQ #TSize, A0 ; Skip to next type entry
SUBQ #1, D5 ; Decrement number of types
BMI.S @1 ; If this is last type, go on, else
BSR.S UTOffsets ; update following type offsets.
@1 SUBQ.W #1, TCount(A2) ; decrement resource count for this type
BPL.S @9 ; If still more resources of this type, quit
; If this was the last resource of the type, remove the type entry.
ADDQ #TSize, A2 ; Skip to next type entry
MOVE.L A2, A0 ; Moving next type over current, to delete.
ADD D0, A1 ; move down name address by resource entry size
MOVEQ #-TSize, D0 ; Shift this block down by type entry size
ADD.L D0, D7 ; Decrement down TSize more, for names.
BSR ShiftBlock
MOVE.L (A4), A0 ; Dereference map handle
ADDA.W MTypes(A0), A0 ; A2 points to the type block
SUBQ #1, (A0) ; Decrement number of types
MOVE.W (A0)+, D5 ; Get number of types in D5
BMI.S @9 ; No types left! just return
BSR UTOffsets ; Update all type offsets by TSize.
@9 MOVE.L D7, D0 ; Get accumulated shuffle in D0.
BSR.S MoveNames ; Move names down 12 or 20
CMP.W #1,D6 ; IS THIS THE ROM MAP?? <04nov85> BBM
BEQ.S @5 ; CC=EQ means ROM map (don't do SetEOF) <04nov85> BBM
BSR SetRFEOF ; set new EOF <26aug85> BBM
@5 CLR.W ResErr ; Remove succeeded! <04nov85> BBM
RmveExit
CLR.L HSCHandle ; Invalidate cache <12mar85> BBM
BRA StdFourExit
;<SM51> CSS added RmveErr label so that we don't have to keep loading ResErr
RmveErr
MOVE.W #RmvResFailed,ResErr ; indicate error doing remove
BRA.S RmveExit ; and exit
;_______________________________________________________________________________
;
; Routine: AddName (utility)
;
; Arguments: A0 (input.L) pointer to a name
; A2 (input.L) pointer to a resource entry
;
; Called By: SetResInfo, AddResource
; Calls: ResizeMap, CopyStr
;
; Function: Sets RNameOff(A2) to a name offset, and copies the name to the
; map block.
;_______________________________________________________________________________
AddName
CLR.L HSCHandle ; invalidate cache always <18jul85> BBM
MOVEM.L D0-D2/A0-A1, -(SP) ; save regs used (returning D2), and
MOVEQ #-1, D2 ; Assume no string
MOVE.L A0,D0 ; is the ptr nil? <13> stb
BEQ.S @9 ; if so, return -1 for RNameOff
TST.B (A0) ; is it empty?
BEQ.S @9 ; if so, return -1 for RNameOff.
MOVE.L (A4), A1 ; Dereference map handle
MOVE.L MapSize(A1), D1 ; Copy current map size to D1.
MOVE.L D1, D2 ; and to D2.
MOVEQ #0, D0 ; Zero D0
MOVE.B (A0), D0 ; Get string length
ADDQ.L #1, D0 ; Add 1 for len byte
BSR.S ResizeMap ; Grow the map by string size.
MOVEQ #0,D0 ; use all of D0 <06may85> BBM
MOVE.L (A4), A1 ; Get map ptr again
MOVE.W MNames(A1), D0 ; D0=offset to name block
SUB.L D0, D2 ; mapSize-nameBlkoff := off to newname <06may85> BBM
ADD.L D1, A1 ; Add endOfMap to get end address in A1
BSR CopyStr ; Copy the string in!
@9 MOVE.W D2, RNameOff(A2) ; Set name offset in the entry
MOVEM.L (SP)+, D0-D2/A0-A1 ; Restore regs
RTS ; and exit.
;_______________________________________________________________________________
;
; Routine: MoveNames (utility)
;
; Arguments: D0 (input.L) byte count
; A2 (input.L) pointer to map (see note below)
; A3 (input.L) pointer into map (see note below)
; A4 (input.L) handle to the map
;
; Called By: AddNewRef, RmveCmn
; Calls: ResizeMap, ShiftBlock
;
; Function: Moves the names up or down by the amount specified in D0.
; Resizes map each time.
;
; note: Adjusts A3, A2 to compensate for any block moving.
;_______________________________________________________________________________
MoveNames
MOVEM.L D0-D1/D7/A0-A1, -(SP) ; Save regs
MOVE.L (A4), A0
MOVE.L MapSize(A0), D1 ; Save original map size in D1
TST.L D0 ; Are we shrinking or growing?
BMI.S @1 ; if Shrinking, resize after move
BSR.S ResizeMap ; Otherwise grow first
MOVE.L (A4), A0 ; Dereference handle (may have moved)
@1
MOVE.L A0,A1 ; Copy address
MOVEQ #0,D7 ; Get MNames(A0) into D7 with high word = 0 <06may85> BBM
MOVE.W MNames(A0),D7 ; get offset to names
ADDA.L D7,A0 ; and add offset to pointer.
ADD.W D0,MNames(A1) ; (Update name block offset now)
ADD.L D1,A1 ; Point A1 to original end of map
BSR.S ShiftBlock ; Shift (A0..A1) up or down by D0
TST.L D0 ; Did we shrink or grow?
BPL.S @9 ; Grew, map already resized, otherwise
BSR.S ResizeMap ; Shrink it now
@9 MOVEM.L (SP)+, D0-D1/D7/A0-A1 ; Restore regs
RTS ; ...and return
;_______________________________________________________________________________
;
; Routine: ResizeMap (utility)
;
; Arguments: D0 (input.L) delta byte count
; A2 (input.L) pointer to map (see note below)
; A3 (input.L) pointer into map (see note below)
; A4 (input.L) handle to the map
;
;
; Called By: MoveNames, AddName, RmveName
; Calls: _SetHandleSize, SetRFEOF
;
; Function: Given a byte count in D0, grows or shrinks the map. The map may
; move when growing, though not when shrinking. Calls SetRFEOF to
; set resource file EOF (reserving space).
;
; note: Adjusts A3, A2 to compensate for any block moving.
;_______________________________________________________________________________
ResizeMap
BSR SaveRegs ; Saves A1/A0/D1/D0 and makes A2/A3 offsets <22aug85> BBM
MOVE.L (A4), A0 ; Dereference handle
ADD.L MapSize(A0), D0 ; Add delta to current size for new size_
MOVE.L D0, MapSize(A0) ; Set new mapSize.
MOVE.L A4, A0 ; Get handle in A0
_SetHandleSize ; Set the new size (error handled in CheckGrow)
BRA RestRegs ; Set EOF and exit through SetEOF2 <26aug85> BBM
;_______________________________________________________________________________
;
; Routine: ShiftBlock (utility)
;
; Arguments: D0 (input.L) delta byte count
; A0 (input.L) low pointer to block to move
; A1 (input.L) high pointer to block to move
;
; Called By: AddNewRef, RmveCmn, MoveNames, RmveName
; Calls: _BlockMove
;
; Function: Given a delta (in bytes) in D0, shifts the block (A0..A1) up or
; down by D0.
;_______________________________________________________________________________
ShiftBlock
MOVEM.L A0-A1/D0, -(SP) ; Save regs
EXG D0, A1 ; D0=bytes to move, A1=delta
SUB.L A0, D0 ; Subtract low from high to give size
AND.L Lo3Bytes,D0 ; AND off high 8 bits
ADD.L A0, A1 ; Add low to bytes to move, giving dest.
_BlockMove ; Move the bytes
MOVEM.L (SP)+, A0-A1/D0 ; Restore regs
RTS ; ...and return
;_______________________________________________________________________________
;
; Routine: NameUsedByOthers (utility) <11> stb
;
; Arguments: D0 (input.L) offset to name in name list
; A2 (input.L) resource entry of interest
;
; Called By: RmveName
; Calls:
;
; Function: Given an offset to a name in the namelist, return non-zero if
; any resource other than the resource of interest uses the same name
; offset. While this shouldnÕt ever be the case, such files do exist,
; and weÕll make them work.
;_______________________________________________________________________________
NameUsedByOthers
MOVEM.L D3-D5/A2-A3,-(SP) ; Save rest of registers.
; MOVE.L A2,A3 ; A3 is now the resource of interest <LW15>
MOVE.L A2,-(SP) ; Save A2 <LW15>
BSR GetRsrcCnt ; Check all entries and update name offsets.
; A2 now points to the first rsrc entry
; D4 has the number of entries
MOVE.L (SP)+,A3 ; A3 is now the resource of interest <LW15>
@loop
CMP.L A2,A3 ; current resource vs. resource of interest
BEQ.S @NextEntry ; skip this one, we already know it uses the name
CMP.W RNameOff(A2),D0 ; is this name offset = the one of interest?
BEQ.S @NameInUse ; yes? return non-zero
@NextEntry
ADD.W #RESize,A2 ; point to the next entry
DBRA D4,@loop ; if there are more entries loop back
MOVEQ #0,D0 ; zero indicates not in use
BRA.S @done
@NameInUse
MOVEQ #1,D0 ; non-zero indicates in-use
@done
MOVEM.L (SP)+,D3-D5/A2-A3 ; Restore inner regs.
RTS ; ...and return
;_______________________________________________________________________________
;
; Routine: RmveName (utility)
;
; Arguments: A2 (input.L) pointer to resource entry
; A3 (input.L) pointer into map
; A4 (input.L) handle to map
;
; Called By: SetResInfo, RmveCmn
; Calls: ShiftBlock, ResizeMap, GetEntries
;
; Function: Given A2 pointing to a resource entry, removes the name pointed
; to by RNameOff(A2). Removing reference names requires that A2
; point to RefID instead of RID.
;_______________________________________________________________________________
RmveName
MOVEM.L D0-D2/A0-A1,-(SP) ; Save working regs
MOVE.W RNameOff(A2),D2 ; Copy name offset to D2.
BMI.S @9 ; if not a real offset, just exit.
MOVE.L D2,D0 ; offset into namelist <11> stb
BSR.S NameUsedByOthers ; Is anyone else is using this instance of the name? <11>
BNE.S @9 ; ItÕs in use. DonÕt remove the name <11>
MOVE.L (A4),A0 ; Dereference map handle
MOVE.L A0,A1 ; Copy ptr to A1
MOVEQ #0,D0 ; Get name offset (upto 64k) <06may85> BBM
MOVE.W MNames(A0),D0 ; ... and stuff into low word
ADD.L D0,A0 ; A0 points to the name block
ADD.W D2,A0 ; and finally the string itself.
ADDA.L MapSize(A1),A1 ; A1 points to the end of the map.
MOVEQ #0, D0 ; Zero high order
MOVE.B (A0), D0 ; Get length byte
ADDQ.L #1, D0 ; Add 1 to include the length byte
ADD.L D0, A0 ; point A0 to the NEXT string
NEG.L D0 ; Negate, since shrinking
MOVE.L D0, D1 ; Copy delta to D1 for updating offsets.
BSR.S ShiftBlock ; Shift the block (A0..A1) down strSize.
BSR.S ResizeMap ; and shrink the map. A2-A3 corrected.
MOVEM.L D3-D5/A2-A3,-(SP) ; Save rest of registers. <24aug85> BBM
BSR GetRsrcCnt ; Check all entries and update name offsets. <24aug85> BBM
@1 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-D5/A2-A3 ; Restore inner regs. <24aug85> BBM
@9 MOVEM.L (SP)+, D0-D2/A0-A1 ; Restore outer regs
MOVE.W MinusOne, RNameOff(A2) ; Set name offset to -1.
RTS ; and return.
;_______________________________________________________________________________
;
; Routine: FUNCTION SizeResource(theResource: Handle): LONGINT;
;
; Arguments: 8(A6) (input.L) resource handle
; A0 (input.L) resource handle
; 12(A6) (output.L) resource size
;
; Called By: A-trap through dispatcher
; Calls: StdResEntry, _GetHandleSize, SizeRsrc, StdFourExit
;
; Function: Return the size of the resource pointed at by <theResource>. If
; no resource was found for <theResource>, return (-1).
; note:
; <22Jan85> BBM This was first includeded in the Ram System in 1984. It was not
; put in ROM 7.0. This routine will return the size of a resource.
;_______________________________________________________________________________
SizeResource
BSR Std2ResEntry ; Link A6, save regs <21aug85> BBM
TST.L (A1) ; has it been purged?
BEQ.S @0 ; if so, read size from file
MOVE.L A1,A0 ; Resource is already in memory.
_GetHandleSize ; (handle to resource is in A0)
BRA.S SizeRExit ; EXIT
@0 MOVE.B RAttr(A2),-(SP) ; Rsrc not in memory, save state of ...
BSR SizeRsrcDecomp ; attributes. Figure out the size on disk after decompression. <sm21>kc
MOVE.B (SP)+,RAttr(A2) ; restore attributes state.
SizeRExit ; added common exit for MaxsizeRsrc <21aug85> BBM
MOVE.L D0,12(A6) ; Return the result and ...
BRA StdFourExit ; Pop 4 bytes and standard exit
;_______________________________________________________________________________
;
; Routine: FUNCTION MaxSizeRsrc(theResource: Handle): LONGINT;
;
; Arguments: 8(A6) (input.L) resource handle
; A0 (input.L) resource handle
; 12(A6) (output.L) resource size
;
; Called By: A-trap through dispatcher
; Calls: StdResEntry, SpaceAt, _GetHandleSize, SizeRExit
;
; Function: Return the maximum size of the given resource. Note
; no resource was found for <theResource>, return (-1).
;_______________________________________________________________________________
MaxSizeRsrc ; <02may85> BBM
BSR Std2ResEntry ; Link A6, save regs <21aug85> BBM
TST.L (A1) ; has it been purged?
BNE.S @0 ; if CC=EQ, read size from Map
BSR SpaceAt ; Get the Size available <13aug85> BBM
BRA.S @9 ; EXIT
@0 MOVE.L A1,A0 ; Resource is already in memory.
_GetHandleSize ; (handle to resource is in A0)
@9 BRA.S SizeRExit ; write out result and exit <21aug85> BBM
;_______________________________________________________________________________
;
; Routine: FUNCTION RsrcMapEntry(theResource: Handle): LONGINT;
;
; Arguments: 8(A6) (input.L) resource handle
; A0 (input.L) resource handle
; 12(A6) (output.L) resource entry offset
;
; Called By: A-trap through dispatcher
; Calls: StdResEntry, SizeRExit
;
; Function: Return the offset in the map to the resource entry.
;_______________________________________________________________________________
RsrcMapEntry ; <21aug85> BBM
BSR Std2ResEntry ; Link A6, save regs
MOVE.L A2,D0 ; Get pointer to rsrc entry
SUB.L (A4),D0 ; sub pointer to beginning of map
_StripAddress ; get rid of any masterpointer bits <c396>
@9 BRA.S SizeRExit ; write out result and exit <21aug85> BBM
;_______________________________________________________________________________
;
; Routine: FUNCTION rGetResource(theType: ResType; theID: INTEGER): Handle; <C628>
;
; Arguments: 10(A6) (input.L) resource type
; 8(A6),A0(input.W) resource ID
; 14(A6) (output.L) resource handle
;
; Called By: A-trap through dispatcher
; Calls: GetResource
;
; Function: do a normal GetResource without the rom map; if that fails,
; do GetResource with the rom map inserted.
;
; NOTE: _GetResource expects a specific items on the stack when called.
; This routine depends heavily on that stack. Below is a picture
; of the stack just before the _GetResource trap is executed
; (starting in the middle of the stack and ending at the top of stack,
; or starting in high memory and decending down in memory).
;
; handle 4 bytes
; type 4 bytes (E bytes back on stack after < subq #4,sp >)
; ID 2 bytes (C bytes back on stack after < subq #4,sp >)
; rtn addr 4 bytes (8 bytes back on stack after < subq #4,sp >)
; rtn addr 4 bytes (4 bytes back on stack after < subq #4,sp >)
; handle 4 bytes (0 bytes back on stack after < subq #4,sp >)
; type 4 bytes
; ID 2 bytes
;_______________________________________________________________________________
;¥¥¥ Do not roll in patch from system file into this routine <PN> ¥¥¥
grStFr equ $0E ; size of the stack frame. (see note above)
rGetResource
clr.b ROMMapInsert ; make sure we donÕt use rom map
bsr.s @getrsrc ;
bne.s @exit ; if handle is not zero, then we donÕt check rom
st.b ROMMapInsert ; else make sure we use rom map
bsr.s @getrsrc ;
@exit ; std exit to strip the stack
move.l (sp)+,a0 ; strip off the return address into a0 <C669>
addq #6,sp ; strip off type and ID
jmp (a0) ; and return through a0
@getrsrc ; go do GetResource
move.b resload,ROMMapInsert+1 ; set temp value of resload to current resload
subq #4,sp ; save room for another handle (see note above)
move.l grStFr(sp),-(sp) ; push type again
move.w grStFr+2(sp),-(sp) ; push ID again
_GetResource ;
move.l (sp)+,grStFr(sp) ; push the handle we got back into the area
; the user saved for the handle and set ccÕs
rts ;
;=== HereÕs some new stuff as of 3/11/92 ================================================
;_______________________________________________________________________________
; 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
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É
@overridingNotOn
move.l ExpandMemRec.emResourceCache(a0),d0 ; Get cached resource from expanded low mem
beq.s @setupCache ; Cache doesnÕ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Õ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Õ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.
;
; Get current map to start walking the resource chainÉ
@buildCache
movem.l a2-a4/d1-d2/d6,-(sp) ; save registers trashed by GetCurMap
BSR GetTopMap ; get the current maphndl in a4
move.l a4,d0 ; keep it in d0
movem.l (sp)+,a2-a4/d1-d2/d6 ; save registers trashed by GetCurMap
moveq #0,d5 ; Count of entries placed in the cache so far
@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 @cacheNextMap ; If no resources in this map, go on to next map <SM25> CSS
;
; 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 @cacheNextMap ; If we fall through, no resources of this type in this map <SM25> CSS
;
; 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Õ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Õs still space left in the cache, add the entry
;
; Out of space in the cache. Double itÕ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Õ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Õ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
TST.B ResOneDeep ; if one deep set, don't get next map <26jun85> BBM
BEQ.S @notOneDeepMap ; ... else do normal stuff
tst.w ResourceMgrStack.doOverrides(a6) ; <41> Is overriding on?
beq.s @endOfChain ; <41> No. don't check the 2 deep bit.
; The requested resource wasnÕt found in the map in A4. Check if the twoDeepBit is set on this
; map, and if it is, search the next map down.
move.l (a4),a1 ; Try the next map, but only if this map has twoDeep set.
btst #twoDeepBit,mInMemoryAttr(a1) ; Is the twoDeepBit set?
beq.s @endOfChain ; ... yes ignore oneDeep, so don't zero handle
@notOneDeepMap
move.l (a4),a1
move.l mNext(a1),d0 ; Go until the end of the resource chain
bne.s @buildLoop
@endOfChain
move.l (a3),a0
move.l d5,kResourceCount(a0) ; Stash the count
@exitCacheResource
movem.l (sp)+,d2-d7/a1-a4 ; Restore registers
rts ; Return
;_______________________________________________________________________________
; 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
moveq #1,d0 ; Assume itÕ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Õ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Õ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Õ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
;_______________________________________________________________________________
; <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
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Õve got an override case
; OK, I lied in all the comments up to now. Testing just the overrideNextMap bit isnÕ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Õs not, and we should stop looking now, too.
move.l mNext(a1),d0 ; ItÕ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Õt use it hereÉ
add.w #paramSize,sp ; Pop off the parameters
move.l d0,-(sp)
rts
;_______________________________________________________________________________
;
; Routine: CheckAndFlushFontCache (utility)
;
; Arguments: A4 (input.L) map handle
;
; Called By: OpenResFile, HOpenResFile, OpenRFPerm, CloseResFile
;
; Calls: TypeScan
;
; Function: If the map in A4 has a 'FONT' or 'FOND' resource we invalidate
; the font caches.
;_______________________________________________________________________________
CheckAndFlushFontCache
movem.l a0-a4/d0-d5,-(sp)
move.l #'FONT',d3
bsr TypeScan
bpl.s @doFlush
move.l #'FOND',d3
bsr TypeScan
bmi.s @dontFlush
@doFlush
MOVE.L MinusOne,LastSPExtra ; invalidate font cache
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)
clr.l LastFOND ; nuke this handle, just in case it was one of the FONDs in this file <52>
@dontFlush
bsr FlushResourceCache
movem.l (sp)+,a0-a4/d0-d5
rts
;_______________________________________________________________________________
;
; Routine: FlushChangedFONDs
;
; Arguments: a2 - Handle Entry for the resource we are checking
;
; Called By: ChangedResource, AddResource, RmveResource
; Calls: _DisposeHandle
;
; Function: invalidate the 'FOND' candidate list if a 'FOND' resource in the
; candidate cache is being changed
;
; Trashes: nothing
;
; Written by: Dean Yu; rolled in by Scott Boyd and Fred Monroe
;_______________________________________________________________________________
FlushChangedFONDs
movem.l a0-a1/d0-d1,-(sp)
cmp.l #'FOND',TType(a2) ; Check are we messing w/ a 'FOND' Resource
bne.s @notFONDResource ; ItÕs not a FOND
;
; ItÕs 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),a1 ; Get Candidate in A1
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 4(a0),a1 ; 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 4(a0)
@notFONDResource
movem.l (sp)+,a0-a1/d0-d1
rts
;
; Compare the ID of the cached FOND information. If the ID matches the resource that changed,
; invalidate the candidate entry.
;
; Arguments A2 (input.L) resource handle
; A1 (input.L) Candidate to check (possibly nil handle)
; d1 (output.L) result (Z if disposed)
;
; Trashes: d0-d1, A1
;
CheckCandidate
moveq #-1,d1 ; Assume handle is not disposed
move.l a1,d0 ; Get the handle
bz.s @notSameFamily ; Bail out if handle is NIL
move.l (a1),d0 ; Get the pointer
bz.s @notSameFamily ; 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 RID(a2),d0 ; Compare it against the resource ID of the changed 'FOND'
bne.s @notSameFamily ; DonÕt invalidate if not the right ID
_DisposeHandle ; If ID matches, dispose the handle
moveq #0,d1 ; Mark as handle was disposed
@notSameFamily
rts
;_______________________________________________________________________________
;
; Routine: UpdateOverriddenChangedBits (utility)
;
; Arguments: A4 (input.L) map handle
;
; Called By: Anywhere a mapChanged bit is setÉ
;
; Calls:
;
; Function: If the map in A4 overrides another file than we set the changed bit
; in that overridden file.
;_______________________________________________________________________________
UpdateOverriddenChangedBits
movem.l a0-a2/a4/d0-d1,-(sp)
move.l (a4),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Õ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 a4,-(sp)
bsr FindOverriddenMap ; trashes a0-a1/d0
move.l (sp)+,a4 ; Save the handle to the overriden map
bra.s @setMapChangedOnOverrideMap ; Go set the bit
@notAnOverrideMap
subq #2,sp
move.l a4,-(sp)
_IsThisASystemResourceMap ; See if this is a font file
tst.b (sp)+ ; Well is it?
bz.s @exit ; If itÕs not, then we donÕt know why this map has override bits on it. Just call AddResource, and donÕ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)+,a0-a2/a4/d0-d1
rts
;_______________________________________________________________________________
; 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.
;
; trashes a0-a1/d0
FindOverriddenMap
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Õt set, then weÕ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Õ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
; <SM11> CSS Add the following routine for rsrczoneinit patch
;_______________________________________________________________________________
; 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.
;
; should preserve a0É
FlushResourceCache
movem.l d0/a0,-(sp)
move.l ExpandMem,a0
clr.w ExpandMemRec.emLastMapOverridden(a0) ; And force an override synchronization next time <SM51> CSS
move.l ExpandMemRec.emResourceCache(a0),d0 ; Get resource cache handle
beq.s @noExpandMem ; DoesnÕt exist
clr.l ExpandMemRec.emResourceCache(a0) ; Zero it out
move.l d0,a0
_DisposeHandle ; Get rid of the cache
@noExpandMem
movem.l (sp)+,d0/a0
rts
EndProc
END
;=== End Of File ========================================================================