delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2010/03/29/17:43:15

X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f
X-Recipient: djgpp AT delorie DOT com
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com.ar; s=s1024; t=1269902507; bh=pVoHb/u2Z9URUJIyACzLUJ2x3jQ9r+R45V8kOYHksuU=; h=Message-ID:X-YMail-OSG:Received:X-Mailer:Date:From:Subject:To:MIME-Version:Content-Type:Content-Transfer-Encoding; b=dFZ5ZPkTHtHO6pBkHr29sMIeL0Hh1shGrropFrsYGm6aER05eB0/ynkJVWLRytxjPjt6EXm7eaIIUts2qMa2ldWYXvxhMDqiD95SL9u45y8U3BssOZDpCxYGxV2cQQCdDt00j+qEoyUfUELa4RdafX+b8lzOxL2B+kpQXi/7aKE=
DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws;
s=s1024; d=yahoo.com.ar;
h=Message-ID:X-YMail-OSG:Received:X-Mailer:Date:From:Subject:To:MIME-Version:Content-Type:Content-Transfer-Encoding;
b=1SM/Ug19/hRih5laq7oDEzGRmgmG4bfil+h4jC3npEcUPE2zswNlgeuFbw8Z9ahMuYXb6lVMUf0VShEeggtejTlkuSU0FlqsHxze5rAweGEU5t+35yo3k6CDpasAYYyaOSJCfvtErlUWvYh89AreDjUui3sjL/EQtxDjxaZL4IQ=;
Message-ID: <515911.46482.qm@web45104.mail.sp1.yahoo.com>
X-YMail-OSG: lrIH3XoVM1mdHyyHwUT9qjaetFveJY.x5GSN5ZDsM665dll
5dRXEDiE..NF4jbtbYOK_oXGLYv3wp1EPoDDftMhjR585f6v6HikDX1bcUTr
Kx6tltskpOln2HaBmZTkTQAnrCb8.GDLRLuUwHmIvEqj15Me_7KCnOtKAGNx
PHU5RdcVTbZmYY0ro_W3_DqiYYnoM4Z82Ho2jcx0c2R2Wh_Is.vwAy6BvQk8
LoAf0zU8AfCVm_uipblSeb42RddISO.lzZdgGip7peU2EhjNWQLhBy4YYn1V
MQ1GeW3wKLQ5vgM5L.X_RGjeekA--
X-Mailer: YahooMailClassic/10.0.8 YahooMailWebService/0.8.100.260964
Date: Mon, 29 Mar 2010 15:41:47 -0700 (PDT)
From: Pablo Marty <tigrepotrazosalvaje AT yahoo DOT com DOT ar>
Subject: please help me with VBE
To: djgpp AT delorie DOT com
MIME-Version: 1.0
Reply-To: djgpp AT delorie DOT com

I stole this, from 2 pages, from one the structs and from the other the cod=
e
I thought that with VBE my game would run faster under DOSBox than with VES=
A, because VBE treat the screen as just one array, ignoring the bank switch=
ing (or something like that)
I couldn't compile it .... does someone know where to find it more detailed=
, or just the complete code without errors to use linear framebuffer with V=
BE?
And about FreeDOS it's impossible install it without killing the actual sys=
tem .... I'll have to use DOSBox


#include <dpmi.h>
#include <sys/farptr.h>
#include <stdio.h>
#include <stdlib.h>

#define uchar unsigned char
#define ushort unsigned short
#define shint short int
#define uint unsigned int
#define ulong unsigned long

typedef struct VBE_VgaInfo  =20
{ char VESASignature[4];
  short VESAVersion;
  char *OemStringPtr;
  ulong Capabilities;
  ulong VideoModePtr;
  short TotalMemory;
  //VBE 2.0
  short OemSoftwareRev;
  char *OemVendorNamePtr;
  char *OemProductNamePtr;
  char *OemProductRevPtr;
  char reserved[222];
  char OemData[256];
};

