Mail Archives: djgpp/1997/05/16/14:34:39
From: | Cory Bloyd <bloydcg AT cs DOT purdue DOT edu>
|
Newsgroups: | comp.os.msdos.djgpp
|
Subject: | Trying to find VESA mode numbers
|
Date: | Fri, 16 May 1997 11:43:10 -0500
|
Organization: | Dept of Computer Sciences, Purdue University
|
Lines: | 120
|
Message-ID: | <337C8E9E.1D80@cs.purdue.edu>
|
Reply-To: | bloydcg AT cs DOT purdue DOT edu
|
NNTP-Posting-Host: | govora.cs.purdue.edu
|
Mime-Version: | 1.0
|
To: | djgpp AT delorie DOT com
|
DJ-Gateway: | from newsgroup comp.os.msdos.djgpp
|
Call me stubborn, but I still insist on writing my own libraries even
though such wonders as Allegro exist. And now I'm paying for it.
I'm trying to create a run-of-the-mill VESA mode finding function to
match screen dimension requests with actual mode numbers.
Unfortunately, the vbeInfo.VideoModePtr doesn't seem to be pointing
at anything resembling a list of video modes.
I know that my vbeinfo structure is correct because I've checked it
against several reliable sources. I'm pretty sure my VBE_detect()
function is correct because again it is taken from several sources and
it checks for the "VESA" Signature and always finds it.
Below is the code I'm using. Much of it is practically a direct rip
from Allegro. Which is why I'm baffled that Allegro works on my system
but this doesn't.
Running setMode(anything,anything,anything) I get a list of completely
random hex numbers which by chance eventually contains a 0xffff to end
the program.
#define MASK_LINEAR(addr) (addr & 0x000FFFFF)
#define RM_TO_LINEAR(addr) ((((addr) & 0xFFFF0000) >> 12) + ((addr) &
0xFFFF))
#define RM_OFFSET(addr) (MASK_LINEAR(addr) & 0xFFFF)
#define RM_SEGMENT(addr) ((MASK_LINEAR(addr) & 0xFFFF0000) >> 4)
unsigned short FindMode(int x, int y, int bpp)
{
extern VideoInfo vidInfo;
VBE_ModeInfo *modeinfo;
unsigned short mode;
long modePtr;
modePtr = RM_TO_LINEAR(vidInfo.vbeInfo.VideoModePtr);
mode = _farpeekw(_dos_ds, modePtr);
while(mode != 0xffff)
{
printf("\nMode: %x", mode);
if (VBE_getmodeinfo(mode, modeinfo) != 0)
{
if (modeinfo->XResolution == x && modeinfo->YResolution == y
&& modeinfo->BitsPerPixel == bpp) return mode;
printf(" XREZ: %u YREZ: %u BPP: %u", modeinfo->XResolution,
modeinfo->YResolution, modeinfo->BitsPerPixel);
}
modePtr += 2;
mode = _farpeekw(_dos_ds, modePtr);
}
return 0;
}
int setMode(int x, int y, int bpp)
{
extern VideoInfo vidInfo;
if (!(VBE_detect(&vidInfo.vbeInfo)))
{printf("Get VESA vga info failed.\n"); return(1);}
if(!(vidInfo.mode = FindMode(x,y,bpp)))
{printf("VESA mode not found.\n"); return(2);}
if(VBE_Set_Mode(vidInfo.mode))
{printf("VESA set mode failed.\n"); return(3);}
if (!(VBE_getmodeinfo(vidInfo.mode, &vidInfo.modeInfo)))
{printf("Get VESA mode info failed.\n"); return(4);}
if (!(vidInfo.modeInfo.ModeAttributes & 0x10))
{printf("Linear frame buffer not supported for VESA mode.\n");
return(5);}
if (!(vidInfo.page = (char *)VBE_get_linear_address(vidInfo.modeInfo,
vidInfo.vbeInfo)))
{printf("VESA Address mapping failed.\n"); return(6); }
vidInfo.bitsPerPixel = vidInfo.modeInfo.BitsPerPixel;
vidInfo.bytesPerPixel = (vidInfo.bitsPerPixel+7)>>3; //fix if use 1 or
4 bit
vidInfo.xrez = vidInfo.modeInfo.XResolution;
vidInfo.yrez = vidInfo.modeInfo.YResolution;
vidInfo.pageSize = vidInfo.bytesPerPixel * vidInfo.xrez * vidInfo.yrez;
vidInfo.buffer = (char *)malloc(vidInfo.pageSize);
//Get video selector
vidInfo.selector = __dpmi_allocate_ldt_descriptors(1);
return(0);
};
int VBE_detect(VBE_VbeInfo *vbeinfo) {
__dpmi_regs regs;
int c;
for (c=0; c<sizeof(VBE_VbeInfo); c++)
_farpokeb(_dos_ds, MASK_LINEAR(__tb)+c, 0);
regs.x.ax = 0x4F00;
regs.x.di = RM_OFFSET(__tb);
regs.x.es = RM_SEGMENT(__tb);
dosmemput(vbeinfo,sizeof(VBE_VbeInfo),__tb);
__dpmi_int(0x10, ®s);
if(regs.h.ah) return 0;
dosmemget(MASK_LINEAR(__tb), sizeof(VBE_VbeInfo), vbeinfo);
if(strncmp(vbeinfo->VESASignature,"VESA",4) != 0) return 0;
else return vbeinfo->VESAVersion;
}
int VBE_getmodeinfo(unsigned short mode, VBE_ModeInfo *modeinfo) {
__dpmi_regs regs;
int c;
for (c=0; c<sizeof(VBE_ModeInfo); c++)
_farpokeb(_dos_ds, MASK_LINEAR(__tb)+c, 0);
regs.x.ax = 0x4F01;
regs.x.cx = mode;
regs.x.di = RM_OFFSET(__tb);
regs.x.es = RM_SEGMENT(__tb);
__dpmi_int(0x10, ®s);
if(regs.h.ah) return 0;
dosmemget(MASK_LINEAR(__tb), sizeof(VBE_ModeInfo), modeinfo);
return 1;
}
- Raw text -