delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2010/05/22/18:54:59

X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f
X-Recipient: djgpp AT delorie DOT com
X-Yahoo-Newman-Property: ymail-3
X-Yahoo-Newman-Id: 552096 DOT 20634 DOT bm AT omp611 DOT mail DOT sp1 DOT yahoo DOT com
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com.ar; s=s1024; t=1274568108; bh=IT3upnRnyKGxQ1vdjvIDZPo14NGC9KmEIYmssRBzs+0=; h=Message-ID:X-YMail-OSG:Received:X-Mailer:Date:From:Subject:To:MIME-Version:Content-Type:Content-Transfer-Encoding; b=a0YMRMY86tRrtLHIqQZcZ4cLHkg9PHWr0ScN25ZH+UQ8qVk33cvDzEHBnXUIU7l/EU5aXsm0pjllWR3R4HCRN7ea3h4ReSkZfsy/YgbLIRsMWUFPGPbcsbkULnamGDOVxA4alS1CZCsi+xmv5GAmdZo/mFKW8aY9jotpcuwh4sM=
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=bEY5IFhwSeR+Xy2Ih9DNy0i3cwIaoVp75e3lH4qARDXb03vEo+YM/jVl4rwZY65mlt9laDbANWdl6WgzN1tgZP83we3KPnKv9t1oMGFfuiBH/X3qAY4x8PldcLtLlTRVnoaqK+bKNRUonL6voq3yeCs+4OhJxeGGtoVKQFAWKec=;
Message-ID: <448871.21810.qm@web45108.mail.sp1.yahoo.com>
X-YMail-OSG: wodlZdUVM1mgS7sz3GAsr38TbEbG8Ds6HUyjtT3fwKBwNM7
W3iYWep44Sb9nq.IQdVb.B6J7Xc68kQbvL_iLzAowch5ifOlZ9OBaN7twbWl
oo7NYndyi8VbwixrJbcPNxW0YJVi8knWJlpgvH2fmRNR136MBmmy4JiTLsH9
hlMLGpUpYXvCmxbIi57abch5ekmOP2meiMt9up5xTZP_VdR.gQI2sstGUCZS
oIsbLl.hhjozEueN6QNUs5Tfl_gUej6J9fkDnQRhQBGc8YN05FoLoOmfW_.D
z1i1pphM-
X-Mailer: YahooMailClassic/11.0.8 YahooMailWebService/0.8.103.269680
Date: Sat, 22 May 2010 15:41:48 -0700 (PDT)
From: Pablo Marty <tigrepotrazosalvaje AT yahoo DOT com DOT ar>
Subject: my videogame in DJGPP and VBE
To: djgpp AT delorie DOT com
MIME-Version: 1.0
Reply-To: djgpp AT delorie DOT com

Dear Rugxulo and other members

Hi, I tried my game again with DOSBox and it ran quit faster and now the mu=
sic sounded correctly.=20
Now I'm looking for the VESA or VBE mode with no bank switching (linear fra=
mebuffer) in order to make my game (Super Mario, I'm a great fan ... also S=
onic the hedgehog) normally fast.=20
Obviously I googled something like "SVGA DJGPP with no bank switching"
And I got this from: http://www.delorie.com/djgpp/doc/ug/graphics/vbe20.htm=
l=20

/************/
   typedef struct VESA_PM_INFO
   {
      unsigned short setWindow            __attribute__ ((packed));
      unsigned short setDisplayStart      __attribute__ ((packed));
      unsigned short setPalette           __attribute__ ((packed));
      unsigned short IOPrivInfo           __attribute__ ((packed));
   } VESA_PM_INFO;


   VESA_PM_INFO *vesa_pm_info;

   void *pm_bank_switcher;


   int get_vesa_pm_functions()
   {
      __dpmi_regs r;

      /* check that the driver is at least VBE version 2.0 */
      if (vesa_info.VESAVersion < 0x200)=20
=09 return -1;

      /* call the VESA function */
      r.x.ax =3D 0x4F0A;
      r.x.bx =3D 0;
      __dpmi_int(0x10, &r);
      if (r.h.ah)
=09 return -1;

      /* allocate space for the code stubs */
      vesa_pm_info =3D malloc(r.x.cx);

      /* copy the code into our address space */
      dosmemget(r.x.es*16+r.x.di, r.x.cx, vesa_pm_info);

      /* store a pointer to the bank switch routine */
      pm_bank_switcher =3D (void *)((char *)vesa_pm_info +=20
=09=09=09=09  vesa_pm_info->setWindow);

      return 0;
   }

