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 -