From: Cory Bloyd 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 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Precedence: bulk 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; cVESASignature,"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