Mail Archives: djgpp/1996/01/19/03:28:06
Shawn Hargreaves <slh100 AT york DOT ac DOT uk> wrote:
>Hi everyone! Version 2.0 of my Allegro library is about 60/70% done. This a
>game programming library for djgpp which provides a range of graphics
>primitives, low level access to the mouse, keyboard and millisecond
>timers, file compression, fixed point maths, and a set of simple GUI
>routines.
>The major new feature in version 2.0 is support for svga graphics modes
>(the original version only worked in mode 13h). So far I have written a
>driver that uses real mode VESA bank switching functions, and one that
>programs my Tseng ET4000 directly at register level. And the real mode
>VESA calls are a killer as far as speed is concerned. On some simple
>tests the ET4000 driver goes over twice as fast as the VESA one. So, I
>would like to add register level support for more cards (it is generally
>only a matter of a couple of port writes). To do that, though, I need
>some kind people who would be willing to test it for me. So, if you are
>interested in helping with this, please email me (slh100 AT tower DOT york DOT ac DOT uk)
>and let me know what sort of video card you have....
It sounds like we are both working toward a common goal, you are
working on a gaming API where I am working on a windowing API. I too
have reallized that practically all graphics adaptors have common
functionality. They have 0xFFFF of address space that starts at
0xA0000 that is a window into the adaptors actual memory. To select a
certian page of that memory you write to ports. The problem is that no
2 manufacturers do the paging the same way.
Your call to int 10 function 4F05 to set the graphics page is not only
slow it cannot be performed during interrutpt service. Which means
that an interrupt driven mouse service routine (int 33 function 0xC)
cannot draw the mouse on the screen and the mouse has to be drawn in
some kind of program loop. So, when your program needs to do something
intense the mouse gets jerky or stalls completely.
We need a portable way to set the graphics page that does not rely on
the bios.
I was working with a different compiler so I could not use drivers or
any kind of code that is linked at run time, I tried to figure out a
way to tell my program what registers to write to in a configuration
file. I got it to work for two cards, here is the code and 2
configuration files.
This only works for 256 color modes! This code will not work with
DJGPP, the int386 and outp calls must be converted!
#define SCREEN_AREA 0xA000
#define SCREEN_LIN_ADDR ((SCREEN_AREA) << 4)
short width;
short height;
char *point=(char *)SCREEN_LIN_ADDR;
int page = 0xFFFF;
int index_reg;
int index_val;
int data_reg;
int sleft;
int xor;
void init_video(void)
{
union REGS inregs,outregs;
FILE *vf;
char line[41];
char *dummy;
vf=fopen("256.vid","r");
if(vf==NULL)
{
printf("Could no open video configuration file 256.vid");
exit(0);
}
fgets(line,40,vf);
line[strlen(line)-1]=NULL; /*probably don't need this*/
inregs.h.al=strtol(line,&dummy,0);
inregs.h.ah=0;
int386(0x10,&inregs,&outregs); /*set the video mode*/
fgets(line,40,vf);
line[strlen(line)-1]=NULL;
width = strtol(line,&dummy,0);
fgets(line,40,vf);
line[strlen(line)-1]=NULL;
height = strtol(line,&dummy,0);
fgets(line,40,vf);
line[strlen(line)-1]=NULL;
index_reg = strtol(line,&dummy,0);
fgets(line,40,vf);
line[strlen(line)-1]=NULL;
index_val = strtol(line,&dummy,0);
fgets(line,40,vf);
line[strlen(line)-1]=NULL;
data_reg = strtol(line,&dummy,0);
fgets(line,40,vf);
line[strlen(line)-1]=NULL;
xor = strtol(line,&dummy,0);
fgets(line,40,vf);
line[strlen(line)-1]=NULL;
sleft = strtol(line,&dummy,0);
fclose(vf);
}
void set_page(char page_no)
{
outp(index_reg,index_val);
page_no = page_no ^ xor;
page_no = page_no << sleft;
outp(data_reg,page_no);
}
void put_pixel(unsigned int x,unsigned int y,char color)
{
int vadd,nadd,npage;
if(x>=width || y>=height)
return;
vadd = y*(int)(width)+x;
nadd = vadd & 0xFFFF;
npage = vadd & 0xF0000;
if(npage != page)
{
page = npage;
set_page(page>>16);
}
*(point+nadd)=color;
}
char get_pixel(int x,int y)
{
int vadd,nadd,npage;
if(x>=width || y>=height)
return(0);
vadd = y*(int)(width)+x;
nadd = vadd & 0xFFFF;
npage = vadd & 0xF0000;
if(npage != page)
{
page = npage;
set_page(page>>16);
}
return(*(point+nadd));
}
This is a Trident configuration file. Since the program would only
read so far I just kept the configuration for all the modes that I
knew about in one file. If I wanted to change modes I just copied that
section to the top.
0x62
1024
768
0x3C4
0xE
0x3C5
2
0
0x5E
800
600
0x3C4
0xE
0x3C5
2
0
And a file for a Western Digital 9031:
0x60
1024
768
0x3CE
9
0x3CF
0
4
0x5C
800
600
0x3CE
9
0x3CF
0
4
0x5F
640
480
0x3CE
9
0x3CF
0
4
I know you would prefer I just told you what data to write to what
register, but I can't remember that.
I too would like this type of information about any video card you
research. I esspecially need info on S3 chips.
>Also, I would really like to add support for VESA 2.0 linear
>framebuffers, but my card doesn't support this. If anyone had a card
>capable of using a linear buffer, or even better, some example code that
>uses this feature, I would _really_ like to hear from you :-)
I will look into this.
I would offer to help test your library but I'm up to my eyeballs in
my own code. Keep plugging at it :-)
- Raw text -