home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / t / tcsel003.zip / OVERSIZE.PAS < prev    next >
Pascal/Delphi Source File  |  1992-10-16  |  6KB  |  155 lines

  1. unit Oversize;
  2.  
  3. {  Author:  Trevor J Carlsen
  4.             Algorithm Enterprises Pty Ltd
  5.             PO Box 568
  6.             Port Hedland  6721
  7.             Western Australia
  8.             Telephone:  (Voice)  +61 [0]91 73 2026
  9.                         (Data )  +61 [0]91 73 2569
  10.                         
  11.   Released into the Public Domain 1991.
  12.  
  13.   An unit that will enable logical arrays to be created using up to the amount 
  14.   of heap memory available.
  15.  
  16.   The line marked (**) MUST be altered to reflect the type of data in big 
  17.   array and the unit MUST be recompiled after this change.
  18.  
  19.   No provision is made in this unit for recovering the memory used by the big 
  20.   array as the intention was to keep it appearing to the programmer as close 
  21.   as possible to static type global variables.
  22.  
  23.   Bear in mind that you do NOT declare your array anywhere using this unit.  
  24.   That is all handled automatically.  All you have to do is give the global 
  25.   variable MaxElements a value with the number of elements you want in the 
  26.   array and then call the procedure initialise.  From then on your array is 
  27.   called data^. (Actually it is called nothing as it is dynamic and is 
  28.   referenced via the pointer "data" but if you think of it as being called 
  29.   "data^" you don't even need to know how pointers work!)
  30.  
  31.   The array, using this unit, can only be singly dimensioned although there is 
  32.   no reason why the unit could not be hacked to allow multi-dimensions.
  33.   
  34.  }
  35.  
  36. interface
  37.  
  38. type
  39. (**)  Datatype = longint;   { change to whatever type you want for the array }
  40.   bigarray = array[0..0] of Datatype;
  41.   bigptr   = ^bigarray;
  42. var
  43.   data : bigptr;
  44.   MaxElements : longint;    { this variable must have the number of elements }
  45.  
  46. {----------------------------------------------------------------------------}
  47. function Element(l:longint):byte;
  48.   
  49.   { Call by passing the element number you wish to reference.                }
  50.   { Always returns zero.  It works by changing the value of the pointer      }
  51.   { data.  This means that you cannot ever reference your big array by       }
  52.   {   data^[100000] := whatever;                                             }
  53.   { It MUST always be referenced by calling this function eg.                }
  54.   {   data^[Element(100000)] := whatever;                                    }
  55.  
  56.  
  57. {----------------------------------------------------------------------------}
  58. function AllocateMem(var b,l): boolean;
  59.   
  60.   { Returns true if memory was allocated successfully for the big array and  }
  61.   { false if there was insufficient memory.                                  }
  62.  
  63. {----------------------------------------------------------------------------}
  64. procedure Initialise;  { Must be called before using any other procedure     }
  65.  
  66. {============================================================================}
  67.  
  68. implementation
  69.  
  70. {============================================================================}
  71. { private declarations }
  72.  
  73. const
  74.   max          = 65520 div sizeof(datatype);{ The number of elements/segment }
  75.   initialised  : boolean = false;
  76.   
  77. type
  78.   address  =  record                     { allows arithmetic on the pointers }
  79.                 offset,
  80.                 segment : word;
  81.               end;
  82.   baseArray = array[0..9] of address;    { for the addresses of the segments }
  83.  
  84. var
  85.   base : baseArray;
  86.   
  87.  
  88. {----------------------------------------------------------------------------}
  89. function Element(l:longint):byte;
  90.  
  91.   var
  92.     theaddress : address absolute data;
  93.     bigaddress : baseArray absolute base;
  94.  
  95.   begin
  96.     
  97.     { First make sure that initialisation has been done correctly            }
  98.     if not initialised then begin 
  99.       writeln('Initialise procedure has not been called');
  100.       halt(254);
  101.     end;  { if not initialised }
  102.     
  103.     Element := 0; { It is really irrelevent but any other value here would   }
  104.                   { produce a range check error at runtime if R+             }
  105.     
  106.     { Now let us fool TP into thinking that the address of element zero is   }
  107.     { address of the element we are looking for.                             }
  108.     with theaddress do begin
  109.       segment := bigaddress[l div max].segment;            { Get the segment }
  110.       offset  := (l mod max) * sizeof(datatype);            { Get the offset }
  111.     end;  { with theaddress }
  112.   end;  { ElementNumber }
  113.  
  114. {----------------------------------------------------------------------------}
  115. function AllocateMem(var b,l): boolean;
  116.   
  117.   type
  118.     ptrarray = array[0..9] of pointer;
  119.   var
  120.     barray: ptrarray absolute b;
  121.     x     : byte;
  122.     count : longint;
  123.   begin
  124.     count := MaxElements;
  125.     AllocateMem := true;
  126.     for x := 0 to (count div max) do     { allocate in 64K contiguous chunks }
  127.       if (count * sizeof(datatype)) > 65520 then begin
  128.         if MaxAvail < (max * sizeof(datatype)) then begin { not enough memory} 
  129.           dec(count,max);
  130.           AllocateMem := false;
  131.         end 
  132.         else
  133.           GetMem(barray[x],max * sizeof(datatype));
  134.       end
  135.       else
  136.         if MaxAvail < (count * sizeof(datatype)) then
  137.            AllocateMem := false
  138.         else
  139.            GetMem(barray[x],count * sizeof(datatype)); 
  140.   end;  { AllocateMem }
  141.   
  142. {----------------------------------------------------------------------------}
  143. procedure Initialise;
  144.   begin
  145.     FillChar(base,sizeof(base),0);
  146.     if not AllocateMem(base,MaxElements) then begin
  147.       writeln('Insufficient memory');
  148.       halt(255);
  149.     end;
  150.     initialised := true;              { All Ok and memory has been allocated }
  151.   end;  { Initialise }
  152.   
  153. end.  { Unit Oversize }
  154.