{$R-}
Unit VesaChk;

interface

type RealPtr = record Rofs,Rseg:word; end;
type VesaInfoRec = record
       VesaSignature : array[0..3] of char;
       VesaVersion   : word;
       OemString     : RealPtr;
       Capabilities  : array[0..3] of byte;
       VideoModeInfo : RealPtr;
       TotalMemory   : word;
     end;
var VesaInfo : VesaInfoRec;

function IsVesa:boolean;

implementation
{$IFDEF DPMI}
  uses WinApi;
{$ENDIF}


{----------------------------------------------------------------------}
{This processes the Vesa interupt $10 call to manage the protected     }
{verses real mode TSR calling problem with selectors via the DPMI      }

function VESAInt(BufPtr:longint):boolean;

var SimInt : record
      RealDI : longint;   {register structure used for    }
      RealSI : longint;   {processing real mode interrupts}
      RealBP : longint;   {from protected mode operation  }
      RealXX : longint;
      RealBX : longint;
      RealDX : longint;
      RealCX : longint;
      RealAX : longint;
      RealFlags : word;
      RealES : word;
      RealDS : word;
      RealFS : word;
      RealGS : word;
      RealIP : word;
      RealCS : word;
      RealSP : word;
      RealSS : word;
    end;

begin
  {$IFNDEF DPMI}       {if not DPMI, call via normal int $10}
    asm
      MOV @Result,0    {assume failure}
      LES DI,[Dword Ptr BufPtr]
      MOV AX,$4F00
      INT $10
      CMP AX,$004F
      JNZ @VESAintFail
      MOV @Result,1    {return true if call succeeds}
     @VESAintFail:
    end;
  {$ELSE}  {process VESA int $10 call via DPMI protected mode operation}
    asm
      MOV @Result,0    {assume failure}
      MOV word ptr [SimInt.RealAX],$4F00 {pass command number}
      MOV word ptr [SimInt.RealDI],0     {buf adr in ES:DI}
      MOV DI,word ptr [BufPtr + 2]
      MOV word ptr [SimInt.RealES],DI
      MOV word ptr [SimInt.RealSS],0	 {let DPMI make it's own stack}
      MOV word ptr [SimInt.RealSP],0
      MOV word ptr [SimInt.RealXX],0
      MOV word ptr [SimInt.RealXX+2],0
      LEA DI,SimInt
      MOV AX,SS
      MOV ES,AX
      MOV AX,$0300
      MOV BL,$10
      MOV BH,0
      MOV CX,0
      INT $31
      JC @VesaProtRet  {eek! dpmi call failed}
      MOV AX,word ptr [SimInt.RealAX]
      CMP AX,$004F     {check on vesa call status}
      JNZ @VesaProtRet {sigh... it failed}
      MOV @Result,1    {Joy! call was successful}
     @VesaProtRet:
    end;
  {$ENDIF}
end;


function IsVesa:boolean;
var Temp : longint;
    Result : boolean;
begin
  {$IFDEF DPMI}
    Temp := GlobalDosAlloc(512);
    fillchar(ptr(loWord(Temp),0)^,512,0);
    Result := VesaInt(Temp);
    move(ptr(loword(Temp),0)^,VesaInfo,sizeof(VesaInfo));
    Temp := GlobalDosFree(loword(Temp));
  {$ELSE}
    GetMem(pointer(Temp),512);
    fillchar(pointer(Temp)^,512,0);
    Result := VesaInt(Temp);
    move(pointer(Temp)^,VesaInfo,sizeof(VesaInfo));
    FreeMem(pointer(Temp),512);
  {$ENDIF}
  IsVesa := (VesaInfo.VesaSignature = 'VESA') or Result;
end;


end.


