Mail Archives: djgpp/2001/11/07/11:19:20
"Eli Zaretskii" <eliz AT is DOT elta DOT co DOT il> writes:
> > From: Felix Natter <f DOT natter AT ndh DOT net>
> > Newsgroups: comp.os.msdos.djgpp
> > Date: 03 Nov 2001 17:50:57 +0100
> >
> > __dpmi_meminfo meminf;
> > meminf.address = vbe_modeinfo.PhysicalBasePtr;
> > meminf.size = screensize;
> > if (__dpmi_physical_address_mapping(&meminf) == - 1)
> > => error
> >
> > __dpmi_physical_address_mapping fails on Windows 2000 (both with
> > cwsdpmi 4/5 and when I select Dos on startup).
>
> It's not surprising that W2K doesn't let you do this (it disallows
> access to hardware), but it should work on DOS.
>
> However, without knowing the values of vbe_modeinfo.PhysicalBasePtr
> and screensize, it's very hard to say something intelligent.
Sorry, my fault. the address was 0.
the getVBEModeInfo function returns true, but
vbe_modeinfo.PhysicalBasePtr is 0 !
So either that graphics card isn't VESA 1.2 compliant or my code is wrong.
(It's a matrox card so I guess I'm wrong :-()
static bool getVBEModeInfo(unsigned short mode)
{
__dpmi_regs regs;
regs.x.ax = 0x4F01;
regs.x.cx = mode;
regs.x.es = __tb / 16;
regs.x.di = 0x0000;
safe_int(0x10, ®s);
dosmemget(__tb, sizeof(VBE_MODEINFO), &vbe_modeinfo);
if (regs.x.ax != 0x004F || !(vbe_modeinfo.ModeAttributes & vbeModeAvailablewithLFB))
return false;
else
return true;
};
struct VBE_MODEINFO
{
unsigned short ModeAttributes PACKED;
unsigned char WinAAttributes PACKED;
unsigned char WinBAttributes PACKED;
unsigned short WinGranularity PACKED;
unsigned short WinSize PACKED;
unsigned short WinASegment PACKED;
unsigned short WinBSegment PACKED;
unsigned short WinFuncPtrOffset PACKED;
unsigned short WinFuncPtrSegment PACKED;
unsigned short BytesPerScanline PACKED;
// VBE 1.2+
unsigned short XResolution PACKED;
unsigned short YResolution PACKED;
unsigned char XCharSize PACKED;
unsigned char YCharSize PACKED;
unsigned char NumberOfPlanes PACKED;
unsigned char BitsPerPixel PACKED;
unsigned char NumberOfBanks PACKED;
unsigned char MemoryModel PACKED;
unsigned char BankSize PACKED;
unsigned char NumberOfImagePages PACKED;
unsigned char reserved1 PACKED;
// required for direct color memory models (RGB, YUV)
unsigned char RedMaskSize PACKED;
unsigned char RedFieldPosition PACKED;
unsigned char GreenMaskSize PACKED;
unsigned char GreenFieldPosition PACKED;
unsigned char BlueMaskSize PACKED;
unsigned char BlueFieldPosition PACKED;
unsigned char RsvdMaskSize PACKED;
unsigned char RsvdFieldPosition PACKED;
unsigned char DirectColorModeInfo PACKED;
// VBE 2.0+
unsigned long PhysicalBasePtr PACKED; /* Physical address for LFB */
unsigned long OffScreenMemOffset PACKED;/* Pointer to Offscreen-memory */
unsigned short OffScreenMemSize PACKED; /* Size of Offscreen-memory in K */
unsigned char reserved2[206] PACKED;
};
here is the beginning of the openVBE-function:
bool openVBE(int width, int height, unsigned char bpp = 8)
{
if (!initVBE())
{
printf("\nNo VBE 2.0 loaded.\n");
abort();
}
int modeidx = 0;
unsigned short mode;
while (1)
{
mode = AvailableModes[modeidx++];
if (mode == 0xFFFF)
return false;
if (getVBEModeInfo(mode) == false)
continue;
if (vbe_modeinfo.XResolution != width)
continue;
if (vbe_modeinfo.YResolution != height)
continue;
if (vbe_modeinfo.BitsPerPixel != bpp)
continue;
break;
}
xres = vbe_modeinfo.XResolution;
yres = vbe_modeinfo.YResolution;
BPP = vbe_modeinfo.BitsPerPixel;
BytesPerScanline = vbe_modeinfo.BytesPerScanline;
unsigned long screensize = BytesPerScanline * yres;
if (screensize % 4)
ErrorMessage::handleError(ErrorMessage("Screensize [PARAM1] isn't dword-aligned.", "", screensize));
offscreen = (char*)malloc(screensize);
screensize_dword = screensize / 4;
__dpmi_meminfo meminf;
meminf.address = vbe_modeinfo.PhysicalBasePtr;
meminf.size = screensize;
// TODO: fails on Windows 2000
if (__dpmi_physical_address_mapping(&meminf) == - 1)
=> this fails because meminf.address is 0
The complete source is here:
http://www.ndh.net/home/natter/vbetest.cpp
--
Felix Natter
- Raw text -