home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / tsr / tsrsrc33.zip / XMS.PAS < prev   
Pascal/Delphi Source File  |  1992-01-08  |  9KB  |  356 lines

  1. {**************************************************************************
  2. *   XMS - unit of XMS functions                                           *
  3. *   Copyright (c) 1991 Kim Kokkonen, TurboPower Software.                 *
  4. *   May be freely distributed and used but not sold except by permission. *
  5. *                                                                         *
  6. *   Version 3.0 9/24/91                                                   *
  7. *     first release                                                       *
  8. *   Version 3.1 11/4/91                                                   *
  9. *     no change                                                           *
  10. *   Version 3.2 11/22/91                                                  *
  11. *     add AllocateUmbMem, FreeUmbMem functions                            *
  12. *   Version 3.3 1/8/92                                                    *
  13. *     no change                                                           *
  14. ***************************************************************************}
  15.  
  16. {$R-,S-,I-,V-,B-,F-,A-,E-,N-,G-,X-}
  17.  
  18. unit Xms;
  19.   {-XMS functions needed for TSR Utilities}
  20.  
  21. interface
  22.  
  23. const
  24.   ExhaustiveXms : Boolean = False;
  25.  
  26. type
  27.   XmsHandleRecord =
  28.   record
  29.     Handle : Word;
  30.     NumPages : Word;
  31.   end;
  32.   XmsHandles = array[1..16380] of XmsHandleRecord;
  33.   XmsHandlesPtr = ^XmsHandles;
  34.  
  35. function XmsInstalled : Boolean;
  36.   {-Returns True if XMS memory manager installed}
  37.  
  38. function QueryFreeExtMem(var TotalFree, LargestBlock : Word) : Byte;
  39.   {-Return info about free XMS (in k bytes)}
  40.  
  41. function GetHandleInfo(XmsHandle : Word;
  42.                        var LockCount    : Byte;
  43.                        var HandlesLeft  : Byte;
  44.                        var BlockSizeInK : Word) : Byte;
  45.   {-Return info about specified Xms handle}
  46.  
  47. function AllocateExtMem(SizeInK : Word; var XmsHandle : Word) : Byte;
  48.   {-Allocate XMS memory}
  49.  
  50. function FreeExtMem(XmsHandle : Word) : Byte;
  51.   {-Free XMS memory}
  52.  
  53. function AllocateUmbMem(SizeInP : Word; var Segment, Size : Word) : Byte;
  54.   {-Allocate UMB memory}
  55.  
  56. function FreeUmbMem(Segment : Word) : Byte;
  57.   {-Deallocate UMB memory}
  58.  
  59. function GetXmsHandles(var XmsPages : XmsHandlesPtr) : Word;
  60.   {-Return number of XMS handles allocated, and pointer to array of handle records}
  61.  
  62. function ExtMemPossible : Boolean;
  63.   {-Return true if raw extended memory is possible}
  64.  
  65. function ExtMemTotalPrim : LongInt;
  66.   {-Returns total number of bytes of extended memory in the system}
  67.  
  68. {=======================================================================}
  69.  
  70. implementation
  71.  
  72. var
  73.   XmsControl       : Pointer;          {ptr to XMS control procedure}
  74.  
  75.   function XmsInstalled : Boolean;
  76.     {-Returns True if XMS memory manager installed}
  77.   begin
  78.     XmsInstalled := (XmsControl <> nil);
  79.   end;
  80.  
  81.   function XmsInstalledPrim : Boolean; assembler;
  82.     {-Returns True if an XMS memory manager is installed}
  83.   asm
  84.     mov ah,$30
  85.     int $21
  86.     cmp al,3
  87.     jae @Check2F
  88.     mov al,0
  89.     jmp @Done
  90. @Check2F:
  91.     mov ax,$4300
  92.     int $2F
  93.     cmp al,$80
  94.     mov al,0
  95.     jne @Done
  96.     inc al
  97. @Done:
  98.   end;
  99.  
  100.   function XmsControlAddr : Pointer; assembler;
  101.     {-Return address of XMS control function}
  102.   asm
  103.     mov ax,$4310
  104.     int $2F
  105.     mov ax,bx
  106.     mov dx,es
  107.   end;
  108.  
  109.   function QueryFreeExtMem(var TotalFree, LargestBlock : Word) : Byte; assembler;
  110.     {-Return info about free XMS}
  111.   asm
  112.     mov ah,$08
  113.     call dword ptr [XmsControl]
  114.     or ax,ax
  115.     jz @Done
  116.     les di,TotalFree
  117.     mov es:[di],dx
  118.     les di,LargestBlock
  119.     mov es:[di],ax
  120.     xor bl,bl
  121. @Done:
  122.     mov al,bl
  123.   end;
  124.  
  125.   function GetHandleInfo(XmsHandle : Word;
  126.                          var LockCount    : Byte;
  127.                          var HandlesLeft  : Byte;
  128.                          var BlockSizeInK : Word) : Byte; assembler;
  129.     {-Return info about specified Xms handle}
  130.   asm
  131.     mov ah,$0E
  132.     mov dx,XmsHandle
  133.     call dword ptr [XmsControl]
  134.     test ax,1
  135.     jz @Done
  136.     les di,LockCount
  137.     mov byte ptr es:[di],bh
  138.     les di,HandlesLeft
  139.     mov byte ptr es:[di],bl
  140.     les di,BlockSizeInK
  141.     mov es:[di],dx
  142.     xor bl,bl
  143. @Done:
  144.     mov al,bl
  145.   end;
  146.  
  147.   function AllocateExtMem(SizeInK : Word; var XmsHandle : Word) : Byte; assembler;
  148.     {-Allocate XMS memory}
  149.   asm
  150.     mov ah,$09
  151.     mov dx,SizeInK
  152.     call dword ptr [XmsControl]
  153.     test ax,1
  154.     jz @Done
  155.     les di,XmsHandle
  156.     mov es:[di],dx
  157.     xor bl,bl
  158. @Done:
  159.     mov al,bl
  160.   end;
  161.  
  162.   function FreeExtMem(XmsHandle : Word) : Byte; assembler;
  163.     {-Free XMS memory}
  164.   asm
  165.     mov ah,$0A
  166.     mov dx,XmsHandle
  167.     call dword ptr [XmsControl]
  168.     test ax,1
  169.     jz @Done
  170.     xor bl,bl
  171. @Done:
  172.     mov al,bl
  173.   end;
  174.  
  175.   function AllocateUmbMem(SizeInP : Word; var Segment, Size : Word) : Byte; assembler;
  176.   asm
  177.     mov ah,$10
  178.     mov dx,SizeInP
  179.     call dword ptr [XmsControl]
  180.     les di,Size
  181.     mov es:[di],dx            {return size of allocated block or largest block}
  182.     test ax,1
  183.     jz @Done
  184.     les di,Segment
  185.     mov es:[di],bx            {return segment}
  186.     xor bl,bl                 {no error}
  187. @Done:
  188.     mov al,bl                 {return error result}
  189.   end;
  190.  
  191.   function FreeUmbMem(Segment : Word) : Byte; assembler;
  192.   asm
  193.     mov ah,$11
  194.     mov dx,Segment
  195.     call dword ptr [XmsControl]
  196.     test ax,1
  197.     jz @Done
  198.     xor bl,bl
  199. @Done:
  200.     mov al,bl
  201.   end;
  202.  
  203.   function GetXmsHandles(var XmsPages : XmsHandlesPtr) : Word;
  204.     {-Return number of XMS handles allocated, and pointer to array of handle records}
  205.   var
  206.     H : Word;
  207.     H0 : Word;
  208.     H1 : Word;
  209.     HCnt : Word;
  210.     FMem : Word;
  211.     FMax : Word;
  212.     HMem : Word;
  213.     LockCount : Byte;
  214.     HandlesLeft : Byte;
  215.     Delta : Integer;
  216.     Status : Byte;
  217.     Done : Boolean;
  218.  
  219.     procedure ExhaustiveSearchHandles(var Handles : Word; XmsPages : XmsHandlesPtr);
  220.       {-Search handles exhaustively}
  221.     var
  222.       H : Word;
  223.       HCnt : Word;
  224.     begin
  225.       HCnt := 0;
  226.       for H := 0 to 65535 do
  227.         if GetHandleInfo(H, LockCount, HandlesLeft, HMem) = 0 then begin
  228.           inc(HCnt);
  229.           if XmsPages <> nil then
  230.             with XmsPages^[HCnt] do begin
  231.               Handle := H;
  232.               NumPages := HMem;
  233.             end;
  234.         end;
  235.       Handles := HCnt;
  236.     end;
  237.  
  238.   begin
  239.     GetXmsHandles := 0;
  240.  
  241.     Status := QueryFreeExtMem(FMem, FMax);
  242.     if Status = $A0 then begin
  243.       FMem := 0;
  244.       FMax := 0;
  245.     end else if Status <> 0 then
  246.       Exit;
  247.  
  248.     if ExhaustiveXms then begin
  249.       {Search all 64K XMS handles for valid ones}
  250.       HCnt := 0;
  251.       ExhaustiveSearchHandles(HCnt, nil);
  252.       if HCnt <> 0 then begin
  253.         GetMem(XmsPages, HCnt*SizeOf(XmsHandleRecord));
  254.         ExhaustiveSearchHandles(HCnt, XmsPages);
  255.         GetXmsHandles := HCnt;
  256.       end;
  257.  
  258.     end else begin
  259.       {Heuristic algorithm to find used handles quickly}
  260.  
  261.       {Allocate two dummy handles}
  262.       if FMem > 1 then
  263.         HMem := 1
  264.       else
  265.         HMem := 0;
  266.       Status := AllocateExtMem(HMem, H0);
  267.       if Status <> 0 then
  268.         Exit;
  269.       Status := AllocateExtMem(HMem, H1);
  270.       if Status <> 0 then begin
  271.         {Deallocate dummy handle}
  272.         Status := FreeExtMem(H0);
  273.         Exit;
  274.       end;
  275.       Delta := H1-H0;
  276.       {Deallocate one dummy}
  277.       Status := FreeExtMem(H1);
  278.  
  279.       {Trace back through valid handles, counting them}
  280.       HCnt := 0;
  281.       H1 := H0;
  282.       repeat
  283.         Status := GetHandleInfo(H1, LockCount, HandlesLeft, HMem);
  284.         Done := (Status <> 0);
  285.         if not Done then begin
  286.           dec(H1, Delta);
  287.           inc(HCnt);
  288.         end;
  289.       until Done;
  290.  
  291.       if HCnt > 1 then begin
  292.         dec(HCnt);
  293.         GetMem(XmsPages, HCnt*SizeOf(Word));
  294.         {Go forward again through valid handles, saving them}
  295.         inc(H1, Delta);
  296.         H := 0;
  297.         while H1 <> H0 do begin
  298.           Status := GetHandleInfo(H1, LockCount, HandlesLeft, HMem);
  299.           if Status = 0 then begin
  300.             inc(H);
  301.             with XmsPages^[H] do begin
  302.               Handle := H1;
  303.               NumPages := HMem;
  304.             end;
  305.           end;
  306.           inc(H1, Delta);
  307.         end;
  308.         GetXmsHandles := HCnt;
  309.       end;
  310.  
  311.       {Deallocate dummy handle}
  312.       Status := FreeExtMem(H0);
  313.     end;
  314.   end;
  315.  
  316.   function DosVersion : Byte; Assembler;
  317.     {-Return major DOS version number}
  318.   asm
  319.     mov     ah,$30
  320.     int     $21
  321.   end;
  322.  
  323.   function ExtMemPossible : Boolean;
  324.     {-Return true if raw extended memory is possible}
  325.   const
  326.     ATclass = $FC;              {machine ID bytes}
  327.     Model80 = $F8;
  328.   var
  329.     MachineId : Byte absolute $FFFF : $000E;
  330.   begin
  331.     {don't allow allocation if running PC or XT, or under DOS 2.x or OS/2}
  332.     ExtMemPossible := False;
  333.     case DosVersion of
  334.       3..5 :
  335.         case MachineId of
  336.           ATclass, Model80 : ExtMemPossible := True;
  337.         end;
  338.     end;
  339.   end;
  340.  
  341.   function ExtMemTotalPrim : LongInt; assembler;
  342.     {-Returns total number of bytes of extended memory in the system}
  343.   asm
  344.     mov ah,$88
  345.     int $15
  346.     mov cx,1024
  347.     mul cx
  348.   end;
  349.  
  350. begin
  351.   if XmsInstalledPrim then
  352.     XmsControl := XmsControlAddr
  353.   else
  354.     XmsControl := nil;
  355. end.
  356.