pcem/src/ega.c
TomW 9312de19ac Now up to date with current dev version.
Changes since v0.7 :
- Major CPU reorganisation. This has possibly broken some stuff, though I fixed all the regressions I could find
- Lazy flags. This brought 10% speed improvement at one point, but that's probably been lost now
- 430 VX chipset emulation
- IDT Winchip emulation (currently sans MMX). Timing is probably wrong
- Fixed a few FPU bugs
- Timer reorganisation
- Sound reorganisation
- Other general reorganisation
- AdLib Gold emulation
- Windows Sound System emulation
- Pro Audio Spectrum 16 emulation. This currently works with most DOS stuff, but not in Windows
- Major improvements to GUS emulation. Has the downside that it now conflicts with SB emulation, so probably best to not enable both simultaneously
- New graphics cards :
  - ATI-18800 (VGA Edge-16)
  - ATI-28800 (VGA Charger)
  - ATI Mach64GX (Graphics Pro Turbo). Quite a few features missing, but Windows doesn't seem to use half the features of this card
  - Cirrus Logic CL-GD5429. Blitter is a bit broken
  - Oak OTI-067
  - S3 Trio64 (Number Nine 9FX)
  - S3 Virge. Only framebuffer stuff at the minute, Windows won't recognise the card
  - Trident TGUI-9440
  - VGA. Doesn't work yet
- Beginnings of 3DFX emulation, however this is in extremely early stages and doesn't do anything useful
- Fixed DMA bug stopping floppy drives working in Windows 3.x
- Fixed some other stuff probably
- Broke some other stuff probably as well
2013-05-27 17:46:42 +01:00

297 lines
8.2 KiB
C

