Mail Archives: djgpp/1997/05/23/18:24:53
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 <iostream.h>
#include <conio.h>
#include <dos.h>
#endif*/
#if !defined(__DPMI_H)
#include <dpmi.h>
#endif
#if !defined(__STRING_H)
#include <string.h>
#endif
#if !defined(__GO32_H)
#include <go32.h>
#endif
#if !defined(__FARPTR_H)
#include <sys\farptr.h>
#endif
#if !defined(__NEARPTR_H)
#include <sys\nearptr.h>
#endif
#if !defined(__MATH_H)
#include <math.h>
#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
***************************************
- Raw text -