www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/05/23/18:24:53

Message-ID: <338617FF.D8019CFC@abc.se>
Date: Sat, 24 May 1997 00:19:43 +0200
From: Henrik Baarnhielm <Henrik DOT Baarnhielm AT abc DOT se>
MIME-Version: 1.0
Newsgroups: comp.os.msdos.djgpp
To: djgpp AT delorie DOT com
Subject: VBE 2.0

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, &regs);
	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, &regs);
	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,&regs);
	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,&regs);
			}
		}
		_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 -


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