unit VesaInt;

{ Vesa interface unit,
  Copr. 1994,1996 by Matthias K"oppe

  $Id: vesaint.pas 1.3 1999/02/09 10:52:00 mkoeppe Exp $
 
  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Library General Public
  License as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public
  License along with this library; if not, write to the Free
  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
}

{$G+,S-}

interface

{$ifdef VER60}
type
  PChar = ^Char;
{$endif}

const
  { vesa mode attribute bits }

  vmaSupported    = 1;
  vmaOptionalInfo = 2;
  vmaBiosOutput   = 4;
  vmaColor        = 8;
  vmaGraphic      = 16;
  vmaNoVGA	  = 32;
  vmaNoBankswitch = 64;
  vmaLinear       = 128;

  { vesa window attribute bits }

  vwaExists       = 1;
  vwaReadable     = 2;
  vwaWritable     = 4;

  { vesa memory models }

  vmmText	  = 0;
  vmmCGA	  = 1;
  vmmHGC	  = 2;
  vmmEGA	  = 3;
  vmmPacked       = 4;
  vmmSequ256      = 5;
  vmmDirect       = 6;
  vmmYUV          = 7;

  { vesa video state }

  vvsHardware     = 1;
  vvsBiosData     = 2;
  vvsDAC          = 4;
  vvsSuperVGA     = 8;

  { vesa protected mode }

  vpmSetBank      = 1;
  vpmSetDispStart = 2;
  vpmSetPalette   = 3;

type
  { vesa bios information }

  PVesaInfo = ^TVesaInfo;
  TVesaInfo = record
    viSignature: LongInt;
    viVersion: Word;
    viOemName: PChar;
    viCapabilities: LongInt;
    viModeList: pointer;
    viReserved: array[0..237] of Byte
  End;

  { vesa mode information }

  PVesaModeInfo = ^TVesaModeInfo;
  TVesaModeInfo = record
    vmModeAttrib: Word;
    vmAWindowAttrib: Byte;
    vmBWindowAttrib: Byte;
    vmGranularity: Word;
    vmWindowSize: Word;
    vmAWindowSegment: Word;
    vmBWindowSegment: Word;
    vmPositionProc: pointer;
    vmBytesPerLine: Word;
    vmWidth: Word;
    vmHeight: Word;
    vmCharWidth: Byte;
    vmCharHeight: Byte;
    vmPlanes: Byte;
    vmBits: Byte;
    vmBanks: Byte;
    vmModel: Byte;
    vmBankSize: Byte;
    vmReserved: array[0..226] of Byte
  end;

function GetVesaInfo: Boolean;
function GetVesaModeInfo(Mode: Word): Boolean;
function SetVesaMode(Mode: Word): Boolean;
function GetVesaMode: Word;

{ Result: Size in bytes
}
function GetVesaStateSize(Flags: Word): Word;

function SaveVesaState(Flags: Word): Boolean;
function RestoreVesaState(Flags: Word): Boolean;

{ Result = -1 fail
}
function SelectVesaWindow(Address: Word): Integer;

{ HIGH Result: Window number
  LOW Result: Window address (in granularity units)
  Result = -1 fail
}
function GetVesaWindow: LongInt;

{ LOW Result: actual number of pixels per scan line
  HIGH Result: maximum number of scan lines
  Result = -1 fail
}
function SetVesaLogicalLL(Width: Word): LongInt;
function GetVesaLogicalLL: LongInt;

function SetVesaDispStart(x, y: Word): Boolean;

{ LOW Result: x, HIGH Result: y, Result = -1 fail
}
function GetVesaDispStart: LongInt;

{$ifdef DPMI}
function GetProtModeCode(Func: Word): pointer;
procedure FreeProtModeCode(Code: pointer);
{$endif}

{ Info Area Managment
}

var
  InfoPtr: pointer;
  InfoDos: pointer;
  InfoSize: Word;

procedure AllocInfoArea(ASize: Word);
procedure FreeInfoArea;