typedef struct VBE_ModeInfo
{short ModeAttributes;
 char WinAAttributes;
 char WinBAttributes;
 short WinGranularity;
 short WinSize;
 ushort WinASegment;
 ushort WinBSegment;
 void *WinFuncPtr;
 short BytesPerScanLine;
 short XRes;
 short YRes;
 char XCharSize;
 char YCharSize;
 char NumberOfPlanes;
 char BitsPerPixel;
 char NumberOfBanks;
 char MemoryModel;
 char BankSize;
 char NumberOfImagePages;
 char res1;
 char RedMaskSize;
 char RedFieldPosition;
 char GreenMaskSize;
 char GreenFieldPosition;
 char BlueMaskSize;
 char BlueFieldPosition;
 char RsvedMaskSize;
 char RsvedFieldPosition;
 //VBE 2.0
 ulong PhysBasePtr;
 ulong OffScreenMemOffset;
 short OffScreenMemSize;
 //VBE 2.1
 short LinbytesPerScanLine;
 char BankNumberOfImagePages;
 char LinNumberOfImagePages;
 char LinRedMaskSize;
 char LinRedFieldPosition;
 char LingreenMaskSize;
 char LinGreenFieldPosition;
 char LinBlueMaskSize;
 char LinBlueFieldPosition;
 char LinRsvdMaskSize;
 char LinRsvdFieldPosition;
 char res2[194];
};

short int       xres, yres;                 /* x & y resolutions for the re=
quested mode */
int             bpp;                        /* bytes per pixel */
struct VBE_Modeinfo    modeinfo;                   /* VESA modeinfo struct =
*/
struct VBE_VgaInfo     vbeinfo;
__dpmi_meminfo  meminfo;
unsigned int    VBE_linaddr;
int             VBE_selector;

int info_svga(void) {
   __dpmi_regs ireg;

   memset(&ireg, 0, sizeof(ireg));
   assert(sizeof(vbeinfo) < _go32_info_block.size_of_transfer_buffer);

   ireg.x.ax =3D 0x4f00;
   ireg.x.di =3D 0;
   ireg.x.es =3D (__tb >> 4);                     /* =3D /16 */
   strncpy(vbeinfo.VESASignature, "VBE2", 4);
   dosmemput(&vbeinfo, sizeof(vbeinfo), __tb);

   __dpmi_int(0x10, &ireg);
   dosmemget(__tb, sizeof(vbeinfo), &vbeinfo);

   if((ireg.h.ah =3D=3D 0x00))
   {
      svga_present =3D 0;
      return (1);                   /* if successful */
   }
/*
   AL =3D=3D 0x4f:  Function supported
   AL !=3D 0x4f:  Function is not supported
    AH =3D=3D 0   :         Function call successful
    AH =3D=3D 0x01:         Function call failed
    AH =3D=3D 0x02:         Function is not supported in the current hw con=
fig
    AH =3D=3D 0x03:         Function call invalid in current video mode
*/
   return (0);
}

/* The VBE implementation on Millennium is very affordable and there should=
n't be any problems. So if the answer is positive we can start to ask our b=
oard for all the VBE information.
This is obtained in a very similar way by filling up an appropriate structu=
re:
*/

int info_svga_mode(shint mode)
{
   __dpmi_regs ireg;

   memset(&ireg, 0, sizeof(ireg));
   assert(sizeof(modeinfo) < _go32_info_block.size_of_transfer_buffer);

   ireg.x.ax =3D 0x4f01;
   ireg.x.cx =3D mode;
   ireg.x.di =3D 0;
   ireg.x.es =3D (__tb >> 4);
   dosmemput(&modeinfo, sizeof(modeinfo), __tb);

   __dpmi_int(0x10, &ireg);
=20
   dosmemget(__tb, sizeof(modeinfo), &modeinfo);

   if((modeinfo.ModeAttributes & 0x0001) =3D=3D 1 && (ireg.h.ah =3D=3D 0))
      return 1;                /* if successful */
/*
   bit values:
       =20
   D0: 0 mode not supported in hw
       1 mode supported in hw

   D1: 1 reserved

   D2: 0 output function not supported from BIOS
       1 output function supported from BIOS

   D3: 0 monochrome mode
       1 color mode

   D4: 0 text mode
       1 graphics mode
*/
   return 0;
}

// Wishing to print all the available modes I have used the poor function t=
o duplicate their list in a different pointer:

