mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-27 10:29:32 +00:00
7653 lines
322 KiB
Plaintext
7653 lines
322 KiB
Plaintext
;
|
||
; 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 ========================================================================
|
||
|
||
|