#include "ibm.h"
#include "video.h"
void doblit();
int egareads=0,egawrites=0;
int framecount=0;
int changeframecount=2;
void redotextlookup();
int output;
int svgaon=0;
uint32_t svgarbank,svgawbank;
uint8_t svgaseg,svgaseg2;
uint8_t svga3d8;
uint8_t oldvram=0;
int frames;
int hsync;
uint8_t cgastat;
uint8_t gdcreg[16];
int gdcaddr;
uint8_t attrregs[32];
int attraddr,attrff=0;
uint8_t ega3c2;
uint8_t rotatevga[8][256];
uint8_t writemask,charset;
int writemode,readmode,readplane,chain4;
uint8_t colourcompare,colournocare;
uint8_t la,lb,lc,ld;
uint8_t *vram;
int egares;
uint8_t seqregs[64];
int seqaddr;
uint8_t oak_regs[32];
int oak_index;
extern int egaswitchread,egaswitches;
/*For VGA non-interlace colour, ID bits should be 1 1 0 or 6*/
int vres=0;
PALETTE vgapal;
uint32_t *pallook,pallook16[256],pallook64[256],pallook256[256];
int dacread,dacwrite,dacpos=0;
int palchange=1;
int fullchange;
int dispontime,dispofftime;
double disptime;
int ega_vtotal,ega_dispend,ega_vsyncstart,ega_split,ega_hdisp,ega_rowoffset;
int vidclock;
float cpuclock;
int bpp;
uint32_t vrammask;
uint8_t changedvram[(8192*1024)/1024];
int charseta,charsetb;
int egapal[16];
int displine;
int rowdbl=0;
int scrblank=0;
uint8_t edatlookup[4][4];
uint32_t textlookup[256][2][16][16];
/*void redotextlookup()
{
int c,d,e;
uint32_t temp;
int coffset=(VGA)?0:64;
for (c=0;c<256;c++)
{
for (d=0;d<16;d++)
{
// printf("ATTR %i=%02X+%02X\n",d,attrregs[d],coffset);
for (e=0;e<16;e++)
{
temp=0;
if (c&0x80) temp|=(attrregs[d]+coffset);
else temp|=(attrregs[e]+coffset);
if (c&0x40) temp|=(attrregs[d]+coffset)<<8;
else temp|=(attrregs[e]+coffset)<<8;
if (c&0x20) temp|=(attrregs[d]+coffset)<<16;
else temp|=(attrregs[e]+coffset)<<16;
if (c&0x10) temp|=(attrregs[d]+coffset)<<24;
else temp|=(attrregs[e]+coffset)<<24;
// if (c==0x5) printf("%08X %i %i %02X %02X\n",temp,d,e,attrregs[d],attrregs[e]);
textlookup[c][0][d][e]=temp;
temp=0;
if (c&0x08) temp|=(attrregs[d]+coffset);
else temp|=(attrregs[e]+coffset);
if (c&0x04) temp|=(attrregs[d]+coffset)<<8;
else temp|=(attrregs[e]+coffset)<<8;
if (c&0x02) temp|=(attrregs[d]+coffset)<<16;
else temp|=(attrregs[e]+coffset)<<16;
if (c&0x01) temp|=(attrregs[d]+coffset)<<24;
else temp|=(attrregs[e]+coffset)<<24;
textlookup[c][1][d][e]=temp;
}
}
}
}*/
void initega()
{
int c,d,e;
bpp=8;
for (c=0;c<256;c++)
{
e=c;
for (d=0;d<8;d++)
{
rotatevga[d][c]=e;
e=(e>>1)|((e&1)?0x80:0);
}
}
crtc[0xC]=crtc[0xD]=0;
for (c=0;c<4;c++)
{
for (d=0;d<4;d++)
{
edatlookup[c][d]=0;
if (c&1) edatlookup[c][d]|=1;
if (d&1) edatlookup[c][d]|=2;
if (c&2) edatlookup[c][d]|=0x10;
if (d&2) edatlookup[c][d]|=0x20;
// printf("Edat %i,%i now %02X\n",c,d,edatlookup[c][d]);
}
}
/*redotextlookup();*/
for (c=0;c<256;c++)
{
pallook64[c]=makecol32(((c>>2)&1)*0xAA,((c>>1)&1)*0xAA,(c&1)*0xAA);
pallook64[c]+=makecol32(((c>>5)&1)*0x55,((c>>4)&1)*0x55,((c>>3)&1)*0x55);
pallook16[c]=makecol32(((c>>2)&1)*0xAA,((c>>1)&1)*0xAA,(c&1)*0xAA);
pallook16[c]+=makecol32(((c>>4)&1)*0x55,((c>>4)&1)*0x55,((c>>4)&1)*0x55);
if ((c&0x17)==6) pallook16[c]=makecol32(0xAA,0x55,0);
// printf("%03i %08X\n",c,pallook[c]);
}
pallook=pallook16;
seqregs[0xC]=0x20;
vrammask=(ET4000)?0xFFFFF:0x1FFFFF;
// writeega_func=writeega;
gdcreg[6]=8;
gdcreg[8]=0xFF;
writemode=0;
chain4=0;
writemask=3;
et4k_b8000=0;
svgarbank=svgawbank=0;
}
uint32_t egabase,egaoffset;
void cacheega()
{
egabase=(crtc[0xC]<<8)|crtc[0xD];
if (ET4000 || ET4000W32 || TRIDENT)
egabase|=((crtc[0x33]&3)<<18);
// printf("EGABASE %05X\n",egabase);
// egaoffset=8-((attrregs[0x13])&7);
// printf("Cache base!\n");
}
void cacheega2()
{
// egabase=(crtc[0xC]<<8)|crtc[0xD];
if (gdcreg[5]&0x40) egaoffset=8-(((attrregs[0x13])&7)>>1);
else egaoffset=8-((attrregs[0x13])&7);
// printf("Cache offset!\n");
}
int olddisplines,oldxsize;
int oldreadflash;
int oldegaaddr,oldegasplit;
int vc,sc;
int egadispon=0;
int linepos;
int displine;
uint32_t ma,maback,ca;
int firstline,lastline;
int xsize,ysize;
int scrollcache;
int con,cursoron,cgablink;
BITMAP *buffer,*vbuf,*buffer32;
int linecountff=0;
void dumpegaregs()
{
int c;
printf("CRTC :");
for (c=0;c<0x20;c++) printf(" %02X",crtc[c]);
printf("\n");
printf(" EXT :");
for (c=0;c<0x20;c++) printf(" %02X",crtc[c+32]);
printf("\n");
printf(" EXT2:");
for (c=0;c<0x20;c++) printf(" %02X",crtc[c+64]);
printf("\n");
printf("SEQ :");
for (c=0;c<0x10;c++) printf(" %02X",seqregs[c]);
printf("\n");
printf(" EXT :");
for (c=0;c<0x10;c++) printf(" %02X",seqregs[c + 0x10]);
printf("\n");
printf("ATTR :");
for (c=0;c<0x20;c++) printf(" %02X",attrregs[c]);
printf("\n");
printf("GDC :");
for (c=0;c<0x10;c++) printf(" %02X",gdcreg[c]);
printf("\n");
// printf("OLD CTRL2 = %02X NEW CTRL2 = %02X DAC = %02X 3C2 = %02X\n",tridentoldctrl2,tridentnewctrl2,tridentdac,ega3c2);
printf("BPP = %02X\n",bpp);
}
int oddeven;
int wx,wy;
int vslines;
int frames = 0;
void doblit()
{
startblit();
if ((wx!=xsize || wy!=ysize) && !vid_resize)
{
xsize=wx;
ysize=wy+1;
if (xsize<64) xsize=656;
if (ysize<32) ysize=200;
if (vres) updatewindowsize(xsize,ysize<<1);
else updatewindowsize(xsize,ysize);
}
video_blit_memtoscreen(32, 0, 0, ysize, xsize, ysize);
if (readflash) rectfill(screen,winsizex-40,8,winsizex-8,14,0xFFFFFFFF);
endblit();
frames++;
}
int ega_getdepth()
{
if (!(gdcreg[6]&1)) return 0;
switch (gdcreg[5]&0x60)
{
case 0x00:
return 4;
case 0x20:
return 2;
case 0x40: case 0x60:
if (TRIDENT || ET4000W32) return bpp;
return 8;
}
return 0;
}
int ega_getx()
{
int x;
if (!(gdcreg[6]&1)) return (crtc[1]+1);
if ((attrregs[0x10]&0x40) && !(tridentoldctrl2&0x10)) x=(crtc[1]+1)*4;
else x=(crtc[1]+1)*8;
if (TRIDENT && (bpp==15 || bpp==16)) x>>=1;
if (TRIDENT && bpp==24) x=(x<<1)/3;
return x;
}
int ega_gety()
{
if (crtc[0x1E]&4) return (ega_dispend/((crtc[9]&31)+1))<<1;
if (crtc[9]&0x80) return (ega_dispend/((crtc[9]&31)+1))>>1;
return ega_dispend/((crtc[9]&31)+1);
}