www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1996/11/21/21:28:16

Message-ID: <329528C4.47DF@gbrmpa.gov.au>
Date: Fri, 22 Nov 1996 12:24:36 +0800
From: Leath Muller <leathm AT gbrmpa DOT gov DOT au>
Reply-To: leathm AT gbrmpa DOT gov DOT au
Organization: Great Barrier Reef Marine Park Authority
MIME-Version: 1.0
To: "G.P. Tootell" <gpt20 AT thor DOT cam DOT ac DOT uk>
CC: djgpp AT delorie DOT com
Subject: Re: boo hoo i can't make this work :( (vesa stuff)
References: <5728a5$sgq AT lyra DOT csx DOT cam DOT ac DOT uk>

> i'm trying to get the info about modes supported by a video card, now under real
> mode there was no problem, i just followed the pointer, but despite various
> (sometimes random) attempts at getting this to work under djgpp i can't do it :(
> could someone please just tell me where i've gone wrong.
> (the code should return the first supported screen mode into 'value', eventually
> i want to return all the supported screen modes and find one that matches the
> specs i supply.)

> ps. yes i know the seg and off calculations are really screwy, this is like the
> 454365436th rewrite of this code and i was clutching at straws by this time :)
> it is true to say the pointer returned can be cast as a long in this way tho
> right? at least under standard dos it was.. and the calculation for farpeek i got
> from chapter 18 of the faq :(
 
> #define PACKED __attribute__ ((packed))
 
> #pragma pack(1)
> /* SuperVGA information block */
> typedef struct {
>   char    VESASignature[4] PACKED;      /* 'VESA' 4 byte signature          */
>   short   VESAVersion PACKED;           /* VBE version number               */
>   char    *OEMStringPtr PACKED;         /* Pointer to OEM string            */
>   long    Capabilities PACKED;          /* Capabilities of video card       */
>   short   *VideoModePtr PACKED;         /* Pointer to supported modes       */
>   short   TotalMemory PACKED;           /* Number of 64kb memory blocks     */
>   char    reserved[236] PACKED;         /* Pad to 256 byte block size       */
> } VBE_VgaInfo;
> #pragma pack()

I don't think you need the pragma's if you including packed with every
line...

> void VBE_detect(VBE_VgaInfo *vbeinfo) {
>         __dpmi_regs regs;
>         short value,seg,off;
 
>         assert(sizeof(*vbeinfo)<_go32_info_block.size_of_transfer_buffer);
>         regs.x.ax=0x4F00;
>         regs.x.di=__tb & 0x0F;
>         regs.x.es=(__tb>>4) & 0xFFFF;
>         dosmemput(vbeinfo,sizeof(*vbeinfo),__tb);
>         __dpmi_int(0x10, &regs);
>         dosmemget(__tb,sizeof(*vbeinfo),vbeinfo);
>         if (strncmp(vbeinfo->VESASignature,"VESA",4)!=0) {
>                 printf("vesa not supported.\n");
>                 exit(0);
>         }
>         else {
>                 seg=(unsigned long)vbeinfo->VideoModePtr>>16;
>                 off=(unsigned long)vbeinfo->VideoModePtr & 0xffff;
>                 value=_farpeekw(_dos_ds,seg*16+off);
>                 printf("%d ",value);
>         }
> }

Ok, you setting your registers up wrong, and only have to do this:

	regs.x.ax = 0x4F00;
	regs.x.es = __tb / 16; // this could be __tb >> 4;
	regs.x.di = 0;	// This is always 0
	__dpmi_int(0x10, &regs);

Note I didn't dosmemput first, as the GetVESAInfo BIOS call doesn't
require anything to be put first for VBE 1.2 and before. If your
using VBE 2.0, your should set VESASignature to VBE2 and then dosmemput.
(Although, I don't do this, and the code works fine for me...)

When your doing a dosmemget, your getting the sizeof(*vbeinfo), which
is 4 (a pointer is only 4 bytes), when you should be getting the
sizeof(vbeinfo).

To convert the VideoModePtr to segment/offset format, you must to
the following:
	seg = (VideoModePtr & 0xFFFF0000) >> 12;
	off = VideoModePtr & 0xFFFF;
	value = _farpeekw(_dos_ds, seg + off);	

The VideoModePtr is stored in a really strange format. The segment is in
the
4 most significant bits of the 16 most significant bits of the 32 bit
VideoModePtr... easy eh? ;)  The segment is in the least significant
bits
of the 32 bit VideoModePtr. Once you understand this, its no problem...
:)

You perform an AND operation to gather the top 16 bits of the
VideoModePtr,
and then shift these right 12 bits to make the 4 MSB the 4 LSB, which is
a plain segment value in the 0-15 range, which is what you want, and
where you went wrong... :)

Leathal.

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019