{ Map Func Handling
}

function MapFunc(Func: pointer): pointer;

implementation

{$ifdef DPMI}
uses WinApi;
{$endif}

procedure ResultBool; near; assembler;
asm
	cmp     al, 4fh                 { installed }
	mov     al, 0
	jnz     @@0
	cmp     ah, 1                   { failed }
	jz      @@0
	mov     al, 1
@@0:
end;

procedure ResultWord; near; assembler;
asm
	mov     dx, 0
	xchg    ax, dx
	cmp     dl, 4fh
	jnz     @@0
	cmp     dh, 0
	jnz     @@0
	mov     ax, bx
@@0:
end;

procedure ResultLong; near; assembler;
asm
	cmp     al, 4fh
	jnz     @@0
	cmp     ah, 1
	jz      @@0
	mov     ax, cx
	ret
@@0:    mov     ax, -1
	mov     dx, ax
end;

{$ifdef dpmi}
{$i vesaipm.pas}
{$else}

procedure AllocInfoArea;
Begin
  GetMem(InfoPtr, ASize);
  InfoSize := ASize;
  InfoDos := InfoPtr
End;

procedure FreeInfoArea;
Begin
  FreeMem(InfoPtr, InfoSize);
End;

procedure CallInt; assembler;
asm
	mov	es, WORD PTR InfoDos[2]
	int	10h
end;

function Mapfunc;
Begin
  Mapfunc := Func
End;

{$endif}

function GetVesaInfo; assembler;
asm
	mov	di, WORD PTR InfoDos[0]
	mov     ax, 4f00h
	call	CallInt
	call    ResultBool
end;

function GetVesaModeInfo; assembler;
asm
	mov	di, WORD PTR InfoDos[0]
	mov     ax, 4f01h
	mov     cx, Mode
	call	CallInt
	call    ResultBool
end;

function SetVesaMode; assembler;
asm
	mov     bx, Mode
	mov     ax, 4f02h
	call	CallInt
	call    ResultBool
end;

function GetVesaMode; assembler;
asm
	mov     ax, 4f03h
	call	CallInt
	call    ResultWord
end;

function GetVesaStateSize; assembler;
asm
	mov     ax, 4f04h
	mov     dl, 0
	mov     cx, Flags
	call	CallInt
	shl     bx, 6
	call    ResultWord
end;

function SaveVesaState; assembler;
asm
	mov     ax, 4f04h
	mov     dl, 1
	mov	bx, WORD PTR InfoDos[0]
	mov     cx, Flags
	call	CallInt
	call    ResultBool
end;

function RestoreVesaState; assembler;
asm
	mov     ax, 4f04h
	mov     dl, 2
	mov	bx, WORD PTR InfoDos[0]
	mov     cx, Flags
	call	CallInt
	call    ResultBool
end;

function SelectVesaWindow; assembler;
asm
	mov     ax, 4f05h
	mov     bh, 0
	mov     dx, Address
	call	CallInt
	mov     bh, 0
	inc     bx
	call    ResultWord
	dec     ax
end;

function GetVesaWindow; assembler;
asm
	mov     ax, 4f05h
	mov     bh, 1
	call	CallInt
	mov     cx, dx
	mov     dl, bl
	mov     dh, 0
	call    ResultWord
end;

function SetVesaLogicalLL; assembler;
asm
	mov     ax, 4f06h
	mov     bl, 0
	mov     cx, Width
	call	CallInt
	call    ResultLong
end;

function GetVesaLogicalLL; assembler;
asm
	mov     ax, 4f06h
	mov     bl, 1
	call	CallInt
	call    ResultLong
end;

function SetVesaDispStart; assembler;
asm
	mov     ax, 4f07h
	mov     bx, 0
	mov     cx, x
	mov     dx, y
	call	CallInt
	call    ResultBool
end;

function GetVesaDispStart; assembler;
asm
	mov     ax, 4f07h
	mov     bx, 1
	call	CallInt
	call    ResultLong
end;

end.
