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
This commit is contained in:
TomW 2013-05-27 17:46:42 +01:00
commit 9312de19ac
87 changed files with 4528 additions and 9373 deletions

View file

@ -1,9 +1,14 @@
/*Generic SVGA handling*/
/*This is intended to be used by another SVGA driver, and not as a card in it's own right*/
#include "ibm.h"
#include "mem.h"
#include "video.h"
#include "vid_svga.h"
#include "vid_svga_render.h"
#include "io.h"
#include "timer.h"
#define svga_output 0
uint32_t svga_vram_limit;
@ -11,15 +16,19 @@ extern uint8_t edatlookup[4][4];
uint8_t svga_miscout;
static uint8_t la, lb, lc, ld;
static uint8_t svga_rotate[8][256];
uint8_t svga_rotate[8][256];
static int svga_fast;
void svga_out(uint16_t addr, uint8_t val)
void (*svga_render)();
static uint8_t dacmask, dacstatus;
void svga_out(uint16_t addr, uint8_t val, void *priv)
{
int c;
uint8_t o;
//printf("OUT SVGA %03X %02X %04X:%04X %i %08X\n",addr,val,CS,pc,TRIDENT,svgawbank);
// printf("OUT SVGA %03X %02X %04X:%04X %i %08X\n",addr,val,CS,pc,TRIDENT,svgawbank);
switch (addr)
{
case 0x3C0:
@ -45,10 +54,16 @@ void svga_out(uint16_t addr, uint8_t val)
svga_miscout = val;
vres = 0; pallook = pallook256;
vidclock = val & 4; printf("3C2 write %02X\n",val);
if (val&1)
io_sethandler(0x03a0, 0x0020, video_in, NULL, NULL, video_out, NULL, NULL);
if (val & 1)
{
pclog("Remove mono handler\n");
io_removehandler(0x03a0, 0x0020, video_in, NULL, NULL, video_out, NULL, NULL, NULL);
}
else
io_sethandler(0x03a0, 0x0020, video_in_null, NULL, NULL, video_out_null, NULL, NULL);
{
pclog("Set mono handler\n");
io_sethandler(0x03a0, 0x0020, video_in, NULL, NULL, video_out, NULL, NULL, NULL);
}
break;
case 0x3C4: seqaddr=val; break;
case 0x3C5:
@ -58,7 +73,12 @@ void svga_out(uint16_t addr, uint8_t val)
if (o!=val && (seqaddr&0xF)==1) svga_recalctimings();
switch (seqaddr&0xF)
{
case 1: if (scrblank && !(val&0x20)) fullchange=3; scrblank=(scrblank&~0x20)|(val&0x20); break;
case 1:
if (scrblank && !(val&0x20))
fullchange=3;
scrblank=(scrblank&~0x20)|(val&0x20);
svga_recalctimings();
break;
case 2: writemask=val&0xF; break;
case 3:
charset=val&0xF;
@ -71,9 +91,16 @@ void svga_out(uint16_t addr, uint8_t val)
break;
}
break;
case 0x3c6: dacmask=val; break;
case 0x3C7: dacread=val; dacpos=0; break;
case 0x3C8: dacwrite=val; dacpos=0; break;
case 0x3C9:
dacstatus = 0;
/* if (pc == 0x68AD)
{
dumpregs();
exit(-1);
}*/
palchange=1;
fullchange=changeframecount;
switch (dacpos)
@ -85,6 +112,7 @@ void svga_out(uint16_t addr, uint8_t val)
break;
case 0x3CE: gdcaddr=val; break;
case 0x3CF:
o = gdcreg[gdcaddr & 15];
switch (gdcaddr&15)
{
case 2: colourcompare=val; break;
@ -93,21 +121,21 @@ void svga_out(uint16_t addr, uint8_t val)
case 6:
if ((gdcreg[6] & 0xc) != (val & 0xc))
{
mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
// pclog("Write mapping %02X\n", val);
mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
pclog("Write mapping %02X\n", val);
switch (val&0xC)
{
case 0x0: /*128k at A0000*/
mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
break;
case 0x4: /*64k at A0000*/
mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
break;
case 0x8: /*32k at B0000*/
mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
break;
case 0xC: /*32k at B8000*/
mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
break;
}
}
@ -116,11 +144,13 @@ void svga_out(uint16_t addr, uint8_t val)
}
gdcreg[gdcaddr&15]=val;
svga_fast = (gdcreg[8]==0xFF && !(gdcreg[3]&0x18) && !gdcreg[1]) && chain4;
if (((gdcaddr & 15) == 5 && (val ^ o) & 0x70) || ((gdcaddr & 15) == 6 && (val ^ o) & 1))
svga_recalctimings();
break;
}
}
uint8_t svga_in(uint16_t addr)
uint8_t svga_in(uint16_t addr, void *priv)
{
uint8_t temp;
// if (addr!=0x3da) pclog("Read port %04X\n",addr);
@ -128,12 +158,20 @@ uint8_t svga_in(uint16_t addr)
{
case 0x3C0: return attraddr;
case 0x3C1: return attrregs[attraddr];
case 0x3C2: return 0x10;
case 0x3c2:
if ((vgapal[0].r + vgapal[0].g + vgapal[0].b) >= 0x50)
temp = 0;
else
temp = 0x10;
return temp;
case 0x3C4: return seqaddr;
case 0x3C5:
return seqregs[seqaddr&0xF];
case 0x3c6: return dacmask;
case 0x3c7: return dacstatus;
case 0x3C8: return dacwrite;
case 0x3C9:
dacstatus=3;
palchange=1;
switch (dacpos)
{
@ -156,8 +194,9 @@ uint8_t svga_in(uint16_t addr)
}
int svga_vtotal, svga_dispend, svga_vsyncstart, svga_split;
int svga_hdisp, svga_htotal, svga_rowoffset;
int svga_hdisp, svga_htotal, svga_hdisp_time, svga_rowoffset;
int svga_lowres, svga_interlace;
int svga_linedbl, svga_rowcount;
double svga_clock;
uint32_t svga_ma;
void (*svga_recalctimings_ex)() = NULL;
@ -166,7 +205,8 @@ void (*svga_hwcursor_draw)(int displine) = NULL;
void svga_recalctimings()
{
double crtcconst;
int temp;
double _dispontime, _dispofftime;
svga_vtotal=crtc[6];
svga_dispend=crtc[0x12];
svga_vsyncstart=crtc[0x10];
@ -204,32 +244,131 @@ void svga_recalctimings()
svga_interlace = 0;
svga_ma = (crtc[0xC]<<8)|crtc[0xD];
svga_hdisp_time = svga_hdisp;
svga_render = svga_render_blank;
if (!scrblank)
{
if (!(gdcreg[6]&1)) /*Text mode*/
{
if (seqregs[1]&8) /*40 column*/
{
svga_render = svga_render_text_40;
svga_hdisp *= (seqregs[1] & 1) ? 16 : 18;
}
else
{
svga_render = svga_render_text_80;
svga_hdisp *= (seqregs[1] & 1) ? 8 : 9;
}
}
else
{
svga_hdisp *= (seqregs[1] & 8) ? 16 : 8;
switch (gdcreg[5]&0x60)
{
case 0x00: /*16 colours*/
if (seqregs[1]&8) /*Low res (320)*/
svga_render = svga_render_4bpp_lowres;
else
svga_render = svga_render_4bpp_highres;
break;
case 0x20: /*4 colours*/
svga_render = svga_render_2bpp_lowres;
break;
case 0x40: case 0x60: /*256+ colours*/
switch (bpp)
{
case 8:
if (svga_lowres)
svga_render = svga_render_8bpp_lowres;
else
{
svga_render = svga_render_8bpp_highres;
// svga_hdisp <<= 1;
}
break;
case 15:
if (svga_lowres)
svga_render = svga_render_15bpp_lowres;
else
{
svga_render = svga_render_15bpp_highres;
svga_hdisp <<= 1;
}
break;
case 16:
if (svga_lowres)
svga_render = svga_render_16bpp_lowres;
else
{
svga_render = svga_render_16bpp_highres;
svga_hdisp <<= 1;
}
break;
case 24:
if (svga_lowres)
{
svga_render = svga_render_24bpp_lowres;
svga_hdisp = ((svga_hdisp<<3)/3);
}
else
{
svga_render = svga_render_24bpp_highres;
svga_hdisp = ((svga_hdisp<<3)/3);
}
break;
case 32:
if (svga_lowres)
svga_render = svga_render_32bpp_lowres;
else
{
svga_render = svga_render_32bpp_highres;
svga_hdisp <<= 1;
}
break;
}
break;
}
}
}
// pclog("svga_render %08X : %08X %08X %08X %08X %08X %i %i %02X %i %i\n", svga_render, svga_render_text_40, svga_render_text_80, svga_render_8bpp_lowres, svga_render_8bpp_highres, svga_render_blank, scrblank,gdcreg[6]&1,gdcreg[5]&0x60,bpp,seqregs[1]&8);
svga_linedbl = crtc[9] & 0x80;
svga_rowcount = crtc[9] & 31;
if (svga_recalctimings_ex) svga_recalctimings_ex();
crtcconst=(seqregs[1]&1)?(svga_clock*8.0):(svga_clock*9.0);
disptime =svga_htotal;
dispontime=svga_hdisp;
_dispontime = svga_hdisp_time;
// printf("Disptime %f dispontime %f hdisp %i\n",disptime,dispontime,crtc[1]*8);
if (seqregs[1]&8) { disptime*=2; dispontime*=2; }
dispofftime=disptime-dispontime;
dispontime*=crtcconst;
dispofftime*=crtcconst;
if (seqregs[1]&8) { disptime*=2; _dispontime*=2; }
_dispofftime=disptime-_dispontime;
_dispontime*=crtcconst;
_dispofftime*=crtcconst;
dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
// printf("SVGA horiz total %i display end %i clock rate %i vidclock %i %i\n",crtc[0],crtc[1],egaswitchread,vidclock,((ega3c2>>2)&3) | ((tridentnewctrl2<<2)&4));
// printf("SVGA vert total %i display end %i max row %i vsync %i\n",svga_vtotal,svga_dispend,(crtc[9]&31)+1,svga_vsyncstart);
// printf("total %f on %f cycles off %f cycles frame %f sec %f %02X\n",disptime*crtcconst,dispontime,dispofftime,(dispontime+dispofftime)*svga_vtotal,(dispontime+dispofftime)*svga_vtotal*70,seqregs[1]);
// pclog("svga_render %08X\n", svga_render);
}
void (*svga_render)();
static uint32_t ma,maback,ca;
static int vc,sc;
static int linepos, displine, vslines, linecountff, oddeven;
uint32_t ma, maback, ca;
static int vc;
int sc;
static int linepos, vslines, linecountff, oddeven;
static int svga_dispon;
static int con, coff, cursoron, cgablink;
static int scrollcache;
int con, coff, cursoron, cgablink;
int scrollcache;
int svga_hwcursor_on;
@ -237,17 +376,13 @@ SVGA_HWCURSOR svga_hwcursor, svga_hwcursor_latch;
int svga_hdisp_on;
static int firstline_draw = 2000, lastline_draw = 0;
int firstline_draw = 2000, lastline_draw = 0;
int displine;
void svga_poll()
{
uint8_t chr,dat,attr;
uint32_t charaddr;
int x,xx;
uint32_t fg,bg;
int offset;
uint8_t edat[4];
int drawcursor=0;
int x;
if (!linepos)
{
// if (!(vc & 15)) pclog("VC %i %i\n", vc, GetTickCount());
@ -264,305 +399,17 @@ void svga_poll()
ma&=vrammask;
if (firstline==2000) firstline=displine;
if (scrblank)
{
if (firstline_draw == 2000) firstline_draw = displine;
lastline_draw = displine;
for (x=0;x<svga_hdisp;x++)
{
switch (seqregs[1]&9)
{
case 0:
for (xx=0;xx<9;xx++) ((uint32_t *)buffer32->line[displine])[(x*9)+xx+32]=0;
break;
case 1:
for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[(x*8)+xx+32]=0;
break;
case 8:
for (xx=0;xx<18;xx++) ((uint32_t *)buffer32->line[displine])[(x*18)+xx+32]=0;
break;
case 9:
for (xx=0;xx<16;xx++) ((uint32_t *)buffer32->line[displine])[(x*16)+xx+32]=0;
break;
}
}
}
else if (!(gdcreg[6]&1)) /*Text mode*/
{
if (firstline_draw == 2000) firstline_draw = displine;
lastline_draw = displine;
if (fullchange)
{
for (x=0;x<svga_hdisp;x++)
{
drawcursor=((ma==ca) && con && cursoron);
chr=vram[(ma<<1)];
attr=vram[(ma<<1)+4];
if (attr&8) charaddr=charsetb+(chr*128);
else charaddr=charseta+(chr*128);
if (drawcursor) { bg=pallook[egapal[attr&15]]; fg=pallook[egapal[attr>>4]]; }
else
{
fg=pallook[egapal[attr&15]];
bg=pallook[egapal[attr>>4]];
if (attr&0x80 && attrregs[0x10]&8)
{
bg=pallook[egapal[(attr>>4)&7]];
if (cgablink&16) fg=bg;
}
}
dat=vram[charaddr+(sc<<2)];
if (seqregs[1]&8) /*40 column*/
{
if (seqregs[1]&1) { for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[((x<<4)+32+(xx<<1))&2047]=((uint32_t *)buffer32->line[displine])[((x<<4)+33+(xx<<1))&2047]=(dat&(0x80>>xx))?fg:bg; }
else
{
for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[((x*18)+32+(xx<<1))&2047]=((uint32_t *)buffer32->line[displine])[((x*18)+33+(xx<<1))&2047]=(dat&(0x80>>xx))?fg:bg;
if ((chr&~0x1F)!=0xC0 || !(attrregs[0x10]&4)) ((uint32_t *)buffer32->line[displine])[((x*18)+32+16)&2047]=((uint32_t *)buffer32->line[displine])[((x*18)+32+17)&2047]=bg;
else ((uint32_t *)buffer32->line[displine])[((x*18)+32+16)&2047]=((uint32_t *)buffer32->line[displine])[((x*18)+32+17)&2047]=(dat&1)?fg:bg;
}
}
else /*80 column*/
{
if (seqregs[1]&1) { for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[((x<<3)+32+xx)&2047]=(dat&(0x80>>xx))?fg:bg; }
else
{
for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[((x*9)+32+xx)&2047]=(dat&(0x80>>xx))?fg:bg;
if ((chr&~0x1F)!=0xC0 || !(attrregs[0x10]&4)) ((uint32_t *)buffer32->line[displine])[((x*9)+32+8)&2047]=bg;
else ((uint32_t *)buffer32->line[displine])[((x*9)+32+8)&2047]=(dat&1)?fg:bg;
}
}
ma+=4; ma&=vrammask;
}
}
}
else
{
// if (hwcursor_on) changedvram[ma>>10]=changedvram[(ma>>10)+1]=2;
switch (gdcreg[5]&0x60)
{
case 0x00: /*16 colours*/
if (firstline_draw == 2000) firstline_draw = displine;
lastline_draw = displine;
if (seqregs[1]&8) /*Low res (320)*/
{
offset=((8-scrollcache)<<1)+16;
for (x=0;x<=svga_hdisp;x++)
{
edat[0]=vram[ma];
edat[1]=vram[ma|0x1];
edat[2]=vram[ma|0x2];
edat[3]=vram[ma|0x3];
ma+=4; ma&=vrammask;
dat=edatlookup[edat[0]&3][edat[1]&3]|(edatlookup[edat[2]&3][edat[3]&3]<<2);
((uint32_t *)buffer32->line[displine])[(x<<4)+14+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+15+offset]=pallook[egapal[dat&0xF]];
((uint32_t *)buffer32->line[displine])[(x<<4)+12+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+13+offset]=pallook[egapal[dat>>4]];
dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2);
((uint32_t *)buffer32->line[displine])[(x<<4)+10+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+11+offset]=pallook[egapal[dat&0xF]];
((uint32_t *)buffer32->line[displine])[(x<<4)+8+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+9+offset]=pallook[egapal[dat>>4]];
dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2);
((uint32_t *)buffer32->line[displine])[(x<<4)+6+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+7+offset]=pallook[egapal[dat&0xF]];
((uint32_t *)buffer32->line[displine])[(x<<4)+4+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+5+offset]=pallook[egapal[dat>>4]];
dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2);
((uint32_t *)buffer32->line[displine])[(x<<4)+2+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+3+offset]=pallook[egapal[dat&0xF]];
((uint32_t *)buffer32->line[displine])[(x<<4)+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+1+offset]=pallook[egapal[dat>>4]];
}
}
else /*High res (640)*/
{
offset=(8-scrollcache)+24;
for (x=0;x<=svga_hdisp;x++)
{
edat[0]=vram[ma];
edat[1]=vram[ma|0x1];
edat[2]=vram[ma|0x2];
edat[3]=vram[ma|0x3];
ma+=4; ma&=vrammask;
dat=edatlookup[edat[0]&3][edat[1]&3]|(edatlookup[edat[2]&3][edat[3]&3]<<2);
((uint32_t *)buffer32->line[displine])[(x<<3)+7+offset]=pallook[egapal[dat&0xF]];
((uint32_t *)buffer32->line[displine])[(x<<3)+6+offset]=pallook[egapal[dat>>4]];
dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2);
((uint32_t *)buffer32->line[displine])[(x<<3)+5+offset]=pallook[egapal[dat&0xF]];
((uint32_t *)buffer32->line[displine])[(x<<3)+4+offset]=pallook[egapal[dat>>4]];
dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2);
((uint32_t *)buffer32->line[displine])[(x<<3)+3+offset]=pallook[egapal[dat&0xF]];
((uint32_t *)buffer32->line[displine])[(x<<3)+2+offset]=pallook[egapal[dat>>4]];
dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2);
((uint32_t *)buffer32->line[displine])[(x<<3)+1+offset]=pallook[egapal[dat&0xF]];
((uint32_t *)buffer32->line[displine])[(x<<3)+offset]= pallook[egapal[dat>>4]];
}
}
break;
case 0x20: /*4 colours*/
if (firstline_draw == 2000) firstline_draw = displine;
lastline_draw = displine;
offset=((8-scrollcache)<<1)+16;
/*Low res (320) only, though high res (640) should be possible*/
for (x=0;x<=svga_hdisp;x++)
{
if (sc&1 && !(crtc[0x17]&1))
{
edat[0]=vram[(ma<<1)+0x8000];
edat[1]=vram[(ma<<1)+0x8004];
}
else
{
edat[0]=vram[(ma<<1)];
edat[1]=vram[(ma<<1)+4];
}
ma+=4; ma&=vrammask;
((uint32_t *)buffer32->line[displine])[(x<<4)+14+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+15+offset]=pallook[egapal[edat[1]&3]];
((uint32_t *)buffer32->line[displine])[(x<<4)+12+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+13+offset]=pallook[egapal[(edat[1]>>2)&3]];
dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2);
((uint32_t *)buffer32->line[displine])[(x<<4)+10+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+11+offset]=pallook[egapal[(edat[1]>>4)&3]];
((uint32_t *)buffer32->line[displine])[(x<<4)+8+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+9+offset]=pallook[egapal[(edat[1]>>6)&3]];
dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2);
((uint32_t *)buffer32->line[displine])[(x<<4)+6+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+7+offset]=pallook[egapal[(edat[0]>>0)&3]];
((uint32_t *)buffer32->line[displine])[(x<<4)+4+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+5+offset]=pallook[egapal[(edat[0]>>2)&3]];
dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2);
((uint32_t *)buffer32->line[displine])[(x<<4)+2+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+3+offset]=pallook[egapal[(edat[0]>>4)&3]];
((uint32_t *)buffer32->line[displine])[(x<<4)+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+1+offset]=pallook[egapal[(edat[0]>>6)&3]];
}
break;
case 0x40: case 0x60: /*256 colours (and more, with high/true colour RAMDAC)*/
if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
{
if (firstline_draw == 2000) firstline_draw = displine;
lastline_draw = displine;
if (svga_lowres) /*Low res (320)*/
{
// if (!displine) pclog("Lo res %i %i %i\n",bpp,svga_hdisp,(svga_hdisp<<3)/3);
offset=(8-(scrollcache&6))+24;
if (bpp==8) /*Regular 8 bpp palette mode*/
{
for (x=0;x<=svga_hdisp;x++)
{
edat[0]=vram[ma];
edat[1]=vram[ma|0x1];
edat[2]=vram[ma|0x2];
edat[3]=vram[ma|0x3];
ma+=4; ma&=vrammask;
((uint32_t *)buffer32->line[displine])[(x<<3)+6+offset]= ((uint32_t *)buffer32->line[displine])[(x<<3)+7+offset]=pallook[edat[3]];
((uint32_t *)buffer32->line[displine])[(x<<3)+4+offset]= ((uint32_t *)buffer32->line[displine])[(x<<3)+5+offset]=pallook[edat[2]];
((uint32_t *)buffer32->line[displine])[(x<<3)+2+offset]= ((uint32_t *)buffer32->line[displine])[(x<<3)+3+offset]=pallook[edat[1]];
((uint32_t *)buffer32->line[displine])[(x<<3)+offset]= ((uint32_t *)buffer32->line[displine])[(x<<3)+1+offset]=pallook[edat[0]];
}
}
else if (bpp==16) /*16 bpp 565 mode*/
{
for (x=0;x<=svga_hdisp;x++)
{
fg=vram[ma]|(vram[ma|0x1]<<8);
bg=vram[ma|0x2]|(vram[ma|0x3]<<8);
ma+=4; ma&=vrammask;
((uint32_t *)buffer32->line[displine])[(x<<2)+2+offset]=((uint32_t *)buffer32->line[displine])[(x<<2)+3+offset]=((bg&31)<<3)|(((bg>>5)&63)<<10)|(((bg>>11)&31)<<19);
((uint32_t *)buffer32->line[displine])[(x<<2)+0+offset]=((uint32_t *)buffer32->line[displine])[(x<<2)+1+offset]=((fg&31)<<3)|(((fg>>5)&63)<<10)|(((fg>>11)&31)<<19);
}
}
else if (bpp==15) /*15 bpp 555 mode*/
{
for (x=0;x<=svga_hdisp;x++)
{
fg=vram[ma]|(vram[ma|0x1]<<8);
bg=vram[ma|0x2]|(vram[ma|0x3]<<8);
ma+=4; ma&=vrammask;
((uint32_t *)buffer32->line[displine])[(x<<1)+2+offset]=((uint32_t *)buffer32->line[displine])[(x<<2)+3+offset]=((bg&31)<<3)|(((bg>>5)&31)<<11)|(((bg>>10)&31)<<19);
((uint32_t *)buffer32->line[displine])[(x<<1)+0+offset]=((uint32_t *)buffer32->line[displine])[(x<<2)+1+offset]=((fg&31)<<3)|(((fg>>5)&31)<<11)|(((fg>>10)&31)<<19);
}
}
else if (bpp==24) /*24 bpp 888 mode*/
{
for (x=0;x<=((svga_hdisp<<3)/3);x++)
{
fg=vram[ma]|(vram[ma+1]<<8)|(vram[ma+2]<<16);
ma+=3; ma&=vrammask;
((uint32_t *)buffer32->line[displine])[(x<<1)+offset]=((uint32_t *)buffer32->line[displine])[(x<<1)+1+offset]=fg;
}
}
else if (bpp==32) /*32 bpp 8888 mode*/
{
for (x = 0; x <= svga_hdisp; x++)
{
fg = vram[ma] | (vram[ma + 1] << 8) | (vram[ma + 2] << 16);
ma += 4; ma &= vrammask;
((uint32_t *)buffer32->line[displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[displine])[(x << 1) + 1 + offset] = fg;
}
}
}
else /*High res (SVGA only)*/
{
// if (!displine) pclog("Hi res %i %i %i\n",bpp,svga_hdisp,(svga_hdisp<<3)/3);
offset=(8-((scrollcache&6)>>1))+24;
if (bpp==8)
{
for (x=0;x<=(svga_hdisp<<1);x++)
{
edat[0]=vram[ma];
edat[1]=vram[ma|0x1];
edat[2]=vram[ma|0x2];
edat[3]=vram[ma|0x3];
ma+=4; ma&=vrammask;
((uint32_t *)buffer32->line[displine])[(x<<2)+3+offset]=pallook[edat[3]];
((uint32_t *)buffer32->line[displine])[(x<<2)+2+offset]=pallook[edat[2]];
((uint32_t *)buffer32->line[displine])[(x<<2)+1+offset]=pallook[edat[1]];
((uint32_t *)buffer32->line[displine])[(x<<2)+offset]= pallook[edat[0]];
}
}
else if (bpp==16)
{
for (x=0;x<=(svga_hdisp<<1);x++)
{
fg=vram[ma]|(vram[ma|0x1]<<8);
bg=vram[ma|0x2]|(vram[ma|0x3]<<8);
ma+=4; ma&=vrammask;
((uint32_t *)buffer32->line[displine])[(x<<1)+1+offset]=((bg&31)<<3)|(((bg>>5)&63)<<10)|(((bg>>11)&31)<<19);
((uint32_t *)buffer32->line[displine])[(x<<1)+0+offset]=((fg&31)<<3)|(((fg>>5)&63)<<10)|(((fg>>11)&31)<<19);
}
}
else if (bpp==15)
{
for (x=0;x<=(svga_hdisp<<1);x++)
{
fg=vram[ma]|(vram[ma|0x1]<<8);
bg=vram[ma|0x2]|(vram[ma|0x3]<<8);
ma+=4; ma&=vrammask;
((uint32_t *)buffer32->line[displine])[(x<<1)+1+offset]=((bg&31)<<3)|(((bg>>5)&31)<<11)|(((bg>>10)&31)<<19);
((uint32_t *)buffer32->line[displine])[(x<<1)+0+offset]=((fg&31)<<3)|(((fg>>5)&31)<<11)|(((fg>>10)&31)<<19);
}
}
else if (bpp==24)
{
for (x=0;x<=((svga_hdisp<<3)/3);x++)
{
fg=vram[ma]|(vram[ma+1]<<8)|(vram[ma+2]<<16);
ma+=3; ma&=vrammask;
((uint32_t *)buffer32->line[displine])[x+offset]=fg;
}
}
else if (bpp==32)
{
for (x = 0; x <= (svga_hdisp<<2); x++)
{
fg = vram[ma] | (vram[ma + 1] << 8) | (vram[ma + 2] << 16);
ma += 4; ma &= vrammask;
((uint32_t *)buffer32->line[displine])[x + offset] = fg;
}
}
}
}
break;
}
if (svga_hwcursor_on) changedvram[ma >> 10] = changedvram[(ma >> 10) + 1] = 2;
svga_render();
if (svga_hwcursor_on)
{
svga_hwcursor_draw(displine);
svga_hwcursor_on--;
}
}
if (lastline<displine) lastline=displine;
}
@ -592,12 +439,12 @@ void svga_poll()
if (sc==(crtc[11]&31)) con = 0;
if (svga_dispon)
{
if ((crtc[9]&0x80) && !linecountff)
if (svga_linedbl && !linecountff)
{
linecountff=1;
ma=maback;
}
else if (sc==(crtc[9]&31))
else if (sc == svga_rowcount)
{
linecountff=0;
sc=0;
@ -642,11 +489,11 @@ void svga_poll()
// pclog("VC vsync %i %i\n", firstline_draw, lastline_draw);
svga_dispon=0;
cgastat|=8;
if (seqregs[1]&8) x=svga_hdisp*((seqregs[1]&1)?8:9)*2;
else x=svga_hdisp*((seqregs[1]&1)?8:9);
/*if (seqregs[1]&8) x=(svga_hdisp*((seqregs[1]&1)?8:9))*2;
else */x = svga_hdisp;//*((seqregs[1]&1)?8:9);
if (bpp == 16 || bpp == 15) x /= 2;
if (bpp == 24) x /= 3;
// if (bpp == 24) x /= 3;
if (bpp == 32) x /= 4;
if (svga_interlace && !oddeven) lastline++;
if (svga_interlace && oddeven) firstline--;
@ -704,7 +551,7 @@ void svga_poll()
case 0x40: case 0x60: video_bpp = bpp; break;
}
}
video_bpp = bpp;
// if (svga_interlace && oddeven) ma=maback=ma+(svga_rowoffset<<2);
// pclog("Addr %08X vson %03X vsoff %01X %02X %02X %02X %i %i\n",ma,svga_vsyncstart,crtc[0x11]&0xF,crtc[0xD],crtc[0xC],crtc[0x33], svga_interlace, oddeven);
@ -751,20 +598,17 @@ int svga_init()
#define egacycles 1
#define egacycles2 1
void svga_write(uint32_t addr, uint8_t val)
void svga_write(uint32_t addr, uint8_t val, void *priv)
{
int x,y;
char s[2]={0,0};
uint8_t vala,valb,valc,vald,wm=writemask;
int writemask2 = writemask;
int bankaddr;
egawrites++;
cycles -= video_timing_b;
cycles_lost += video_timing_b;
// pclog("Writeega %06X ",addr);
if (svga_output) pclog("Writeega %06X ",addr);
if (addr>=0xB0000) addr&=0x7FFF;
else
{
@ -783,8 +627,8 @@ void svga_write(uint32_t addr, uint8_t val)
{
addr<<=2;
}
// pclog("%08X %02X %i %i %i\n", addr, val, writemask2, writemode, chain4);
addr&=0x7FFFFF;
if (svga_output) pclog("%08X (%i, %i) %02X %i %i %i\n", addr, addr & 1023, addr >> 10, val, writemask2, writemode, chain4);
changedvram[addr>>10]=changeframecount;
switch (writemode)
@ -929,10 +773,9 @@ void svga_write(uint32_t addr, uint8_t val)
}
}
uint8_t svga_read(uint32_t addr)
uint8_t svga_read(uint32_t addr, void *priv)
{
uint8_t temp,temp2,temp3,temp4;
uint32_t addr2;
cycles -= video_timing_b;
cycles_lost += video_timing_b;
@ -985,20 +828,17 @@ uint8_t svga_read(uint32_t addr)
return vram[addr|readplane];
}
void svga_write_linear(uint32_t addr, uint8_t val)
void svga_write_linear(uint32_t addr, uint8_t val, void *priv)
{
int x,y;
char s[2]={0,0};
uint8_t vala,valb,valc,vald,wm=writemask;
int writemask2 = writemask;
int bankaddr;
cycles -= video_timing_b;
cycles_lost += video_timing_b;
egawrites++;
// pclog("Write LFB %08X %02X ", addr, val);
if (svga_output) pclog("Write LFB %08X %02X ", addr, val);
if (!(gdcreg[6]&1)) fullchange=2;
if (chain4)
{
@ -1010,7 +850,7 @@ void svga_write_linear(uint32_t addr, uint8_t val)
addr<<=2;
}
addr &= 0x7fffff;
// pclog("%08X\n", addr);
if (svga_output) pclog("%08X\n", addr);
changedvram[addr>>10]=changeframecount;
switch (writemode)
@ -1155,7 +995,7 @@ void svga_write_linear(uint32_t addr, uint8_t val)
}
}
uint8_t svga_read_linear(uint32_t addr)
uint8_t svga_read_linear(uint32_t addr, void *priv)
{
uint8_t temp,temp2,temp3,temp4;
@ -1220,8 +1060,16 @@ void svga_doblit(int y1, int y2)
ysize=wy+1;
if (xsize<64) xsize=656;
if (ysize<32) ysize=200;
if (vres) updatewindowsize(xsize,ysize<<1);
else updatewindowsize(xsize,ysize);
/* if (bpp > 8)
{
if (vres) updatewindowsize(xsize<<1,ysize<<1);
else updatewindowsize(xsize<<1,ysize);
}
else
{*/
if (vres) updatewindowsize(xsize,ysize<<1);
else updatewindowsize(xsize,ysize);
// }
}
if (vid_resize)
{
@ -1234,12 +1082,12 @@ void svga_doblit(int y1, int y2)
}
void svga_writew(uint32_t addr, uint16_t val)
void svga_writew(uint32_t addr, uint16_t val, void *priv)
{
if (!svga_fast)
{
svga_write(addr, val);
svga_write(addr + 1, val >> 8);
svga_write(addr, val, priv);
svga_write(addr + 1, val >> 8, priv);
return;
}
@ -1248,22 +1096,22 @@ void svga_writew(uint32_t addr, uint16_t val)
cycles -= video_timing_w;
cycles_lost += video_timing_w;
// pclog("Writew %05X ", addr);
if (svga_output) pclog("Writew %05X ", addr);
addr = (addr & 0xffff) + svgawbank;
addr &= 0x7FFFFF;
// pclog("%08X %04X\n", addr, val);
if (svga_output) pclog("%08X (%i, %i) %04X\n", addr, addr & 1023, addr >> 10, val);
changedvram[addr >> 10] = changeframecount;
*(uint16_t *)&vram[addr] = val;
}
void svga_writel(uint32_t addr, uint32_t val)
void svga_writel(uint32_t addr, uint32_t val, void *priv)
{
if (!svga_fast)
{
svga_write(addr, val);
svga_write(addr + 1, val >> 8);
svga_write(addr + 2, val >> 16);
svga_write(addr + 3, val >> 24);
svga_write(addr, val, priv);
svga_write(addr + 1, val >> 8, priv);
svga_write(addr + 2, val >> 16, priv);
svga_write(addr + 3, val >> 24, priv);
return;
}
@ -1272,19 +1120,19 @@ void svga_writel(uint32_t addr, uint32_t val)
cycles -= video_timing_l;
cycles_lost += video_timing_l;
// pclog("Writel %05X ", addr);
if (svga_output) pclog("Writel %05X ", addr);
addr = (addr & 0xffff) + svgawbank;
addr &= 0x7FFFFF;
// pclog("%08X %08X\n", addr, val);
if (svga_output) pclog("%08X (%i, %i) %08X\n", addr, addr & 1023, addr >> 10, val);
changedvram[addr >> 10] = changeframecount;
*(uint32_t *)&vram[addr] = val;
}
uint16_t svga_readw(uint32_t addr)
uint16_t svga_readw(uint32_t addr, void *priv)
{
if (!svga_fast)
return svga_read(addr) | (svga_read(addr + 1) << 8);
return svga_read(addr, priv) | (svga_read(addr + 1, priv) << 8);
egareads += 2;
@ -1300,10 +1148,10 @@ uint16_t svga_readw(uint32_t addr)
return *(uint16_t *)&vram[addr];
}
uint32_t svga_readl(uint32_t addr)
uint32_t svga_readl(uint32_t addr, void *priv)
{
if (!svga_fast)
return svga_read(addr) | (svga_read(addr + 1) << 8) | (svga_read(addr + 2) << 16) | (svga_read(addr + 3) << 24);
return svga_read(addr, priv) | (svga_read(addr + 1, priv) << 8) | (svga_read(addr + 2, priv) << 16) | (svga_read(addr + 3, priv) << 24);
egareads += 4;
@ -1319,12 +1167,12 @@ uint32_t svga_readl(uint32_t addr)
return *(uint32_t *)&vram[addr];
}
void svga_writew_linear(uint32_t addr, uint16_t val)
void svga_writew_linear(uint32_t addr, uint16_t val, void *priv)
{
if (!svga_fast)
{
svga_write_linear(addr, val);
svga_write_linear(addr + 1, val >> 8);
svga_write_linear(addr, val, priv);
svga_write_linear(addr + 1, val >> 8, priv);
return;
}
@ -1333,19 +1181,20 @@ void svga_writew_linear(uint32_t addr, uint16_t val)
cycles -= video_timing_w;
cycles_lost += video_timing_w;
if (svga_output) pclog("Write LFBw %08X %04X\n", addr, val);
addr &= 0x7FFFFF;
changedvram[addr >> 10] = changeframecount;
*(uint16_t *)&vram[addr] = val;
}
void svga_writel_linear(uint32_t addr, uint32_t val)
void svga_writel_linear(uint32_t addr, uint32_t val, void *priv)
{
if (!svga_fast)
{
svga_write_linear(addr, val);
svga_write_linear(addr + 1, val >> 8);
svga_write_linear(addr + 2, val >> 16);
svga_write_linear(addr + 3, val >> 24);
svga_write_linear(addr, val, priv);
svga_write_linear(addr + 1, val >> 8, priv);
svga_write_linear(addr + 2, val >> 16, priv);
svga_write_linear(addr + 3, val >> 24, priv);
return;
}
@ -1354,15 +1203,16 @@ void svga_writel_linear(uint32_t addr, uint32_t val)
cycles -= video_timing_l;
cycles_lost += video_timing_l;
if (svga_output) pclog("Write LFBl %08X %08X\n", addr, val);
addr &= 0x7fffff;
changedvram[addr >> 10] = changeframecount;
*(uint32_t *)&vram[addr] = val;
}
uint16_t svga_readw_linear(uint32_t addr)
uint16_t svga_readw_linear(uint32_t addr, void *priv)
{
if (!svga_fast)
return svga_read_linear(addr) | (svga_read_linear(addr + 1) << 8);
return svga_read_linear(addr, priv) | (svga_read_linear(addr + 1, priv) << 8);
egareads += 2;
@ -1375,10 +1225,10 @@ uint16_t svga_readw_linear(uint32_t addr)
return *(uint16_t *)&vram[addr];
}
uint32_t svga_readl_linear(uint32_t addr)
uint32_t svga_readl_linear(uint32_t addr, void *priv)
{
if (!svga_fast)
return svga_read_linear(addr) | (svga_read_linear(addr + 1) << 8) | (svga_read_linear(addr + 2) << 16) | (svga_read_linear(addr + 3) << 24);
return svga_read_linear(addr, priv) | (svga_read_linear(addr + 1, priv) << 8) | (svga_read_linear(addr + 2, priv) << 16) | (svga_read_linear(addr + 3, priv) << 24);
egareads += 4;