-- SpaceA.Mesa Last Edited by Curry on October 1, 1980 DIRECTORY AltoDefs USING [PageSize], FSPDefs USING [ AddToNewZone, DestroyZone, FreeNode, MakeNewZone, MakeNode, NoRoomInZone, NodeOverhead, ZoneOverhead, ZonePointer], InlineDefs, IODefs, Space, SegmentDefs, StringDefs, SystemDefs; SpaceA: PROGRAM IMPORTS InlineDefs, IODefs, FSPDefs, SegmentDefs, StringDefs, SystemDefs EXPORTS Space = PUBLIC BEGIN OPEN AltoDefs, SegmentDefs, Space; -- Free Storage Package -- myHeap:FSPDefs.ZonePointer _ NIL; Machine: SegmentDefs.MachineType = SegmentDefs.GetMemoryConfig[].AltoType; DMachine: BOOLEAN = (Machine = D0) OR (Machine = Dorado); CurrentBase, RefBase:PageNumber _ DefaultBase2; Base2:PageNumber _ DefaultBase2; Base3:PageNumber _ DefaultBase3; Base4:PageNumber _ Base3 - 1; Base5:PageNumber _ Base4 - 1; HeapZone:PROCEDURE RETURNS [POINTER] = BEGIN RETURN[myHeap] END; InitHeap:PROCEDURE[np:CARDINAL] = BEGIN OPEN SystemDefs, FSPDefs; IF myHeap # NIL THEN EraseHeap[]; myHeap _ MakeNewZone[ AllocateResidentPages[np], np*AltoDefs.PageSize, FreePages]; RETURN END; EraseHeap:PROCEDURE = BEGIN FSPDefs.DestroyZone[myHeap]; myHeap _ NIL; RETURN END; GetSpace:PROCEDURE[nwords:CARDINAL] RETURNS[p:POINTER] = BEGIN OPEN SystemDefs, FSPDefs; np:CARDINAL; IF myHeap = NIL THEN InitHeap[1]; p _ MakeNode[myHeap, nwords ! NoRoomInZone => BEGIN np _ PagesForWords [nwords + ZoneOverhead + NodeOverhead]; AddToNewZone[ myHeap, AllocateResidentPages[np], np*AltoDefs.PageSize, FreePages]; RESUME END]; RETURN END; FreeSpace:PROCEDURE[p:POINTER] = BEGIN FSPDefs.FreeNode[myHeap, p]; RETURN END; GetSpaceLong:PROCEDURE[nwords:CARDINAL] RETURNS[lp:LONG POINTER]= BEGIN OPEN SegmentDefs; IF DMachine THEN lp _ LongDataSegmentAddress[NewDataSegment [DefaultXMBase, (nwords+255)/256 ]] ELSE lp _ SystemDefs.AllocateSegment[nwords]; RETURN[ lp ]; END; OldGetSpaceLong:PROCEDURE[nwords:CARDINAL] RETURNS[lp:LONG POINTER]= BEGIN OPEN SegmentDefs; RefBase _ CurrentBase; IF DMachine THEN lp _ LongDataSegmentAddress[NewDataSegment [CurrentBase, (nwords+255)/256 ! InsufficientVM => BEGIN CurrentBase _ CurrentBase - 1; IF CurrentBase < Base5 THEN CurrentBase _ Base2; IF CurrentBase = RefBase THEN ERROR ELSE RETRY; END ] ] ELSE lp _ SystemDefs.AllocateSegment[nwords]; RETURN[ lp ]; END; FreeSpaceLong:PROCEDURE[lp:LONG POINTER]= BEGIN OPEN SegmentDefs; IF DMachine THEN DeleteDataSegment [LongVMtoDataSegment[lp]] ELSE SystemDefs.FreeSegment[InlineDefs.LowHalf[lp]]; END; GetString:PROCEDURE[nchars:CARDINAL] RETURNS [s:STRING] = BEGIN s _ GetSpace[StringDefs.WordsForString[nchars]]; s^ _ [length:0, maxlength:nchars, text: ]; RETURN END; FreeString:PROCEDURE[s:STRING] = LOOPHOLE[FreeSpace]; CopyString:PROCEDURE [s: STRING, longer: CARDINAL _ 0] RETURNS [STRING] = BEGIN ns: STRING; IF s = NIL THEN RETURN [IF longer = 0 THEN NIL ELSE GetString[longer]]; ns _ GetString[s.length + longer]; InlineDefs.COPY[from: @s.text, to: @ns.text, nwords: (s.length + 1)/2]; ns.length _ s.length; RETURN[ns]; END; (635)\320b6B192b6B28b7B69b8B50b20B28b5B28b5B28b5B25b5B26b8B60b8B191b9B75b8B372b9B73b12B244b15B447b13B173b9B160b10B45b10B CheckLongStorage:PROCEDURE[str:STRING _ "?"] = BEGIN bank,npages:CARDINAL; lp:LONG POINTER _ GetSpaceLong[1]; FreeSpaceLong[lp]; bank _ InlineDefs.HighHalf[lp]; npages _ InlineDefs.BITSHIFT[ InlineDefs.LowHalf[lp],-8 ]; IODefs.WriteLine[" "]; IODefs.WriteDecimal[LOOPHOLE[npages]]; IODefs.WriteString[" pages available in bank "]; IODefs.WriteDecimal[LOOPHOLE[bank]]; IODefs.WriteString[" at "]; IODefs.WriteString[str]; IODefs.WriteLine[" .... Ready?"]; [] _ IODefs.ReadChar[]; END; END. \b16B