This code will give you a pointer to the protected mode bank switching func=
tion, but you cannot call this directly from C because it uses a special re=
gister based argument passing convention. A little bit of inline asm is nee=
ded to make sure the parameters go into the correct registers, eg:

   void set_vesa_bank_pm(int bank_number)
   {
      asm (
=09 " call *%0 "
      :                             /* no outputs */

      : "r" (pm_bank_switcher),     /* function pointer in any register */
=09"b" (0),                    /* set %ebx to zero */
=09"d" (bank_number)           /* bank number in %edx */

      : "%eax",                     /* clobber list (we have no way of */
=09"%ebx",                     /* knowing which registers the VESA */
=09"%ecx",                     /* code is going to change, so we */
=09"%edx",                     /* have to assume the worst and list */
=09"%esi",                     /* them all here) */
=09"%edi"
      );
   }

This routine is an exact drop-in replacement for the set_vesa_bank() functi=
on described in the previous chapter, but will run several hundred times fa=
ster!

VBE 2.0 also provides the ability to use a linear framebuffer mode in which=
 the entire video memory can accessed as a single block at some location ot=
her than the standard 0xA0000, which gets rid of the need for bank switchin=
g altogether. This is both the fastest and the easiest way to program SVGA =
graphics, but unfortunately you can't count on it being supported by all ha=
rdware. Even if the card has a VBE 2.0 driver, many older boards don't supp=
ort linear framebuffers at all, and a few of the more recent ones can only =
use linear addressing in certain resolutions.

Setting a linear framebuffer mode is extremely simple. After calling the fi=
nd_vesa_mode() function, check that bit 7 of mode_info.ModeAttributes is se=
t, to make sure that linear addressing is possible in this mode. Assuming t=
hat it is supported, when you call function 0x4F02 to select the mode you s=
hould put (mode_number | 0x4000) into the BX register, instead of just mode=
_number, and you will have a linear framebuffer!

The video memory is located at the physical address specified by the mode_i=
nfo.PhysBasePtr field, but you must map this area into your address space b=
efore you can access it. This can be done with the code:

   __dpmi_meminfo mapping;
   int selector;

   /* map into linear memory */
   mapping.address =3D mode_info.PhysBasePtr;
   mapping.size =3D vesa_info.TotalMemory << 16;
   if (__dpmi_physical_address_mapping(&mapping) !=3D 0)
      return -1;

   /* allocate an LDT descriptor to access the linear region */
   selector =3D __dpmi_allocate_ldt_descriptors(1);
   if (selector < 0) {
      __dpmi_free_physical_address_mapping(&mapping);
      return -1;
   }

   /* set the descriptor location and size */
   __dpmi_set_segment_base_address(selector, mapping.address);
   __dpmi_set_segment_limit(selector, mapping.size-1);

You can now write to any part of the screen using the selector that we just=
 created, and without any need for bank switching, eg:

   void linear_putpixel(int x, int y, int color)
   {
      _farpokeb(selector, y*640+x, color);
   }

Finally, at the end of your program you should free the video memory mappin=
g with the code:

   __dpmi_free_physical_address_mapping(&mapping);
   __dpmi_free_ldt_descriptor(selector);
/***************/

The compiler detected that these functions try to access fields of the VESA=
_PM_INFO struct that are not declared.=20
I remmember having seen in other page a code like this and the definition o=
f VESA_PM_INFO was also absent
Can you tell me where find this code correct or how to fix this?=20
Also I fixed almost all bugs in my program and added music with play_midi()=
; in brief, when I get it some better I'll ask you to send it again.
Thank you
Pablo=20
Bs As Argentina
=0A=0A=0A      

- Raw text -


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