Message-ID: <338617FF.D8019CFC@abc.se> Date: Sat, 24 May 1997 00:19:43 +0200 From: Henrik Baarnhielm MIME-Version: 1.0 Newsgroups: comp.os.msdos.djgpp To: djgpp AT delorie DOT com Subject: VBE 2.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Precedence: bulk I am trying to do a C++-class in DJGPP for VBE 2.0 but I have some tiresome problems. I have done so it should support both banking and linear buffer modes. Most of it seem to work, but my putpixel-routine doesn't work. I have checked the official specs, the FAQ, the mail archives but I can't find a good answer, and everybody says different things. At the moment I am using the farptr functions, but I have tried the nearptr functions without success and that is my other problem. Could some of you gurus help me? Here's my code... class vesascreen { public: vesascreen(); int putpixel(unsigned int x,unsigned int y,unsigned char color); int isvesadetected(); int ismodesupported(unsigned int mode); int setmode(unsigned int modenum); int getvesamodeinfo(unsigned int mode,unsigned int &screenwidth,unsigned int &screenheight,unsigned long &ncolors); int clear(); private: struct vesainfotyp { char signatur[4]; //VESA short version; //VESA version char *oem; //Name of the card unsigned long capabilities; unsigned int *videomodes; //pointer to available modes short totalmemory; short oemsoftwarerev; char *oemvendorname; char *oemproductname; char *oemproductrev; char reserved[222]; char oemdata[256]; }; struct modeinfotyp { unsigned short modeattr; unsigned char wina; unsigned char winb; unsigned short granularity; //granularity and winsize are unsigned short winsize; //used to calculate the bankshift unsigned short winasegment; unsigned short winbsegment; void (*bankSwitch)(void); //bankswitch function unsigned short bytesperline; unsigned short width; //width and unsigned short height; //height of the mode unsigned char charwidth; unsigned char charheight; unsigned char bitplanes; unsigned char bitsperpixel; //if this is 8 then it's 256 colors unsigned char banks; unsigned char memorymodel; unsigned char banksize; //in KB unsigned char imagepages; unsigned char reserved1; unsigned char redmasksize; unsigned char redfieldposition; unsigned char greenmasksize; unsigned char greenfieldposition; unsigned char bluemasksize; unsigned char bluefieldposition; unsigned char rsvdmasksize; unsigned char rsvdfieldposition; unsigned char directcolormode; unsigned long physicaladdress; unsigned long offscreenmemoffset; unsigned short offscreenmemsize; unsigned char reserved2[206]; }; vesainfotyp vesainfo; modeinfotyp modeinfo; void (*switchbank)(void); void getmodeinfo(int mode,modeinfotyp *info); int vesadetected; unsigned int bankshift,currentmode,banksize,nbanks; int currentbank; unsigned int width,height; int invesamode; unsigned long lineaddress; unsigned long screenptr; unsigned int banking,bytesperline; }; #include #include #include #endif*/ #if !defined(__DPMI_H) #include #endif #if !defined(__STRING_H) #include #endif #if !defined(__GO32_H) #include #endif #if !defined(__FARPTR_H) #include #endif #if !defined(__NEARPTR_H) #include #endif #if !defined(__MATH_H) #include #endif #include "vesa.h" vesascreen::vesascreen() { union __dpmi_regs regs; regs.x.ax=0x4f00; regs.x.es=__tb >> 4; regs.x.di=0; strcpy(vesainfo.signatur,"VBE2"); dosmemput(&vesainfo,sizeof(vesainfo),__tb); __dpmi_int(0x10, ®s); dosmemget(__tb, sizeof(vesainfo),&vesainfo); if(regs.h.al==0x4f) { vesadetected=1; } else vesadetected=0; invesamode=0; } inline int vesascreen::isvesadetected() { return vesadetected; } int vesascreen::ismodesupported(unsigned int mode) { unsigned long modepointer; unsigned int modenum; if(!isvesadetected()) return 0; modepointer=(unsigned long)vesainfo.videomodes; _farsetsel(_dos_ds); while((modenum=_farnspeekw(modepointer))!=(unsigned)-1) { if(modenum==mode) { return 1; } modepointer++; } return 0; } void vesascreen::getmodeinfo(int mode,modeinfotyp *info) { union __dpmi_regs regs; regs.x.ax=0x4f01; regs.x.cx=mode; regs.x.di=0; regs.x.es=__tb >> 4; __dpmi_int(0x10, ®s); dosmemget(__tb, sizeof(modeinfo),&modeinfo); } int vesascreen::setmode(unsigned int modenum) { int shift=0; unsigned long colors,modepointer; union __dpmi_regs regs; __dpmi_meminfo memory; if(!isvesadetected()) return 0; getmodeinfo(modenum,&modeinfo); if(!(modeinfo.modeattr & 0x80)) { bankshift=0; while((unsigned)(64 >> bankshift) != modeinfo.granularity) bankshift++; switchbank=modeinfo.bankSwitch; screenptr=(((unsigned long)modeinfo.winasegment) << 4 | 0); currentbank=-1; banking=1; } else { memory.size=modeinfo.width*modeinfo.height*modeinfo.bitsperpixel/8; memory.address=modeinfo.physicaladdress; if(__dpmi_physical_address_mapping(&memory)) return 0; lineaddress=memory.address; shift=0x4000; banking=0; } regs.x.ax=0x4f02; regs.x.bx=(modenum | shift); __dpmi_int(0x10,®s); if (regs.h.al == 0x4f && regs.h.ah==0) { width=modeinfo.width; height=modeinfo.height; bytesperline=modeinfo.bytesperline; invesamode=1; currentmode=modenum; return 1; } else return 0; } int vesascreen::putpixel(unsigned int x,unsigned int y,unsigned char color) { if(!invesamode) return 0; unsigned long offset; __dpmi_regs regs; offset=(long)y*bytesperline+x; if(banking) { if(currentbank != (int)(offset >> 16)) { currentbank=((int)(offset >> 16)) << bankshift; for(int temp=0;temp<2;temp++) { regs.x.ax=0x4f05; regs.x.bx=temp; regs.x.dx=currentbank; __dpmi_int(0x10,®s); } } _farpokeb(_dos_ds,screenptr+(offset & 0xffff),color); return 1; } _farpokeb(_dos_ds,(unsigned long)lineaddress+(offset & 0xffff),color); } int vesascreen::getvesamodeinfo(unsigned int mode,unsigned int &screenwidth,unsigned int &screenheight,unsigned long &ncolors) { if(!ismodesupported(mode)) return 0; getmodeinfo(mode,&modeinfo); screenwidth=modeinfo.width; screenheight=modeinfo.height; ncolors=(unsigned long)pow2(modeinfo.bitsperpixel); return 1; } int main() { vesascreen scr; int x=0,y=0; int temp; if (!scr.isvesadetected()) { cout << "VESA isn't there.\n"; return 0; } if(!scr.ismodesupported(0x101)) return 0; if(!scr.setmode(0x101)) { cout << "Couldn't change mode.\n"; return 0; } scr.putpixel(320,240,255); getch(); textmode(C80); } Thank you -- *************************************** Internet : Henrik DOT Baarnhielm AT abc DOT se Fidonet : Henrik Baarnhielm, 2:201/235 ***************************************