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