Technical Information Database TI355D.txt - Using the VESA16.BGI that Comes with BP 7.0 Category :Turbo Pascal Platform :All Product : Description: VESA DRIVERS With the release of Borland Pascal for Objects 7.0, programmers can now use BGI graphics to obtain 16 color resolutions of 800 X 600, 1024 X 768, and 1280 X 1024. HOW TO USE THE VESA16.BGI DRIVER The VESA unit included with this Tech Info Sheet shows you a simple way to use the new VESA driver in your own program. To get started, you need only include the word VESA in your uses clause and then call the included Initialize procedure. So the simplest possible program using the VESA driver might look like this: program Simple; uses Graph, Vesa; begin Initialize('c:\bp\bgi'); OutText('Hello'); ReadLn; CloseGraph; end. This program assumes, of course, that you have the VESA unit available on disk and that your BGI drivers are kept in the C:\BP\BGI sub directory. If the system this program is run on does not support the VESA BIOS then the code in the VESA unit will automatically switch your computer into the highest available mode. The next few paragraphs describe a somewhat more complex program, also included in this TI, which shows you how to use the new high resolution modes. This program is called VesaSamp.Pas. It uses the VESA unit, also listed below, to load the BGI VESA graphics driver into memory. The program then shows you the highest available resolution on your system. In order to simplify the process of entering graphics mode, the VESA UNIT provides you with an easy to use Initialize procedure which takes the location of the BGI drivers as its sole parameter. This procedure will automatically switch you into graphics mode, and also initialize several useful variables. As presented below, program VesaSamp.Pas hardcodes the location of the BGI drivers as being in the C:\BP\BGI sub directory. If this is not the case on your system, then you need to change this code before running the program. For instance, if you store the BGI drivers in the D:\PASCAL\DRIVERS sub directory, then you should change the call that reads: Initialize('c:\bp\bgi'); so that it reads: Initialize('d:\pascal\drivers'); If you have the BGI drivers available in the current sub directory, then you would initialize the graphics system with the following code: Initialize(''); After correctly setting up the Initialize procedure, the VesaSamp program will pop into graphics mode and show you the highest available resolution. WHAT IS THE VESA BIOS? The VESA BIOS represents a standard for accessing SUPER VGA resolutions. The problem it addresses is that there are many different Super VGA boards on the market, but no common API for addressing them. To attempt to bring some sort of sanity to this madness, the Video Electronics Standards Association (VESA) defined a set of BIOS extensions that allow programmers to ask the video adapter about its abilities. These BIOS extensions are sometimes implemented directly in ROM and sometimes loaded into memory by a special TSR. Many of these TSRs are available on the Compuserve Information Service (1-800-848-8990). Since it is always possible that the video card on any particular system might not support the VESA extensions, you should be aware that your program might not actually run in a high resolution mode. But the Borland Graphics Interface will find the highest available mode and then switch you into it. The rest of this TI contains the sample code which shows you how to use the VESA BGI driver. You should be aware of the fact that it is necessary for the VESA .PAS unit to automatically detect whether or not you have compiled your program as a protected mode application. In other words, if you want to copy code from the VESA unit directly into your program, make sure you are getting the DOS code for DOS apps and the DPMI code for DPMI apps. program VesaSamp; { A test program for unit Vesa which provides Super VGA Resolutions } uses Graph, Vesa; { Converts an integer to a string } function Int2Str(L : LongInt) : string; var S : string; begin Str(L, S); Int2Str := S; end; { Int2Str } var S: String; begin Initialize('c:\bp\bgi'); Rectangle(0,0,MaxX,MaxY); SetColor(LightGreen); SetBkColor(Blue); SetTextStyle(TriplexFont, HorizDir, 8); S := 'MaxX = ' + Int2Str(MaxX); OutTextXY((MaxX Div 2) - (TextWidth(S) div 2), (MaxY div 2) - 220, S); S := 'MaxY = ' + Int2Str(MaxY); OutTextXY((MaxX Div 2) - (TextWidth(S) div 2), (MaxY div 2) - 80, S); S := 'MemAvail = ' + Int2Str(MemAvail); OutTextXY((MaxX Div 2) - (TextWidth(S) div 2), (MaxY div 2) + 60, S); ReadLn; CloseGraph; end. {***************************************************} {******************** VESA UNIT *********************} {***************************************************} unit Vesa; { Add this unit to programs that want Vesa support for high resolutions such as 800 X 600, 1024 X 768 and 1280 X 1024. If Vesa is not supported on a system the code automatically defaults to an available driver such as EGAVGA. To Initialize the graphics system, just call Initialize with the path to VESA.BGI as the sole parameter. Pass an empty string if the driver is in the current subdirectory. The code will automatically detect if you are running in protected mode or real mode. Examples: Initialize('c:\bp\bin'); Initialize(''); } Interface uses Graph {$IfDef DPMI}, WinApi {$EndIf}; const VESA16Modes: array[0..2] of Word = ($0102, $0104, $0106); type VgaInfoBlock = record VESASignature: array[0..3] of Byte; VESAVersion: Word; OEMStringPtr: Pointer; Capabilities: array[0..3] of Byte; VideoModePtr: Pointer; end; var MaxColor, MaxX, MaxY: Integer; procedure Initialize(PathToDriver: String); implementation var VESA16 : Integer; { Driver number of 16 color driver } function GetHighestCap(Table: Pointer; Modes: Word; Size: Integer): Integer; near; assembler; asm XOR AX,AX LES DI, Table 1: MOV SI, Modes ADD SI, Size ADD SI, Size SUB SI, 2 MOV BX, ES:[DI] CMP BX, 0FFFFH JE 4 INC DI INC DI MOV CX,Size 2: CMP BX,[SI] JZ 3 DEC SI DEC SI LOOP 2 3: CMP AX,CX JA 1 MOV AX,CX JMP 1 4: DEC AX end; {$IFDEF DPMI} type TRealRegs = record RealEDI: Longint; RealESI: Longint; RealEBP: Longint; Reserved: Longint; RealEBX: Longint; RealEDX: Longint; RealECX: Longint; RealEAX: Longint; RealFlags: Word; RealES: Word; RealDS: Word; RealFS: Word; RealGS: Word; RealIP: Word; RealCS: Word; RealSP: Word; RealSS: Word; end; function DetectVesa16: Integer; far; assembler; var Segment, Selector, VesaCap: Word; asm {$IFOPT G+} PUSH 0000H PUSH 0100H {$ELSE} XOR AX,AX PUSH AX INC AH PUSH AX {$ENDIF} CALL GlobalDosAlloc MOV Segment,DX MOV Selector,AX MOV DI,OFFSET RealModeRegs MOV WORD PTR [DI].TRealRegs.RealSP, 0 MOV WORD PTR [DI].TRealRegs.RealSS, 0 MOV WORD PTR [DI].TRealRegs.RealEAX, 4F00H MOV WORD PTR [DI].TRealRegs.RealES, DX MOV WORD PTR [DI].TRealRegs.RealEDI, 0 MOV AX,DS MOV ES,AX MOV AX,0300H MOV BX,0010H XOR CX,CX INT 31H MOV DI,OFFSET RealModeRegs MOV AX,grError PUSH AX CMP WORD PTR [DI].TRealRegs.RealEAX,004FH JNZ Exit POP AX MOV ES,Selector XOR DI,DI CMP ES:[DI].VgaInfoBlock.VESASignature.Word[0], 'EV' JNZ Exit CMP ES:[DI].VgaInfoBlock.VESASignature.Word[2], 'AS' JNZ Exit MOV AX,0000 MOV CX,1 INT 31H MOV VesaCap,AX MOV DX,ES:[DI].VgaInfoBlock.VideoModePtr.Word[2] MOV CX,4 XOR AX,AX Convert: SHL DX,1 RCL AX,1 LOOP Convert ADD DX,ES:[DI].VgaInfoBlock.VideoModePtr.Word[0] ADC AX,0 MOV CX,AX MOV BX,VesaCap MOV AX,0007H INT 31H INC AX XOR CX,CX MOV DX,0FFFFH INT 31H MOV ES,BX PUSH ES PUSH DI {$IFOPT G+} PUSH OFFSET Vesa16Modes PUSH 0003H {$ELSE} MOV SI, OFFSET Vesa16Modes PUSH SI MOV AX, 5 PUSH AX {$ENDIF} CALL GetHighestCap PUSH AX MOV BX,VesaCap MOV AX,0001H INT 31H Exit: PUSH Selector CALL GlobalDosFree POP AX end; {$ELSE} function DetectVesa16: Integer; far; assembler; var VesaInfo: array[0..255] of Byte; asm MOV AX,SS MOV ES,AX LEA DI,VesaInfo MOV AX,4F00H INT 10H CMP AX,004FH MOV AX,grError JNZ Exit CMP ES:[DI].VgaInfoBlock.VESASignature.Word[0], 'EV' JNZ Exit CMP ES:[DI].VgaInfoBlock.VESASignature.Word[2], 'AS' JNZ Exit LES DI,ES:[DI].VgaInfoBlock.VideoModePtr PUSH ES PUSH DI MOV AX, OFFSET Vesa16Modes PUSH AX MOV AX,3 PUSH AX CALL GetHighestCap Exit: end; {$ENDIF} procedure Initialize(PathToDriver: String); var MaxColor, ErrorCode, GraphMode, GraphDriver: Integer; begin VESA16 := InstallUserDriver('VESA16', DetectVESA16); GraphDriver := Detect; InitGraph(GraphDriver, GraphMode, PathToDriver); ErrorCode := GraphResult; if ErrorCode <> grOK then begin WriteLn('Graphics error: ', GraphErrorMsg(ErrorCode)); ReadLn; Halt; end; MaxX := GetMaxX; MaxY := GetMaxY; MaxColor := GetMaxColor; end; end. Reference: 3/30/99 2:58:27 PM
Last Modified: 01-SEP-99