Discussion:
Vesa unit
(too old to reply)
Chiel Landsheer
2007-01-20 20:33:00 UTC
Permalink
Hi,
I have been using the unit Vesa.pas with Borland Pascal 7.0 since 1998
in order to get, in the graphical mode under MS-DOS, a higher resolution
than the standard 640 x 480. I have downloaded this unit from (then)
Inprise. It has always worked fine, upto 1024 x 768, on (then) modern
graphical cards (non-AGP), in (or one should say "from") DOS-boxes in
Windows 98SE.
Now I have a new computer with Windows XP SP2, and it doesn't work
anymore. The only thing the procedure Initialize does is switch to full
screen text-mode.
The old 640 x 480 mode still works OK.
The new graphical card is: RAGE 128 PRO Ultra GL AGP.
Has anyone a suggestion for a solution?

For those who might be interested: the source of the unit follows. It is
mainly assembler, though.
Chiel Landsheer


{***************************************************}
{******************** 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.
Marco van de Voort
2007-01-20 22:21:16 UTC
Permalink
Post by Chiel Landsheer
Hi,
I have been using the unit Vesa.pas with Borland Pascal 7.0 since 1998
in order to get, in the graphical mode under MS-DOS, a higher resolution
than the standard 640 x 480. I have downloaded this unit from (then)
Inprise. It has always worked fine, upto 1024 x 768, on (then) modern
graphical cards (non-AGP), in (or one should say "from") DOS-boxes in
Windows 98SE.
Now I have a new computer with Windows XP SP2, and it doesn't work
anymore. The only thing the procedure Initialize does is switch to full
screen text-mode.
The old 640 x 480 mode still works OK.
The new graphical card is: RAGE 128 PRO Ultra GL AGP.
Has anyone a suggestion for a solution?
Try to find some TSR that implements a VESA driver for this card? There are
iirc payware ones called UniVBE.
Chiel Landsheer
2007-01-22 17:05:47 UTC
Permalink
Post by Marco van de Voort
Post by Chiel Landsheer
Hi,
I have been using the unit Vesa.pas with Borland Pascal 7.0 since 1998
in order to get, in the graphical mode under MS-DOS, a higher resolution
than the standard 640 x 480. I have downloaded this unit from (then)
Inprise. It has always worked fine, upto 1024 x 768, on (then) modern
graphical cards (non-AGP), in (or one should say "from") DOS-boxes in
Windows 98SE.
Now I have a new computer with Windows XP SP2, and it doesn't work
anymore. The only thing the procedure Initialize does is switch to full
screen text-mode.
The old 640 x 480 mode still works OK.
The new graphical card is: RAGE 128 PRO Ultra GL AGP.
Has anyone a suggestion for a solution?
Try to find some TSR that implements a VESA driver for this card? There are
iirc payware ones called UniVBE.
Thank you for your advice. It indeed seems to have been the only
solution, but alas, UniVBE is an abandoned product and all versions that
are available are too old to work with my environment. The other poster,
Loren Pechtel, is right. I give it up.
Marco van de Voort
2007-01-23 08:04:56 UTC
Permalink
Post by Chiel Landsheer
Post by Marco van de Voort
Post by Chiel Landsheer
The old 640 x 480 mode still works OK.
The new graphical card is: RAGE 128 PRO Ultra GL AGP.
Has anyone a suggestion for a solution?
Try to find some TSR that implements a VESA driver for this card? There are
iirc payware ones called UniVBE.
Thank you for your advice. It indeed seems to have been the only
solution, but alas, UniVBE is an abandoned product and all versions that
are available are too old to work with my environment. The other poster,
Loren Pechtel, is right. I give it up.
(the card is new, but the Rage family is quite old)
Chiel Landsheer
2007-01-23 18:23:56 UTC
Permalink
Post by Marco van de Voort
Post by Chiel Landsheer
Post by Marco van de Voort
Post by Chiel Landsheer
The old 640 x 480 mode still works OK.
The new graphical card is: RAGE 128 PRO Ultra GL AGP.
Has anyone a suggestion for a solution?
Try to find some TSR that implements a VESA driver for this card? There are
iirc payware ones called UniVBE.
Thank you for your advice. It indeed seems to have been the only
solution, but alas, UniVBE is an abandoned product and all versions that
are available are too old to work with my environment. The other poster,
Loren Pechtel, is right. I give it up.
(the card is new, but the Rage family is quite old)
Indeed. As Mr. Humm suggested, the problem is Windows, not the graphical
card.
Groet,
Chiel
Loren Pechtel
2007-01-21 02:09:02 UTC
Permalink
On Sat, 20 Jan 2007 21:33:00 +0100, Chiel Landsheer
Post by Chiel Landsheer
Hi,
I have been using the unit Vesa.pas with Borland Pascal 7.0 since 1998
in order to get, in the graphical mode under MS-DOS, a higher resolution
than the standard 640 x 480. I have downloaded this unit from (then)
Inprise. It has always worked fine, upto 1024 x 768, on (then) modern
graphical cards (non-AGP), in (or one should say "from") DOS-boxes in
Windows 98SE.
Now I have a new computer with Windows XP SP2, and it doesn't work
anymore. The only thing the procedure Initialize does is switch to full
screen text-mode.
The old 640 x 480 mode still works OK.
The new graphical card is: RAGE 128 PRO Ultra GL AGP.
Has anyone a suggestion for a solution?
For those who might be interested: the source of the unit follows. It is
mainly assembler, though.
Chiel Landsheer
I've found that anything remotely recent in the way of video doesn't
support the old commands. I long since gave up on anything beyond
640x480x16 in a dos box.
Markus.Humm
2007-01-22 20:08:05 UTC
Permalink
Hello,

maybe the problem is not the graphics card but windows!
Try to boot from plain DOS (yes you need a bootable floppy or CD) and
then try it.

Greetings

Markus
Chiel Landsheer
2007-01-23 18:19:45 UTC
Permalink
Post by Markus.Humm
Hello,
maybe the problem is not the graphics card but windows!
Try to boot from plain DOS (yes you need a bootable floppy or CD) and
then try it.
Greetings
Markus
Yes, you are right! How foolish I am that I haven't tried it already.
However impractical (dual booting, non-NTFS partition), it is a solution.
Thank you,
Chiel.
Iain Macmillan
2007-01-24 01:48:51 UTC
Permalink
Post by Chiel Landsheer
However impractical (dual booting, non-NTFS partition), it is a solution.
I'd suspect that the Windows 'Dos emulator in a box' no longer supports Int
31H.

There might be an alternative solution going to the next level underneath
interrupts, that is, to use In and Out port commands to interrogate and
program the video card.

.. but it would be tricky!

(possibly a little less so if you can assume that the hardware actually
supports the resolution you are trying to set, which VESA unit does not)
quick
2007-01-24 17:14:07 UTC
Permalink
Post by Chiel Landsheer
Hi,
I have been using the unit Vesa.pas with Borland Pascal 7.0 since 1998
in order to get, in the graphical mode under MS-DOS, a higher resolution
than the standard 640 x 480. I have downloaded this unit from (then)
Inprise. It has always worked fine, upto 1024 x 768, on (then) modern
graphical cards (non-AGP), in (or one should say "from") DOS-boxes in
Windows 98SE.
Now I have a new computer with Windows XP SP2, and it doesn't work
anymore. The only thing the procedure Initialize does is switch to full
screen text-mode.
The old 640 x 480 mode still works OK.
The new graphical card is: RAGE 128 PRO Ultra GL AGP.
Has anyone a suggestion for a solution?
For those who might be interested: the source of the unit follows. It is
mainly assembler, though.
Chiel Landsheer
{***************************************************}
{******************** 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.
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
MOV SI, Modes
ADD SI, Size
ADD SI, Size
SUB SI, 2
MOV BX, ES:[DI]
CMP BX, 0FFFFH
INC DI
INC DI
MOV CX,Size
CMP BX,[SI]
DEC SI
DEC SI
CMP AX,CX
MOV AX,CX
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
POP AX
MOV ES,Selector
XOR DI,DI
CMP ES:[DI].VgaInfoBlock.VESASignature.Word[0], 'EV'
CMP ES:[DI].VgaInfoBlock.VESASignature.Word[2], 'AS'
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
SHL DX,1
RCL AX,1
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
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
CMP ES:[DI].VgaInfoBlock.VESASignature.Word[0], 'EV'
CMP ES:[DI].VgaInfoBlock.VESASignature.Word[2], 'AS'
LES DI,ES:[DI].VgaInfoBlock.VideoModePtr
PUSH ES
PUSH DI
MOV AX, OFFSET Vesa16Modes
PUSH AX
MOV AX,3
PUSH AX
CALL GetHighestCap
end;
{$ENDIF}
procedure Initialize(PathToDriver: String);
var
MaxColor,
ErrorCode,
GraphMode,
GraphDriver: Integer;
begin
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.
There is a free DOS emulator at http://dosbox.sourceforge.net
It was created to run games

Loading...