mirror of
https://github.com/elliotnunn/sys7.1-doc-wip.git
synced 2025-01-29 14:29:45 +00:00
3854 lines
155 KiB
Plaintext
3854 lines
155 KiB
Plaintext
;__________________________________________________________________________________________________
|
||
;
|
||
; File: MemoryMgr.a
|
||
;
|
||
; Contains: Client interface routines for 32-Bit Macintosh Memory Manager
|
||
;
|
||
; Supports multiple heap zones with mixed relocatable and non-relocatable storage blocks.
|
||
; Reorganized from code designed and written by Bud Tribble, 27-Nov-81, and maintained
|
||
; and modified by Angeline Lo, Larry Kenyon, and Andy Hertzfeld.
|
||
;
|
||
; Written by: Bud Tribble
|
||
;
|
||
; Copyright © 1981-1993 by Apple Computer, Inc. All rights reserved.
|
||
;
|
||
; Change History (most recent first):
|
||
;
|
||
; <SM32> 10/12/93 SAM Roll in <MC2> from mc900ftjesus.
|
||
; <MC2> 10/12/93 SAM Updated InitMemMgr to be in sync with the figment version. From
|
||
; now on we should always build with Figment and choose which
|
||
; memmgr we want at a per launch basis.
|
||
; <SM31> 5/20/93 BT Update sources to conditionally compile Figment under the build
|
||
; flag "hasNewHeapMgr".
|
||
; <SM30> 5/18/93 BT Change names of InitMemMgr, InitMemVect, and
|
||
; SetApplBaseAfterBoot to "old_≈". Changed some BSR's to BSR.L's.
|
||
; All in the name of Figment, our beloved Walt Disney friend.
|
||
; <SM29> 4/23/93 kc Roll in MoveHHi, NewPtr and RealocHandle patches from
|
||
; MemoryMgrPatches.a. Integrate some of the other patches to save
|
||
; a few cycles.
|
||
; <SM28> 4/22/93 rab Removed code from FlushFontCaches that skipped the routine if
|
||
; CurApName wasn't valid. This fixes Radar# 1077877 and 1078314.
|
||
; <SM27> 4/12/93 chp Rewrote MoveHHi head patch using half the number of
|
||
; instructions.
|
||
; <SM26> 3/9/93 rab Bumped StkSlop in MoveHHi from 1024 to 3072 per Jim Reekes
|
||
; suggestion in bug #1067917.
|
||
; <SM25> 2/22/93 PN Quad-word align the stackbuffer in MoveHHi call for 040
|
||
; machines.
|
||
; <SM24> 1/27/93 kc Fix bug in MaxAppleZone where we were rounding down the address
|
||
; of the HeapZone to the nearest quadword but not the address we
|
||
; were asking for. Fixes bug 1061295.
|
||
; <SM23> 1/5/93 PN In the SuperMario ROM, many resources are put in ROM that used
|
||
; to be in the system disk. DisposeHandle is modified to leave the
|
||
; handle alone if it is passed a handle to a table or resource in
|
||
; ROM.
|
||
; <SM22> 12/4/92 RB Rolled in changes to support NuKernel from Wayne Meretski and
|
||
; Russell Williams. Make RHBusErrHandler compatible with NuKernel.
|
||
; <SM21> 12/4/92 SWC Moved InitMemMgr here from StartInit.a.
|
||
; <SM20> 12/3/92 PN Back out previous change. This is the patch
|
||
; BracketSetAppBaseWithInitApplZones
|
||
; It will patch out the SetApplBase at Gibbly time when
|
||
; InstallMgr get called. The time when this patch applied is
|
||
; crucial (during boot time up to gibbly time this patch is NOT to
|
||
; be used, it is used after gibbly time)
|
||
; <SM19> 11/19/92 PN Radar #1050264 the SetAppBase was calling bsr IAZ instead of
|
||
; _InitApplZone so a lot of clean up code was missing and lead to
|
||
; the bug. So I bracket the routine SetApplBase with the whole
|
||
; _InitApplZone. This is the patch
|
||
; BracketSetAppBasewithInitApplZone.
|
||
; <SM18> 11/3/92 RB Do not force 32 bit mode for the LC930 by checking the feature
|
||
; conditional Supports24Bit.
|
||
; <SM17> 10/26/92 CSS Fix some short branches and remove cache flushing from
|
||
; HLock. Also, added Supports24Bit conditional to conditionalize
|
||
; _StripAddress.
|
||
; <SM16> 9/16/92 CSS Fix bsr to IOPram to use bsr.l.
|
||
; <SM15> 7/28/92 PN Put CacheFlush back in HLock for compatibilty's sake
|
||
; <SM14> 7/28/92 PN Bug fix. NewPtr call that grows the system heap will crash into
|
||
; Macsbug. The setting of semaphore flag was done incorrectly in
|
||
; ResrvMem and consequently caused the problem. It is fixed. Also,
|
||
; I take out the 040 cache flush in HLock to improve performance.
|
||
; <SM13> 7/16/92 PN Take out cpu ≥ 020 conditionals
|
||
; <SM12> 6/11/92 PN Roll in FixStripAddress from PatchIIciROM.a
|
||
; <SM11> 5/22/92 kc Append "Trap" to the names of
|
||
; CompactMem,GetPtrSize,HandleZone,InitZone,MaxBlock,NewEmptyHandl
|
||
; e,PtrZone,PurgeSpace,ReAllocHandle,RecoverHandle,SetHandleSize,S
|
||
; etPtrSize and StackSpace to avoid name conflict with the glue.
|
||
; <SM10> 5/7/92 stb Added purge proc in InitZone for the TrueType disk cache (from
|
||
; DiskCachePatches.a). Moved some "other mgr" cleanup code around
|
||
; so it’s all grouped nicely.
|
||
; <SM9> 4/22/92 TN Clean up BracketSetAppBaseWithInitApplZones, roll in
|
||
; AllowNILDisposePtr, ResrvMemGrowSystemHeap,
|
||
; NewPtrGrowSystemHeapCleanly MoveHHiPatch from MemoryMgrPatches.a
|
||
; <SM8> 4/16/92 PN Roll in SetAppBaseCacheCleaner and InitAppZoneCacheCleaner from
|
||
; BassPatches.a to remove any app memory allocated by Bass
|
||
; whenever the application heap is reformatted.
|
||
; <SM7> 3/26/92 kc Force 32-bit mode. (see <SM3> in MMU.a)
|
||
; •••• This should be backed out as soon as we carve out space for
|
||
; the 2 Meg rom from the slot address space. ••••;
|
||
; <SM6> 3/24/92 PN Roll in BracketSetAppBaseWithInitApplZones into _SetappBase By
|
||
; calling bsr IAZ three times.
|
||
; <SM5> 3/10/92 PN Back out the last change
|
||
; <SM4> 3/9/92 kc Don't call jSoundDead untill we install the SoundMgr.
|
||
; <SM3> 3/4/92 kc Add a semicolon.
|
||
; <SM2> 3/4/92 kc Roll in vxxHlockPatch, vxxMaxMemPatch, v??CMGutsPatch
|
||
; InitxxZoneAlign, vxxMaxApplPatch, InitxxZoneAlign,
|
||
; AlignxxTrailer and SetApplBasePatch from Terror. Add patch to
|
||
; HLock that flushes cache on 040's.
|
||
; <T8> 7/10/91 RP Patched MaxApplZone for line alignment.
|
||
; <T7> 7/7/91 RP Patched MaxMem, CompactMem and MaxBlock to line-align free space
|
||
; values on 040s.
|
||
; <T6> 6/25/91 RP Patched to line align all blocks on 040 CPUs
|
||
; <T5> 5/29/91 CCH Backed out revision 4.
|
||
; <T4> 5/29/91 WM Changed MOVE to SR into ANDI to SR
|
||
; <T3> 4/21/91 CCH Removed HSetState patch since it was not used and is not needed.
|
||
; <T2> 4/2/91 CCH Patched HLock and HSetState to flush the cache.
|
||
; <1> 10/2/91 JSM first checked in
|
||
; <0> 10/1/91 JSM Created from Heap32.a.
|
||
;
|
||
; Modification history from Heap32.a below:
|
||
;
|
||
; <15> 9/27/91 JSM Don’t use hasCQD conditional, all future ROMs will have color
|
||
; QuickDraw.
|
||
; <14> 9/16/91 JSM Cleanup header.
|
||
; <13> 6/12/91 LN removed #include 'HardwareEqu.a'
|
||
; <12> 12/19/90 DFH Removed StackSpace and MoveHHi jamming of HiHeapMark when
|
||
; HiHeapMark >= ApplLimit (from change <4>). This was really just
|
||
; a workaround for an app bug (SuperCard 1.00 on a portable), but
|
||
; that app has been fixed. Furthermore, the jamming interferes
|
||
; with parts of the system that want to use stacks other than the
|
||
; current application stack.
|
||
; <11> 7/30/90 BG Removed CPU = 040 conditional in preparation to move from Mac040
|
||
; to Mac32 build.
|
||
; <10> 7/17/90 dba change names of GetHandleSize and StripAddress so they don’t
|
||
; conflict with glue
|
||
; <9> 3/22/90 MSH New PRAM routines in clock.a require a small change to the
|
||
; caller.
|
||
; <8> 3/8/90 JAL Removed include of QuickEqu.a because it was colliding with StandardEqu.d
|
||
; <7> 1/25/90 BG Removed AERRORs from RecoverHandle and RHBusErrHandler. Added
|
||
; RH040BusErrHandler, and modified RecoverHandle to use the 040
|
||
; bus error handler when necessary.
|
||
; <6> 1/18/90 DVB Include PalettePriv.a
|
||
; <5> 1/11/90 CCH Added include of “HardwarePrivateEqu.a”.
|
||
; <4> 1/11/90 MSH StkSpacePatch - Because some apps jam ApplLimit directly, it is
|
||
; possible for HiHeapMark>ApplLimit which should never be. This
|
||
; fix will jam ApplLimit into HiHeapMark if this is the case.
|
||
; MoveHHIPatch - MoveHHi uses HiHeapMark which may be in error due
|
||
; to the above problem. This patch forces MoveHHi to make the same
|
||
; check as above.
|
||
; <3> 1/3/90 BG Modifying the AERROR statements related to the 040 to use the
|
||
; correct quoting (single quotes, not double quotes).
|
||
; <2> 1/2/90 SWC Modified RecoverHandle to do a last-ditch check to see if a
|
||
; handle points to a ROM resource if the handle isn't in the
|
||
; system or app heap. Also compressed v24RecoverHandle and
|
||
; v32RecoverHandle into essentially one routine since very little
|
||
; is different. They'll enter with a value to mask off either 24
|
||
; or 32 bits of an address.
|
||
; <2.2> 8/27/89 PKE Delete superfluous withs in InitApplZone; remove unnecessary
|
||
; include of 'ScriptPriv.a'. No code changes.
|
||
; <2.1> 8/22/89 SES Removed references to nFiles.
|
||
; <2.0> 7/14/89 CSL initialized sysheapis32bit flag in systemInfo byte.
|
||
; <1.9> 6/15/89 CSL Changed InitMemVect's way to initialize the 24 and 32 bit memory
|
||
; trap vector table. Used value from RealMemTop instead of MaxSize
|
||
; whenever an outlandish request for memory size. Added vectors
|
||
; for MMPrologue, MMPPrologue, MMHPrologue, MMRHPrologue,
|
||
; MMnoPrologue, MMEpilogue, MMNoErrEpilogue. MMnoPrologue is a new
|
||
; routine to handle routine that did not jump throught any
|
||
; Prologue routine.
|
||
; <•1.8> 6/10/89 CEL Moved Private.a QuickDraw Equates into proper QuickDraw private
|
||
; file (colorequ.a), got rid of QuickDraw nFiles dependencies and
|
||
; fixed up necessary files…
|
||
; <1.7> 5/24/89 GGD Converted to feature based conditionals, added checks for 68040
|
||
; in places where changes will most likely be needed and generate
|
||
; assembly errors if assembling for a 68040. No code changes.
|
||
; <1.6> 4/28/89 CSL fixed bug in Reallochandle
|
||
; <1.5> 4/17/89 CSL Fixed the slimy Microsoft bugs in MaxBlock per BBM request.
|
||
; <1.4> 3/30/89 CSL write a safe address in address 0 for nil handle.
|
||
; <1.3> 3/22/89 CSL now Hlock, Hunlock, HPurge, HnoPurge, HRSRC, HnoRsrc, HGetFlags
|
||
; and HSetFlags all jump thu MMHPrologue, also added prevention
|
||
; code for slimy Light Speed C.
|
||
; <1.2> 3/11/89 CSL replaced reference of minfree by minfree24 and minfree32.
|
||
; <1.1> 2/28/89 CSL Added initialization for Jump vectors for MM traps and
|
||
; duplicate routines for 32 bit operations.
|
||
; <1.0> 2/13/89 CCH Adding to EASE for first time from 24-Bit source.
|
||
;
|
||
; <C914> 10/29/87 rwh Port to Modern Victorian (on MvMac)
|
||
; <C897> 9/30/87 MSH Port to HcMac (Laguna) by closing sound like numac
|
||
; 6/10/87 EHB Roll in patch to iazInit to clean up palette manager
|
||
; <PB092> 6/2/87 JTC Roll in patch to MoveHHi to handle teeny leftovers.
|
||
;
|
||
; <C817> 2/14/87 JTC In the spirit of C778, adjust the initialization of ApplLimit
|
||
; and HiHeapMark in IAZ to use simply SP-DefltStack rather than
|
||
; old TomaxLimit value.
|
||
; <C778> 2/10/87 JTC Yet YET YET! another HiHeapMark change. C765 above fails because
|
||
; of the Pascal glue in the world that implements MaxApplZone sans
|
||
; trap; that code will grow the zone without changing HHM, causing
|
||
; many deaths to old apps. So we pin things at ApplLimit, even
|
||
; though that’s pessimistic. Also, add simple bus error handler to
|
||
; RecoverHandle, to jam ROMBase as bogus relative handle.
|
||
; <C765> 2/5/87 JTC Yet another HiHeapMark (HackHeapMark?) to accommodate the
|
||
; nonstandard mem config at boot time. Until now, HHM was set to
|
||
; ApplLimit (just below BufPtr) when the ApplZone was created.
|
||
; This breaks at start time, when the stack is artificially
|
||
; created down at MemTop/2. The change is to tighten HiHeapMark to
|
||
; indicate more accurately where the highest zone end is, as
|
||
; opposed to where it COULD BE. When the ApplZone is created, we
|
||
; set HiHeapMark to HeapEnd; thereafter, InitZone can set it
|
||
; higher if a strange zone is built above HiHeapMark, and the
|
||
; HeapGuts GrowZone can set it if ApplZone is grown beyond
|
||
; HiHeapMark.
|
||
; <C741> 2/2/87 JTC Undo C587 above, since we’re using the more conservative
|
||
; approach of running with the stack mid-zone. Change to HeapGuts
|
||
; only.
|
||
; <C731> 2/1/87 JTC Fix MaxApplZone to jam HiHeapMark, in case it’s out of sync with
|
||
; ApplLimit due to app’s jamming latter without calling SetApplLimit.
|
||
; <C681> 1/24/87 JTC Move init code from Launch to InitApplZone. When 64K ROM patches
|
||
; were rolled into Heap, IAZ (the old InitApplZone) was kept
|
||
; separate from InitApplZone (the patch stuff, which called IAZ to
|
||
; do the real work). The effect was to deprive SetApplBase (who
|
||
; called IAZ) of the good init stuff. Because SetApplBase is
|
||
; called so early, it cannot benefit from the init code. WARNING:
|
||
; after the earliest time, callers of SetAB should also call
|
||
; InitApplZone to guarantee the best initialization. Among the new
|
||
; init things are the VBL and Snd cleanups and a call to
|
||
; _RDrvrInstall, which code is spread between the sound world and
|
||
; SegmentLoader.a.
|
||
; <C636> 1/14/87 JTC Make SetApplLimit sensitive to minimum stack size in DefltStack.
|
||
; Old-style apps like MacDraw and MacPaint jam ApplLimit to within
|
||
; 8K of SP, causing problems in color. Add bus error handlers to
|
||
; xxxPrologue routines DerefHandle and ZoneCheck, to allow bogus
|
||
; address to return with error codes rather than Deep6ing.
|
||
; <C587> 1/3/87 JTC Support boot time sizing of SysZone by making special case of
|
||
; (SP < bkLim(SysZone)) in HeapGuts routine MaxLimit. That routine
|
||
; constrains the (growing) application zone according to SP and a
|
||
; proposed limit; the test against SP is omitted in the case above
|
||
; to permit jamming the stack into a system heap block. The basis
|
||
; of the trick is that HiHeapMark is the stack lower bound; by
|
||
; forcing it to point into the stack block during boot time, stack
|
||
; can be allocated correctly by QD, _StackSpace, etc. while the
|
||
; heap merrily grows. StackSpace is changed to use HiHeapMark, as
|
||
; it should have from Mac+ days.
|
||
; <C415> 12/9/86 JTC Reinstate C251 alignment. Change to HeapGuts.a only.
|
||
; <A415> 11/17/86 JTC Back out some of the wonderful <C251> alignment feature to
|
||
; support our friends at Microsoft who gang-bang a large set of
|
||
; handles into a large, fixed block without checking for the 2
|
||
; slop bytes we would like to give them to force longword
|
||
; alignment when their request is (2n+1)*2. Parts of <C251> that
|
||
; force alignment of the beginning of the zone are left in for the
|
||
; modest improvement they admit, and because there may be a way to
|
||
; salvage the Microsoft-style apps. The principal change is to
|
||
; routine ActualS in HeapGuts.a, where the rounding to a multiple
|
||
; of 4 is done.
|
||
; <A305> 10/30/86 JTC Roll in Mac+ patch to RecoverHandle to use the more reasonable
|
||
; of SysZone and ApplZone as “TheZone” when incoming TheZone is
|
||
; one of Sys or Appl. Since RecoverHandle is strange, passing a
|
||
; pointer to a handle-related routine, the cleanest way is to
|
||
; customize a MMRHPrologue, “RH” as in RecoverHandle, of course,
|
||
; to do the A6 fixing. The only change to the code here in Heap is
|
||
; to JSR to MMRHPrologue rather than MMPrologue. MMRHPrologue has
|
||
; several extra lines to choose A6 wisely.
|
||
; <C251> 10/24/86 JTC Changes to support longword alignment of blocks. Since the heap
|
||
; header as well as individual block headers are multiples of 4 in
|
||
; size, the problem reduces to getting heaps started on longword
|
||
; boundaries and then allocating blocks in multiples of longwords.
|
||
; The first issue depends on the start code, which determines the
|
||
; system zone, maintainence of a 4x system heap (since the app
|
||
; heap always starts at its end), and a little change in
|
||
; SetAppBase to keep a resized system heap on a long boundary. For
|
||
; home-brew heaps that start on 4x+2 boundaries, InitZone contains
|
||
; some code to fudge the initial block, necessarily a master
|
||
; pointer block, to ensure that all following blocks are longword
|
||
; aligned. Code in InitZone ensures that the heap limit is on a
|
||
; long boundary.
|
||
; Once the zone is aligned, it’s up to internal code to keep
|
||
; allocations properly aligned. Internal routine ActualS is the key.
|
||
; It now rounds up to the nearest multiple of 4 (not 2, as before);
|
||
; the slop is picked up by internal routine SetLogSize as usual.
|
||
; ApplLimit and its associated routine SetApplLimit are left as is,
|
||
; since the variable may be tweaked from within an app with impunity.
|
||
; Instead, uses of ApplLimit for resizing the zone or calculating
|
||
; available size are carefully monitored. Internal routine MaxLimit
|
||
; usually brackes uses of ApplLimit, so it is made to round down to
|
||
; the nearest multiple of 4. MaxApplZone, which uses ApplLimit
|
||
; directly, are modified to round it down to a multiple of 4 first.
|
||
; StackSpace rounds the SP down to a multiple of 4 before computing
|
||
; available space.
|
||
; 10/17/86 CRC InitApplZone sets up FMExist, LastSpExtra only for Font Manager.
|
||
; <C206> 10/9/86 bbm Modified to mpw aincludes/ changed resourc to resource.
|
||
; <C169> 9/23/86 JTC Add _StripAddress.
|
||
; 3/31/86 BBM added a blank line in order to work with the assembler.
|
||
; 2/19/86 BBM Made some modifications to work under MPW
|
||
; 1/13/86 JTC 1. Patch InitApplZone to inval font cach by setting LastSPExtra
|
||
; to -1. <13Jan86 JTC>
|
||
; 2. Save/Restore theZone across MoveHHi so theZone can be set to
|
||
; that of the moving handle.
|
||
; 3. Add 4 calls to set/clr rsrc bit of handle and pull flag byte
|
||
; from master ptr.
|
||
;
|
||
; 11/1/85 JTC New global HiHeapMark tracks heap ends below SP -- InitApplZone,
|
||
; SetApplLimit, <01Nov85> InitZone, MoveHHi.
|
||
;
|
||
; 10/27/85 BBM needed more space, added three branch shorts.
|
||
; 5/29/85 JTC Made a MOVE a MOVEQ to be sure error code is long. <29May85>
|
||
; 5/21/85 JTC Distinguish Nil and empty in Disposehandle. <21May85>
|
||
; 5/10/85 KWK Removed JSR to OS code. <10May85>
|
||
; 5/10/85 JTC InitMem moved to Start code to facilitate separate linking. <10May85>
|
||
; 5/9/85 JTC Added call StackSpace. <09May85>
|
||
; 5/6/85 JTC Initialize new FontMgr globals. <06May85>
|
||
; 5/4/85 JTC Incorporated MoveHHi. <04May85>
|
||
; 4/27/85 JTC Moved MakeStkPB into code with conditional assembly, to
|
||
; facilitate RAM-based... <27Apr85>
|
||
; 4/25/85 JTC Add new common exit for non-MMEpilogue routines to stuff return
|
||
; code in MemErr. <25Apr85> Amend RecoverHandle to use special
|
||
; MMNoErrEpilogue.
|
||
; 4/24/85 JTC Modify HLock, etc. to bypass MMHPrologue to weaken their error
|
||
; checking (since <24Apr85> MicroSoft calls with bad handles) but
|
||
; to bypass 0 when passed in.
|
||
; 4/24/85 JTC Added MaxApplLimit, with slight modifications from OSTraps
|
||
; source. <24Apr85>
|
||
; 4/23/85 JTC Backed out validity check and error code in RecoverHandle --
|
||
; it's documented as <23Apr85> as such in Inside Mac! Code
|
||
; restored to original version.
|
||
; 4/17/85 JTC Add call PurgeSpace. <17Apr85>
|
||
; 4/16/85 JTC Fix no-error code at end of InitApplZone. <16Apr85>
|
||
; 4/14/85 JTC Change InitApplZone to start zone up high in stack. Subject to
|
||
; further tuning... <14Apr85>
|
||
; 4/13/85 JTC Add validity check and error code to RecoverHandle. <13Apr85>
|
||
; 4/10/85 JTC Add call MaxBlock, to return max available free space that could
|
||
; be gotten <10Apr85> without purge or grow. Revitalize
|
||
; EmptyHandle and DisposeHandle to be effective even in ROZ, so
|
||
; that apps trying to make space by deleting, say, Pack5 will get
|
||
; past that and into some real space savings. EmptyHandle will
|
||
; indeed zero the (bogus) MP, but not attempt to actually free
|
||
; space. DisposeHandle will do likewise; and it won't return the
|
||
; MP to the free list, since there is a permanent connection
|
||
; between ROM bogus MP's and ROM resources.
|
||
; 3/12/85 LAK&JTC Modified sys heap start to $1400, making room for 1K ToolTable @ $C00
|
||
; 3/4/85 JTC Changes to support so-called read-only zones (for ROM map zone,
|
||
; currently). <04Mar85>
|
||
; 1) Add ROZ .EQU 0 to NewEqu, reusing bit fOnCheck.
|
||
; 2) Add memROZWarn .EQU -99 to NewEqu -- report error on abuse.
|
||
; 3) Add memROZError .EQU -99 to NewEqu -- same thing.
|
||
; 4) DisposPtr, DisposHandle -- warning if ROZ.
|
||
; 5) ReallocHandle -- if nonempty, don't empty and warn if try to grow
|
||
; 6) SetHandleSize, SetPtrSize -- don't shrink it.
|
||
; 7) EmptyHandle (the big one) -- don't do it and DON'T signal error!
|
||
; 8) Add _NewEmptyHandle, parallel to NewHandle.
|
||
; 1/30/85 LAK Added ram patch to InitApplZone for world reinit stuff (with REF
|
||
; for MakeStackPB).
|
||
; 1/29/85 LAK New system heap start is $C00.
|
||
; 1/29/85 JTC Rolled in patches, marked <29jan85>:
|
||
; 1) SetApplLimit -- check for memfull error
|
||
; 2) MoreMasters -- add new call
|
||
; 3) InitZone, SetGrowZone -- change to 2-level GrowZoneProc
|
||
; 4) StdGZ -- add standard GrowZoneProc
|
||
; 5) MakePtrSpc -- (internal routine) new code after return from MakeSpace
|
||
; 1/23/85 LAK Adapted for new equate files. Changed 'MoreMasters' to mAllocCnt.
|
||
; 9/12/83 LAK Added GZ semaphores to ReallocHandle.
|
||
; 9/10/83 LAK Changed CompactMem to force heap compact by setting FNSelCompct
|
||
; bit in flags word.
|
||
; 9/4/83 LAK Fixed bug in ReallocHandle (don't dispose handle on memFullErr).
|
||
; 8/18/83 LAK Fixed potential problem with ResrvMem (if used to make room for
|
||
; a handle, it needs to reserve extra space for a master pointer
|
||
; block if we are out of master pointers . . .)
|
||
; 8/12/83 LAK Added clear option for NewPtr, NwHandle, and ReAllocHandle.
|
||
; 7/31/83 LAK DefltFlags now reside in low memory location mmDefFlags: placed
|
||
; there by InitMem and loaded into zone vars by InitZone.
|
||
; 7/28/83 LAK CompactMem, PurgeMem, MaxMem, and FreeMem now call MMPrologue
|
||
; and MMEpilogue; added ResrvMem.
|
||
; 7/24/83 LAK Removed all free-list references; removed .word constants from
|
||
; checking code; made numerous optimizations; initialize DefltStack,
|
||
; MinStack in InitMem and now use these values instead of hard-wired
|
||
; constants.
|
||
; 6/21/83 MPH Put FreeList code under assembly switch: FList.
|
||
; 6/18/83 MPH Put maintenance of minCBFree under Statistics switch.
|
||
; 6/17/83 MPH Space Saving Changes:
|
||
; - Removed CallMoveProc calls
|
||
; - InitMem: tightened Mask Init
|
||
; - SetApplBase:
|
||
; Sub.L #x,A0 => Sub.W #x,A0
|
||
; JSR InitApplZone => BSR.S
|
||
; - InitApplZone:
|
||
; Add.L #x,A0 => Add.W #x,A0
|
||
; Move.L y,x(SP) => Move.L y,-(SP)
|
||
; - Removed unneeded Tst.L D0
|
||
; - GetZone: Repackaged checking code
|
||
; - SetZone: Repackaged checking code
|
||
; - PurgeMem: Moved PMFail to save space,
|
||
; - HLock, HUnLock, HPurge, HNoPurge:
|
||
; Removed unneeded Move.L A1,A0 at HGood.
|
||
; 6/16/83 MPH Removed error return from InitMem, InitApplZone in all cases.
|
||
; Fix CompactMem to adjust size correctly.
|
||
; Remove unused code at MMFail from MaxMem.
|
||
; 6/11/83 theGang Fixed register trashed bug in InitApplZone
|
||
; 6/10/83 MPH Changed order of _RsrcZoneInit, _InitZone in InitApplZone.
|
||
; Included GrafTypes so that Nil is defined.
|
||
; 6/5/83 MPH Fixed InitApplZone by moving IAZCommon to module Heap.
|
||
; 6/2/83 MPH More minor revisions for release, share common code.
|
||
; 4/12/83 MPH Final revisions for release.
|
||
; 2/22/83 LAK,MPH changed to observe pascal regsave conventions
|
||
; 2/17/83 LAK default ApplLimit is now figured from current stack pointer;
|
||
; initmem just inits the system zone.
|
||
; 2/10/83 MPH Changed SetApplLimit to take argument in A0 instead of D0
|
||
; 1/26/83 LAK Changed system heap size to 12K.
|
||
; 1/14/83 AJH Changed RsrcZoneInit invocation to a trap
|
||
; 10/27/82 MPH Begin Zone refinement per suggestions of Andy J. Hertzfeld
|
||
; and Larry A. Kenyon
|
||
; 8/16/82 AL Added ReAllocHandle core routine call
|
||
; 7/30/82 AL Modified for 128K... 16 MBytes memory expansion
|
||
; 4/28/82 AL added locked, purgeble, permanent relocatable blocks
|
||
; 4/7/82 AL use A0 to interface
|
||
; 1/25/82 BT All routines added, preliminary testing done.
|
||
; 12/13/81 BT More routines added.
|
||
;__________________________________________________________________________________________________
|
||
|
||
|
||
BLANKS ON
|
||
STRING ASIS
|
||
|
||
LOAD 'StandardEqu.d'
|
||
INCLUDE 'ColorEqu.a'
|
||
INCLUDE 'palettePriv.a'
|
||
INCLUDE 'MemoryMgrPriv.a'
|
||
INCLUDE 'FontPrivate.a'
|
||
INCLUDE 'HardwarePrivateEqu.a'
|
||
INCLUDE 'UniversalEqu.a'
|
||
|
||
Heap PROC EXPORT ; moved up here to contain equates!
|
||
|
||
IMPORT a24ActualS
|
||
IMPORT a32ActualS
|
||
IMPORT a24AllocBk
|
||
IMPORT a32AllocBk
|
||
IMPORT a24BkCompactS
|
||
IMPORT a32BkCompactS
|
||
IMPORT ClearGZStuff
|
||
IMPORT a24CompactHp
|
||
IMPORT a32CompactHp
|
||
IMPORT a24EH
|
||
IMPORT a32EH
|
||
IMPORT a24FreeBk
|
||
IMPORT a32FreeBk
|
||
IMPORT a24GetSize
|
||
IMPORT a32GetSize
|
||
IMPORT a24HMakeMoreMasters
|
||
IMPORT a32HMakeMoreMasters
|
||
IMPORT a24MakeBkf
|
||
IMPORT a32MakeBkf
|
||
IMPORT a24MakePtrSpc
|
||
IMPORT a32MakePtrSpc
|
||
IMPORT a24MaxLimit
|
||
IMPORT a32MaxLimit
|
||
IMPORT ToMaxLimit
|
||
IMPORT MMNoErrEpilogue
|
||
IMPORT MMEpilogue
|
||
IMPORT MMHPrologue
|
||
IMPORT MMPPrologue
|
||
IMPORT MMPrologue
|
||
IMPORT MMRHPrologue
|
||
IMPORT MMNoPrologue
|
||
IMPORT MMMMPrologue
|
||
IMPORT a24NextMaster
|
||
IMPORT a32NextMaster
|
||
|
||
IMPORT a24PurgeHeap
|
||
IMPORT a32PurgeHeap
|
||
IMPORT ReleaseMP
|
||
IMPORT a24SetSize
|
||
IMPORT a32SetSize
|
||
IMPORT StdGZ
|
||
IMPORT a24ZoneAdjustEnd
|
||
IMPORT a32ZoneAdjustEnd
|
||
|
||
IMPORT FlushApplVBLs ; code borrowed from SegLoader
|
||
IMPORT AppZoneAddr ; code borrowed from SegLoader
|
||
|
||
IMPORT FlushApplNM ; from NotificationMgr.c
|
||
|
||
IF RAMTest THEN
|
||
ELSE
|
||
IMPORT MakeStkPB ;<30jan85> for initapplzone stuff
|
||
ENDIF
|
||
|
||
IMPORT a24TotePurgeables ;new guts routine
|
||
IMPORT a32TotePurgeables ;new guts routine
|
||
|
||
IMPORT BaseofRom
|
||
IMPORT PramIO
|
||
|
||
IMPORT DiskCachePurgeProcedure ; <sm10>
|
||
|
||
EXPORT SetApplBase ; <SM20>
|
||
If hasNewHeapMgr Then
|
||
EXPORT Old_AfterBootSetApplBase ;<SM20>, <SM30 BT>
|
||
else
|
||
EXPORT AfterBootSetApplBase ;<SM20>
|
||
endif
|
||
EXPORT IAZ ; <SM19>
|
||
EXPORT InitApplZone
|
||
EXPORT InitZoneTrap
|
||
EXPORT GetZone
|
||
EXPORT SetZone
|
||
|
||
EXPORT MaxBlockTrap
|
||
EXPORT PurgeSpaceTrap
|
||
EXPORT CompactMemTrap
|
||
EXPORT PurgeMem
|
||
EXPORT FreeMem
|
||
EXPORT ResrvMem
|
||
EXPORT MaxMemTrap
|
||
|
||
EXPORT SetGrowZone
|
||
EXPORT SetApplLimit
|
||
EXPORT StackSpaceTrap
|
||
EXPORT MaxApplZone
|
||
|
||
EXPORT NewPtrTrap
|
||
EXPORT DisposePtr
|
||
EXPORT GetPtrSizeTrap
|
||
EXPORT SetPtrSizeTrap
|
||
EXPORT PtrZoneTrap
|
||
|
||
EXPORT NwHandle
|
||
EXPORT NewEmptyHandleTrap
|
||
EXPORT DsposeHandle
|
||
EXPORT __GetHandleSize
|
||
EXPORT SetHandleSizeTrap
|
||
EXPORT HandleZoneTrap
|
||
EXPORT RecoverHandleTrap
|
||
EXPORT EmptyHandle
|
||
EXPORT ReAllocHandleTrap
|
||
|
||
EXPORT HLock
|
||
EXPORT HUnlock
|
||
EXPORT HPurge
|
||
EXPORT HNoPurge
|
||
EXPORT HRSRC ; set the RSRC bit
|
||
EXPORT HNoRSRC ; clear the RSRC bit
|
||
EXPORT HGetFlags ; get flag byte of master ptr
|
||
EXPORT HSetFlags ; set flag byte of master ptr
|
||
|
||
EXPORT MoreMasters ; new trap added
|
||
EXPORT __StripAddress
|
||
EXPORT MoveHHi ; moved in from glue land
|
||
|
||
EXPORT vIAZInit ; init at top of InitApplZone for vector
|
||
EXPORT vIAZPostInit ; init after zone is created for vector
|
||
|
||
if hasNewHeapMgr Then
|
||
EXPORT Old_InitMemVect ; initialization for Memory Vectors <SM30 BT>
|
||
EXPORT Old_InitMemMgr ; initialize Memory Manager low mem, vectors <SM21>,<SM30 BT>
|
||
else
|
||
EXPORT InitMemVect ; initialization for Memory Vectors <SM30 BT>
|
||
EXPORT InitMemMgr ; initialize Memory Manager low mem, vectors <SM21>,<SM30 BT>
|
||
endif
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
; PROCEDURE InitMemVect;
|
||
;
|
||
; This routine initialize the jump vector tables for both 24 and 32 bit
|
||
; memory traps.
|
||
;
|
||
|
||
MACHINE MC68030
|
||
|
||
MMTrapTable ; table for all Memory Manager traps
|
||
; entries have to be in pairs.....
|
||
DC.L v24SetApplBase-BaseofROM ;
|
||
DC.L v32SetApplBase-BaseofROM ;
|
||
DC.L vInitApplZone-BaseofROM ;
|
||
DC.L vInitApplZone-BaseofROM ;
|
||
DC.L v24InitZone-BaseofROM ;
|
||
DC.L v32InitZone-BaseofROM ;
|
||
DC.L vGetZone-BaseofROM ;
|
||
DC.L vGetZone-BaseofROM ;
|
||
DC.L vSetZone-BaseofROM ;
|
||
DC.L vSetZone-BaseofROM ;
|
||
DC.L v24MaxBlock-BaseofROM ;
|
||
DC.L v32MaxBlock-BaseofROM ;
|
||
DC.L v24PurgeSpace-BaseofROM ;
|
||
DC.L v32PurgeSpace-BaseofROM ;
|
||
DC.L v24CompactMem-BaseofROM ;
|
||
DC.L v32CompactMem-BaseofROM ;
|
||
DC.L v24PurgeMem-BaseofROM ;
|
||
DC.L v32PurgeMem-BaseofROM ;
|
||
DC.L vFreeMem-BaseofROM ;
|
||
DC.L vFreeMem-BaseofROM ;
|
||
DC.L v24ResrvMem-BaseofROM ;
|
||
DC.L v32ResrvMem-BaseofROM ;
|
||
DC.L v24MaxMem-BaseofROM ;
|
||
DC.L v32MaxMem-BaseofROM ;
|
||
DC.L vSetGrowZone-BaseofROM ;
|
||
DC.L vSetGrowZone-BaseofROM ;
|
||
DC.L v24SetApplLimit-BaseofROM ;
|
||
DC.L v32SetApplLimit-BaseofROM ;
|
||
DC.L vStackSpace-BaseofROM ;
|
||
DC.L vStackSpace-BaseofROM ;
|
||
DC.L v24MaxApplZone-BaseofROM ;
|
||
DC.L v32MaxApplZone-BaseofROM ;
|
||
DC.L v24NewPtr-BaseofROM ;
|
||
DC.L v32NewPtr-BaseofROM ;
|
||
DC.L v24DisposePtr-BaseofROM ;
|
||
DC.L v32DisposePtr-BaseofROM ;
|
||
DC.L v24GetPtrSize-BaseofROM ;
|
||
DC.L v32GetPtrSize-BaseofROM ;
|
||
DC.L v24SetPtrSize-BaseofROM ;
|
||
DC.L v32SetPtrSize-BaseofROM ;
|
||
DC.L vPtrZone-BaseofROM ;
|
||
DC.L vPtrZone-BaseofROM ;
|
||
DC.L v24NwHandle-BaseofROM ;
|
||
DC.L v32NwHandle-BaseofROM ;
|
||
DC.L v24NewEmptyHandle-BaseofROM ;
|
||
DC.L v32NewEmptyHandle-BaseofROM ;
|
||
DC.L v24DsposeHandle-BaseofROM ;
|
||
DC.L v32DsposeHandle-BaseofROM ;
|
||
DC.L v24GetHandleSize-BaseofROM ;
|
||
DC.L v32GetHandleSize-BaseofROM ;
|
||
DC.L v24SetHandleSize-BaseofROM ;
|
||
DC.L v32SetHandleSize-BaseofROM ;
|
||
DC.L vHandleZone-BaseofROM ;
|
||
DC.L vHandleZone-BaseofROM ;
|
||
DC.L v24RecoverHandle-BaseofROM ;
|
||
DC.L v32RecoverHandle-BaseofROM ;
|
||
DC.L v24EmptyHandle-BaseofROM ;
|
||
DC.L v32EmptyHandle-BaseofROM ;
|
||
DC.L v24ReAllocHandle-BaseofROM ;
|
||
DC.L v32ReAllocHandle-BaseofROM ;
|
||
DC.L v24Hlock-BaseofROM ;
|
||
DC.L v32Hlock-BaseofROM ;
|
||
DC.L v24HUnlock-BaseofROM ;
|
||
DC.L v32HUnlock-BaseofROM ;
|
||
DC.L v24HPurge-BaseofROM ;
|
||
DC.L v32HPurge-BaseofROM ;
|
||
DC.L v24HNoPurge-BaseofROM ;
|
||
DC.L v32HNoPurge-BaseofROM ;
|
||
DC.L v24HRSRC-BaseofROM ;
|
||
DC.L v32HRSRC-BaseofROM ;
|
||
DC.L v24HNoRSRC-BaseofROM ;
|
||
DC.L v32HNoRSRC-BaseofROM ;
|
||
DC.L v24HGetFlags-BaseofROM ;
|
||
DC.L v32HGetFlags-BaseofROM ;
|
||
DC.L v24HSetFlags-BaseofROM ;
|
||
DC.L v32HSetFlags-BaseofROM ;
|
||
DC.L v24MoreMasters-BaseofROM ;
|
||
DC.L v32MoreMasters-BaseofROM ;
|
||
DC.L v24MoveHHi-BaseofROM ;
|
||
DC.L v32MoveHHi-BaseofROM ;
|
||
TableEnd
|
||
|
||
;----------------------------------------------------------------
|
||
; InitMemMgr: Set up some low memory constants related to the memory manager.
|
||
; Destroys none
|
||
; Called by System initialization sequence.
|
||
;----------------------------------------------------------------
|
||
IF hasNewHeapMgr Then
|
||
Old_InitMemMgr
|
||
ELSE
|
||
InitMemMgr
|
||
ENDIF
|
||
|
||
IF hasNewHeapMgr Then
|
||
Old_InitMemVect
|
||
ELSE
|
||
InitMemVect
|
||
ENDIF
|
||
BSET #MMStartMode,MMFlags ; Force 32-bit mode
|
||
BSET #MMMixed,MMFlags ; Force 32-bit mode
|
||
BSET #MMSysheap,MMFlags ; Force 32-bit mode
|
||
BSET #MMROZheap,MMFlags ; Force 32-bit mode
|
||
BCLR #mmHighSysHeap,MMFlags ; Force 32-bit mode
|
||
|
||
BCLR.B #Systemis24bit,SystemInfo ; set system to be 32 bit
|
||
BCLR.B #Sysheapis24bit,SystemInfo ; set system heap to be 32 bit
|
||
@2
|
||
MOVE.L ROMBase,D0 ; get ROMbase <v1.4>
|
||
LEA MMTrapTable,A0 ; A3 gets beginning of table
|
||
LEA JMemMgr24,A1 ; set A1 to start of 24 bit table <v1.1>
|
||
LEA JMemMgr32,A2 ; set A2 to start of 32 bit table <v1.1>
|
||
MOVE.L #(((TableEnd-MMTrapTable)>>3)-1),D1 ; get number of entry pairs <v1.9>
|
||
@NextEntry
|
||
MOVE.L (A0)+,(A1) ; copy offset to entries in 24 bit table <v1.9>
|
||
ADD.L D0,(A1)+ ; Add ROM Base to offset <v1.9>
|
||
MOVE.L (A0)+,(A2) ; copy offset to entries in 32 bit table <v1.9>
|
||
ADD.L D0,(A2)+ ; Add ROM Base to offset <v1.9>
|
||
DBRA D1,@NextEntry ; loop until end <v1.9>
|
||
|
||
ADD.L #$00010000,D0 ; makeup a safe address <v1.9>
|
||
MOVE.L D0,$0 ; write address for nil handle <v1.9>
|
||
MOVE.L D0,$4 ; write address for nil window pointer <v1.9>
|
||
|
||
LEA MMNoPrologue,A0 ; get address <v1.9>
|
||
Move.L A0,vMMNoPrologue ;
|
||
LEA MMPPrologue,A0 ; get address
|
||
Move.L A0,vMMPPrologue ;
|
||
LEA MMPrologue,A0 ; get address
|
||
Move.L A0,vMMPrologue ;
|
||
LEA MMHPrologue,A0 ; get address
|
||
Move.L A0,vMMHPrologue ;
|
||
LEA MMRHPrologue,A0 ; get address
|
||
Move.L A0,vMMRHPrologue ;
|
||
LEA MMMMPrologue,A0 ; get address
|
||
Move.L A0,vMMMMPrologue ;
|
||
LEA MMEpilogue,A0 ; get address
|
||
Move.L A0,vMMEpilogue ;
|
||
LEA MMNoErrEpilogue,A0 ; get address
|
||
Move.L A0,vMMNoErrEpilogue ; <v1.9>
|
||
|
||
|
||
MOVEM.L (SP)+,D0-D3/A0-A3 ; restore registers <v1.1>
|
||
RTS ; <v1.1>
|
||
|
||
;----------------------------------------------------------------------
|
||
; PROCEDURE SetApplBase(a: Address);
|
||
;
|
||
; Sets the Application Zone Base, and Inits the Application Zone
|
||
; No error setting required here,since IAZ does all the hard work. <25Apr85>
|
||
; These days use the full splendor of InitApplZone.
|
||
;
|
||
; Argument:
|
||
; A0: New Base Address for Applic Zone.
|
||
;
|
||
; Result:
|
||
; D0: ec: error code.
|
||
;
|
||
; Registers:
|
||
; D0: amount to adjust counter by, new counter value.
|
||
; A0: points to counter, max pair.
|
||
;
|
||
|
||
SetApplBase
|
||
; Roll in SetAppBaseCacheCleaner from BassPatches.a <SM8> <PN>
|
||
; Remove any application memory allocated by Bass whenever the application heap is
|
||
; reformatted. SetAppBase and InitApplZone must be patched since they both trash the
|
||
; application heap.
|
||
TST.B CurApName ;checking for app name <SM8> <PN>
|
||
BMI @SkipIt ;still in booting, skip the patch <SM8> <PN>
|
||
MOVEM.L A0-A2/D0-D3,-(sp) ; save registers <SM8> <PN>
|
||
CLR.L -(SP) ; room for result <SM8> <PN>
|
||
MOVE.L applZone,A0 ; point to zone hdr <SM8> <PN>
|
||
MOVE.L A0,-(SP) ; push start ptr <SM8> <PN>
|
||
MOVE.L (A0),-(SP) ; push zone trailer <SM8> <PN>
|
||
_sbKillSomeCaches ; <SM8> <PN>
|
||
ADDQ #4,SP ; ignore result <SM8> <PN>
|
||
MOVEM.L (sp)+,A0-A2/D0-D3 ; restore registers <SM8> <PN>
|
||
@SkipIt
|
||
Move.L #JSetApplBase,-(SP) ; get offset onto stack <v1.9>
|
||
Move.L vMMNoPrologue,-(SP) ; get vector to MMnoPrologue<v1.9>
|
||
RTS
|
||
|
||
; 24 bit version
|
||
v24SetApplBase
|
||
MoveM.L D3/A2-A6,-(SP) ; Save Registers.
|
||
Move.L SysZone,A6 ; Get sysZone pointer.
|
||
Move.L A0,D0 ; round base up to 4x <C251><sm9>stb
|
||
Cmpi.b #cpu68040,CPUFlag ; on an 040 or greater? <2> kc.start
|
||
Blo.s @0 ; No? Then long align.
|
||
|
||
Add.L #15,D0 ; Quad-word align
|
||
AndI.W #$FFF0,D0 ; D0 = 16x; D0 >= A0
|
||
bra.s @continue
|
||
|
||
@0 AddQ.L #3,D0 ;
|
||
AndI.W #$FFFC,D0 ; D0 = 4x; D0 >= A0
|
||
@continue ; <2> kc.end
|
||
MoveA.L D0,A0 ; <C251>
|
||
Sub.W #MinFree24,A0 ; Point to new end block. <v1.2>
|
||
Cmp.L BkLim(A6),A0 ; New sysZone end <= current?
|
||
BLS.S @SABInitAppl ; Yes, just init applZone.
|
||
BSR a24ZoneAdjustEnd ; Adjust the sysZone end. <v1.1>
|
||
@SABInitAppl
|
||
BSR IAZ ; use historical IAZ call <C681>
|
||
MoveM.L (SP)+,D3/A2-A6
|
||
RTS
|
||
|
||
; 32 bit version
|
||
v32SetApplBase
|
||
MoveM.L D3/A2-A6,-(SP) ; Save Registers.
|
||
Move.L SysZone,A6 ; Get sysZone pointer.
|
||
Move.L A0,D0 ; round base up to 4x <C251><sm9>stb
|
||
Cmpi.b #cpu68040,CPUFlag ; on an 040 or greater? <2> kc.start
|
||
Blo.s @0 ; No? Then long align.
|
||
|
||
Add.L #15,D0 ; Quad-word align
|
||
AndI.W #$FFF0,D0 ; D0 = 16x; D0 >= A0
|
||
bra.s @continue
|
||
|
||
@0 AddQ.L #3,D0 ;
|
||
AndI.W #$FFFC,D0 ; D0 = 4x; D0 >= A0
|
||
@continue ; <2> kc.end
|
||
MoveA.L D0,A0 ; <C251>
|
||
Sub.W #MinFree32,A0 ; Point to new end block. <v1.2>
|
||
Cmp.L BkLim(A6),A0 ; New sysZone end <= current?
|
||
BLS.S @SABInitAppl ; Yes, just init applZone.
|
||
BSR a32ZoneAdjustEnd ; Adjust the sysZone end. <v1.1>
|
||
@SABInitAppl
|
||
BSR.S IAZ ; use historical IAZ call <C681>
|
||
MoveM.L (SP)+,D3/A2-A6
|
||
RTS
|
||
|
||
;----------------------------------------------------------------------
|
||
; PROCEDURE AfterBootSetApplBase(a: Address);
|
||
;
|
||
; This is the patch BracketSetAppBaseWithInitApplZones
|
||
; It will patch out the SetApplBase at Gibbly time when InstallMgr
|
||
; get called. The time when this patch applied is crucial (during boot
|
||
; time up to gibbly time this patch is NOT to be used, it is used
|
||
; after gibbly time) <SM20> PN
|
||
;
|
||
|
||
If hasNewHeapMgr Then
|
||
; <SM30 BT>: Change AfterBootSetApplBase to Old_AfterBootSetApplBase so we can export a wrapper to
|
||
; BootRetry instead. The wrapper muxes the call based on if figment is active
|
||
Old_AfterBootSetApplBase ;<SM20> PN
|
||
else
|
||
AfterBootSetApplBase
|
||
endif
|
||
|
||
_InitApplZone ;<SM20> PN
|
||
jsr SetApplBase ;<SM20> PN
|
||
_InitApplZone ;<SM20> PN
|
||
rts ;<SM20> PN
|
||
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; Procedure InitApplZone;
|
||
;
|
||
; Common code for initializing the Application Zone. Requires SPBot,
|
||
; sysZone to be set up. Sets up ApplLimit, applZone. Invokes
|
||
; RsrcZoneInit, if needed. Sets up HiHeapMark := ApplLimit, as always, <C765><C778>
|
||
; but uses the more conservative result (D1) from ToMaxLimit rather than <C765><C778>
|
||
; the BufPtr-based result (D2) which was historical. <C778>
|
||
;
|
||
; New wrinkle -- start ApplZone up high, then let it grow downwards. <14Apr85>
|
||
; Stuff error codes in IAZ (for SetApplBase) and InitApplZone. <25Apr85>
|
||
; Init ApplZone and OrgApplZone before InitZone, to simplify MakeMoreMasters <27Apr85>
|
||
; Roll all of InitApplZone into one blob, leaving IAZ for history. <C681>
|
||
;
|
||
; Arguments:
|
||
; None.
|
||
;
|
||
; Result:
|
||
; D0: ec: error code.
|
||
; <0: InitZone failed.
|
||
; 0: Success.
|
||
;
|
||
; Registers:
|
||
; D1: appLim: Computed ApplLimit value.
|
||
; D2: lTemp: Proposed appl Limit value.
|
||
; A0: start: Points to proposed applZone start.
|
||
; A0: args: Points to InitZone argument list.
|
||
; A1: end: Points to proposed applZone end.
|
||
; A6: z: Points to sysZone, eventually applZone.
|
||
;
|
||
|
||
|
||
InitApplZone
|
||
Move.L #JInitApplZone,-(SP) ; get offset onto stack <v1.9>
|
||
Move.L vMMNoPrologue,-(SP) ; get vector to MMnoPrologue<v1.9>
|
||
RTS
|
||
|
||
vInitApplZone
|
||
|
||
MoveA.L jIAZInit,A0 ; get pre-processing routine vector <C681>
|
||
JSR (A0) ; do it <C681>
|
||
BSR.S IAZ ; get the real zone <C681>
|
||
MoveA.L jIAZPostInit,A0 ; get post-processing routine vector <C681>
|
||
JSR (A0) ; do it <C681>
|
||
|
||
MoveQ #0,D0 ; re-stuff the no-error code <16Apr85>
|
||
Move.W D0,MemErr ; Record it globally, too <25Apr85>
|
||
RTS
|
||
|
||
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
; IAZ <C681>
|
||
; - Do the real work of initing the appl zone.
|
||
; Major change to use stack&BufPtr-based ApplLimit and HiHeapMark, not
|
||
; just to hammer BufPtr-MinStack, as has been done since the early days.
|
||
; This fixes problems at start time, when SetApplBase is called with the
|
||
; stack in mid-ram and StackSpace is forced to say there is no
|
||
; Registers: D0-D2/A0-A1
|
||
; Called by InitApplZone and SetApplBase.
|
||
;----------------------------------------------------------------------
|
||
IAZ Move.L A6,-(SP) ;Save A6.
|
||
|
||
_RsrcZoneInit ;initialize resources in appl heap
|
||
Clr.L applZone ;No applZone exists during init.
|
||
|
||
; Do the Launch-type computation of ApplLimit, to give ample stack <C817>
|
||
; at boot time. Remove use of antiquated ToMaxLimit. <C817>
|
||
Move.l SP,D1 ;current stack <C817>
|
||
Sub.L DefltStack,D1 ;enough space for even QD <C817>
|
||
Move.L D1,ApplLimit ;Use stack limit, NOT BufPtr’s <C778>
|
||
Move.L D1,HiHeapMark ;Start HiHeapMark in sync with <C778>
|
||
;ApplLimit in case of glue MaxApplZone<C778>
|
||
|
||
Move.L sysZone,A6 ;SysZone pointer.
|
||
Move.L BkLim(A6),A0 ;Current Last Block in sysZone.
|
||
|
||
TST.B Zone32Flag(A6) ;is it 32 bit zone <v1.2>
|
||
BNE.S @1 ;branch if yes <v1.2>
|
||
|
||
; Ordinarily start ApplZone just after SysZone, but if GrowDown is true, <14Apr85>
|
||
; and there's room, start up offset by CacheSize. <27Apr85>
|
||
LEA MinFree24(A0),A0 ;Points to first of cur. applZone. <v1.2>
|
||
BRA.S @5 ; <v1.2>
|
||
@1
|
||
LEA MinFree32(A0),A0 ;Points to first of cur. applZone. <v1.2>
|
||
|
||
@5
|
||
; Now proceed building the zone... <14Apr85>
|
||
Move.L A0,A1 ;New Application zone base.
|
||
Add.W #AppZoneSize,A1 ;Compute new end address.
|
||
Cmp.L D1,A1 ;New End Address < ApplLimit?
|
||
BCS.S @10 ;Yes, use new end address.
|
||
|
||
Move.L D1,A1 ;use ApplLimit as end address.
|
||
|
||
@10
|
||
; Move.L A0,StartPtr(SP) ;New Applic Zone Base.
|
||
; Move.L A1,LimitPtr(SP) ;New Applic Zone End.
|
||
; Move.W #<2*dfltMasters>,CMoreMasters(SP)
|
||
; Move.L #0,PGrowZone(SP) ;No Grow Zone procedure.
|
||
|
||
Move.L #0,-(SP) ;No Grow Zone procedure.
|
||
Move.W #(2*dfltMasters),-(SP) ;Number of masters to alloc.
|
||
Move.L A1,-(SP) ;New Applic Zone End.
|
||
Move.L A0,-(SP) ;New Applic Zone Base.
|
||
|
||
Move.L A0,applZone ;Save as the application heap zone.
|
||
|
||
Move.L SP,A0 ;Point to argument block.
|
||
_InitZone ;Ask OS to do request.
|
||
|
||
Add.W #14,SP ;Restore stack pointer.
|
||
|
||
Move.L theZone,A6 ;Application heap zone.
|
||
Move.L BkLim(A6),HeapEnd ;Set up HeapEnd.
|
||
|
||
MoveQ #0,D0 ;Success result code.
|
||
Move.W D0,MemErr ;Record it globally, too <25Apr85>
|
||
|
||
Move.L (SP)+,A6 ;Restore A6.
|
||
RTS ; <C681>
|
||
;------------------------------------------------------------------- <C681>
|
||
; End of historical IAZ.
|
||
;------------------------------------------------------------------- <C681>
|
||
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
; vIAZInit new <C681>
|
||
; - Inits before ApplZone is created.
|
||
; Registers: D0-D2/A0-A1
|
||
; Called by InitApplZone via jIAZInit vector.
|
||
;----------------------------------------------------------------------
|
||
vIAZInit
|
||
MOVE.L IAZNotify,D0 ; anyone to notify?
|
||
BLE.S @0 ; br if not
|
||
MOVE.L D0,A0 ; give them a call if so
|
||
JSR (A0)
|
||
|
||
@0 MOVE.W #-1,WWExist ; $FF for non-existence (also sets QDExist)
|
||
ST FMExist ; $FF for InitFonts hasn’t been called
|
||
; BSET #7,DSWndUpdate ; cancel pending PaintBehind
|
||
CLR.L MenuList
|
||
; Clr.L LastFOND ; <06May85>
|
||
; Move.W #-1,FONDID ; <06May85>
|
||
Move.L MinusOne,LastSPExtra ; flag to inval cache <13Jan86 JTC>
|
||
ST SEvtEnb ; re-enable system event
|
||
|
||
MoveQ #(IOVQElSize/2)-1,D0 ; <10May85>
|
||
@99
|
||
Clr.W -(SP)
|
||
DBrA D0,@99
|
||
MoveA.L SP,A0
|
||
|
||
MOVE.L VCBQHdr+QHead,D0
|
||
@2 BEQ.S @4
|
||
MOVE.L D0,A1
|
||
MOVE.W VCBDrvNum(A1),IOVDrvNum(A0)
|
||
BEQ.S @3
|
||
_FlushVol ; flush all on-line volumes
|
||
@3 MOVE.L QLink(A1),D0
|
||
BRA.S @2
|
||
@4
|
||
ADD #IOVQElSize,SP ; clean up stack
|
||
|
||
; Init code moved from Launch
|
||
CLR.L DragHook ;No drag hook yet
|
||
CLR.L DeskHook ;No desk hook for hit-testing desk.
|
||
LEA CloseOrnHook, A0 ; Point to closeOrnHook
|
||
CLR.L (A0)+ ;clear closeOrnHook
|
||
CLR.L (A0)+ ;clear RestProc
|
||
CLR.L (A0)+ ;clear saveProc
|
||
CLR.W TaskLock ;clear taskLock, fScaleDisable.
|
||
CLR.L ResErrProc ;and resource error proc.
|
||
CLR.L EjectNotify ;moved here from InitApplZone (from patches) <24Apr85>
|
||
|
||
IF hasASC THEN ; <C897><C914><1.7>
|
||
MOVE.L jSoundDead,A0 ;get vector to kill all current sounds in ... <C681>
|
||
JSR (A0) ;...the application heap <C681>
|
||
ENDIF
|
||
|
||
BSR.L FlushApplVbls ;kill off doomed vbl tasks <27Mar85>, <SM30 BT>
|
||
BigJSR FlushApplNM,A0 ; And bogus NM requests <V1.1><1.2>
|
||
|
||
BSR.S FlushFontCaches ; flush TrueType caches <sm10>stb
|
||
BSR.S FlushApplPorts ;kill off doomed grafPorts <C699>
|
||
BSR.S FlushPalettes ;as well as doomed palettes <10Jun87 EHB>
|
||
|
||
; this cleanup is needed, for instance, if an ES is done from MacsBug. <10Jun87 EHB>
|
||
|
||
MOVE.L MainDevice,A0 ; get the main device <10Jun87 EHB>
|
||
MOVE.L A0,SrcDevice ; set the src device <10Jun87 EHB>
|
||
MOVE.L A0,theGDevice ; and the current device <10Jun87 EHB>
|
||
MOVE #$2000,SR ; make sure interrupts enabled <10Jun87 EHB>
|
||
RTS
|
||
|
||
FlushFontCaches
|
||
;----------------------------------------------------------------------
|
||
; Remove any application memory allocated by TrueType whenever the application heap is
|
||
; reformatted. SetAppBase and InitApplZone are both patched since they both trash the
|
||
; application heap.
|
||
; Rolled in InitApplZoneCacheCleaner from BassPatches.a <SM8> <PN><sm10>stb
|
||
; Registers: saves all registers, trashes condition codes
|
||
;----------------------------------------------------------------------
|
||
|
||
MOVEM.L A0-A2/D0-D3,-(sp) ; save registers <SM8> <PN>
|
||
CLR.L -(SP) ; room for result <SM8> <PN>
|
||
MOVE.L applZone,A0 ; point to zone hdr <SM8> <PN>
|
||
MOVE.L A0,-(SP) ; push start ptr <SM8> <PN>
|
||
MOVE.L (A0),-(SP) ; push zone trailer <SM8> <PN>
|
||
_sbKillSomeCaches ; <SM8> <PN>
|
||
ADDQ #4,SP ; ignore result <SM8> <PN>
|
||
MOVEM.L (sp)+,A0-A2/D0-D3 ; restore registers <SM8> <PN>
|
||
@SkipIt
|
||
RTS
|
||
|
||
FlushApplPorts
|
||
;----------------------------------------------------------------------
|
||
; FlushApplPorts new <C681>
|
||
; -- clean up portList just before ApplZone is eliminated
|
||
; Registers: D0-D2/A0-A1
|
||
; Called by vIAZInit.
|
||
;----------------------------------------------------------------------
|
||
; Remove from the PortList any ports in the application heap zone
|
||
|
||
@REPEAT MOVE.L portList,A1 ;get the portList <C699>
|
||
CMP.L MinusOne,A1 ;are they equal? <C699>
|
||
BEQ.S @DONE ;=>if so,invalid portlist, just return <C699>
|
||
MOVE.L (A1),A1 ;point to it <C699>
|
||
MOVE.L A1,A0 ;save pointer in A0 <C699>
|
||
MOVE (A1)+,D1 ;get count of elements? <C699>
|
||
BRA.S @NEXT ;=> and dive into loop <C699>
|
||
|
||
@SEARCH MOVE.L (A1)+,D0 ;get next element from list <C699>
|
||
BSR.L AppZoneAddr ;in application area (or zero)? <C699>,<SM30 BT>
|
||
BEQ.S @DELETE ;=>yes, delete it <C699>
|
||
@NEXT DBRA D1,@SEARCH ;=>else try next in list <C699>
|
||
BRA.S @DONE ;=>none left, continue <C699>
|
||
|
||
@DELETE SUB #1,(A0) ;decrement port count <C699>
|
||
MOVE.L -(A1),-(SP) ;stk: port < etc. <C699>
|
||
CLR.L -(SP) ;stk: result < port < etc. <C699>
|
||
MOVE.L portList,-(SP) ;stk: plist < res < port < etc. <C699>
|
||
MOVEQ #2,D0 ;search after length <C699>
|
||
MOVE.L D0,-(SP) ;stk: #2 < plist < res < port < etc. <C699>
|
||
PEA 12(SP) ;PTR1 = GrafPtr <C699>
|
||
MOVEQ #4,D0 ;LEN1 = 4 bytes <C699>
|
||
MOVE.L D0,-(SP) ;stk: #4 < ptr1 < #2 < plist < res < port < <C699>
|
||
PEA @DONE ;PTR2 = XXX <C699>
|
||
CLR.L -(SP) ;LEN2 = 0 <C699>
|
||
_Munger ;rhymes with plunger <C699>
|
||
ADDQ #8,SP ;strip result, grafPort <C699>
|
||
BRA.S @REPEAT ;=>repeat until no more <C699>
|
||
@DONE RTS
|
||
|
||
|
||
FlushPalettes ; patch rolled in <10Jun87 EHB>
|
||
;-----------------------------------------------------------------------
|
||
; Call DisposePalette for all palettes in the app heap.
|
||
;
|
||
; Registers: D0-D2/A0-A1
|
||
; Called by vIAZInit.
|
||
;----------------------------------------------------------------------
|
||
MOVEM.L A2-A3/D3,-(SP) ; save work registers
|
||
MOVE.L PMgrHandle,A2 ; get paletteMgr handle
|
||
CMP.L MinusOne,A2 ; is it there?
|
||
BEQ.S @DONE ; => no, just return
|
||
MOVE.L (A2),A1 ; point to data structure
|
||
MOVE.L PListHandle(A1),A0 ; get handle to palette list
|
||
_HLock ; and lock it down
|
||
MOVE.L (A0),A3 ; point to palette list
|
||
|
||
Move APalettes(A1),D3 ; get number of active handles
|
||
Beq.s @NoPals ; no friends => go home
|
||
Add FreeSpaces(A1),D3 ; calculate total number of entries
|
||
BRA.S @FindEnd ; => check for no entries
|
||
|
||
@FindLoop Move.L PaletteRef(A3),D1 ; get first entry
|
||
BEQ.S @FindNext ; => no palette in entry
|
||
MOVE.L D1,D0 ; and get for routine
|
||
BSR.L AppZoneAddr ; in application area (or zero)? <SM30 BT>
|
||
BNE.S @FindNext ; => not in app heap
|
||
MOVE.L D1,-(SP) ; push palette handle
|
||
_DisposePalette ; and dispose it in place
|
||
@FindNext AddQ #PLstEntrySz,A3 ; bump to the next entry
|
||
@FindEnd DBra D3,@FindLoop ; repeat for all spaces
|
||
|
||
@NoPals MOVE.L (A2),A1 ; point to palette stuff
|
||
MOVE.L PListHandle(A1),A0 ; get handle to palette list
|
||
_HUnlock ; and unlock it
|
||
|
||
@DONE MOVEM.L (SP)+,A2-A3/D3 ; restore work registers
|
||
RTS
|
||
|
||
;----------------------------------------------------------------------
|
||
; vIAZPostInit new <C681>
|
||
; - last-minute inits after ApplZone has been created.
|
||
; Registers: D0-D2/A0-A1
|
||
; Called by InitApplZone via jIAZPostInit vector.
|
||
;----------------------------------------------------------------------
|
||
vIAZPostInit
|
||
_InitAllPacks ; reinstall the packages -- may trash MemErr <25Apr85>
|
||
|
||
CLR.W CurApRefNum ; since all app heap res files closed <C681>
|
||
_RDrvrInstall ; fix up ram based drivers <C681>
|
||
|
||
; clear the pack6 resource cache when launching (for Int'l Utilities / Script Mgr)
|
||
; moved here from InitApplZone because it seems to make more sense. <sm10>stb
|
||
with ExpandMemRec
|
||
move.l expandMem,a0 ; expand pointer
|
||
add.w #emItlCache,a0 ; point to cache
|
||
move.l #emItlCacheSize/4-1,d0 ; dbra ptr
|
||
@ClearCache
|
||
clr.l (a0)+ ; clear part of cache
|
||
dbra d0,@ClearCache ; until done
|
||
endWith
|
||
|
||
RtS
|
||
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
; InitZone(startPtr, limitPtr: Ptr; mAllocCnt: INTEGER;
|
||
; growZone: ProcPtr);
|
||
; - Initialize a heap zone, and set theZone to that zone.
|
||
; Signal noErr globally, nowadays. <25Apr85>
|
||
; Set HiHeapMark if new heap end is below SP. <01Nov85 JTC>
|
||
; startPtr - start of heap zone
|
||
; limitPtr - end of heap zone
|
||
; mAllocCnt - number of master pointers to allocate initially
|
||
; and when more are needed.
|
||
; growZone - user supplied procedure to grow zone (must be
|
||
; supplied):
|
||
; FUNCTION growZone(bytesNeeded: LongInt): LongInt;
|
||
; (returns the number of bytes zone was grown by)
|
||
; <29jan85> User growZone in GZProc, StdGZ salted in spare1
|
||
;
|
||
;----------------------------------------------------------------------
|
||
|
||
InitZoneTrap
|
||
Move.L #jInitZone,-(SP) ; get offset onto stack <v1.9>
|
||
Move.L vMMNoPrologue,-(SP) ; get vector to MMnoPrologue<v1.9>
|
||
RTS
|
||
|
||
|
||
v24InitZone
|
||
MoveM.L A2-A3/A6,-(SP) ;Save registers
|
||
|
||
Move.L A0,A1 ;Argument vector pointer
|
||
Move.L (A1)+,A6 ;StartPtr (zone obj.)
|
||
SetZ A6 ;set theZone
|
||
|
||
Move.L A6,A0 ;zone object ptr
|
||
MOVE.L A6,A2 ;used for filling in fields
|
||
MoveQ #(HeapData-4)/4,D1
|
||
|
||
@IZClr24 Clr.L (A0)+ ;Zero heapzone header
|
||
DBrA D1,@IZClr24 ;leave A0=HeapData(A6)
|
||
|
||
; note that AllocPtr is zeroed . . .
|
||
; Set up hi heap mark according to LimitPtr. <01Nov85 JTC>
|
||
Move.L (A1)+,D1 ;LimitPtr, to be stripped of high bits <01Nov85 JTC>
|
||
And.L Lo3Bytes,D1 ;24 bits only <01Nov85 JTC>
|
||
|
||
;---------------------------------------------------------------------- <T6> <2> kc.start
|
||
; Align the trailer block on 040 cpus so that when a MoveHHi call is made the block will
|
||
; be line aligned.
|
||
|
||
Align24Trailer
|
||
Cmpi.b #cpu68040,CPUFlag ; Are we on an 040 or greater?
|
||
Blo.s @0 ; No? Then long align.
|
||
Tst.l pVMGlobals ; VM running? <T7>
|
||
Bpl.s @0 ; Yea? Then don't patch.<T7>
|
||
|
||
Subq.l #16-MinFree24,D1
|
||
AndI.w #$FFF0,D1
|
||
Add.l #16-MinFree24,D1
|
||
MoveA.L D1,A3 ; LimitPtr
|
||
bra.s @05
|
||
|
||
@0 AndI.W #$FFFC,D1 ; LimitPtr = 4x
|
||
MoveA.L D1,A3 ; LimitPtr
|
||
@05 ; <2> kc.end
|
||
|
||
CmpA.L HiHeapMark,A3 ;24-bit subtract A3-HiHeapMark <01Nov85 JTC>
|
||
BLT.S @1 ;Less Than (unsigned OK) ==> below HiHeap <01Nov85 JTC>
|
||
Move.L SP,D1 ;Must strip to compare successfully! <01Nov85 JTC>
|
||
And.L Lo3Bytes,D1 ;24-bit sp <01Nov85 JTC>
|
||
CmpA.L D1,A3 ;LimitPtr-SP <01Nov85 JTC>
|
||
BGT.S @1 ;Greater Than (signed OK) ==> in stack <01Nov85 JTC>
|
||
Move.L A3,HiHeapMark ;a new 24-bit limit! <01Nov85 JTC>
|
||
@1 ;bypass point for setting HiHeapMark <01Nov85 JTC>
|
||
|
||
MoveQ #MinFree24,D1 ;MinFree=16 bytes <v1.2>
|
||
Sub.L D1,A3 ;LimitPtr-MinFree
|
||
Move.L D1,TagBC24(A3) ;make limit block <v1.1>
|
||
|
||
Move.L A3,(A2)+ ;BkLim(A6)
|
||
Move.L A0,(A2)+ ;PurgePtr(A6) - rover starts at
|
||
; HeapData(A6)
|
||
AddQ #4,A2 ;skip HFstFree
|
||
|
||
Sub.L A0,A3 ;BkLim(A6) - HeapData(A6)
|
||
Move.L A3,D0
|
||
Move.L D0,(A2)+ ;ZCBFree(A6)
|
||
|
||
Move.W (A1)+,D1 ;CMoreMasters
|
||
Move.L (A1)+,(A2)+ ;PGrowZone -> GZProc(A6)
|
||
|
||
; <29jan85> Stuff system growZone into spare1. Use fact that A1 is free; A2 = mAllocCnt(A6)
|
||
LEA StdGZ,A1 ;system GZProc <29jan85>
|
||
Move.L A1,(spare1-mAllocCnt)(A2)
|
||
|
||
Move.W D1,(A2)+ ;CMoreMasters -> mAllocCnt(A6)
|
||
Move.W mmDefFlags,(A2)+ ;Flags(A6)
|
||
|
||
Move.B #Is24Zone,Zone32Flag(A6); set zone to be 24 bit <v1.1>
|
||
Move.L #JMemMgr24,ZoneJumpV(A6); set jump vector in the zone <v1.1>
|
||
|
||
BSR a24MakeBKF ;start with 1 large free block <v1.1>
|
||
;A0=blk ptr, D0=size
|
||
BSR a24HMakeMoreMasters ;HFstFree(A6)=0 <v1.1>
|
||
|
||
; After first block of master pointers is allocated, check that zone is line aligned on 040s. <2> kc.start
|
||
; If not, pad the mp block out by two bytes, diminishing the free block following and the
|
||
; the global free count. This ensures that all subsequent allocations will be aligned.
|
||
; Be sure to update the allocation rover, which may be pointing to the big free block.
|
||
|
||
Init24ZoneAlign
|
||
Cmpi.b #cpu68040,CPUFlag ; Are we on an 040 or greater?
|
||
Blt.s @0 ; No? Then long align.
|
||
Tst.l pVMGlobals ; VM running? <T7>
|
||
Bpl.s @0 ; Yea? Then don't patch.<T7>
|
||
|
||
LEA heapData(A6),A0 ; A0 -> mp block
|
||
Move.l A0,D0 ;
|
||
Add.l #BlkData24,D0
|
||
Move.L (A0),D1 ; D0 := length of mp block
|
||
And.L Lo3Bytes,D1 ;
|
||
Add.l D1,D0
|
||
And.l #$F,D0 ; Eq => multiple of 16, ok
|
||
BEq.S @postMPAlign ;
|
||
|
||
Not.b D0 ; Get remainder.
|
||
And.b #$F,D0 ; Only care about bottom 4 bits.
|
||
Addq.b #1,D0 ; Add in 1.
|
||
|
||
Sub.L D0,ZCBFree(A6) ; taking up xx free bytes for pad
|
||
MoveA.L A0,A1 ;
|
||
AddA.L D1,A1 ; A1 -> free block after mp
|
||
Add.B D0,(A0) ; increment slop count
|
||
Add.L D0,(A0) ; increment block size
|
||
Sub.L D0,(A1) ; decrement free block size
|
||
Move.L (A1),0(A1,D0) ; move relevant part of free block header
|
||
Add.L D0,A1 ; A1 -> new free block
|
||
Move.L A1,allocPtr(A6) ; be sure rover is valid
|
||
Bra.s @postMPAlign
|
||
|
||
@0 Move.L A6,D0 ;
|
||
BTst #1,D0 ; Eq => multiple of 4, ok
|
||
BEq.S @postMPAlign ;
|
||
|
||
SubQ.L #2,ZCBFree(A6) ; taking up 2 free bytes for pad
|
||
LEA heapData(A6),A0 ; A0 -> mp block
|
||
MoveA.L A0,A1 ;
|
||
Move.L (A0),D0 ; D0 := length of mp block
|
||
And.L Lo3Bytes,D0 ;
|
||
AddA.L D0,A1 ; A1 -> free block after mp
|
||
AddQ.B #2,(A0) ; increment slop count
|
||
AddQ.L #2,(A0) ; increment block size
|
||
SubQ.L #2,(A1) ; decrement free block size
|
||
Move.L (A1),2(A1) ; move relevant part of free block header
|
||
AddQ.L #2,A1 ; A1 -> new free block
|
||
Move.L A1,allocPtr(A6) ; be sure rover is valid <2> kc.end
|
||
@postMPAlign
|
||
|
||
; TrueType has a disk-based cache which puts font caches onto disk when they <sm10>stb
|
||
; get purged. This purgeProc will check to see whether a block which is being <sm10>stb
|
||
; purged is a font cache, and save it to disk if it is. <sm10>stb
|
||
lea DiskCachePurgeProcedure,A0 ; TrueType purge procedure <sm10>stb
|
||
move.l A0,purgeProc(A6) ; install purge procedure <sm10>stb
|
||
|
||
MoveM.L (SP)+,A2-A3/A6 ;Restore registers
|
||
MoveQ #0,D0 ;Success return <25Apr85>
|
||
Move.W D0,MemErr ;Record it globally, too <25Apr85>
|
||
RTS ;and return to caller
|
||
|
||
|
||
v32InitZone
|
||
MoveM.L A2-A3/A6,-(SP) ;Save registers
|
||
|
||
Move.L A0,A1 ;Argument vector pointer
|
||
Move.L (A1)+,A6 ;StartPtr (zone obj.)
|
||
SetZ A6 ;set theZone
|
||
|
||
Move.L A6,A0 ;zone object ptr
|
||
MOVE.L A6,A2 ;used for filling in fields
|
||
MoveQ #(HeapData-4)/4,D1
|
||
|
||
@IZClr32 Clr.L (A0)+ ; Zero heapzone header
|
||
DBrA D1,@IZClr32 ; leave A0=HeapData(A6)
|
||
|
||
; note that AllocPtr is zeroed . . .
|
||
; Set up hi heap mark according to LimitPtr. <01Nov85 JTC>
|
||
Move.L (A1)+,D1 ; LimitPtr, to be stripped of high bits <01Nov85 JTC>
|
||
Cmpi.b #cpu68040,CPUFlag ; Are we on an 040 or greater? <2> kc.start
|
||
Blt.s @0 ; No? Then long align.
|
||
Subq.l #4,D1
|
||
AndI.w #$FFF0,D1
|
||
Addq.l #4,D1
|
||
MoveA.L D1,A3 ; LimitPtr
|
||
bra.s @05
|
||
|
||
@0 AndI.W #$FFFC,D1 ; LimitPtr = 4x
|
||
MoveA.L D1,A3 ; LimitPtr
|
||
@05 ; <2> kc.end
|
||
CmpA.L HiHeapMark,A3 ; ??-bit subtract A3-HiHeapMark <01Nov85 JTC>
|
||
BLT.S @1 ; Less Than (unsigned OK) ==> below HiHeap <01Nov85 JTC>
|
||
Move.L SP,D1 ; Must strip to compare successfully! <01Nov85 JTC>
|
||
CmpA.L D1,A3 ; LimitPtr-SP <01Nov85 JTC>
|
||
BGT.S @1 ; Greater Than (signed OK) ==> in stack <01Nov85 JTC>
|
||
Move.L A3,HiHeapMark ; new limit <01Nov85 JTC>
|
||
@1 ; bypass point for setting HiHeapMark <01Nov85 JTC>
|
||
|
||
MoveQ #MinFree32,D1 ; MinFree=16 bytes <v1.2>
|
||
Sub.L D1,A3 ; LimitPtr-MinFree
|
||
Clr.L TagBC32(A3) ; set limit block as free block <v1.1>
|
||
Move.L D1,blkSize32(A3) ;make limit block <v1.1>
|
||
|
||
Move.L A3,(A2)+ ; BkLim(A6)
|
||
Move.L A0,(A2)+ ; PurgePtr(A6) - rover starts at
|
||
; HeapData(A6)
|
||
AddQ #4,A2 ; skip HFstFree
|
||
|
||
Sub.L A0,A3 ; BkLim(A6) - HeapData(A6)
|
||
Move.L A3,D0
|
||
Move.L D0,(A2)+ ; ZCBFree(A6)
|
||
|
||
Move.W (A1)+,D1 ; CMoreMasters
|
||
Move.L (A1)+,(A2)+ ; PGrowZone -> GZProc(A6)
|
||
|
||
; <29jan85> Stuff system growZone into spare1. Use fact that A1 is free; A2 = mAllocCnt(A6)
|
||
LEA StdGZ,A1 ; system GZProc <29jan85>
|
||
Move.L A1,(spare1-mAllocCnt)(A2)
|
||
|
||
Move.W D1,(A2)+ ; CMoreMasters -> mAllocCnt(A6)
|
||
Move.W mmDefFlags,(A2)+ ; Flags(A6)
|
||
|
||
Move.B #Is32Zone,Zone32Flag(A6); set zone to be 32 bit <v1.1>
|
||
Move.L #JMemMgr32,ZoneJumpV(A6); set jump vector in the zone <v1.1>
|
||
|
||
BSR a32MakeBKF ; start with 1 large free block <v1.1>
|
||
; A0=blk ptr, D0=size
|
||
BSR a32HMakeMoreMasters ; HFstFree(A6)=0 <v1.1>
|
||
|
||
; After first block of master pointers is allocated, check that zone is longword aligned.
|
||
; If not, pad the mp block out by two bytes, diminishing the free block following and the
|
||
; the global free count. This ensures that all subsequent allocations will be aligned.
|
||
; Be sure to update the allocation rover, which may be pointing to the big free block.
|
||
;
|
||
; This attempt is feeble given the removal of alignment in routine ActualS in HeapGuts.a <A415>
|
||
; but the code is left in to ensure that at least the beginning of the heap is cool. <A415>
|
||
Cmpi.b #cpu68040,CPUFlag ; Are we on an 040 or greater? <2> kc.start
|
||
Blt.s @not040 ; No? Then long align.
|
||
|
||
LEA heapData(A6),A0 ; A0 -> mp block
|
||
Move.l A0,D0 ;
|
||
Add.l #BlkData32,D0
|
||
Move.L BlkSize32(A0),D1 ; D0 := length of mp block
|
||
Add.l D1,D0
|
||
And.l #$F,D0 ; Eq => multiple of 16, ok
|
||
BEq.S @postMPAlign ;
|
||
|
||
Not.b D0 ; Get remainder.
|
||
And.b #$F,D0 ; Only care about bottom 4 bits.
|
||
Addq.b #1,D0 ; Add in 1.
|
||
|
||
Sub.L D0,ZCBFree(A6) ; taking up xx free bytes for pad
|
||
MoveA.L A0,A1 ;
|
||
AddA.L D1,A1 ; A1 -> free block after mp
|
||
Add.B D0,SizeCor32(A0) ; increment slop count
|
||
Add.L D0,BlkSize32(A0) ; increment block size
|
||
Sub.L D0,BlkSize32(A1) ; decrement free block size
|
||
Move.L BlkSize32(A1),BlkSize32(A1,D0) ; move relevant part of free block header
|
||
|
||
Add.L D0,A1 ; A1 -> new free block
|
||
Clr.l tagBC32(A1) ; Clear off old blocksize.
|
||
|
||
Move.L A1,allocPtr(A6) ; be sure rover is valid
|
||
Bra.s @postMPAlign
|
||
|
||
@not040 Move.L A6,D0 ;
|
||
BTst #1,D0 ; Eq => multiple of 4, ok
|
||
BEq.S @postMPAlign ;
|
||
|
||
SubQ.L #2,ZCBFree(A6) ; taking up 2 free bytes for pad
|
||
LEA heapData(A6),A0 ; A0 -> mp block
|
||
MoveA.L A0,A1 ;
|
||
Move.L BlkSize32(A0),D0 ; D0 := length of mp block
|
||
AddA.L D0,A1 ; A1 -> free block after mp
|
||
AddQ.B #2,SizeCor32(A0) ; increment slop count
|
||
AddQ.L #2,BlkSize32(A0) ; increment block size
|
||
SubQ.L #2,BlkSize32(A1) ; decrement free block size
|
||
Move.L BlkSize32(A1),2+BlkSize32(A1) ; move block size
|
||
Move.L (A1),2(A1) ; move relevant part of free block header
|
||
AddQ.L #2,A1 ; A1 -> new free block
|
||
Move.L A1,allocPtr(A6) ; be sure rover is valid
|
||
@postMPAlign ; <2> kc.end
|
||
|
||
; TrueType has a disk-based cache which puts font caches onto disk when they <sm10>stb
|
||
; get purged. This purgeProc will check to see whether a block which is being <sm10>stb
|
||
; purged is a font cache, and save it to disk if it is. <sm10>stb
|
||
lea DiskCachePurgeProcedure,A0 ; TrueType purge procedure <sm10>stb
|
||
move.l A0,purgeProc(A6) ; install purge procedure <sm10>stb
|
||
|
||
MoveM.L (SP)+,A2-A3/A6 ; Restore registers
|
||
IZCleanExit ; Common no-error exit <25Apr85>
|
||
MoveQ #0,D0 ; Success return <25Apr85>
|
||
Move.W D0,MemErr ;Record it globally, too <25Apr85>
|
||
RTS ;and return to caller
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; FUNCTION GetZone: Ptr;
|
||
;
|
||
; - Returns the global pointer to the current heap
|
||
; Uses A0 only.
|
||
;
|
||
|
||
GetZone
|
||
Move.L #JGetZone,-(SP) ; get offset onto stack <v1.9>
|
||
Move.L vMMNoPrologue,-(SP) ; get vector to MMnoPrologue<v1.9>
|
||
RTS
|
||
|
||
|
||
vGetZone ; <v1.1>
|
||
GetZ A0 ;Set up return value
|
||
|
||
BrA.S IZCleanExit ;Use common routine above <25Apr85>
|
||
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
;PROCEDURE SetZone(Hz: Ptr);
|
||
;
|
||
; - Set global pointer to the current heap zone
|
||
; Uses A0 only.
|
||
;
|
||
|
||
SetZone
|
||
Move.L #JSetZone,-(SP) ; get offset onto stack <v1.9>
|
||
Move.L vMMNoPrologue,-(SP) ; get vector to MMnoPrologue<v1.9>
|
||
RTS
|
||
|
||
|
||
vSetZone ; <v1.1>
|
||
SetZ A0 ;Set up return value
|
||
|
||
BrA.S IZCleanExit ;Use common routine above <25Apr85>
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; FUNCTION CompactMem(cb: LongInt):[pblk: Ptr; cbFound: LongInt];
|
||
; FUNCTION MaxBlock :[pblk: Ptr; cbFound: LongInt];
|
||
;
|
||
; MaxBlock is modeled on CompactMem, but calls with #MaxMem as requested size
|
||
; (in order to find the largest available space) and with FNSelCompct=0 to
|
||
; prevent costly compaction.
|
||
;
|
||
MaxBlockTrap ;new routine <10Apr85>
|
||
PEA @Slime ;slimy solution for slimy problem <v1.9>
|
||
MOVE.L RealMemTop,D0 ;make an outlandish request <v1.9>
|
||
|
||
MOVE.L #JMaxBlock,-(SP) ; get offset to routine <v1.9>
|
||
MOVE.L vMMPrologue,-(SP) ; get vector to MMPrologue <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
|
||
|
||
@Slime ; <v1.5>
|
||
SUBQ.L #4,D0 ;reduce size by 4 byte to account for <v1.5>
|
||
;block starts and ends in non long word <v1.5>
|
||
;address, if 4 is too big, the extra 2 <v1.5>
|
||
;byte can act as margin. <v1.5>
|
||
BGE.S @Return ;if less than zero, then return 0 <v1.5>
|
||
MoveQ.L #0,D0 ;return 0 for length <v1.5>
|
||
@Return ; <v1.5>
|
||
RTS ; <v1.5>
|
||
|
||
CompactMemTrap
|
||
MOVE.L #JCompactMem,-(SP) ; get offset to routine <v1.9>
|
||
MOVE.L vMMPrologue,-(SP) ; get vector to MMPrologue <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
|
||
v24MaxBlock
|
||
MOVEQ #1,D1 ; mark routine as MaxBlock <v1.9>
|
||
BRA.S v24CMGuts ; branch to common code <v1.9>
|
||
|
||
v24CompactMem ;
|
||
MOVEQ #0,D1 ; mark as CompactMem <v1.9>
|
||
|
||
v24CMGuts
|
||
BSR a24ActualS ;adjust size <v1.1>
|
||
|
||
LEA Flags(A6),A1 ;useful address
|
||
Move.B (A1),D2 ;preserve current flags in D2
|
||
|
||
TST.B D1 ;nonzero means MaxBlock <10Apr85>
|
||
BNE.S @1 ;don't do compaction <10Apr85>
|
||
BSet #FNSelCompct,(A1) ;compact always for CompactMem <10Apr85>
|
||
BRA.S @3 ; <10Apr85>
|
||
@1 ; <10Apr85>
|
||
BClr #FNSelCompct,(A1) ;never compact for MaxBlock <10Apr85>
|
||
@3 ; <10Apr85>
|
||
|
||
Bsr.l a24CompactHp ;compact heap <2> kc.start
|
||
Move.B D2,(A1) ;restore flags
|
||
|
||
Cmpi.b #cpu68040,CPUFlag ; Are we on an 040 or greater?
|
||
Blt.s @0 ; No? Then no alignment.
|
||
Tst.l pVMGlobals ; VM running?
|
||
Bpl.s @0 ; Yea? Then no alignment.
|
||
|
||
AndI.W #$FFF0,D1 ; Line align result.
|
||
|
||
@0 Move.L D1,D0 ;Size of largest block found <2> kc.end
|
||
BEq PMExit24 ;hasty exit through our epilogue <v1.1>
|
||
SubQ.L #BlkData24,D0 ;convert back to logical cb <v1.1>
|
||
|
||
Move.L A0,D1 ;was a large enough blk found?
|
||
BEq.S PMExit24 ;Eq => NIL, return that
|
||
BrA.S PMOK24
|
||
|
||
|
||
v32MaxBlock
|
||
MOVEQ #1,D1 ; mark routine as MaxBlock <v1.9>
|
||
BRA.S v32CMGuts ; branch to common code <v1.9>
|
||
|
||
v32CompactMem ;
|
||
MOVEQ #0,D1 ; mark as CompactMem <v1.9>
|
||
|
||
v32CMGuts ;entry point from MaxBlock <10Apr85>
|
||
BSR a32ActualS ;adjust size <v1.1>
|
||
|
||
LEA Flags(A6),A1 ;useful address
|
||
Move.B (A1),D2 ;preserve current flags in D2
|
||
|
||
TST.B D1 ;nonzero means MaxBlock <10Apr85>
|
||
BNE.S @1 ;don't do compaction <10Apr85>
|
||
BSet #FNSelCompct,(A1) ;compact always for CompactMem <10Apr85>
|
||
BRA.S @3 ; <10Apr85>
|
||
@1 ; <10Apr85>
|
||
BClr #FNSelCompct,(A1) ;never compact for MaxBlock <10Apr85>
|
||
@3 ; <10Apr85>
|
||
Bsr.l a32CompactHp ;compact heap <2> kc.start
|
||
Move.B D2,(A1) ;restore flags
|
||
|
||
Cmpi.b #cpu68040,CPUFlag ; Are we on an 040 or greater?
|
||
Blt.s @0 ; No? Then no alignment.
|
||
|
||
AndI.W #$FFF0,D1 ; Line align result.
|
||
|
||
@0 Move.L D1,D0 ;Size of largest block found <2> kc.end
|
||
BEq.S PMExit32 ;hasty exit through our epilogue <v1.1>
|
||
Sub.L #BlkData32,D0 ;convert back to logical cb <v1.1>
|
||
|
||
Move.L A0,D1 ;was a large enough blk found? <v1.1>
|
||
BEq.S PMExit32 ;Eq => NIL, return that <v1.1>
|
||
BrA.S PMOK32
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; FUNCTION PurgeMem(cb: LongInt): pblk: Ptr;
|
||
;
|
||
|
||
PurgeMem
|
||
MOVE.L #JPurgeMem,-(SP) ; get offset to routine <v1.9>
|
||
MOVE.L vMMPrologue,-(SP) ; get vector to MMPrologue <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
|
||
v24PurgeMem ; 24 bit version of Purgemem <v1.1>
|
||
BSR a24ActualS ; adjust size <v1.1>
|
||
BSR a24PurgeHeap ; Purge the Heap <v1.1>
|
||
PMRMExit24 Move.L A0,D0 ; was a large enough blk found?
|
||
BNE.S PMNNil24 ; Yes, return success <v1.1>
|
||
|
||
MoveQ #memFullErr,D0 ; No, not enough room in mem.
|
||
BrA.S PMExit24
|
||
PMNNil24
|
||
MoveQ #0,D0 ; and show success return
|
||
PMOk24
|
||
AddQ.L #BlkData24,A0 ; else, point to data field.
|
||
PMExit24
|
||
BRA.S PMExit32 ; go to common exit <v1.9>
|
||
|
||
v32PurgeMem ; 32 bit version of Purgemem <v1.1>
|
||
BSR a32ActualS ; adjust size <v1.1>
|
||
BSR a32PurgeHeap ; Purge the Heap <v1.1>
|
||
PMRMExit32 Move.L A0,D0 ; was a large enough blk found?
|
||
BNE.S PMNNil32 ; Yes, return success <v1.1>
|
||
|
||
MoveQ #memFullErr,D0 ; No, not enough room in mem.
|
||
BrA.S PMExit32 ; <v1.1>
|
||
PMNNil32
|
||
MoveQ #0,D0 ; and show success return
|
||
PMOk32
|
||
Add.L #BlkData32,A0 ; else, point to data field. <v1.1>
|
||
PMExit32
|
||
Move.L vMMEpilogue,-(SP) ; get vector to MMEpilogue <v1.9>
|
||
RTS ; jump to it <v1.9>
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; FUNCTION PurgeSpace: [totalPurgeAndFree, contigPurgeAndFree : LongInt]; <17Apr85>
|
||
; On exit:
|
||
; D0 - total number of purgeable and free bytes in zone
|
||
; A0 - maximum possible contiguous space after purge (that is, max total of free
|
||
; and purgeable by 'region'.
|
||
; This function scans only; it does not purge, compact, nor allocate!
|
||
;
|
||
|
||
PurgeSpaceTrap
|
||
MOVE.L #JPurgeSpace,-(SP) ; get offset to routine <v1.9>
|
||
MOVE.L vMMPrologue,-(SP) ; get vector to MMPrologue <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
|
||
v24PurgeSpace ; 24 bit version of PurgeSpace <v1.1>
|
||
BSR a24TotePurgeables ; returns D0,A0 trashes others... <17Apr85>
|
||
BRA.S PurgeSExit ; go to common exit routine <v1.9>
|
||
|
||
v32PurgeSpace ; 32 bit version of PurgeSpace <v1.1>
|
||
BSR a32TotePurgeables ; returns D0,A0 trashes others... <17Apr85>
|
||
|
||
PurgeSExit Move.L vMMEpilogue,-(SP) ; get vector to MMEpilogue <v1.9>
|
||
RTS ; jump to it <v1.9>
|
||
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; FUNCTION FreeMem: Longint;
|
||
; On exit:
|
||
; D0 - Returns the number of free bytes in the zone.
|
||
|
||
FreeMem
|
||
MOVE.L #JFreeMem,-(SP) ; get offset to routine <v1.9>
|
||
MOVE.L vMMPrologue,-(SP) ; get vector to MMPrologue <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
|
||
vFreeMem ; <v1.1>
|
||
Move.L ZCBFree(A6),D0 ; set result
|
||
Move.L vMMEpilogue,-(SP) ; get vector to MMEpilogue <v1.9>
|
||
RTS ; jump to it <v1.9>
|
||
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE ResrvMem;
|
||
; On exit:
|
||
; A0 - ptr to free block made or found.
|
||
; D0 - 0 if large enough block was found, memfullerr if not.
|
||
;
|
||
; This routine is used to open a block of free space as low in the heap
|
||
; as possible; it should be called before NwHandle if that handle is to
|
||
; be locked permanently (i.e., when using handles as non-relocatables) to
|
||
; prevent fragmentation of the heap.
|
||
;
|
||
; Arguments:
|
||
; D0: size of block required (logical size).
|
||
;
|
||
|
||
; ————————— SuperMario roll in <SM9> tcn ——————————————————————————————————————
|
||
; ResrvMem - make it grow System Heap, too.
|
||
; ResrvMem will not grow any heap other than ApplZone. This is a problem with the new, growable system heap.
|
||
; Process Mgr will grow the system heap for NewHandle calls. ResrvMem usually precedes a NewHandle,
|
||
; HLock sequence. If ResrvMem fails, the following NewHandle will cause the heap to grow (if it can).
|
||
; Then the block is allocated where the free space was made -- at the top.
|
||
;
|
||
; This proc not only causes the heap to grow, it also calls ResrvMem again to see how low the free block
|
||
; can be made.
|
||
;
|
||
; Notes:
|
||
; NewPtr calls ResrvMem again while doing the StdGZProc. We want it to call the user gzproc, so
|
||
; it’s important that ResrvMem return an error when it’s reentered. That’s why we have a semaphore.
|
||
;
|
||
; See also: NewPtr
|
||
;
|
||
;——————————————————————————————————————————————————————————————————————
|
||
|
||
ResrvMem
|
||
; -- roll in start --
|
||
move.l A1,-(SP) ; save A1
|
||
move.l ExpandMem,A1 ; is this a reentry?
|
||
tst.l ExpandMemRec.emResrvMemSemaphore(A1)
|
||
bne.s @leaveNowStillBusy ; yup, get out.
|
||
move.l #1,ExpandMemRec.emResrvMemSemaphore(a1) ; <PN> nope, set the semaphore
|
||
|
||
movem.l d0-d1,-(sp) ; save how much was asked for
|
||
jsr GetTheMem ; go get it
|
||
tst.w d0 ; test for os error
|
||
beq.s @leaveNowPopEm ; if zero, space was reserved and we’re done
|
||
|
||
; move.l 4(sp),d1 ; restore the trap word our caller used <5>
|
||
btst #tSysOrCurZone,d1 ; is this a _Resrvmem ,SYS?
|
||
bne.s @yupItsTheSystemHeap
|
||
move.l sysZone,a0 ; is this the (growable) system zone?
|
||
cmp.l theZone,a0
|
||
bne.s @leaveNowPopEm ; no, get out and leave other heaps alone
|
||
|
||
@yupItsTheSystemHeap
|
||
move.l (sp),d0 ; restore the amount being requested <5>
|
||
_NewPtr ,SYS ; force open a slot, even though it’s probably at the top of the heap
|
||
; because we just made the heap grow.
|
||
bne @leaveNowPopEm ; leave if we couldn’t get any space
|
||
|
||
_DisposPtr ; ok, we got it. now free it
|
||
movem.l (sp),d0-d1 ; ask ResrvMem again for this much. It will do a better job now that
|
||
jsr GetTheMem ; we know we have enough free space.
|
||
; dispatcher sets the z flag based on the function result
|
||
@leaveNowPopEm
|
||
addq #8,sp
|
||
|
||
@leaveNow
|
||
move.l ExpandMem,A1
|
||
clr.l ExpandMemRec.emResrvMemSemaphore(A1)
|
||
move.l (SP)+,A1 ; restore A1
|
||
rts
|
||
|
||
@leaveNowStillBusy
|
||
move.l (SP)+,A1 ; restore A1
|
||
moveq #memFullErr,d0 ; failure
|
||
move.w d0,MemErr
|
||
rts
|
||
; -- roll in end --
|
||
|
||
GetTheMem
|
||
MOVE.L #JResrvMem,-(SP) ; get offset to routine <v1.9>
|
||
MOVE.L vMMPrologue,-(SP) ; get vector to MMPrologue <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
v24ResrvMem ; 24 bit version of PurgeSpace <v1.1>
|
||
TST.L HFstFree(A6) ;Any masters left?
|
||
BNE.S @1 ;br if so
|
||
Move.W mAllocCnt(A6),D2 ;Number of masters to make.
|
||
Ext.L D2
|
||
|
||
ASL.L #2,D2 ;Convert MP count to byte count.
|
||
AddQ.L #BlkData24,D2 ;And block header <v1.1>
|
||
Add.L D2,D0 ;Increase req count by ptr blk
|
||
|
||
@1 BSR a24MakePtrSpc ;Make room at the low end. <v1.1>
|
||
Move.L A2,A0 ;Ptr to block
|
||
BrA.S PMRMExit24 ;Do the purge mem exit trip . . . <v1.1>
|
||
|
||
v32ResrvMem ; 32 bit version of PurgeSpace <v1.1>
|
||
TST.L HFstFree(A6) ;Any masters left?
|
||
BNE.S @1 ;br if so
|
||
Move.W mAllocCnt(A6),D2 ;Number of masters to make.
|
||
Ext.L D2
|
||
ASL.L #2,D2 ;Convert MP count to byte count.
|
||
|
||
Add.L #BlkData32,D2 ;And block header <v1.1>
|
||
Add.L D2,D0 ;Increase req count by ptr blk
|
||
|
||
@1 BSR a32MakePtrSpc ;Make room at the low end. <v1.1>
|
||
Move.L A2,A0 ;Ptr to block
|
||
BrA.S PMRMExit32 ;Do the purge mem exit trip . . . <v1.1>
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; FUNCTION MaxMem: LongInt;
|
||
; On exit:
|
||
; If request pertains to application heap:
|
||
; A0 - returns the size of memory available for the application heap to grow
|
||
; D0 - Returns the size of the largest available contiguous free space.
|
||
; If request pertains to any other heap heap:
|
||
; A0 - 0, since only application heap may grow
|
||
; D0 - Returns the size of the largest available contiguous free space.
|
||
;----------------------------------------------------------------------
|
||
|
||
MaxMemTrap
|
||
MOVE.L #JMaxMem,-(SP) ; get offset to routine <v1.9>
|
||
MOVE.L vMMPrologue,-(SP) ; get vector to MMPrologue <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
|
||
v24MaxMem ; 24 bit version of MaxMem <v1.1>
|
||
|
||
Move.L RealMemTop,D0 ;BkCompactS(MaxSize <v1.9>
|
||
|
||
MoveQ #0,D2 ; False <2> kc.start
|
||
Bsr.l a24BkCompactS
|
||
|
||
Cmpi.b #cpu68040,CPUFlag ; Are we on an 040 or greater?
|
||
Blt.s @0 ; No? Then no alignment.
|
||
Tst.l pVMGlobals ; VM running?
|
||
Bpl.s @0 ; Yea? Then no alignment.
|
||
|
||
AndI.W #$FFF0,D1 ; Line align result.
|
||
|
||
@0 Move.L D1,D0 ;return adjusted max <2> kc.end
|
||
BEq.S @1 ;block size, unless 0
|
||
|
||
SubQ.L #BlkData24,D0 ;Allow for overhead
|
||
|
||
@1
|
||
Sub.L A0,A0 ;if not applZone => return 0 in A0
|
||
Move.L applZone,A1 ;If request not for
|
||
Cmp.L theZone,A1 ;applic heap...
|
||
BNE.S MMExit24 ;then return <v1.1>
|
||
|
||
; Now return the size of memory available for the application heap to grow
|
||
|
||
Move.L ApplLimit,D2 ;static applLimit
|
||
BSR a24MaxLimit ;don't get closer than MinStack <v1.1>
|
||
Sub.L HeapEnd,D1
|
||
Move.L D1,A0 ;return in A0
|
||
MMExit24
|
||
BRA.S MMExit32 ; jump to common exit <v1.9>
|
||
|
||
v32MaxMem ; 32 bit version of MaxMem <v1.1>
|
||
|
||
Move.L RealMemTop,D0 ;BkCompactS(MaxSize <v1.9>
|
||
|
||
MoveQ #0,D2 ; False <2> kc.start
|
||
Bsr.l a32BkCompactS
|
||
|
||
Cmpi.b #cpu68040,CPUFlag ; Are we on an 040 or greater?
|
||
Blt.s @0 ; No? Then no alignment.
|
||
|
||
AndI.W #$FFF0,D1 ; Line align result.
|
||
|
||
@0 Move.L D1,D0 ;return adjusted max <2> kc.end
|
||
BEq.S @1 ;block size, unless 0
|
||
|
||
Sub.L #BlkData32,D0 ;Allow for overhead <v1.1>
|
||
|
||
@1
|
||
Sub.L A0,A0 ;if not applZone => return 0 in A0
|
||
Move.L applZone,A1 ;If request not for
|
||
Cmp.L theZone,A1 ;applic heap...
|
||
BNE.S MMExit32 ;then return <v1.1>
|
||
|
||
; Now return the size of memory available for the application heap to grow
|
||
|
||
Move.L ApplLimit,D2 ;static applLimit
|
||
BSR a32MaxLimit ;don't get closer than MinStack <v1.1>
|
||
Sub.L HeapEnd,D1
|
||
Move.L D1,A0 ;return in A0
|
||
|
||
MMExit32
|
||
Move.L vMMEpilogue,-(SP) ; get vector to MMEpilogue <v1.9>
|
||
RTS ; jump to it <v1.9>
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE SetGrowZone(GrowZone: Ptr);
|
||
;
|
||
; - sets the GrowZone procedure for the current heap zone to be
|
||
; that supplied by the user
|
||
; On entry, Registers:
|
||
; A0 - GrowZone procedures' address
|
||
;
|
||
|
||
SetGrowZone
|
||
Move.L #JSetGrowZone,-(SP) ; get offset onto stack <v1.9>
|
||
Move.L vMMNoPrologue,-(SP) ; get vector to MMnoPrologue<v1.9>
|
||
RTS
|
||
|
||
vSetGrowZone
|
||
GetZ A1 ; A1 - theZone
|
||
Move.L A0,GZProc(A1) ; set user's GrowZone procedure
|
||
BrA.S SALOk
|
||
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE SetApplLimit(zonelimit: Long);
|
||
;
|
||
; - sets the limit of the application zone
|
||
; - <29jan85> Now checks it, too!
|
||
; Return error code globally now. <25Apr85>
|
||
; Mask A0 with Lo3Bytes before compare with HiHeapMark or BKLim. <01Nov85 JTC>
|
||
; Pin minimum allowed stack to DefltStack in low memory, since larger <C636 JTC>
|
||
; stacks are required on color machines are old-style apps are starving them. <C636 JTC>
|
||
; On entry, Registers:
|
||
; A0 - zone limit (in bytes)
|
||
;
|
||
|
||
SetApplLimit
|
||
Move.L #JSetApplLimit,-(SP) ; get offset onto stack <v1.9>
|
||
Move.L vMMNoPrologue,-(SP) ; get vector to MMnoPrologue<v1.9>
|
||
RTS
|
||
|
||
v24SetApplLimit ; 24 bit version of setApplLimit <v1.1>
|
||
Move.L A0,D0 ; suggested new value <01Nov85 JTC>
|
||
And.L Lo3Bytes,D0 ; 24-bit address candidate for new limit <01Nov85 JTC>
|
||
MoveA.L D0,A0 ; presume this is lower value <01Nov85 JTC>
|
||
Move.L SP,D1 ; try SP-DefltStack <C636>
|
||
And.L Lo3Bytes,D1 ; 24-bit SP <C636>
|
||
Sub.L DefltStack,D1 ; masked(SP-DefltStack) <C636>
|
||
Cmp.L D0,D1 ; (SP-DefltStack) - <suggested> <C636>
|
||
BGT.S @1 ; D0 < D1 --> suggested value OK <C636>
|
||
MoveA.L D1,A0 ; D1 ≤ D0 --> use SP-DefltStack <C636>
|
||
@1 ; bypass using DefltStack pinning <C636>
|
||
Move.L A0,ApplLimit ; Set the application limit
|
||
; (don't worry, GrowZone checks it dynamically)
|
||
; the above claim is B.S. <29jan85>
|
||
Move.L A0,HiHeapMark ; New high! <01Nov85 JTC><C765><C778>
|
||
|
||
Move.L ApplZone,A1 ; point to the app zone <29jan85>
|
||
Move.L BKLim(A1),A1 ; point to limit block <29jan85>
|
||
MoveQ #MemFullErr,D0 ; presume the worst <29jan85>
|
||
Cmp.L A0,A1 ; BKLim - ApplZone <29jan85>
|
||
BHi.S SALNotOk ; Hi ==> already beyond limit <29jan85>
|
||
; LowOrSame ==> fall through Ok <29jan85>
|
||
SALOk
|
||
MoveQ #0,D0 ; return success
|
||
SALNotOk ; get here if memFull above <29jan85>
|
||
Move.W D0,MemErr ; stuff error globally <25Apr85>
|
||
RTS
|
||
|
||
v32SetApplLimit ; 32 bit version of setApplLimit <v1.1>
|
||
Move.L A0,D0 ; suggested new value <v1.1>
|
||
Move.L SP,D1 ; try SP-DefltStack <v1.1>
|
||
Sub.L DefltStack,D1 ; masked(SP-DefltStack) <C636>
|
||
Cmp.L D0,D1 ; (SP-DefltStack) - <suggested> <C636>
|
||
BGT.S @1 ; D0 < D1 --> suggested value OK <C636>
|
||
MoveA.L D1,A0 ; D1 ≤ D0 --> use SP-DefltStack <C636>
|
||
@1 ; bypass using DefltStack pinning <C636>
|
||
Move.L A0,ApplLimit ; Set the application limit
|
||
; (don't worry, GrowZone checks it dynamically)
|
||
; the above claim is B.S. <29jan85>
|
||
Move.L A0,HiHeapMark ; New high! <01Nov85 JTC><C765><C778>
|
||
|
||
Move.L ApplZone,A1 ; point to the app zone <29jan85>
|
||
Move.L BKLim(A1),A1 ; point to limit block <29jan85>
|
||
MoveQ #MemFullErr,D0 ; presume the worst <29jan85>
|
||
Cmp.L A0,A1 ; BKLim - ApplZone <29jan85>
|
||
BHi.S @SALNotOk ; Hi ==> already beyond limit <29jan85>
|
||
; LowOrSame ==> fall through Ok <29jan85>
|
||
MoveQ #0,D0 ; return success
|
||
@SALNotOk ; get here if memFull above <29jan85>
|
||
Move.W D0,MemErr ; stuff error globally <25Apr85>
|
||
RTS
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; FUNCTION StackSpace : LongInt; <09May85>
|
||
;
|
||
; - returns Delta between SP and HiHeapMark. <C587>
|
||
; Stack on entry is:
|
||
; ret to dispatch << A0-A1 << ret within dispatch << D1-D2/A2 << trash long << ret to app
|
||
; so there are 4 + 8 + 4 + 12 + 4 + 4 = 36 more bytes available than indicated by the current
|
||
; SP. Since bkLim(xxx) refers to the beginning of a 16-byte block (change from 12 byte < v1,1>), <v1.1>
|
||
; and HiHeapMark is bkLim of the highest zone to date, the correct arithmetic is <C587>
|
||
; StackSpace := ( SP - BKLim(xxx) ) - 16 + 36 = SP - bkLim(xxx) + 20 <v1.1>
|
||
; The high bits of ApplZone and HiHeapMark are guaranteed to be clean. <C587>
|
||
;
|
||
|
||
StackSpaceTrap
|
||
Move.L #JStackSpace,-(SP) ; get offset onto stack <v1.9>
|
||
Move.L vMMNoPrologue,-(SP) ; get vector to MMnoPrologue<v1.9>
|
||
RTS
|
||
|
||
vStackSpace ; <v1.1>
|
||
MoveQ #20,D0 ;fudge factor <v1.1>
|
||
Add.L SP,D0 ; <09May85>
|
||
AndI.W #$FFFC,D0 ;round down to multiple of 4 <C251>
|
||
Sub.L HiHeapMark,D0 ; <C587>
|
||
Clr.W MemErr ;no problem here <09May85>
|
||
RtS
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE MaxApplZone;
|
||
;
|
||
; - lengthens the application zone out to ApplLimit, without extending the latter. <24Apr85>
|
||
; This routine depends on the values of bkLim(ApplZone), ApplLimit, and HeapEnd being
|
||
; free of extraneous high bits, since address arithmetic (comparable to that of ZoneAdjustEnd,
|
||
; MaxLimit, and GrowZone in HeapGuts) is performed. Also, ApplLimit is forced to be (unsigned)
|
||
; greater or equal to HeapEnd, so their difference may be interpreted as unsigned.
|
||
;
|
||
; Uses SALOk to stuff noErr code. <25Apr85>
|
||
; Take care to force HiHeapMark if it was less than current ApplLimit. <C731>
|
||
;
|
||
; On entry: none
|
||
; On exit: D0=0
|
||
; Trashes: A0-A1/D0-D2
|
||
;
|
||
|
||
MaxApplZone
|
||
Move.L #JMaxApplZone,-(SP) ; get offset onto stack <v1.9>
|
||
Move.L vMMNoPrologue,-(SP) ; get vector to MMnoPrologue<v1.9>
|
||
RTS
|
||
|
||
v24MaxApplZone ; 24 bit version of MaxApplZone <v1.1>
|
||
Move.L ApplLimit,D0 ; alleged end of the zone
|
||
Cmpi.b #cpu68040,CPUFlag ; Are we on an 040 or greater? <2> kc.start
|
||
Blt.s @0 ; No? Then no alignment.
|
||
Tst.l pVMGlobals ; VM running?
|
||
Bpl.s @0 ; Yea? Then no alignment.
|
||
|
||
Andi.w #$FFF0,D0 ; Force line alignment.
|
||
Sub.l #BlkData24,D0 ; Header size.
|
||
Bra.s @1
|
||
|
||
@0 AndI.W #$FFFC,D0 ; round down to multiple of 16
|
||
@1 Move.L D0,D1 ; <2> kc.end
|
||
LEA HeapEnd,A1 ; we'll use and possibly set this value
|
||
Sub.L (A1),D0 ; amount of heap growth, if any; (this value is NONNEGATIVE) NOT!
|
||
BCS.S @MAZFini ; Carry Set => minFree > delta, no dice... <SM24>
|
||
MoveQ #minFree24,D2 ; beneath this epsilon we will not grow <v1.2>
|
||
Cmp.L D2,D0
|
||
BCS.S @MAZFini ; Carry Set => minFree > delta, no dice...
|
||
|
||
MoveA.L (A1),A0 ; current bkLim ptr is the new (large) free block
|
||
Move.L D0,(A0) ; force large free block there, freeing A0
|
||
Move.L D1,(A1) ; new heapEnd := bkLim, freeing A1
|
||
MoveA.L D1,A0 ; we need it as a ptr, in an A-register
|
||
CmpA.L HiHeapMark,A0 ; is this a new high for heap extents? <C731>
|
||
BLS.S @noNewHigh ; HiHeapMark ≥ A0 => no change <C731>
|
||
Move.L A0,HiHeapMark ; HiHeapMark < A0 => reset HiHeapMark <C731>
|
||
@noNewHigh ; skip to here when HiHeapMark OK <C731>
|
||
MoveA.L ApplZone,A1 ; now adjust the zone header
|
||
Move.L A0,bkLim(A1)
|
||
Move.L D2,(A0) ; make it a minFree block
|
||
Add.L D0,ZCBFree(A1) ; adjust free block count
|
||
@MAZFini
|
||
BrA.S SALOk ; stuff the noErr code there <25Apr85>
|
||
|
||
|
||
v32MaxApplZone ; 32 bit version of MaxApplZone <v1.1>
|
||
Move.L ApplLimit,D0 ; alleged end of the zone
|
||
Cmpi.b #cpu68040,CPUFlag ; Are we on an 040 or greater? <2> kc.start
|
||
Blt.s @0 ; No? Then no alignment.
|
||
|
||
Andi.w #$FFF0,D0 ; Force line alignment.
|
||
Sub.l #BlkData32,D0 ; Header size.
|
||
Bra.s @1
|
||
|
||
@0 AndI.W #$FFFC,D0 ; round down to multiple of 16
|
||
@1 Move.L D0,D1 ; <2> kc.end
|
||
LEA HeapEnd,A1 ; we'll use and possibly set this value
|
||
Sub.L (A1),D0 ; amount of heap growth, if any; this value is NONNEGATIVE!!
|
||
BCS.S @MAZFini ; Carry Set => minFree > delta, no dice... <SM24>
|
||
MoveQ #minFree32,D2 ; beneath this epsilon we will not grow <v1.2>
|
||
Cmp.L D2,D0
|
||
BCS.S @MAZFini ; Carry Set => minFree > delta, no dice...
|
||
|
||
MoveA.L (A1),A0 ; current bkLim ptr is the new (large) free block
|
||
Clr.L TagBC32(A0) ; set as free block <v1.1>
|
||
Move.L D0,BlkSize32(A0); get block size <v1.1>
|
||
Move.L D1,(A1) ; new heapEnd := bkLim, freeing A1
|
||
MoveA.L D1,A0 ; we need it as a ptr, in an A-register
|
||
CmpA.L HiHeapMark,A0 ; is this a new high for heap extents? <C731>
|
||
BLS.S @noNewHigh ; HiHeapMark ≥ A0 => no change <C731>
|
||
Move.L A0,HiHeapMark ; HiHeapMark < A0 => reset HiHeapMark <C731>
|
||
@noNewHigh ; skip to here when HiHeapMark OK <C731>
|
||
MoveA.L ApplZone,A1 ; now adjust the zone header
|
||
Move.L A0,bkLim(A1)
|
||
Clr.L tagBC32(A0) ; clear 1st long word in header block <v1.1>
|
||
Move.L D2,BlkSize32(A0); make it a minFree block <v1.1>
|
||
Add.L D0,ZCBFree(A1) ; adjust free block count
|
||
@MAZFini
|
||
BrA.S SALOk ; stuff the noErr code there <25Apr85>
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; FUNCTION NewPtr(byteCount: LongInt): Ptr;
|
||
;
|
||
; On entry: D0 - size in bytes to allocate
|
||
; On exit : A0 - Returns a pointer to a block of (data) size byteCount.
|
||
;
|
||
;----------------------------------------------------------------------
|
||
|
||
; ———————————SuperMario roll in <SM9> tcn ————————————————————————————
|
||
; NewPtr - make it grow System Heap and place the block down low, too.
|
||
; Now that the system heap can grow, all of a sudden NewPtr is dropping locked blocks at the top of
|
||
; the heap. This stems from the fact the routine which reserves the block (MkPtrSpace) only grows ApplZone.
|
||
; This proc calls NewPtr, then checks to see whether the heap grew. If it did, this throws away the
|
||
; newly allocated block and calls NewPtr again. This gives MkPtrSpace the chance to allocate space
|
||
; down low because now there’s room to put relocatable blocks (the space the heap growing gave us).
|
||
;
|
||
; See also: ResrvMemGrowSystemHeap
|
||
;
|
||
; I re-rolled this patch so it won't overload the cpu :-) <SM29> kc
|
||
;
|
||
;——————————————————————————————————————————————————————————————————————
|
||
NewPtrTrap
|
||
MOVE.L #JNewPtr,-(SP) ; get offset to routine <v1.9>
|
||
MOVE.L vMMPrologue,-(SP) ; get vector to MMPrologue <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
; --- 24 bit version ----
|
||
v24NewPtr ; 24 bit version of NewPtr <v1.1>
|
||
CMPA.L SysZone,a6 ; is this handle going in the System heap?
|
||
BEQ.S NPSysZone24 ; yup
|
||
BTST #tSysOrCurZone,d1 ; is the "sys" bit set in the trapword?
|
||
BEQ.S NPNotSysZone24 ; nope
|
||
NPSysZone24
|
||
MOVE.L bkLim(a6),-(sp) ; save the end of system zone
|
||
SUB.L A1,A1 ; Handle Nil => fixed block
|
||
BSR a24MakePtrSpc ; Make room at the low end. <v1.1>
|
||
BSR a24AllocBk ; Allocate the block <v1.1>
|
||
MOVE.L (sp)+,A1 ; Recover the old end of system zone
|
||
BEQ.S NPNoMem24 ; Br if out of mem
|
||
|
||
CMP.L bkLim(a6),A1 ; Did the system heap grow?
|
||
BEQ.S NPCheckClear24 ; No, carry on as normal
|
||
BSR a24FreeBk ; Yes, free the block and try again.
|
||
NPNotSysZone24
|
||
SUB.L A1,A1 ; Handle Nil => fixed block
|
||
BSR a24MakePtrSpc ; Make room at the low end. <v1.1>
|
||
BSR a24AllocBk ; Allocate the block <v1.1>
|
||
BEQ.S NPNoMem24 ; Br if out of mem
|
||
NPCheckClear24
|
||
BSR CheckClear ; Clear block if requested
|
||
NPOk24
|
||
MOVEQ #0,D0
|
||
NPExit24
|
||
BRA.S NPExit ; jump to common exit <v1.9>
|
||
NPNoMem24
|
||
MOVEQ #memFullErr,D0
|
||
BRA.S NPExit24
|
||
|
||
; --- 32 bit version ----
|
||
v32NewPtr ; 32 bit version of NewPtr <v1.1>
|
||
|
||
CMPA.L SysZone,a6 ; is this handle going in the System heap?
|
||
BEQ.S NPSysZone32 ; yup
|
||
BTST #tSysOrCurZone,d1 ; is the "sys" bit set in the trapword?
|
||
BEQ.S NPNotSysZone32 ; nope
|
||
NPSysZone32
|
||
MOVE.L bkLim(a6),-(sp) ; save the end of system zone
|
||
SUB.L A1,A1 ; Handle Nil => fixed block
|
||
BSR a32MakePtrSpc ; Make room at the low end. <v1.1>
|
||
BSR a32AllocBk ; Allocate the block <v1.1>
|
||
MOVE.L (sp)+,A1 ; Recover the old end of system zone
|
||
BEQ.S NPNoMem ; Br if out of mem
|
||
|
||
CMP.L bkLim(a6),A1 ; Did the system heap grow?
|
||
BEQ.S NPCheckClear32 ; No, carry on as normal
|
||
BSR a32FreeBk ; Yes, free the block and try again.
|
||
NPNotSysZone32
|
||
SUB.L A1,A1 ; Handle Nil => fixed block
|
||
|
||
BSR a32MakePtrSpc ; Make room at the low end. <v1.1>
|
||
BSR a32AllocBk ; Allocate the block <v1.1>
|
||
BEQ.S NPNoMem ; Br if out of mem
|
||
NPCheckClear32
|
||
BSR CheckClear ; Clear block if requested
|
||
NPOk
|
||
MOVEQ #0,D0
|
||
NPExit
|
||
MOVE.L vMMEpilogue,-(SP) ; get vector to MMEpilogue <v1.9>
|
||
RTS ; jump to it <v1.9>
|
||
NPNoMem
|
||
MOVEQ #memFullErr,D0
|
||
BrA.S NPExit
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE DisposePtr(p: Ptr);
|
||
;
|
||
; On entry: A0 - ptr to block to be disposed
|
||
; - Disposes of previousely allocated Ptr object -- unless ROZ <04Mar85>
|
||
;
|
||
;----------------------------------------------------------------------
|
||
|
||
DisposePtr
|
||
move.l a0,d0 ; be cool when a NIL ptr comes through <sm9>stb
|
||
bne.w @NonNIL ; not nil, so call the real thing <sm9>stb
|
||
move.w d0,MemErr ; return no error even though it’s not a ptr stb
|
||
rts ; <sm9>stb
|
||
|
||
@NonNIL MOVE.L #jDisposePtr,-(SP) ; get offset to routine <v1.9>
|
||
MOVE.L vMMPPrologue,-(SP) ; get vector to MMpprologue <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
v24DisposePtr ; 24 bit version of DisposePtr <v1.1>
|
||
; Move.L (SP)+,A0 ; restore A0 <v1.1>
|
||
DisposeTail24
|
||
BTST #ROZ,flags(A6) ; skip if read-only <04Mar85>
|
||
BNE.S DisposeSkip ; <04Mar85>
|
||
|
||
BSR a24FreeBk ; <v1.1>
|
||
BrA.S NPOk
|
||
|
||
v32DisposePtr ; 32 bit version of DisposePtr <v1.1>
|
||
; Move.L (SP)+,A0 ; restore A0 <v1.1>
|
||
DisposeTail32
|
||
BTST #ROZ,flags(A6) ; skip if read-only <04Mar85>
|
||
BNE.S DisposeSkip ; <04Mar85>
|
||
|
||
BSR a32FreeBk ; <v1.1>
|
||
BrA.S NPOk
|
||
DisposeSkip
|
||
MOVEQ #memROZWarn,D0 ; deliver warning <04Mar85>
|
||
BRA.S NPExit ; <04Mar85>
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; FUNCTION GetPtrSize(p: Ptr): Size;
|
||
;
|
||
; On entry: A0.L- ptr
|
||
; On exit : D0.L- size in bytes
|
||
; Returns the actual data size of a Ptr object.
|
||
|
||
GetPtrSizeTrap
|
||
MOVE.L #jGetPtrSize,-(SP) ; get offset to routine <v1.9>
|
||
MOVE.L vMMPPrologue,-(SP) ; get vector to MMpprologue <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
|
||
v24GetPtrSize ; 24 bit version of MaxMem <v1.1>
|
||
BSR a24GetSize ; Get its size <v1.1>
|
||
BrA.S NPExit ; Check Zone, Restore, Return
|
||
|
||
v32GetPtrSize ; 32 bit version of MaxMem <v1.1>
|
||
BSR a32GetSize ; Get its size <v1.1>
|
||
BrA.S NPExit ; Check Zone, Restore, Return
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; FUNCTION SetPtrSize(blk: Ptr; cb: Size): result;
|
||
;
|
||
; This routine is used to set the size of non-relocatable memory blocks
|
||
;
|
||
; Arguments:
|
||
; D0 - cb: new block size
|
||
; A0 - blk: pointer to block data
|
||
; A1 - h: NIL, set up by MMPPrologue
|
||
;
|
||
; Result:
|
||
; D0 - 0 => success; memFullErr => failure
|
||
;
|
||
; Registers:
|
||
;
|
||
; A0 - next free block
|
||
; A1 - current free block
|
||
; A2 - theZone
|
||
; D0 - number of bytes needed
|
||
; D1 - number of bytes in current free block
|
||
; D2 - new block length (temporary)
|
||
;
|
||
|
||
SetPtrSizeTrap
|
||
MOVE.L #jSetPtrSize,-(SP) ; get offset to routine <v1.9>
|
||
MOVE.L vMMPPrologue,-(SP) ; get vector to MMpprologue <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
v24SetPtrSize ; 24 bit version of MaxMem <v1.1>
|
||
BSR a24SetSize ; set its size <v1.1>
|
||
BrA.S NPExit
|
||
|
||
v32SetPtrSize ; 32 bit version of MaxMem <v1.1>
|
||
BSR a32SetSize ; set its size <v1.1>
|
||
BrA.S NPExit
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; FUNCTION PtrZone(p: Ptr): Zone;
|
||
;
|
||
; Returns the zone in which a memory block belongs.
|
||
;
|
||
; Argument:
|
||
; A0: p: pointer for block
|
||
;
|
||
; Result:
|
||
; D0: ec: error code
|
||
; A0: zone: zone in which block belongs
|
||
;
|
||
|
||
PtrZoneTrap
|
||
MOVE.L #jPtrZone,-(SP) ; get offset to routine <v1.9>
|
||
MOVE.L vMMPPrologue,-(SP) ; get vector to MMpprologue <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
vPtrZone ; 24/32 bit version of PtrZone <v1.1>
|
||
Move.L A6,A0
|
||
BrA.S NPOk
|
||
|
||
CheckClear
|
||
BTst #ClearBit,D1 ;clear the allocated memory?
|
||
BEq.S @2 ;br if not
|
||
Move.L A0,-(SP) ;preserve A0
|
||
AddQ.L #1,D0 ;increment allocation size
|
||
LSR.L #1,D0 ;get word size
|
||
|
||
@1 Clr.W (A0)+ ;clear it out
|
||
SubQ.L #1,D0
|
||
BGT.S @1
|
||
Move.L (SP)+,A0 ;restore A0
|
||
|
||
@2 RTS
|
||
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; FUNCTION NewEmptyHandle: Handle;
|
||
; On entry:
|
||
; no input assumptions
|
||
; On exit:
|
||
; A0 - handle
|
||
; D0 - error code
|
||
; - Allocate an empty master pointer in the zone pool.
|
||
; Registers:
|
||
|
||
NewEmptyHandleTrap
|
||
MOVE.L #JNewEmptyHandle,-(SP) ; get offset to routine <v1.9>
|
||
MOVE.L vMMPrologue,-(SP) ; get vector to MMPrologue <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
v24NewEmptyHandle ; 24 bit version of NewEmptyHandle <v1.1>
|
||
BSR a24NextMaster ; Get next master in A1 <v1.1>
|
||
BEQ.S NHNoMaster ; If NIL, exit as in NewHandle
|
||
BRA.S NewEHExit ; use common code <v1.1>
|
||
|
||
v32NewEmptyHandle ; 32 bit version of NewEmptyHandle <v1.1>
|
||
BSR a32NextMaster ; Get next master in A1 <v1.1>
|
||
BEQ.S NHNoMaster ; If NIL, exit as in NewHandle
|
||
NewEHExit
|
||
Move.L A1,A0 ; Get it to A0 for return
|
||
CLR.L (A0) ; Make it NIL
|
||
MoveQ #0,D0 ; Show success
|
||
Move.L vMMEpilogue,-(SP) ; get vector to MMEpilogue <v1.9>
|
||
RTS ; jump to it <v1.9>
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; FUNCTION NwHandle(cb: Size): Handle;
|
||
; On entry:
|
||
; D0 - size to allocate
|
||
; On exit:
|
||
; A0 - handle
|
||
; - Allocate a relocatable object with its master pointer in the
|
||
; zone pool.
|
||
; Registers:
|
||
|
||
NwHandle
|
||
MOVE.L #JNwHandle,-(SP) ; get offset to routine <v1.9>
|
||
MOVE.L vMMPrologue,-(SP) ; get vector to MMPrologue <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
v24NwHandle ; 24 bit version of NwHandle <v1.1>
|
||
; from SetRovingPointerBeforeNewHandle patch<SM29> kc
|
||
CMPA.L SysZone,a6 ; is this handle going in the System heap? <SM29> kc
|
||
BEQ.S @inSysZone ; yup <SM29> kc
|
||
BTST #tSysOrCurZone,d1 ; is the "sys" bit set in the trapword? <SM29> kc
|
||
BEQ.S @notInSysZone ; nope <SM29> kc
|
||
@inSysZone ; <SM29> kc
|
||
CLR.L allocPtr(a6) ; clear the rover <SM29> kc
|
||
@notInSysZone ; <SM29> kc
|
||
BSR a24NextMaster ; Get next master <v1.1>
|
||
BNE.S @NHMaster ; If not NIL, go get block <v1.1>
|
||
|
||
BRA.S NHNoMaster ; if NIL, report error <v1.1>
|
||
@NHMaster
|
||
BSR a24AllocBk ; try to allocate block <v1.1>
|
||
BEq.S NHNoMem ; No luck, fail return
|
||
|
||
BRA.S HCheckHandle
|
||
|
||
|
||
v32NwHandle ; 32 bit version of NwHandle <v1.1>
|
||
; from SetRovingPointerBeforeNewHandle patch<SM29> kc
|
||
CMPA.L SysZone,a6 ; is this handle going in the System heap? <SM29> kc
|
||
BEQ.S @inSysZone ; yup <SM29> kc
|
||
BTST #tSysOrCurZone,d1 ; is the "sys" bit set in the trapword? <SM29> kc
|
||
BEQ.S @notInSysZone ; nope <SM29> kc
|
||
@inSysZone ; <SM29> kc
|
||
CLR.L allocPtr(a6) ; clear the rover <SM29> kc
|
||
@notInSysZone ; <SM29> kc
|
||
BSR a32NextMaster ; Get next master <v1.1>
|
||
BNE.S NHMaster ; If not NIL, go get block <v1.1>
|
||
NHNoMaster
|
||
MoveQ #memFullErr,D0
|
||
BrA.S HNilResult
|
||
NHMaster
|
||
BSR a32AllocBk ; try to allocate block <v1.1>
|
||
BEq.S NHNoMem ; No luck, fail return
|
||
|
||
HCheckHandle BSR.S CheckClear ; Clear memory if requested
|
||
Move.L A1,A0
|
||
NHOk
|
||
MoveQ #0,D0
|
||
NHExit
|
||
Move.L vMMEpilogue,-(SP) ; get vector to MMEpilogue <v1.9>
|
||
RTS ; jump to it <v1.9>
|
||
NHNoMem
|
||
MoveQ #memFullErr,D0
|
||
BrA.S HReleaseMP
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE DsposeHandle(h: Handle);
|
||
; On entry:
|
||
; A0 - handle to block to be disposed -- unless ROZ <04Mar85>
|
||
; Reactivated even if ROZ to just clear (bogus) MP <10Apr85>
|
||
; Distinguish Nil and Empty cases from MMHPrologue. <21May85>
|
||
;----------------------------------------------------------------------
|
||
|
||
DsposeHandle
|
||
Move.L #JDsposeHandle,-(SP) ; get offset to vector onto stack <v1.9>
|
||
Move.L vMMHPrologue,-(SP) ; get MMHPrologue vector onto stack <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
v24DsposeHandle ; 24 bit version of MaxMem <v1.1>
|
||
BNE.S DisposeTail24 ; Release block <v1.1>
|
||
Bra.S DsposeCommon ; branch to commond code <v1.1>
|
||
|
||
|
||
v32DsposeHandle ; 32 bit version of DsposeHandle <v1.1>
|
||
BNE.S DisposeTail32 ; Release block <v1.1>
|
||
DsposeCommon ; commond code <v1.1>
|
||
Move.L A1,D0 ; Masked handle: EQ => Nil passed <21May85>
|
||
BEq.S HNilResult ; No master ptr to release <21May85>
|
||
|
||
BTST #ROZ,flags(A6) ; skip if ROZ <10Apr85>
|
||
BNE.S HROZResult ; <10Apr85>
|
||
|
||
cmp.l ROMBase,d0 ; is it a ROM resource ? <SM23> PN
|
||
bgt.s Nothing ; if in ROM, leave it alone <SM23> PN
|
||
|
||
MoveQ #0,D0 ; Success result
|
||
HReleaseMP
|
||
BSR ReleaseMP ; Return MP to list
|
||
HNilResult
|
||
Sub.L A0,A0 ; Return NIL in A0 for NwHandle
|
||
BrA.S NHExit
|
||
HROZResult
|
||
CLR.L (A1) ; just clear the (bogus) MP <10Apr85>
|
||
Nothing BRA.S NHOk ; go to MMEpilogue, sans error <10Apr85>
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
; FUNCTION GetHandleSize(h: Handle): LongInt;
|
||
; On entry: A0 - handle
|
||
; On exit : D0 - size in bytes
|
||
; Returns the actual data size of a Handle object.
|
||
|
||
__GetHandleSize
|
||
Move.L #JGetHandleSize,-(SP) ; get offset to vector onto stack <v1.9>
|
||
Move.L vMMHPrologue,-(SP) ; get MMHPrologue vector onto stack <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
v24GetHandleSize ; 24 bit version of GetHandleSize <v1.1>
|
||
BEq.S SHSNil
|
||
BSR a24GetSize ; <v1.1>
|
||
|
||
BrA.S SHSExit
|
||
|
||
|
||
v32GetHandleSize ; 32 bit version of GetHandleSize <v1.1>
|
||
BEq.S SHSNil
|
||
BSR a32GetSize ; <v1.1>
|
||
|
||
BrA.S SHSExit
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; FUNCTION SetHandleSize(h: Handle; cb: LongInt): result;
|
||
;
|
||
; This routine is used to change the size of a relocatable memory block.
|
||
; The block handle remains the same; the Master Pointer is unchanged if
|
||
; the new length is less than or equal to the old.
|
||
;
|
||
; Arguments:
|
||
; D0 - cb: new block size
|
||
; A0 - handle: pointer to master pointer
|
||
;
|
||
; Result:
|
||
; D0 - 0 => success; memFullErr => failure
|
||
;
|
||
; Registers:
|
||
;
|
||
; A0 - next free block
|
||
; A1 - handle
|
||
;
|
||
|
||
SetHandleSizeTrap
|
||
Move.L #JSetHandleSize,-(SP) ; get offset to vector onto stack <v1.9>
|
||
Move.L vMMHPrologue,-(SP) ; get MMHPrologue vector onto stack <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
|
||
v24SetHandleSize ; 24 bit version of SetHandleSize <v1.1>
|
||
BEQ.S SHSNil
|
||
BSR a24SetSize ; Set size as specified in D0 <v1.1>
|
||
BrA.S SHSExit ; <v1.1>
|
||
|
||
|
||
v32SetHandleSize ; 32 bit version of SetHandleSize <v1.1>
|
||
BNE.S SHSOk
|
||
|
||
SHSNil
|
||
MoveQ #nilHandleErr,D0 ;return error code
|
||
BrA.S SHSExit
|
||
SHSOk
|
||
BSR a32SetSize ;Set size as specified in D0 <v1.1>
|
||
SHSExit
|
||
Move.L A1,A0 ;restore A0 for RecoverHandle
|
||
BrA.S NHExit
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; FUNCTION HandleZone(h: Handle): Zone;
|
||
;
|
||
; Returns the zone in which a memory block belongs.
|
||
;
|
||
; Argument:
|
||
; A0: h: handle for block
|
||
;
|
||
; Result:
|
||
; D0: ec: error code
|
||
; A0: zone: zone in which block belongs
|
||
;
|
||
|
||
HandleZoneTrap
|
||
Move.L #JHandleZone,-(SP) ; get offset to vector onto stack <v1.9>
|
||
Move.L vMMHPrologue,-(SP) ; get MMHPrologue vector onto stack <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
vHandleZone ; 24/32 bit version of HandleZone <v1.1>
|
||
Move.L A6,A0
|
||
BrA.S NHOk
|
||
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
; FUNCTION RecoverHandle(ptr: Ptr): Handle;
|
||
; On entry: A0 - pointer
|
||
; On exit : A0 - handle
|
||
; Must preserve D0!!!!! (As per 64K ROM, that is.) <25Apr85>
|
||
; Given a ptr to an alleged handle data block, returns the handle. Because of
|
||
; 64K ROM permissiveness, no error can be returned in D0, just in MemErr.
|
||
; Uses own exit sequence to MMNoErrEpilogue and stuffs MemErr on its own. <25Apr85>
|
||
; To effect patch from Mac+, special MMRHPrologue (“RH” as in RecoverHandle) <A305>
|
||
; is used to ensure the the more reasonable of SysZone and ApplZone is used for A6
|
||
; when incoming TheZone is one of Sys or Appl.
|
||
; Put a bus error handler on the fetch of the relative handle, pinning to <C778>
|
||
; ROMBase, for safety. <C778>
|
||
|
||
RecoverHandleTrap
|
||
Move.L #JRecoverHandle,-(SP) ; get offset to routine onto stack <v1.9>
|
||
Move.L vMMRHPrologue,-(SP) ; get vector to MMRHPrologue <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
|
||
v24RecoverHandle ; 24 bit version of RecoverHandle <2>
|
||
MOVE.L Lo3Bytes,D2 ; mask to strip extraneous bits <2>
|
||
BRA.S vRecoverHandle ; <2>
|
||
|
||
v32RecoverHandle ; 32 bit version of RecoverHandle <2>
|
||
MOVEQ #-1,D2 ; no extraneous address bits in 32-bit mode <2>
|
||
|
||
vRecoverHandle
|
||
Move.L BusErrVct,A2 ; save current bus error handler <C778><1.7>
|
||
LEA RHBusErrHandler,A3 ; our RH version <C778>
|
||
Move.L A3,BusErrVct ; <C778><1.7>
|
||
|
||
Move.L -4(A0),A1 ; Handle, or ROMBase on bus error <C778>
|
||
ReturnFromBusErr ; <NK1><SM22> rb
|
||
Move.L A2,BusErrVct ;restore old one after danger <C778><1.7>
|
||
|
||
Add.L A6,A1
|
||
|
||
; The following code tests for bad mp, but can only set MemErr <25Apr85>
|
||
|
||
MOVE.L A0,D1 ; original pointer <2>
|
||
AND.L D2,D1 ; stripped to RAW address <2>
|
||
AND.L (A1),D2 ; master pointer value stripped to RAW address <2>
|
||
Sub.L D1,D2 ; if equal, have required error code!
|
||
Beq.S RecoverExit
|
||
|
||
; If we get here, the pointer either didn't point to a block in the suspected
|
||
; heap or is a bogus block pointer. We'll assume it's the first case and try
|
||
; looking in the ROZ created for the ROM resource map before giving up completely.
|
||
; This will not affect the performance of RecoverHandle() since this code is only
|
||
; executed as part of the error path (which shouldn't be taken most of the time).
|
||
; Also, it assumes that the ROZ is ALWAYS a 32-bit heap zone.
|
||
|
||
MOVEA.L A6,A3 ; save the previous zone start pointer <2>
|
||
MOVEA.L RomMapHndl,A6 ; get the handle to the ROM resource map <2>
|
||
MOVEA.L (A6),A2 ; and de-reference it <2>
|
||
SUBA.L -4(A2),A6 ; calculate heap start based on rel hdl in MP <2>
|
||
|
||
CMPA.L A3,A6 ; have we been here before? <2>
|
||
BNE.S v32RecoverHandle ; -> no, try again with the ROZ <2>
|
||
|
||
MoveQ #memBCErr,D2 ; block check failure <13Apr85>
|
||
RecoverExit
|
||
Move.W D2,MemErr ; stuff global error code (is anybody out there?)<25Apr85>
|
||
MoveA.L A1,A0 ; restore A0=handle <25Apr85>
|
||
|
||
Move.L vMMNoErrEpilogue,-(SP) ; get MMNoErrEpilogue vector <v1.9>
|
||
RTS
|
||
|
||
;----------------------------------------------------------------------
|
||
; RHBusErr -- bus error handler for RecoverHandle <NK1><SM22> rb, start
|
||
; A bus error in RecoverHandle causes ROMBase to be jammed for the relative handle. <NK1>
|
||
; Triggered by bus errors in Move.L -4(A0),A1 in RecoverHandle. <NK1>
|
||
; <NK1>
|
||
; Frame types 7 and B are handled. The PC is jammed with the instruction <NK1>
|
||
; following the bus error (it can't be incremented because the emulator <NK1>
|
||
; doesn't guarantee valid PC values) and A1 is jammed with ROMbase. The <NK1>
|
||
; frame is then mutated into a type 0 frame before RTE. This should work <NK1>
|
||
; with VM, NuKernel, and emulator environments. <NK1>
|
||
;
|
||
; Output: A1 = ROMBase <NK1>
|
||
; Regs: A3 <NK1>
|
||
;----------------------------------------------------------------------
|
||
RHBusErrHandler
|
||
movea.l ROMBase,a1 ; stuff fake Nil value into expected dest. reg <NK1>
|
||
movea.w (sp),a3 ; <NK1>
|
||
cmpi.w #$7008,6(SP) ; type 7 frame? <NK1>
|
||
beq.s RHBusErrType7 ; <NK1>
|
||
adda.w #(92-8),SP ; Leave space for type 0 frame <NK1>
|
||
bra.s RHBusErrCommon ; <NK1>
|
||
RHBusErrType7 ; <NK1>
|
||
adda.w #(60-8),SP ; Leave space for type 0 frame <NK1>
|
||
RHBusErrCommon ; <NK1>
|
||
clr.w 6(SP) ; Make it a type 0 frame <NK1>
|
||
move.w a3,(sp) ; Return SR <NK1>
|
||
lea ReturnFromBusErr,a3 ; <NK1>
|
||
move.l a3,2(SP) ; Return PC <NK1>
|
||
RTE ; <NK1><SM22> rb, end
|
||
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE EmptyHandle(h: Handle);
|
||
; - Deallocates data block pointed to by the given handle & zeroes the MP
|
||
; Note that EH will not deallocate the data block if it's a ROZ. <10Apr85>
|
||
; On entry, Registers:
|
||
; A0 - Handle
|
||
|
||
EmptyHandle
|
||
Move.L #JEmptyHandle,-(SP) ; get offset to vector onto stack <v1.9>
|
||
Move.L vMMHPrologue,-(SP) ; get MMHPrologue vector onto stack <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
v24EmptyHandle ; 24 bit version of EmptyHandle <v1.1>
|
||
BNE.S @EHNotNIL
|
||
MoveQ #0,D0
|
||
BrA.S EHExit
|
||
@EHNotNIL
|
||
BSR a24EH ; Common code with ReAllocHandle <v1.1>
|
||
BrA.S EHExit
|
||
|
||
|
||
v32EmptyHandle ; 32 bit version of EmptyHandle <v1.1>
|
||
BNE.S EHNotNIL
|
||
MoveQ #0,D0
|
||
BrA.S EHExit
|
||
EHNotNIL
|
||
BSR a32EH ;Common code with ReAllocHandle
|
||
EHExit
|
||
BrA.S SHSExit
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE: ReAllocHandle
|
||
; Arguments: D0 (input) -- size to allocate (long)
|
||
; A0 (input) -- original handle
|
||
; D0 (output) -- result code (MemFullErr)
|
||
; A0 (output) -- original handle or nil if unsuccessful
|
||
; Function: Allocate a relocatable object given its original Handle.
|
||
; This is useful when a relocatable data block is purged: it can
|
||
; be retrieved without having to destroy the handle & having to
|
||
; update every copy of the handle.
|
||
;
|
||
; If the handle in A0 does not point to a purged block, the
|
||
; block is freed first.
|
||
;
|
||
; This sets up the GZ root semaphores for the grow zone proc
|
||
; so it doesn't mess with the handle in question.
|
||
;
|
||
; If ROZ and empty handle, just do it; if non-empty give warning or error <04Mar85>
|
||
; depending on whether no larger or growing. <04Mar85>
|
||
;
|
||
;----------------------------------------------------------------------
|
||
|
||
ReAllocHandleTrap
|
||
Move.L #JReAllocHandle,-(SP) ; get offset to vector onto stack <v1.9>
|
||
Move.L vMMHPrologue,-(SP) ; get MMHPrologue vector onto stack <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
v24ReAllocHandle ; 24 bit version of ReAllocHandle <v1.1>
|
||
BEQ.S @RAHCont ; <SM29> kc
|
||
; from SetRovingPointerBeforeReallocHandle patch<SM29> kc
|
||
CMPA.L SysZone,a6 ; is this handle going in the System heap? <SM29> kc
|
||
BEQ.S @inSysZone ; yup <SM29> kc
|
||
BTST #tSysOrCurZone,d1 ; is the "sys" bit set in the trapword? <SM29> kc
|
||
BEQ.S @notInSysZone ; nope <SM29> kc
|
||
@inSysZone ; <SM29> kc
|
||
CLR.L allocPtr(a6) ; clear the rover <SM29> kc
|
||
@notInSysZone ; <SM29> kc
|
||
BTST #ROZ,flags(A6) ; Bypass if ROZ <04Mar85>
|
||
BNE.S @RAHSkip ; <04Mar85>
|
||
|
||
BSR a24EH ; Empty the Handle for sure
|
||
BNE.S SHSExit ; EH failed, return error code
|
||
Move.L D2,D0 ; restore D0 (saved by MMHPrologue)
|
||
@RAHCont
|
||
Move.L A1,GZRootHnd ; record handle being reallocated
|
||
Clr.L GZRootPtr ; record lack of pointer
|
||
BSR a24AllocBk ; try to allocate block <v1.1>
|
||
BSR ClearGZStuff ; clean up gz safety stuff
|
||
Move.L A0,D2 ; see if alloc bk worked
|
||
BNE HCheckHandle ; If ok, take the NewHandle exit route.
|
||
MoveQ #memFullErr,D0 ; If we can't find the space, just report
|
||
Bra.S SHSExit ; the error, leaving handle alone . . .
|
||
@RAHSkip
|
||
BSR a24GetSize ; D0 := current data size <v1.1>
|
||
CMP.L D0,D2 ; requested - current ... unsigned <04Mar85>
|
||
BHI.S RAHError ; it's erroneous to grow <04Mar85>
|
||
MOVEQ #memROZWarn,D0 ; <04Mar85>
|
||
BRA.S SHSExit ; <04Mar85>
|
||
|
||
|
||
v32ReAllocHandle ; 32 bit version of ReAllocHandle <v1.1>
|
||
BEQ.S @RAHCont ; <SM29> kc
|
||
; from SetRovingPointerBeforeReallocHandle patch<SM29> kc
|
||
CMPA.L SysZone,a6 ; is this handle going in the System heap? <SM29> kc
|
||
BEQ.S @inSysZone ; yup <SM29> kc
|
||
BTST #tSysOrCurZone,d1 ; is the "sys" bit set in the trapword? <SM29> kc
|
||
BEQ.S @notInSysZone ; nope <SM29> kc
|
||
@inSysZone ; <SM29> kc
|
||
CLR.L allocPtr(a6) ; clear the rover <SM29> kc
|
||
@notInSysZone ; <SM29> kc
|
||
BTST #ROZ,flags(A6) ; Bypass if ROZ <04Mar85>
|
||
BNE.S RAHSkip ; <04Mar85>
|
||
|
||
BSR a32EH ; Empty the Handle for sure
|
||
BNE.S SHSExit ; EH failed, return error code
|
||
Move.L D2,D0 ; restore D0 (saved by MMHPrologue)
|
||
@RAHCont ; <SM29> kc
|
||
Move.L A1,GZRootHnd ; record handle being reallocated
|
||
Clr.L GZRootPtr ; record lack of pointer
|
||
BSR a32AllocBk ; try to allocate block <v1.1>
|
||
BSR ClearGZStuff ; clean up gz safety stuff
|
||
Move.L A0,D2 ; see if alloc bk worked
|
||
BNE HCheckHandle ; If ok, take the NewHandle exit route.
|
||
MoveQ #memFullErr,D0 ; If we can't find the space, just report
|
||
Bra.S SHSExit ; the error, leaving handle alone . . .
|
||
RAHSkip
|
||
BSR a32GetSize ; D0 := current data size <v1.1>
|
||
CMP.L D0,D2 ; requested - current ... unsigned <04Mar85>
|
||
BHI.S RAHError ; it's erroneous to grow <04Mar85>
|
||
MOVEQ #memROZWarn,D0 ; <04Mar85>
|
||
BRA.S SHSExit ; <04Mar85>
|
||
RAHError
|
||
MOVEQ #memROZError,D0 ; <04Mar85>
|
||
BRA.S SHSExit ; <04Mar85>
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE HLock(h: Handle);
|
||
;
|
||
; - Lock the relocatable block pointed to by the given handle.
|
||
;
|
||
; On entry, Registers:
|
||
;
|
||
; A0 - Handle
|
||
;
|
||
|
||
HLock Move.L #JHLock,-(SP) ; get offset to vector onto stack <v1.9>
|
||
Move.L vMMHPrologue,-(SP) ; get MMHPrologue vector onto stack <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
; <2> kc.start
|
||
v24Hlock BEQ HFail ; handle was NIL
|
||
BSET #Lock,(A1) ; set the lock bit
|
||
BRA HGood ; return success
|
||
|
||
v32Hlock BEQ HFail ; handle was NIL
|
||
bset #Lock,MPtag32-blkData32(A0) ; set the lock bit
|
||
BRA HGood ; return success
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE HUnLock(h: Handle);
|
||
;
|
||
; - Unlock the relocatable block pointed to by the given handle.
|
||
;
|
||
; On entry, Registers:
|
||
;
|
||
; A0 - Handle
|
||
;
|
||
|
||
HUnlock
|
||
Move.L #JHUnLock,-(SP) ; get offset to vector onto stack <v1.9>
|
||
Move.L vMMHPrologue,-(SP) ; get MMHPrologue vector onto stack <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
v24HUnlock
|
||
BEq HFail ; handle was NIL
|
||
|
||
BClr #Lock,(A1) ; reset the lock bit
|
||
BrA HGood ; return success
|
||
|
||
v32HUnlock
|
||
BEq.S HFail ; handle was NIL
|
||
|
||
BClr #Lock,MPtag32-blkData32(A0) ;reset the lock bit <v1.3>
|
||
BrA.S HGood ; return success
|
||
|
||
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE HPurge(h: Handle);
|
||
;
|
||
; - Enable purging the relocatable block pointed to by the given handle.
|
||
;
|
||
; On entry, Registers:
|
||
;
|
||
; A0 - Handle
|
||
;
|
||
|
||
HPurge
|
||
Move.L #JHPurge,-(SP) ; get offset to vector onto stack <v1.9>
|
||
Move.L vMMHPrologue,-(SP) ; get MMHPrologue vector onto stack <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
v24HPurge
|
||
BEq.S HFail ; handle was NIL
|
||
|
||
BSet #Purge,(A1) ; set the purge bit
|
||
BrA.S HGood ; return success
|
||
|
||
v32HPurge
|
||
BEq.S HFail ; handle was NIL
|
||
|
||
BSet #Purge,MPtag32-blkData32(A0);set the purge bit <v1.3>
|
||
BrA.S HGood ; return success
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE HNoPurge(h: Handle);
|
||
;
|
||
; - Disable purging the relocatable block pointed to by the given handle.
|
||
; Stuff error code globally. <25Apr85>
|
||
;
|
||
; On entry, Registers:
|
||
;
|
||
; A0 - Handle
|
||
;
|
||
|
||
HNoPurge
|
||
Move.L #JHNoPurge,-(SP) ; get offset to vector onto stack <v1.9>
|
||
Move.L vMMHPrologue,-(SP) ; get MMHPrologue vector onto stack <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
v24HNoPurge
|
||
BEq.S HFail ; handle was NIL
|
||
|
||
BClr #Purge,(A1) ; reset the purge bit
|
||
BrA.S HGood ;return success <v1.1>
|
||
|
||
v32HNoPurge
|
||
BEq.S HFail ; handle was NIL
|
||
|
||
BClr #Purge,MPtag32-blkData32(A0);reset the purge bit <v1.3>
|
||
|
||
HGood
|
||
MoveQ #0,D0
|
||
BrA.S HExit
|
||
HFail
|
||
MoveQ #nilHandleErr,D0
|
||
HExit
|
||
Move.L vMMEpilogue,-(SP) ; get vector to MMEpilogue <v1.9>
|
||
RTS ; jump to it <v1.9>
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE HRSRC(h: Handle); <13Jan86 JTC>
|
||
;
|
||
; - Set the resource bit of the relocatable block pointed to by the given handle.
|
||
;
|
||
; On entry, Registers:
|
||
;
|
||
; A0 - Handle
|
||
;
|
||
|
||
HRSRC ; <13Jan86 JTC>
|
||
Move.L #JHRSRC,-(SP) ; get offset to vector onto stack <v1.9>
|
||
Move.L vMMHPrologue,-(SP) ; get MMHPrologue vector onto stack <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
v24HRSRC
|
||
BEq.S HFail ;handle was NIL <13Jan86 JTC>
|
||
|
||
BSet #Resource,(A1) ; <C206>
|
||
BrA.S HGood ;return success <13Jan86 JTC>
|
||
|
||
|
||
v32HRSRC
|
||
BEq.S HFail ;handle was NIL <13Jan86 JTC>
|
||
|
||
BSet #Resource,MPtag32-blkData32(A0) ;set the Resource bit <v1.3>
|
||
BrA.S HGood ;return success <13Jan86 JTC>
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE HNoRSRC(h: Handle); <13Jan86 JTC>
|
||
;
|
||
; - Clear the resource bit of the relocatable block pointed to by the given handle.
|
||
;
|
||
; On entry, Registers:
|
||
;
|
||
; A0 - Handle
|
||
;
|
||
|
||
HNoRSRC ; <v1.1>
|
||
Move.L #jHNoRSRC,-(SP) ; get offset to vector onto stack <v1.9>
|
||
Move.L vMMHPrologue,-(SP) ; get MMHPrologue vector onto stack <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
v24HNoRSRC
|
||
BEq.S HFail ; handle was NIL <13Jan86 JTC>
|
||
|
||
BClr #Resource,(A1) ; reset the RSRC bit <C206>
|
||
BrA.S HGood ; return success <13Jan86 JTC>
|
||
|
||
v32HNoRSRC
|
||
BEq.S HFail ; handle was NIL <13Jan86 JTC>
|
||
|
||
BClr #Resource,MPtag32-blkData32(A0) ;reset the RSRC bit <v1.3>
|
||
BrA.S HGood ; return success <13Jan86 JTC>
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; FUNCTION HGetFlags(h: Handle) : BYTE; <13Jan86 JTC>
|
||
;
|
||
; - Fetch the flag byte of the master pointer of the given handle.
|
||
;
|
||
; On entry, Registers:
|
||
; A0 - Handle
|
||
; On exit, Registers:
|
||
; D0 - flag byte in D0.B, rest of bits clear
|
||
;
|
||
|
||
HGetFlags ; <13Jan86 JTC>
|
||
Move.L #JHGetFlags,-(SP) ; get offset to vector onto stack <v1.9>
|
||
Move.L vMMHPrologue,-(SP) ; get MMHPrologue vector onto stack <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
v24HGetFlags
|
||
BEq.S HFail ; if Nil, stuff D0 with error code <13Jan86 JTC>
|
||
|
||
MoveQ #0,D0 ; init high bits <13Jan86 JTC>
|
||
Move.B (A1),D0 ; stuff the flag byte <13Jan86 JTC>
|
||
|
||
Bra.S GetFlagsExit ; exit through common code <v.1.9>
|
||
|
||
v32HGetFlags
|
||
BEq.S HFail ; if Nil, stuff D0 with error code <13Jan86 JTC>
|
||
|
||
MoveQ #0,D0 ; init high bits <13Jan86 JTC>
|
||
|
||
|
||
Move.B MPtag32-BlkData32(A0),D0 ;stuff the flag byte <v1.3>
|
||
GetFlagsExit
|
||
Clr.W MemErr ; custom exit, clearing error bits <13Jan86 JTC>
|
||
|
||
MOVE.L vMMNoErrEpilogue,-(SP) ; get MMNoErrEpilogue vector <v1.9>
|
||
RtS ; <13Jan86 JTC>
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE HSetFlags(h: Handle; f: BYTE); <13Jan86 JTC>
|
||
;
|
||
; - Set the flag byte of the master pointer of the given handle.
|
||
;
|
||
; On entry, Registers:
|
||
; A0 - Handle
|
||
; D0 - flag byte in D0.B, rest of bits don't care
|
||
;
|
||
|
||
HSetFlags ; <13Jan86 JTC>
|
||
Move.L #JHSetFlags,-(SP) ; get offset to vector onto stack <v1.9>
|
||
Move.L vMMHPrologue,-(SP) ; get MMHPrologue vector onto stack <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
v24HSetFlags
|
||
BEq.S HFail ; if Nil, stuff D0 with error code <13Jan86 JTC>
|
||
|
||
Move.B D0,(A1) ; stuff flags <v1.3>
|
||
Bra.S HGood ; return OK <13Jan86 JTC>
|
||
|
||
|
||
v32HSetFlags
|
||
BEq.S HFail ; if Nil, stuff D0 with error code <13Jan86 JTC>
|
||
|
||
Move.B D0,MPtag32-BlkData32(A0) ;stuff the flag byte <v1.3>
|
||
Bra.S HGood ; return OK <13Jan86 JTC>
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE MoreMasters();
|
||
;
|
||
; - Direct call from app, as opposed to demand requisition of MPs. <29jan85>
|
||
; Stuff error code globally, now. <25Apr85>
|
||
;
|
||
; No parameters.
|
||
;
|
||
MoreMasters
|
||
Move.L #jMoreMasters,-(SP) ; get offset to vector onto stack <v1.9>
|
||
Move.L vMMMMPrologue,-(SP) ; get MMMMPrologue vector onto stack <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
|
||
v24MoreMasters ; 24 bit version of MoreMasters <v1.1>
|
||
MOVEQ #0,D0 ; assume success
|
||
BSR a24HMakeMoreMasters ; call ROM routine
|
||
BNE.S @1 ; br for success
|
||
MOVEQ #MemFullErr,D0 ; change D0 from 0 to error code
|
||
@1 MOVE.L (SP)+,A6 ; restore A6
|
||
Move.W D0,MemErr ; global error code <25Apr85>
|
||
RTS ; that's all
|
||
|
||
v32MoreMasters ; 32 bit version of MoreMasters <v1.1>
|
||
MOVEQ #0,D0 ; assume success
|
||
BSR a32HMakeMoreMasters ; call ROM routine
|
||
BNE.S @1 ; br for success
|
||
MOVEQ #MemFullErr,D0 ; change D0 from 0 to error code
|
||
@1 MOVE.L (SP)+,A6 ; restore A6
|
||
Move.W D0,MemErr ; global error code <25Apr85>
|
||
RTS ; that's all
|
||
|
||
|
||
|
||
;----------------------------------------------------------------------
|
||
;
|
||
; FUNCTION StripAddress(p: Ptr): Ptr;
|
||
;
|
||
; Make an address in D0 suitable for use in the current environment. Ultimately,
|
||
; this should test some flag and mask suitable bits.
|
||
;
|
||
; D0 <-> Address to be stripped.
|
||
;
|
||
__StripAddress
|
||
;Roll in FixStripAddress to not check the MMStartMode <SM12>
|
||
|
||
IF Supports24Bit THEN ; <SM17> CSS
|
||
BTST.B #Systemis24bit,SystemInfo ; is it 32 bit or 24 bit <SM12>
|
||
BEQ.S @1 ; no strip address for 32 bit mode <SM12>
|
||
AND.L Lo3Bytes,D0
|
||
@1
|
||
ENDIF
|
||
RTS
|
||
|
||
|
||
|
||
;-------------------- Moved in from RAM-based glue ----------------------------------------- <04May85>
|
||
;-------------------------------------------------------------------------------------------
|
||
; PROCEDURE MoveHHi( h : Handle );
|
||
;
|
||
; Moves h up to the top of its region (space between two locked/nonrelocatable objects or
|
||
; between a lockek/nonreloc and the heap end), but with neither purge nor heap growth, only
|
||
; compaction. The idea is to use a stack buffer to move slices of the rising block in steps,
|
||
; compacting along the way to free space at the top. Requires about 1K of stack space.
|
||
; If the block is already high, MoveHHi does nothing.
|
||
;
|
||
; Arguments: A0 = handle to be moved high
|
||
; Results: D0 = error code = 0 no error
|
||
; NilHandleErr
|
||
; LkdHandleErr
|
||
; StackErr
|
||
; Register conventions:
|
||
;
|
||
; A6 - theZone pointer
|
||
; A5 - stack locals, buffer
|
||
; A4 - handle of block we are moving
|
||
; A3 - BkLim(theZone)
|
||
;
|
||
; D6 - current BC of block moved so far (not including header)
|
||
; D7 - current BC of block left to move (not including header)
|
||
;-------------------------------------------------------------------------------------------
|
||
;
|
||
; Modification History:
|
||
; 11-Apr-84 LAK Mask dereferenced handle for end-of-heap compare (get rid of
|
||
; any lock/purge/rsrc bits set . . .
|
||
; 11-Jul-84 MDB, MPH Correctly save Master Pointer flag bits.
|
||
; 14-Nov-84 RS,SC nilHandleErr, already locked err, no compact if there is enough
|
||
; room in heap to make copy of block.
|
||
; 27-Nov-84 RS fix so that multiple heap compacts are not done if not needed.
|
||
; ie. if after a compact there is a large enough free block up high to
|
||
; move all the remaining
|
||
; 14-Mar-85 CC changed to proc that returns error in MemErr; check for new ROM
|
||
; 02 May 85 JTC Moved to ROM, with general scouring. Fixed subtle bug where a free block
|
||
; smaller than minFree would be 'allocated' after a slide.
|
||
; <01Nov85 JTC> Now take stack space bounded above by what is needed (if not smaller than minimum
|
||
; acceptable) and what is available based on HiHeapMark.
|
||
;-------------------------- Post V. 1.0 System Tools ---------------------------------------
|
||
; <13Jan86 JTC> Stuff TheZone across call, so that secondary calls such as _CompactMem will
|
||
; operate on same heap. The trick is to save incoming TheZone in the stack
|
||
; frame until exit, but to be careful about the various exit pts through MMEpilogue.
|
||
;-------------------------------------------------------------------------------------------
|
||
|
||
; ————————————————— SuperMario roll in <SM 8> tcn ————————————————————————
|
||
; MoveHHi - do not let it happen to a handle in the System Heap.
|
||
;
|
||
; MoveHHi is usually called because the caller is about to lock the handle down. This is
|
||
; the right thing to do in app heaps, but is bad for the System Heap. Immobile blocks in
|
||
; the System Heap limit the extendability of the Process Mgr heap.
|
||
;
|
||
; Assumptions:
|
||
; This assumes that the system heap is the lowest heap in memory. In particular, this check will
|
||
; disable MoveHHi in subzones residing in the system heap. This behavior has been around for a
|
||
; while in MultiFinder, but should go away when we rewrite this patch.
|
||
;
|
||
; To Do: Rewrite, using the relative handle to find the zone start, comparing that to
|
||
; SysZone. This will need a safe dereference, perhaps borrowed from the IIci ROM,
|
||
; which would include a bus-error handler.
|
||
;
|
||
;——————————————————————————————————————————————————————————————————————
|
||
|
||
StkSlop EQU 3072 ; leave 3K for system
|
||
StackErr EQU -1 ; not enuf stack space for us
|
||
|
||
OldTagBC24 EQU 0 ; first long in original blk
|
||
MyBufCnt24 EQU 4 ; current buffer count
|
||
MyBufSize24 EQU 8 ; size of stack buffer
|
||
InRgnPtr24 EQU 12 ; region reference point
|
||
SvTagByte24 EQU 16 ; saved tag byte
|
||
SavedZone24 EQU 18 ; saved theZone across the call <13Jan86 JTC>
|
||
MyStkBuf24 EQU 22 ; start of stack buffer <13Jan86 JTC>
|
||
LclVarSize24 EQU MyStkBuf24
|
||
|
||
OldTagBC32 EQU 0 ; first long in original blk <v1.1>
|
||
SvBlkSize32 EQU 4 ; saved block size <v1.1>
|
||
MyBufCnt32 EQU 8 ; current buffer count <v1.1>
|
||
MyBufSize32 EQU 12 ; size of stack buffer <v1.1>
|
||
InRgnPtr32 EQU 16 ; region reference point <v1.1>
|
||
SavedZone32 EQU 20 ; saved theZone across the call <v1.1>
|
||
MyStkBuf32 EQU 24 ; start of stack buffer <v1.1>
|
||
LclVarSize32 EQU MyStkBuf32 ; <v1.1>
|
||
|
||
MoveHHi
|
||
Move.L #JMoveHHi,-(SP) ; get offset to vector onto stack <v1.9>
|
||
Move.L vMMHPrologue,-(SP) ; get MMHPrologue vector onto stack <v1.9>
|
||
RTS ; go to routine <v1.9>
|
||
|
||
v24MoveHHi ; 24 bit version of MoveHHi <v1.1>
|
||
;-------------------------------------------------------------------------------
|
||
; First check for the nasties: locked or purged.
|
||
;-------------------------------------------------------------------------------
|
||
BNE.S @goBubble ; NotEqual => not purged <31mar86>
|
||
; <SM29> kc
|
||
MOVEQ #NilHandleErr,D0 ; nil handle error <SM29> kc
|
||
BRA MHHExit ; go to common exit <SM29> kc
|
||
@goBubble ; <SM29> kc
|
||
CMPA.L SysZone,a6 ; is this handle in the System heap? <SM29> kc
|
||
BNE.S @notInSysZone ; nope <SM29> kc
|
||
; <SM29> kc
|
||
MOVEQ #noErr,D0 ; yup, don't do anything <SM29> kc
|
||
BRA MHHExit ; go to common exit <SM29> kc
|
||
@notInSysZone ; <SM29> kc
|
||
MOVE.L A1,A4 ; save handle to block for the duration <SM29> kc
|
||
TST.B (A4) ; make sure block is unlocked <SM29> kc
|
||
BPL.S @goAhead ; yup, all's cool <SM29> kc
|
||
; <SM29> kc
|
||
MOVEQ #memLockedErr,D0 ; locked handle error <SM29> kc
|
||
BRA MHHExit ; <SM29> kc
|
||
@goAhead
|
||
MOVE.L BkLim(A6),A3 ; last memory block, for the duration <04May85>
|
||
|
||
;-------------------------------------------------------------------------------
|
||
; See if we aren't already packed at top, in which case a compact is avoided.
|
||
; Set up D7 for the duration.
|
||
;-------------------------------------------------------------------------------
|
||
|
||
SUBQ.L #BlkData24,A0 ; point to actual block
|
||
MOVE.L TagBC24(A0),D1 ; block header
|
||
AND.L Lo3Bytes,D1 ; isolate the block size
|
||
MOVE.L D1,D7 ; save in D7 for the duration
|
||
SUBQ.L #BlkData24,D7 ; adjust for data count only
|
||
|
||
MOVEQ #noErr,D0 ; assume no move necessary, ok exit
|
||
ADD.L D1,A0 ; point to next block
|
||
CMP.L A3,A0 ; is it already at the limit?
|
||
BCC MHHExit ; exit if so . . .
|
||
|
||
TST.B TagBC24(A0) ; ck for Free, Rel, or NRel
|
||
BEQ.S @1 ; br if Free
|
||
BPL MHHExit ; exit if NRel (we're at region top)
|
||
|
||
MOVE.L Handle24(A0),A0 ; handle offset
|
||
ADD.L A6,A0 ; master ptr
|
||
TST.B (A0) ; locked Rel?
|
||
BMI MHHExit ; exit if so
|
||
|
||
;-------------------------------------------------------------------------------
|
||
; Set up stack buffer and local vars, with frame ptr in A5 (for the variety's sake).
|
||
; Use as much stack as is available (knowing there will be no ApplZone growth),
|
||
; but no less than 128 bytes, permitting 768 bytes for intermediate stack activity.
|
||
; New intelligence: <01Nov85 JTC>
|
||
; The basic buffer is bounded first by the new HiHeapMark (rather than the old
|
||
; BKLim(ApplZone)). Then it is bounded by the size of the block to be moved plus
|
||
; a modicum of stack slop.
|
||
; Once the frame is set up, save theZone and stuff A6 there, for subsequent MM calls<13Jan86 JTC>
|
||
;-------------------------------------------------------------------------------
|
||
@1 MOVE.L SP,D1 ; figure out the size of our stack buffer
|
||
AND.L Lo3Bytes,D1 ; why not be safe with our pointer arithmetic? <01Nov85 JTC>
|
||
SUB.L HiHeapMark,D1 ; distance between stack and highest nonstack zone <01Nov85 JTC>
|
||
AND.L #$FFFFFFF0,D1 ; quad-word align the stack buffer for 040 <SM25>
|
||
|
||
**** MOVE.L ApplZone,A0 ; (make sure we use appl zone for this) <01Nov85 JTC>
|
||
**** SUB.L BkLim(A0),D1 ; distance between stack and appl heapzone <01Nov85 JTC>
|
||
|
||
MOVE.L #StkSlop,D2 ; we demand at least this much raw space
|
||
MOVE.L D2,D0 ; in case of much space, just take what is needed <01Nov85 JTC>
|
||
ADD.L D7,D0 ; block size + slop <01Nov85 JTC>
|
||
CMP.L D0,D1 ; available-(what's needed for this case) <01Nov85 JTC>
|
||
BLT.S @3 ; Less Than (signed OK) ==> no excess stack <01Nov85 JTC>
|
||
MOVE.L D0,D1 ; use more parsimonious stack block <01Nov85 JTC>
|
||
@3 ; bypass using smaller stack request <01Nov85 JTC>
|
||
MOVEQ #StackErr,D0 ; assume error
|
||
CMP.L D2,D1 ; make sure there's at least 1K
|
||
BLT MHHExit ; just exit if not
|
||
SUB.L #128,D2 ; just use a little of the slop (was SUB.W) <01Nov85 JTC>
|
||
SUB.L D2,D1 ; buffer size is what's left
|
||
|
||
SUB.L D1,SP ; buffer
|
||
SUB.W #LclVarSize24,SP ; and space for locals
|
||
MOVE.L SP,A5 ; save pointer in A5
|
||
MOVE.L D1,MyBufSize24(A5) ; save buffer size
|
||
MOVE.L theZone,SavedZone24(A5) ; preserve incoming theZone... <13Jan86 JTC>
|
||
MOVE.L A6,theZone ; ...to be replace by handle's zone <13Jan86 JTC>
|
||
|
||
MOVE.L (A4),A0 ; also keep TagBC of block we are moving
|
||
SUBQ #BlkData24,A0
|
||
MOVE.L TagBC24(A0),OldTagBC24(A5)
|
||
|
||
MOVE.L (A4),D0 ; deref handle
|
||
AND.L Lo3Bytes,D0 ; get rid of lock, purge, etc. bits
|
||
MOVE.L D0,InRgnPtr24(A5) ; save blk as region hint
|
||
Move.B (A4),SvTagByte24(A5) ; Save tag byte.
|
||
|
||
;-------------------------------------------------------------------------------
|
||
; Don't do compact if there is a free block at the top of the region that
|
||
; is large enough to hold the contents of the block to be moved up.
|
||
;-------------------------------------------------------------------------------
|
||
BSR a24FindRgnTop ;get A2 pointing to the last block before end of region
|
||
TST.B (A2) ;is it free?
|
||
BNE.S @goCont ;no, do the buffering stuff
|
||
MOVE.L TagBC24(A2),D1 ;get the size of the block
|
||
MOVE.L D1,D0
|
||
SUBQ.L #BlkData24,D0 ;last block data space
|
||
CMP.L D0,D7 ;is it enough space?
|
||
BHI.S @goCont ;no, do the buffering stuff
|
||
SUB.L D7,D0 ;must be nonnegative! <02May85>
|
||
BEQ.S @5 ;if just enough space, go do it! <02May85>
|
||
MOVEQ #minFree24,D2 ;need at least this much to have a free block <02May85><v1.2>
|
||
CMP.L D2,D0 ; <02May85>
|
||
BCS.S @goCont ;Carry Set => not minFree left, do it the hard way <02May85>
|
||
@5
|
||
MOVE.L (A4),A0 ;ptr to the block we are moving from
|
||
MOVE.L A2,A1 ;ptr to free block
|
||
ADD.L D1,A1 ;ptr to end of free block
|
||
|
||
;-------------------------------------------------------------------------------
|
||
; One-shot move:
|
||
; D7 = amount of move
|
||
; A0 = ptr to migrating block data
|
||
; A1 = ptr to END of free block at top of region
|
||
;-------------------------------------------------------------------------------
|
||
@moveRest MOVE.L D7,D0 ;number of bytes of data to move
|
||
SUB.L D0,A1 ;grab what we need
|
||
SUB.L D0,ZCBFree(A6) ;
|
||
_BlockMove ;move the bits
|
||
MOVE.L A4,A0 ;get the handle
|
||
_EmptyHandle ;empty it out
|
||
BRA.S @MNSFinish
|
||
|
||
;-------------------------------------------------------------------------------------------
|
||
; Entry to fill/compact/stuff loop...
|
||
;-------------------------------------------------------------------------------------------
|
||
|
||
@goCont
|
||
MOVEQ #0,D6 ; D6 holds number of bytes moved up . . .
|
||
BSR a24FillStkBuf ; this does it and also adjusts handlesize
|
||
BSR DoCompact ; then move everything down
|
||
BSR a24FindRgnTop
|
||
|
||
;-------------------------------------------------------------------------------
|
||
; The top of the MoveNxtSeg loop:
|
||
; The stack buffer is full, the heap is compacted, A2 points to the free block
|
||
; (at least as large as the buffer) at the region's top. This sequence loads
|
||
; the buffer's contents up high in the region.
|
||
;-------------------------------------------------------------------------------
|
||
|
||
@MoveNxtSeg
|
||
MOVE.L TagBC24(A2),D1 ; size of free block we have at top now
|
||
MOVE.L MyBufCnt24(A5),D0 ; stack buffer count
|
||
LEA MyStkBuf24(A5),A0 ; source
|
||
MOVE.L A2,A1 ; compute destination
|
||
ADD.L D1,A1 ; point to end of free block
|
||
SUB.L D0,A1 ; grab what we need
|
||
ADD.L D0,D6 ; update count moved
|
||
SUB.L D0,ZCBFree(A6) ; *** this is a fix ***
|
||
_BlockMove ; move it in
|
||
|
||
TST.L D7 ; are we done?
|
||
BEQ.S @MNSFinish ; br if so <27oct85> BBM
|
||
|
||
;-------------------------------------------------------------------------------
|
||
; There's more to move than the bufferfull we just did. If there's just enough
|
||
; free space, or enough to move the block and have at least a minFree block,
|
||
; then exit via moveRest stub earlier. Otherwise, continue looping with the
|
||
; stack buffer...
|
||
;-------------------------------------------------------------------------------
|
||
MOVE.L A1,D0 ; ptr to dest data
|
||
SUB.L A2,D0 ; free bytes remaining
|
||
BEQ.S @MNSExact ; br if none
|
||
MOVE.L D0,D1 ; get the #free bytes remaining
|
||
SUBQ.L #BlkData24,D1 ; #free for real data
|
||
SUB.L D7,D1 ; enough for the remaining bytes?
|
||
BCS.S @MNSAdj ; Carry Set => not enough, keep buffering <02May85>
|
||
BEQ.S @MNSEscape ; EQual => just enough, so do it <02May85>
|
||
|
||
MOVEQ #minFree24,D2 ; if unequal, must be this much to be worthwhile <02May85><v1.2>
|
||
CMP.L D1,D2 ; extra VERSUS minFree <02May85>
|
||
BCC.S @MNSAdj ; not enough extra for a free block: the hard way <02Jun87>
|
||
; CC => D1 < minFree => fiddle the slack space <02Jun87>
|
||
@MNSEscape
|
||
MOVE.L (A4),A0 ; yes, move it. get source ptr
|
||
BRA.S @moveRest
|
||
@MNSAdj
|
||
MOVE.L D0,TagBC24(A2) ; adjust size of remaining free blk
|
||
@MNSExact
|
||
MOVEM.L (A1),D4-D5 ; save 2 longs at front of blk
|
||
MOVE.L A6,Handle24(A1)
|
||
MOVE.L D6,TagBC24(A1) ; data size is blk size in this case . . .
|
||
MOVE.B #$40,TagBC24(A1) ; make it an nrel blk
|
||
|
||
MOVE.L A1,-(SP)
|
||
BSR a24FillStkBuf ; this does it and also adjusts handlesize <27oct85> BBM
|
||
BSR DoCompact ; then move everything down
|
||
BSR a24FindRgnTop ; point A2 to free bk at top . . . <27oct85> BBM
|
||
MOVE.L (SP)+,A1
|
||
MOVEM.L D4-D5,(A1) ; restore data at front of blk
|
||
BRA @MoveNxtSeg ; then go again
|
||
|
||
;-------------------------------------------------------------------------------
|
||
; Clean-up code: set up any free block left over; set up header of relocated block;
|
||
; update master pointer; recover stack space and saved registers.
|
||
; Registers: A6 Zone
|
||
; A5 Local variables and buffer on stack
|
||
; A4 Handle of migrating block
|
||
; A2 Ptr to any free space
|
||
; A1 Ptr to moved block
|
||
;-------------------------------------------------------------------------------
|
||
|
||
@MNSFinish
|
||
SUBQ.L #8,A1 ; grab 8 more bytes for block header
|
||
SUBQ.L #8,ZCBFree(A6) ; *** this is a fix ***
|
||
MOVE.L A1,D0 ; figure free space left
|
||
SUB.L A2,D0
|
||
BEQ.S @11 ; br if we used it all
|
||
MOVE.L D0,TagBC24(A2) ; create a free block of remaining size
|
||
|
||
@11 MOVE.L A1,A2 ; point A2 to our new block
|
||
MOVE.L OldTagBC24(A5),(A2)+ ; TagBC
|
||
MOVE.L A4,A0
|
||
SUB.L A6,A0 ; form handle offset
|
||
MOVE.L A0,(A2)+ ; Handle
|
||
|
||
MOVE.L A2,(A4) ; update master pointer with ptr to text of block
|
||
MOVE.B SvTagByte24(A5),(A4) ; and restore flags . . .
|
||
MOVE.L SavedZone24(A5),theZone ; and theZone <13Jan86 JTC>
|
||
MOVEQ #noErr,D0 ; ok!
|
||
|
||
ADD.L MyBufSize24(A5),SP ; recover buffer space
|
||
ADD.W #LclVarSize24,SP ; and locals space
|
||
|
||
BRA MHHExit ; <v1.1>
|
||
|
||
|
||
;-------- 32 bit version ---
|
||
|
||
v32MoveHHi ; 32 bit version of MoveHHi <v1.1>
|
||
;-------------------------------------------------------------------------------
|
||
; First check for the nasties: locked or purged.
|
||
;-------------------------------------------------------------------------------
|
||
BNE.S @goBubble ; NotEqual => not purged <31mar86>
|
||
; <SM29> kc
|
||
MOVEQ #NilHandleErr,D0 ; nil handle error <SM29> kc
|
||
BRA MHHExit ; jump to common exit <SM29> kc
|
||
@goBubble ; <SM29> kc
|
||
CMPA.L SysZone,a6 ; is this handle in the System heap? <SM29> kc
|
||
BNE.S @notInSysZone ; nope <SM29> kc
|
||
; <SM29> kc
|
||
MOVEQ #noErr,D0 ; yup, don't do anything <SM29> kc
|
||
BRA MHHExit ; go to common exit <SM29> kc
|
||
@notInSysZone ; <SM29> kc
|
||
MOVE.L A1,A4 ; save handle to block for the duration <SM29> kc
|
||
TST.B MPtag32-BlkData32(A0) ; make sure block is unlocked <SM29> kc
|
||
BPL.S @goAhead ; yup, all's cool <SM29> kc
|
||
; <SM29> kc
|
||
MOVEQ #memLockedErr,D0 ; locked handle error <SM29> kc
|
||
BRA MHHExit ; jump to common exit <SM29> kc
|
||
@goAhead
|
||
MOVE.L BkLim(A6),A3 ; last memory block, for the duration <04May85>
|
||
|
||
;-------------------------------------------------------------------------------
|
||
; See if we aren't already packed at top, in which case a compact is avoided.
|
||
; Set up D7 for the duration.
|
||
;-------------------------------------------------------------------------------
|
||
|
||
SUB.L #BlkData32,A0 ; point to actual block <v1.1>
|
||
Move.L BlkSize32(A0),D1 ; get block size <v1.1>
|
||
MOVE.L D1,D7 ; save in D7 for the duration <v1.1>
|
||
SUB.L #BlkData32,D7 ; adjust for data count only <v1.1>
|
||
|
||
MOVEQ #noErr,D0 ; assume no move necessary, ok exit
|
||
ADD.L D1,A0 ; point to next block
|
||
CMP.L A3,A0 ; is it already at the limit?
|
||
BCC MHHExit ; exit if so . . .
|
||
|
||
TST.B TagBC32(A0) ; ck for Free, Rel, or NRel
|
||
BEQ.S @1 ; br if Free
|
||
BPL MHHExit ; exit if NRel (we're at region top)
|
||
|
||
Tst.B MPtag32(A0) ; locked Rel? <v1.1>
|
||
BMI MHHExit ; exit if so
|
||
|
||
;-------------------------------------------------------------------------------
|
||
; Set up stack buffer and local vars, with frame ptr in A5 (for the variety's sake).
|
||
; Use as much stack as is available (knowing there will be no ApplZone growth),
|
||
; but no less than 128 bytes, permitting 768 bytes for intermediate stack activity.
|
||
; New intelligence: <01Nov85 JTC>
|
||
; The basic buffer is bounded first by the new HiHeapMark (rather than the old
|
||
; BKLim(ApplZone)). Then it is bounded by the size of the block to be moved plus
|
||
; a modicum of stack slop.
|
||
; Once the frame is set up, save theZone and stuff A6 there, for subsequent MM calls<13Jan86 JTC>
|
||
;-------------------------------------------------------------------------------
|
||
@1 MOVE.L SP,D1 ; figure out the size of our stack buffer
|
||
SUB.L HiHeapMark,D1 ; distance between stack and highest nonstack zone <01Nov85 JTC>
|
||
AND.L #$FFFFFFF0,D1 ; quad-word align the stack buffer for 040 <SM25>
|
||
|
||
**** MOVE.L ApplZone,A0 ; (make sure we use appl zone for this) <01Nov85 JTC>
|
||
**** SUB.L BkLim(A0),D1 ; distance between stack and appl heapzone <01Nov85 JTC>
|
||
|
||
MOVE.L #StkSlop,D2 ; we demand at least this much raw space
|
||
MOVE.L D2,D0 ; in case of much space, just take what is needed <01Nov85 JTC>
|
||
ADD.L D7,D0 ; block size + slop <01Nov85 JTC>
|
||
CMP.L D0,D1 ; available-(what's needed for this case) <01Nov85 JTC>
|
||
BLT.S @3 ; Less Than (signed OK) ==> no excess stack <01Nov85 JTC>
|
||
MOVE.L D0,D1 ; use more parsimonious stack block <01Nov85 JTC>
|
||
@3 ; bypass using smaller stack request <01Nov85 JTC>
|
||
MOVEQ #StackErr,D0 ; assume error
|
||
CMP.L D2,D1 ; make sure there's at least 1K
|
||
BLT MHHExit ; just exit if not
|
||
SUB.L #128,D2 ; just use a little of the slop (was SUB.W) <01Nov85 JTC>
|
||
SUB.L D2,D1 ; buffer size is what's left
|
||
|
||
SUB.L D1,SP ; buffer
|
||
SUB.W #LclVarSize32,SP ; and space for locals
|
||
MOVE.L SP,A5 ; save pointer in A5
|
||
MOVE.L D1,MyBufSize32(A5) ; save buffer size
|
||
MOVE.L theZone,SavedZone32(A5) ; preserve incoming theZone... <13Jan86 JTC>
|
||
MOVE.L A6,theZone ; ...to be replace by handle's zone <13Jan86 JTC>
|
||
|
||
MOVE.L (A4),A0 ; also keep TagBC of block we are moving
|
||
SUB.L #BlkData32,A0 ; <v1.1>
|
||
MOVE.L TagBC32(A0),OldTagBC32(A5); save 1st long word <v1.1>
|
||
Move.L (A4),InRgnPtr32(A5) ; save blk as region hint <v1.1>
|
||
Move.L Blksize32(A0),SvBlksize32(A5); save block size <v1.1>
|
||
|
||
;-------------------------------------------------------------------------------
|
||
; Don't do compact if there is a free block at the top of the region that
|
||
; is large enough to hold the contents of the block to be moved up.
|
||
;-------------------------------------------------------------------------------
|
||
BSR a32FindRgnTop ;get A2 pointing to the last block before end of region
|
||
TST.B (A2) ;is it free?
|
||
BNE.S @goCont ;no, do the buffering stuff
|
||
MOVE.L BlkSize32(A2),D1 ;get the size of the block <v1.1>
|
||
MOVE.L D1,D0 ; <v1.1>
|
||
SUB.L #BlkData32,D0 ;last block data space <v1.1>
|
||
CMP.L D0,D7 ;is it enough space?
|
||
BHI.S @goCont ;no, do the buffering stuff
|
||
SUB.L D7,D0 ;must be nonnegative! <02May85>
|
||
BEQ.S @5 ;if just enough space, go do it! <02May85>
|
||
MOVEQ #minFree32,D2 ;need at least this much to have a free block <02May85><v1.2>
|
||
CMP.L D2,D0 ; <02May85>
|
||
BCS.S @goCont ;Carry Set => not minFree left, do it the hard way <02May85>
|
||
@5
|
||
MOVE.L (A4),A0 ;ptr to the block we are moving from
|
||
MOVE.L A2,A1 ;ptr to free block
|
||
ADD.L D1,A1 ;ptr to end of free block
|
||
|
||
;-------------------------------------------------------------------------------
|
||
; One-shot move:
|
||
; D7 = amount of move
|
||
; A0 = ptr to migrating block data
|
||
; A1 = ptr to END of free block at top of region
|
||
;-------------------------------------------------------------------------------
|
||
@moveRest MOVE.L D7,D0 ;number of bytes of data to move
|
||
SUB.L D0,A1 ;grab what we need
|
||
SUB.L D0,ZCBFree(A6) ;
|
||
_BlockMove ;move the bits
|
||
MOVE.L A4,A0 ;get the handle
|
||
_EmptyHandle ;empty it out
|
||
BRA @MNSFinish ; <SM17> CSS
|
||
|
||
;-------------------------------------------------------------------------------------------
|
||
; Entry to fill/compact/stuff loop...
|
||
;-------------------------------------------------------------------------------------------
|
||
|
||
@goCont
|
||
MOVEQ #0,D6 ; D6 holds number of bytes moved up . . .
|
||
BSR a32FillStkBuf ; this does it and also adjusts handlesize
|
||
BSR DoCompact ; then move everything down
|
||
BSR a32FindRgnTop
|
||
|
||
;-------------------------------------------------------------------------------
|
||
; The top of the MoveNxtSeg loop:
|
||
; The stack buffer is full, the heap is compacted, A2 points to the free block
|
||
; (at least as large as the buffer) at the region's top. This sequence loads
|
||
; the buffer's contents up high in the region.
|
||
;-------------------------------------------------------------------------------
|
||
|
||
@MoveNxtSeg
|
||
MOVE.L BlkSize32(A2),D1 ; size of free block we have at top <v1.1>
|
||
MOVE.L MyBufCnt32(A5),D0 ; stack buffer count
|
||
LEA MyStkBuf32(A5),A0 ; source
|
||
MOVE.L A2,A1 ; compute destination
|
||
ADD.L D1,A1 ; point to end of free block
|
||
SUB.L D0,A1 ; grab what we need
|
||
ADD.L D0,D6 ; update count moved
|
||
SUB.L D0,ZCBFree(A6) ; *** this is a fix ***
|
||
_BlockMove ; move it in
|
||
|
||
TST.L D7 ; are we done?
|
||
BEQ.S @MNSFinish ; br if so <27oct85> BBM
|
||
|
||
;-------------------------------------------------------------------------------
|
||
; There's more to move than the bufferfull we just did. If there's just enough
|
||
; free space, or enough to move the block and have at least a minFree block,
|
||
; then exit via moveRest stub earlier. Otherwise, continue looping with the
|
||
; stack buffer...
|
||
;-------------------------------------------------------------------------------
|
||
MOVE.L A1,D0 ; ptr to dest data
|
||
SUB.L A2,D0 ; free bytes remaining
|
||
BEQ.S @MNSExact ; br if none
|
||
MOVE.L D0,D1 ; get the #free bytes remaining
|
||
SUB.L #BlkData32,D1 ;#free for real data <v1.1>
|
||
SUB.L D7,D1 ; enough for the remaining bytes?
|
||
BCS.S @MNSAdj ; Carry Set => not enough, keep buffering <02May85>
|
||
BEQ.S @MNSEscape ; EQual => just enough, so do it <02May85>
|
||
|
||
MOVEQ #minFree32,D2 ; if unequal, must be this much to be worthwhile <02May85><v1.2>
|
||
CMP.L D1,D2 ; extra VERSUS minFree <02May85>
|
||
BCC.S @MNSAdj ; not enough extra for a free block: the hard way <02Jun87>
|
||
; CC => D1 < minFree => fiddle the slack space <02Jun87>
|
||
@MNSEscape
|
||
MOVE.L (A4),A0 ; yes, move it. get source ptr
|
||
BRA.S @moveRest
|
||
@MNSAdj
|
||
Clr.L TagBC32(A2) ; make it a free block <v1.1>
|
||
MOVE.L D0,BlkSize32(A2) ; adjust size of remaining free blk <v1.1>
|
||
@MNSExact
|
||
MOVEM.L (A1),D3-D5 ; save 3 longs at front of blk <v1.1>
|
||
MOVE.L A6,Handle32(A1) ; <v1.1>
|
||
MOVE.L D6,BlkSize32(A1) ; data size is blk size in this case <v1.1>
|
||
MOVE.B #$40,TagBC32(A1) ; make it an nrel blk
|
||
|
||
MOVE.L A1,-(SP)
|
||
BSR a32FillStkBuf ; this does it and also adjusts handlesize <27oct85> BBM
|
||
BSR DoCompact ; then move everything down
|
||
BSR a32FindRgnTop ; point A2 to free bk at top . . . <27oct85> BBM
|
||
MOVE.L (SP)+,A1
|
||
MOVEM.L D3-D5,(A1) ; restore data at front of blk <v1.1>
|
||
BRA @MoveNxtSeg ; then go again
|
||
|
||
;-------------------------------------------------------------------------------
|
||
; Clean-up code: set up any free block left over; set up header of relocated block;
|
||
; update master pointer; recover stack space and saved registers.
|
||
; Registers: A6 Zone
|
||
; A5 Local variables and buffer on stack
|
||
; A4 Handle of migrating block
|
||
; A2 Ptr to any free space
|
||
; A1 Ptr to moved block
|
||
;-------------------------------------------------------------------------------
|
||
|
||
@MNSFinish
|
||
SUB.L #blkData32,A1 ; grab 12 more bytes for block header <v1.1>
|
||
SUB.L #blkData32,ZCBFree(A6) ; *** this is a fix *** <v1.1>
|
||
MOVE.L A1,D0 ; figure free space left
|
||
SUB.L A2,D0
|
||
BEQ.S @11 ; br if we used it all
|
||
Clr.L TagBC32(A2) ; create a free block <v1.1>
|
||
MOVE.L D0,BlkSize32(A2) ; set remaining size <v1.1>
|
||
|
||
@11 MOVE.L A1,A2 ; point A2 to our new block
|
||
MOVE.L OldTagBC32(A5),(A2)+ ; TagBC
|
||
Move.L SvBlkSize32(A5),(A2)+ ; block size <v1.1>
|
||
MOVE.L A4,A0
|
||
SUB.L A6,A0 ; form handle offset
|
||
MOVE.L A0,(A2)+ ; Handle
|
||
|
||
MOVE.L A2,(A4) ; update master pointer with ptr to text of block
|
||
MOVE.L SavedZone32(A5),theZone ; and theZone <13Jan86 JTC>
|
||
MOVEQ #noErr,D0 ; ok!
|
||
|
||
ADD.L MyBufSize32(A5),SP ; recover buffer space
|
||
ADD.W #LclVarSize32,SP ; and locals space
|
||
MHHExit
|
||
Move.L vMMEpilogue,-(SP) ; get vector to MMEpilogue <v1.9>
|
||
RTS ; jump to it <v1.9>
|
||
|
||
;-------------------------------------------------------------------------------------------
|
||
; Utility FUNCTION FindRgnTop( zone : Ptr; localVars : Ptr; hand : Handle; EOZ : Ptr ) : Ptr;
|
||
;
|
||
; Return a pointer to the last block beyond the handle in question, but before the next locked
|
||
; or nonrelocatable or trailing block.
|
||
;
|
||
; Arguments: A6 = heap zone
|
||
; A5 = ptr to local vars and buffer on stack
|
||
; A4 = handle in migration
|
||
; A3 = last block in zone
|
||
;
|
||
; Results: A2 = ptr to 'last' block
|
||
;
|
||
; Registers: D0-D1/A0-A1
|
||
;
|
||
; Called at labels: moveRest (just before), goCont, moveNxtSeg
|
||
;-------------------------------------------------------------------------------------------
|
||
|
||
a24FindRgnTop MOVE.L (A4),D0 ; deref handle
|
||
BEQ.S @10 ; br if nil (disposed)
|
||
|
||
AND.L Lo3Bytes,D0 ; get rid of lock, purge, etc. bits
|
||
MOVE.L D0,A0
|
||
SUBQ #BlkData24,A0 ; start scan from here for speed
|
||
BRA.S @FRTLoop
|
||
|
||
@10 LEA HeapData(A6),A0 ; scan from start of zone
|
||
|
||
@FRTLoop MOVE.L TagBC24(A0),D1 ; block header
|
||
AND.L Lo3Bytes,D1 ; isolate the block size
|
||
TST.B TagBC24(A0) ; ck for Free, Rel, or NRel
|
||
BEQ.S @1 ; br if Free
|
||
BPL.S @2 ; br if NReloc (end of region)
|
||
MOVE.L Handle24(A0),A1 ; handle offset
|
||
ADD.L A6,A1 ; master ptr
|
||
TST.B (A1) ; locked Rel?
|
||
BMI.S @2 ; br if Locked (end of region)
|
||
|
||
@1 MOVE.L A0,A2 ; remember this as the last block
|
||
ADD.L D1,A0 ; point to next block
|
||
CMP.L A3,A0 ; reached the end of zone?
|
||
BCS.S @FRTLoop ; loop if not (fruitloops)
|
||
BRA.S @3 ; otherwise exit (must be in last rgn)
|
||
|
||
@2 CMP.L InRgnPtr24(A5),A0 ; are we in the correct region?
|
||
BLS.S @1 ; keep looking, if not
|
||
|
||
@3 RTS
|
||
|
||
;
|
||
; ------- 32 bit version
|
||
;
|
||
a32FindRgnTop MOVE.L (A4),D0 ; deref handle
|
||
BEQ.S @10 ; br if nil (disposed)
|
||
|
||
MOVE.L D0,A0 ; <v1.1>
|
||
SUB.L #BlkData32,A0 ; start scan from here for speed <v1.1>
|
||
BRA.S @FRTLoop
|
||
|
||
@10 LEA HeapData(A6),A0 ; scan from start of zone
|
||
|
||
@FRTLoop
|
||
MOVE.L BlkSize32(A0),D1 ; block size <v1.1>
|
||
TST.B TagBC32(A0) ; ck for Free, Rel, or NRel
|
||
BEQ.S @1 ; br if Free
|
||
BPL.S @2 ; br if NReloc (end of region)
|
||
Tst.B MPtag32(A0) ; locked Rel? <v1.1>
|
||
BMI.S @2 ; br if Locked (end of region)
|
||
|
||
@1 MOVE.L A0,A2 ; remember this as the last block
|
||
ADD.L D1,A0 ; point to next block
|
||
CMP.L A3,A0 ; reached the end of zone?
|
||
BCS.S @FRTLoop ; loop if not (fruitloops)
|
||
BRA.S @3 ; otherwise exit (must be in last rgn)
|
||
|
||
@2 CMP.L InRgnPtr32(A5),A0 ; are we in the correct region?
|
||
BLS.S @1 ; keep looking, if not
|
||
|
||
@3 RTS
|
||
|
||
;-------------------------------------------------------------------------------------------
|
||
; Utility PROCEDURE FilStkBuf( VAR curDataSize : LongInt; zone : Ptr; localVars : Ptr; hand : Handle; );
|
||
;
|
||
; Fill stack buffer with MIN(MyBufSize,HandleSize) bytes from block in migration. If moving entire
|
||
; handle, just empty that handle on completion. Otherwise, adjust the size of the depleted handle and
|
||
; create a new free block.
|
||
;
|
||
; Arguments: D7 curDataSize = amount left to move
|
||
; A6 zone = heap zone
|
||
; A5 localVars = ptr to stack vars and buffer
|
||
; A4 hand = handle to block being moved
|
||
;
|
||
; Results: D7 updated curDataSize
|
||
;
|
||
; Called after labels: goCont, moveNxtSeg
|
||
;
|
||
; Registers: D0-D2/A0-A1
|
||
;-------------------------------------------------------------------------------------------
|
||
|
||
a24FillStkBuf
|
||
MOVE.L MyBufSize24(A5),D0 ; figure MIN(MyBufSize,HandleSize)
|
||
CMP.L D7,D0 ; D7 is current data size of blk we're moving
|
||
BLT.S @1
|
||
MOVE.L D7,D0 ; use current size if <= buffer size
|
||
@1
|
||
LEA MyStkBuf24(A5),A1 ; destination
|
||
MOVE.L (A4),A0 ; BlkData pointer
|
||
ADD.L D7,A0 ; end of block pointer
|
||
SUB.L D0,A0 ; source (move last D0 bytes of blk)
|
||
SUB.L D0,D7 ; adjust current size
|
||
MOVE.L D0,MyBufCnt24(A5) ; set up buffer count
|
||
MOVE.L D0,D1 ; and save in D1 (size of new free blk)
|
||
_BlockMove
|
||
|
||
MOVE.L A4,A0 ; HBlk
|
||
MOVE.L D7,D0 ; remaining bytes in block
|
||
BNE.S @2 ; br if space left
|
||
_EmptyHandle ; get rid of entire blk when 0 (updates freemem)
|
||
RTS
|
||
|
||
; We still haven't emptied the block, so create a smaller block with data size
|
||
; D0=D7 and a free block of size D1 (the amount we moved). Note that by virtue
|
||
; of this style of block truncation, the physical/logical size fudge factor is
|
||
; guaranteed to be zero.
|
||
@2
|
||
MOVE.L (A0),A0 ; ptr to data portion of what's left
|
||
SUBQ #BlkData24,A0 ; ptr to block that's left
|
||
MOVE.B TagBC24(A0),D2 ; save Tag
|
||
ADDQ.L #BlkData24,D0 ; new physical block size
|
||
MOVE.L D0,TagBC24(A0) ; set BC
|
||
MOVE.B D2,TagBC24(A0) ; and restore tag
|
||
|
||
ADD.L D0,A0 ; point to new free block
|
||
MOVE.L D1,TagBC24(A0) ; set Tag=free, BC
|
||
ADD.L D1, ZCBFree(A6) ; update free count.
|
||
RTS
|
||
|
||
; 32 bit version
|
||
a32FillStkBuf
|
||
MOVE.L MyBufSize32(A5),D0 ; figure MIN(MyBufSize,HandleSize)
|
||
CMP.L D7,D0 ; D7 is current data size of blk we're moving
|
||
BLT.S @1
|
||
MOVE.L D7,D0 ; use current size if <= buffer size
|
||
@1
|
||
LEA MyStkBuf32(A5),A1 ; destination
|
||
MOVE.L (A4),A0 ; BlkData pointer
|
||
ADD.L D7,A0 ; end of block pointer
|
||
SUB.L D0,A0 ; source (move last D0 bytes of blk)
|
||
SUB.L D0,D7 ; adjust current size
|
||
MOVE.L D0,MyBufCnt32(A5) ; set up buffer count
|
||
MOVE.L D0,D1 ; and save in D1 (size of new free blk)
|
||
_BlockMove
|
||
|
||
MOVE.L A4,A0 ; HBlk
|
||
MOVE.L D7,D0 ; remaining bytes in block
|
||
BNE.S @2 ; br if space left
|
||
_EmptyHandle ; get rid of entire blk when 0 (updates freemem)
|
||
RTS
|
||
|
||
; We still haven't emptied the block, so create a smaller block with data size
|
||
; D0=D7 and a free block of size D1 (the amount we moved). Note that by virtue
|
||
; of this style of block truncation, the physical/logical size fudge factor is
|
||
; guaranteed to be zero.
|
||
@2
|
||
MOVE.L (A0),A0 ; ptr to data portion of what's left
|
||
SUB.L #BlkData32,A0 ; ptr to block that's left <v1.1>
|
||
ADD.L #BlkData32,D0 ; new physical block size <v1.1>
|
||
MOVE.L D0,BlkSize32(A0) ; set size <v1.1>
|
||
ADD.L D0,A0 ; point to new free block <v1.1>
|
||
Clr.L tagBC32(A0) ; set as free block <v1.1>
|
||
MOVE.L D1,BlkSize32(A0) ; set free block size <v1.1>
|
||
ADD.L D1, ZCBFree(A6) ; update free count.
|
||
RTS
|
||
|
||
;-------------------------------------------------------------------------------------------
|
||
; Utility PROCEDURE DoCompact;
|
||
;
|
||
; Arguments: none
|
||
; Results: thoroughly compacted heap
|
||
; Registers: D0
|
||
; Called at labels: goCont, moveNxtSeg
|
||
;-------------------------------------------------------------------------------------------
|
||
|
||
DoCompact
|
||
MOVE.L RealMemTop,D0 ; compact to push all the <v1.9>
|
||
_CompactMem ; free space to the top . . .
|
||
RTS
|
||
|
||
|
||
|
||
END ; *********** comment this out for RAMTest
|
||
|