mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-09-08 01:54:55 +00:00
4325cdcc78
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
7629 lines
322 KiB
Plaintext
7629 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.B MMFlags,-(SP) ; save the memory Manager flag
|
||
BSET.B #MMStartMode,MMFlags; set for 32 bit system heap
|
||
|
||
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
|
||
|
||
MOVE.B (SP)+,MMFlags ; restore memory manager flag
|
||
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 (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
|
||
MOVE.L #ROVR,-(SP) ; rsrc type for override
|
||
MOVE.W #0,-(SP) ; rsrc ID of 0
|
||
_GetResource ; get the override rsrc
|
||
MOVE.L (SP)+,D0 ; Check to see if it exists
|
||
BEQ.S ROvrOut ; if handle is zero then just return
|
||
MOVE.L D0,A0 ; get ready to execute this resource
|
||
MOVE.L (A0),A0 ; dereference handle
|
||
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
|
||
_BlockMove ; 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
|
||
_BlockMove ; 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 #kAllButOverrideAttributesMask,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 #mapForceSysHeap,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
|
||
BPL.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
|
||
_BlockMove ; 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 ========================================================================
|
||
|
||
|