mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-22 23:29:27 +00:00
4325cdcc78
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
3854 lines
154 KiB
Plaintext
3854 lines
154 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
|
|
|