unit XMS;

{ XMS Unit, procedures to access XMS functions        }
{                                                     }
{ Copyright (c) 1994-95 Balazs Scheidler              }
{                                                     }
{                                                     }
{ You can freely use this piece of code as long as    }
{ you credit my name, if you use it in a commercial   }
{ or shareware product.                               }
{                                                     }
{ I can be reached at                                 }
{  e-mail: bazsi@vekoll.saturnus.vein.hu              }
{       or bazsi@hal2000.vein.hu                      }

{$G+,S-,V-,R-}

interface

var
  XMSHandler: Pointer;
  XMSInstalled: Boolean;
  XMSErr: Byte;

function XMSGetVersion: Longint;
function XMSAllocHMA(Size: Word): Boolean;
function XMSFreeHMA: Boolean;
function XMSGlobalA20Enable: Boolean;
function XMSGlobalA20Disable: Boolean;
function XMSLocalA20Enable: Boolean;
function XMSLocalA20Disable: Boolean;
function XMSA20Enabled: Boolean;
function XMSMaxEMBAvail: Word;
function XMSMemEMBAvail: Word;
function XMSAllocEMB(Size: Word): Word;
function XMSFreeEMB(Handle: Word): Boolean;
function XMSCopyBlock(DestOfs: Longint; DestHandle: Word; SrcOfs: Longint; SrcHandle:Word;
                      CopyLen: Longint): Boolean;
function XMSLockEMB(Handle: Word): Longint;
function XMSUnLockEMB(Handle: Word): Boolean;
function XMSGetHandleInfo(Handle: Word; var LockCnt, FreeHandles: Byte; var BlkSize: Word): Boolean;
function XMSResizeEMB(Handle: Word; NewSize: Word): Boolean;
function XMSAllocUMB(Size: Word): Word;
function XMSFreeUMB(Segm: Word): Boolean;
function XMSMemUMBAvail: Word;

implementation

procedure XMSCall; near; assembler;
asm
        PUSH    SEG @DATA
        POP     ES
        CMP     ES:[XMSInstalled],1
        JNE     @@2
        CALL    DWORD PTR ES:[XMSHandler]
        OR      AX,AX
        JNE     @@1
        PUSH    DS
        PUSH    ES
        POP     DS
        MOV     XMSErr,BL
        POP     DS
@@2:
        XOR     AX,AX
@@1:
end;

function XMSGetVersion: Longint; assembler;
asm
        XOR     AX,AX
        XOR     DX,DX
        MOV     AH,0
        CALL    XMSCall
        XCHG    DX,BX
end;

function XMSAllocHMA(Size: Word): Boolean; assembler;
asm
        MOV     AH,1
        CALL    XMSCall
end;

function XMSFreeHMA: Boolean; assembler;
asm
        MOV     AH,2
        CALL    XMSCall
end;

function XMSGlobalA20Enable: Boolean; assembler;
asm
        MOV     AH,3
        CALL    XMSCall
end;

function XMSGlobalA20Disable: Boolean; assembler;
asm
        MOV     AH,4
        CALL    XMSCall
end;

function XMSLocalA20Enable: Boolean; assembler;
asm
        MOV     AH,5
        CALL    XMSCall
end;

function XMSLocalA20Disable: Boolean; assembler;
asm
        MOV     AH,6
        CALL    XMSCall
end;

function XMSA20Enabled: Boolean; assembler;
asm
        MOV     AH,7
        CALL    XMSCall
end;

function XMSMaxEMBAvail: Word; assembler;
asm
        MOV     AH,8
        CALL    XMSCall
end;

function XMSMemEMBAvail: Word; assembler;
asm
        XOR     DX,DX
        MOV     AH,8
        CALL    XMSCall
        MOV     AX,DX
end;

function XMSAllocEMB(Size: Word): Word; assembler;
asm
        MOV     AH,9
        MOV     DX,Size
        CALL    XMSCall
        OR      AL,AL
        JZ      @@1
        MOV     AX,DX
@@1:
end;

function XMSFreeEMB(Handle: Word): Boolean; assembler;
asm
        MOV     DX,Handle
        MOV     AH,0AH
        CALL    XMSCall
end;

function XMSCopyBlock(DestOfs: Longint; DestHandle: Word; SrcOfs: Longint; SrcHandle:Word;
                      CopyLen: Longint): Boolean;
begin
  asm
        PUSH    DS
        PUSH    SS
        POP     DS
        LEA     SI,CopyLen
        MOV     AH,0BH
        CALL    XMSCall
        MOV     @Result,AL
        POP     DS
  end;
end;

function XMSLockEMB(Handle: Word): Longint; assembler;
asm
        MOV     AH,0CH
        MOV     DX,Handle
        CALL    XMSCall
        MOV     AX,BX
end;

function XMSUnLockEMB(Handle: Word): Boolean; assembler;
asm
        MOV     AH,0DH
        MOV     DX,Handle
        CALL    XMSCall
end;

function XMSGetHandleInfo(Handle: Word; var LockCnt, FreeHandles: Byte; var BlkSize: Word): Boolean; assembler;
asm
        MOV     DX,Handle
        MOV     AH,0EH
        CALL    XMSCall
        LES     DI,LockCnt
        MOV     BYTE PTR ES:[DI],BH
        LES     DI,FreeHandles
        MOV     BYTE PTR ES:[DI],BL
        LES     DI,BlkSize
        MOV     WORD PTR ES:[DI],DX
end;

function XMSResizeEMB(Handle: Word; NewSize: Word): Boolean; assembler;
asm
        MOV     AH,0FH
        MOV     BX,NewSize
        MOV     DX,Handle
        CALL    XMSCall
end;

function XMSAllocUMB(Size: Word): Word; assembler;
asm
        MOV     AH,10H
        MOV     DX,Size
        CALL    XMSCall
        MOV     AX,BX
end;

function XMSFreeUMB(Segm: Word): Boolean; assembler;
asm
        MOV     AH,11H
        MOV     DX,Segm
        CALL    XMSCall
end;

function XMSMemUMBAvail: Word; assembler;
asm
        MOV     AH,10H
        MOV     DX,0FFFFH
        CALL    XMSCall
        MOV     AX,DX
end;

begin
 asm
        MOV     AX,4300H
        INT     2FH
        CMP     AL,80H
        JNE     @@1
        MOV     AX,4310H
        INT     2FH
        MOV     WORD PTR XMSHandler[0],BX
        MOV     WORD PTR XMSHandler[2],ES
        MOV     XMSInstalled,1
        JMP     @@2
 @@1:
        MOV     XMSInstalled,0
 @@2:
 end;
end.