uint *get_video_modes_from_ptr(uint ptr)
{
   uchar result_int[256];
   ulong oem_ptr =3D 0;
   int i =3D 0;
   ushort value;
   ushort old_selector;

   old_selector =3D _fargetsel();
   memset(result_int, 0, sizeof result_int);
   oem_ptr =3D (vbeinfo.VideoModePtr & 0xFFFF0000) >> 12 | (vbeinfo.VideoMo=
dePtr & 0xFFFF);

   _farsetsel(_dos_ds);
   do{
     result_int[i] =3D (uchar)(_farnspeekw(oem_ptr++));
     i++;
   }while((value !=3D (uint)-1) && (i < 256));

   _farsetsel(old_selector);
   oem_modes =3D (uint *)result_int;
   return(oem_modes);
}

// If this seems clumsy, wait until you've read the next part! This is how =
I've printed the modes obtained...

void print_info(void)
{
   int i=3D0;
   char *sp =3D NULL;
   int modo =3D 0x100;

   sp =3D get_string_from_ptr(vbeinfo.OEMStringPtr);

   printf("%4s %d.%d %s\n",vbeinfo.VESASignature,
                          (vbeinfo.VESAVersionMain >> 8),
                          (vbeinfo.VESAVersionMain & 0xff ),
                           sp);
   printf("\n");

   while(i < 34)
   {
      print_info_mode(modo+i);

      getch();

      i++;
   }
   printf("\n");
}

void print_info_mode(shint mode)
{
   if(info_svga_mode(mode) =3D=3D 0)
   {
      printf("Mode 0x%x not supported from hardware\n",mode);
      return ;
   }
   printf("%x ",mode);
   printf("%4dx%4d ",modeinfo.XResolution,modeinfo.YResolution);
   printf("%4d ",modeinfo.BytesPerScanLine);
/*      if((modeinfo.ModeAttributes >>4)& 0x01)
                printf("%d ",modeinfo.BytesPerScanLine/(modeinfo.BitsPerPix=
el>>3));
*/
   if((modeinfo.ModeAttributes) & 0x08)
      printf("color "); else printf("mono  ");        /* bit 4 (D3) */
   if((modeinfo.ModeAttributes) & 0x10)
      printf("graphics "); else printf("text     ");  /* bit 5 (D4) */
   printf("%2d bit/pixel ",modeinfo.BitsPerPixel);
   printf("%d %d %d ",modeinfo.RedMaskSize,
                      modeinfo.GreenMaskSize,
                      modeinfo.BlueMaskSize);
   printf("%d ", modeinfo.MemoryModel);
   switch (modeinfo.MemoryModel)
   {
      case 0:  printf("Text mode");
                break;
      case 1:  printf("CGA mode");
                break;
      case 2:  printf("Hercules Graphics");
                break;
      case 3:  printf("Planar mode");
                break;
      case 4:  printf("Packed Pixel mode");
                break;
      case 5:  printf("Non chain 4, 256 color");
                break;
      case 6:  printf("RGB direct color");
                break;
      case 7:  printf("YUV direct color");
                break;
   }
   printf("\n");
}


/* Good (or maybe not), the VBE information is now complete; this was manda=
tory for the next steps.
But before going ahead, I have to admit I've fought, and lost, against a st=
upid non-essential point like the char *OEMStringPtr which in VBE_Vgainfo s=
truct should give the OEM string name.=20
I have pinched the solution from a mail of Leath Muller (Leathal...) from t=
he mailing list comp.os.msdos.djgpp .=20
(I will use some typedef contractions like uchar for unsigned char and shin=
t for short int etc.)=20
Instead of the declaration:=20
   char *OEMStringPtr;
he suggests:=20
   unsigned int oem_str_ptr;
and what follows is my interpretation of it:
*/

char *get_string_from_ptr(uint ptr){
   char result_string[256];
   uint oem_ptr =3D 0;
   int i =3D 0;
   char letter;
   ushort old_selector;

   old_selector =3D _fargetsel();
   memset(result_string, 0, 256);
   oem_ptr =3D (ptr & 0xFFFF0000) >> 12 | (ptr & 0xFFFF);

   _farsetsel(_dos_ds);
   do{
      letter =3D (char)_farnspeekb(oem_ptr++);
      result_string[i] =3D letter;
      i++;
   }while((letter !=3D '\0') && (i < 256));

   _farsetsel(old_selector);

   strcpy(oem_string, result_string);
   return(oem_string);
}

/* Et voila the OEM string name has been saved.
Not exactly simple!=20
For the VBE_VgaInfo and VBE_ModeInfo structs, please refers to Brennan's ec=
ho of the VBE 2.0 Scitech specifications.=20
Remember the PACKED attribute at the end of each struct's item.=20
The PACKED has been defined as:
*/

