Re: VESA VGA Frame Buffer

Gerd Knorr (kraxel@goldbach.isdn.cs.tu-berlin.de)
Mon, 27 Jul 1998 20:01:08 +0200 (CEST)


On Mon, 27 Jul 1998, Martin Mares wrote:

> > So I guess that the video mode init has to be done earlier, maybe in
>
> Yes, you should use the "vga=..." parameter.
>
> > linux/arch/i386/boot/video.S. But when I try to pass vga=??? parameter
> > to
> > the kernel it doesn't allow me to use 788 or 769 (0x200 =vesa + 0x114
> > =800x600x32K or +0x101 =640x480x256). My graphics card has VBE 2.0
> > Extensions, if I boot bare DOS with Shift-F5 at boot, and load vbetest
> > from sdd 6.51 it says Creative Labs Graphics Blaster bios, vbe 2.0.
> > I tryed to boot into dos, load univbe 6.51 which has vbe 3.0 and
> > then with loadlin to boot with vga=??? but the also it doesn't work
> > right:
> > Invalid mode ID.
>
> I have looked at the code and there are only three resons why it can
> print "Invalid mode ID":
>
> o The BIOS doesn't recognize the mode at all.
> o The BIOS reports that the mode doesn't support linear framebuffer
> o The BIOS is unable to set up the mode with linear framebuffer.
>
> [Gerd, can you write few lines about this to the documentation?]

Hmm, that you need linear framebuffer support is already in
fb/vesafb.txt. The error message is allways the same, that could be
probably improved. (But I don't like assembler hacking very much...)

For those which have some DOS and a old Borland C-Compiler, I append
a piece if code which will dump the VESA mode information. All modes
where the BIOS reports it can enable the linear frame buffer, it prints
the base address and size. My card gives the following output:

Version : 2.00
OEM Name : Matrox Graphics Inc.
memory : 4194304
100h: 640 x 400 x 8 ff000000 3e800
101h: 640 x 480 x 8 ff000000 4b000
102h: 800 x 600 x 4
103h: 800 x 600 x 8 ff000000 75400
105h: 1024 x 768 x 8 ff000000 c0000
107h: 1280 x 1024 x 8 ff000000 140000
108h: 80 x 60 (text)
109h: 132 x 25 (text)
10bh: 132 x 50 (text)
10ch: 132 x 60 (text)
110h: 640 x 480 x 16 1:5:5:5 ff000000 96000
111h: 640 x 480 x 16 0:5:6:5 ff000000 96000
112h: 640 x 480 x 32 8:8:8:8 ff000000 12c000
113h: 800 x 600 x 16 1:5:5:5 ff000000 ea800
114h: 800 x 600 x 16 0:5:6:5 ff000000 ea800
115h: 800 x 600 x 32 8:8:8:8 ff000000 1d4c00
116h: 1024 x 768 x 16 1:5:5:5 ff000000 180000
117h: 1024 x 768 x 16 0:5:6:5 ff000000 180000
11ch: 1600 x 1200 x 8 ff000000 1d4c00
118h: 1024 x 768 x 32 8:8:8:8 ff000000 300000
119h: 1280 x 1024 x 16 1:5:5:5 ff000000 280000
11ah: 1280 x 1024 x 16 0:5:6:5 ff000000 280000
11dh: 1600 x 1200 x 16 1:5:5:5 ff000000 3a9800
11eh: 1600 x 1200 x 16 0:5:6:5 ff000000 3a9800

Gerd

------------------ cut here -----------------------
#include <stdio.h>
#include <dos.h>

#define TRUE 1
#define FALSE 0

typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned long dword;

struct SVGAINFO {
byte vesa[4]; // muss "VESA" drinstehen
word version; // VESA-Version
char far *OEMname; // Herstellername
byte caps[4]; // ???
word far *modes; // Ptr of array of Mode-Nr's.
word memory; // video memory
char far *s1;
char far *s2;
char far *s3;
byte reserved[222];
byte oemdata[256];
};

struct SVGAMODEINFO {
word attr; // mode attributes
byte winA; // windows A attributes
byte winB; // windows B attributes
word gran;
word size;
word segA;
word segB;
void far* posfunc;
word scan;
word width;
word height;
byte charwidth;
byte charheight;
byte planes;
byte bits;
byte banks;
byte memmodel;
byte banksize;
byte num_of_im_pages;
byte r1;
byte red_mask_size;
byte red_field_pos;
byte green_mask_size;
byte green_field_pos;
byte blue_mask_size;
byte blue_field_pos;
byte reserved_mask_size;
byte reserved_field_pos;
byte direct_color_mode;
dword lfb_base;
dword off_base;
dword off_size;
byte r2[206];
};

struct REGPACK r;
struct SVGAINFO vesa = { "VBE2" };
struct SVGAMODEINFO vesamode;

/*-------------------------------------------------------------------------*/

void vgalist()
{
int i;

for (i = 0; vesa.modes[i] != 0xffff; i++) {
r.r_ax = 0x4f01;
r.r_cx = vesa.modes[i];
r.r_es = _DS;
r.r_di = (word)&vesamode;
intr(0x10,&r);

printf(" ");
printf("%4xh: ",vesa.modes[i]);

if (!(vesamode.attr & 0x10)) { /* graphic ? */
printf("%4d x %4d (text)\n",
vesamode.width,vesamode.height);
continue;
}

printf("%4u x %4u x %2u ",
vesamode.width,vesamode.height,vesamode.bits);
if (vesamode.bits > 8) {
printf("%d:%d:%d:%d ",
vesamode.reserved_mask_size,
vesamode.red_mask_size,
vesamode.green_mask_size,
vesamode.blue_mask_size);
} else {
printf(" ");
}

if (vesamode.attr & 0x80) {
printf("%8lx %8lx ",
vesamode.lfb_base,vesamode.off_base);
}

printf("\n");
fflush(stdout);
}
}

/*-------------------------------------------------------------------------*/

int
main()
{
r.r_ax = 0x4f00;
r.r_es = _DS;
r.r_di = (word)&vesa;
intr(0x10,&r);
if (r.r_ax != 0x004f) {
puts("VESA nicht installiert");
return(0);
}
printf("Version : %u.%2.2u\n",(vesa.version >> 8) & 0xf,(vesa.version >> 4) & 0xf);
printf("OEM Name : %Fs\n",vesa.OEMname);
printf("memory : %lu\n",(long)vesa.memory*64*1024);
if (((vesa.version >> 8) & 0xf) < 2) {
printf("need 2.0, sorry\n");
exit(1);
}

vgalist();
return(0);
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html