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 Subject: please help me with VBE To: djgpp AT delorie DOT com MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable 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 #include #include #include #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/