#define PACKED  __attribute__((packed))

/* Let's now look at a point which is probably not very clear.
As has happened several times before, you've found the fancy "conversion":=
=20
unsigned int pointer =3D ((unsigned int )ptr & & 0xFFFF0000) >> 12 | ((unsi=
gned int)ptr & 0xFFFF);
This annoying requirement is well explained in a mail of Eli Zaretskii to t=
he Djgpp mailing list.=20
He wrote:=20
"The pointers in the VBE structure are real-mode pointers, so you cannot=20
treat them as if they were protected-mode pointers to some buffer inside=20
your program's address space. Instead, you should treat them as a far=20
pointer, i.e. a pair of 16-bit words seg:off and use farptr functions to=20
fetch the buffer contents to a protected-mode buffer.=20
...=20
...=20
Note how the pointers were converted into a seg:off pair, and in reverse=20
order because the way Intel machines store bytes..."=20

VBE linear addressing
I have based my attempt on this feature that VBE 2.0 and Matrox offer the u=
ser.=20
This avoids the need for heavy bank switching and speeds up and simplifies =
every video operation. Following, again, the instructions of Jeff Weeks you=
 should be able to set up this procedure.=20
Any doubts? Assuming you have declared as globals the following variables:
*/

// try to insert in your code something like:

int VBE_linear_mapping(void)
{
   if(!&modeinfo)                          /* check if the requested VESA m=
ode is avalaible */
   {
       printf("Get VESA mode info failed. \n");
       exit(1);                            /* exit or a clever error handli=
ng procedure */
   }

   meminfo.handle =3D 0;
   meminfo.size =3D xres * yres * bpp + 256; /* extra 256 for safe */
   meminfo.address =3D modeinfo.PhysBasePtr;
   if(__dpmi_physical_address_mapping(&meminfo) =3D=3D -1)
   {
      printf("Physical mapping of address 0x%lx failed!\n",
              modeinfo.PhysBasePtr);
      exit(2);                             /* exit or a clever error handli=
ng procedure */
   }
   __dpmi_lock_linear_region(&meminfo);
   VBE_linaddr =3D meminfo.address;

   if((VBE_selector =3D __dpmi_allocate_ldt_descriptors(1)) =3D=3D -1)
   {
      printf("LDT allocation failed!\n");
      exit(4);                             /* exit or a clever error handli=
ng procedure */
   }
   __dpmi_set_segment_base_address(VBE_selector, VBE_linaddr);
   __dpmi_set_segment_limit(VBE_selector, xres*yres*bpp);

   return 0;
}

// At the end, don't forget to free and unlock everything necessary before =
leaving:
void VBE_free_linear_mapping(void)
{
   __dpmi_unlock_linear_region(&meminfo);
   __dpmi_free_physical_address_mapping(&meminfo);
   __dpmi_free_ldt_descriptor(VBE_selector);
   if(pm_info) free(pm_info);               /* free it if allocated */
}

/* With a selector/address couple, every Vesa operation will be definitely.=
.. linear.

Pixel addressing and beyond
This is a chapter I particularly like.=20
The Matrox VBE implementation offers a nice feature: for the true colours m=
odes it assigns four bytes per pixel. This is very useful because it is pos=
sible to address all the colours of a pixel with only one addressing operat=
ion.=20
For this I prefer to use farpointers, so a simple pixel draw becomes (remem=
ber the include for farpointers):
*/

void put_pixel(uint x, uint y,=20
               uchar r, uchar g, uchar b, uchar alfa)
{
   ulong offset;

   if ((x >=3D xres) || (x < 0) || (y >=3D yres) || (y < 0))
           return;

   offset =3D ((long int)y*xres_mode + (long int)x)*(long int)(bpp);

   switch (mode)
   {
      case 0x112:     //640x480       16m
      case 0x115:     //800x600       16m
      case 0x118:     //1024x768      16m
      case 0x11B:     //1280x1024     16m

      _farpokel(VBE_selector, offset,(ulong)(65536*r + 256*g + b));
      break;
   }
}


=0A=0A=0A      Yahoo! Cocina=0A=0AEncontra las mejores recetas con Yahoo! C=
ocina.=0A=0A=0Ahttp://ar.mujer.yahoo.com/cocina/

- Raw text -


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