Video optimisations. Fixed VRAM mask on S3.

This commit is contained in:
TomW 2013-07-09 19:30:53 +01:00
commit f431e74917
19 changed files with 372 additions and 234 deletions

View file

@ -812,14 +812,12 @@ static void setsbc16(uint16_t a, uint16_t b)
if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG;
}
int totaldiff = 0;
int current_diff = 0;
void clockhardware()
{
int diff = cycdiff - cycles - current_diff;
current_diff += diff;
totaldiff += diff;
pit.c[0] -= diff;
pit.c[1] -= diff;
if (ppi.pb & 1) pit.c[2] -= diff;

View file

@ -307,7 +307,7 @@ int sreadlnum,swritelnum,segareads,segawrites, scycles_lost;
int serial_fifo_read, serial_fifo_write;
int emu_fps = 0;
extern int totaldiff;
void runpc()
{
char s[200];
@ -350,8 +350,7 @@ void runpc()
if (win_title_update)
{
win_title_update=0;
sprintf(s, "PCem v0.7 - %s - %s - %s - %i%% - %i", model_getname(), models[model].cpu[cpu_manufacturer].cpus[cpu].name, (!mousecapture) ? "Click to capture mouse" : "Press CTRL-END to release mouse", fps, totaldiff);
totaldiff = 0;
sprintf(s, "PCem v0.7 - %s - %s - %s - %i%%", model_getname(), models[model].cpu[cpu_manufacturer].cpus[cpu].name, (!mousecapture) ? "Click to capture mouse" : "Press CTRL-END to release mouse", fps);
set_window_title(s);
}
done++;

View file

@ -63,7 +63,7 @@ void ati18800_out(uint16_t addr, uint8_t val, void *p)
{
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
{
fullchange = changeframecount;
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}

View file

@ -65,7 +65,7 @@ void ati28800_out(uint16_t addr, uint8_t val, void *p)
{
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
{
fullchange = changeframecount;
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}

View file

@ -230,7 +230,7 @@ void mach64_out(uint16_t addr, uint8_t val, void *p)
{
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
{
fullchange = changeframecount;
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}
@ -1151,7 +1151,7 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p)
case 0x14: case 0x15: case 0x16: case 0x17:
WRITE8(addr, mach64->crtc_off_pitch, val);
svga_recalctimings(&mach64->svga);
fullchange = changeframecount;
svga->fullchange = changeframecount;
break;
case 0x18:

View file

@ -143,7 +143,7 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p)
{
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
{
fullchange = changeframecount;
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}
@ -323,7 +323,7 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p)
// if (svga_output) pclog("Write LFB %08X %02X ", addr, val);
if (!(svga->gdcreg[6] & 1))
fullchange = 2;
svga->fullchange = 2;
if (svga->chain4 && (svga->writemode < 4))
{
writemask2 = 1 << (addr & 3);

View file

@ -52,7 +52,7 @@ void et4000_out(uint16_t addr, uint8_t val, void *p)
{
if (svga->crtcreg < 0xE || svga->crtcreg > 0x10)
{
fullchange = changeframecount;
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}

View file

@ -124,7 +124,7 @@ void et4000w32p_out(uint16_t addr, uint8_t val, void *p)
{
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
{
fullchange = changeframecount;
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}

View file

@ -38,7 +38,7 @@ void oti067_out(uint16_t addr, uint8_t val, void *p)
{
if (svga->crtcreg < 0xE || svga->crtcreg > 0x10)
{
fullchange = changeframecount;
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}

View file

@ -121,7 +121,7 @@ void paradise_out(uint16_t addr, uint8_t val, void *p)
{
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
{
fullchange = changeframecount;
svga->fullchange = changeframecount;
svga_recalctimings(&paradise->svga);
}
}

View file

@ -107,7 +107,7 @@ void s3_out(uint16_t addr, uint8_t val, void *p)
{
case 0x31:
s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4);
svga->vrammask = (val & 8) ? 0x3fffff : 0x3ffff;
svga->vrammask = /*(val & 8) ? */0x3fffff/* : 0x3ffff*/;
break;
case 0x50:
@ -134,6 +134,7 @@ void s3_out(uint16_t addr, uint8_t val, void *p)
break;
case 0x51:
s3->bank = (s3->bank & 0x4f) | ((val & 0xc) << 2);
// pclog("CRTC write R51 %02X\n", val);
if (svga->chain4) svga->write_bank = svga->read_bank = s3->bank << 16;
else svga->write_bank = svga->read_bank = s3->bank << 14;
s3->ma_ext = (s3->ma_ext & ~0xc) | ((val & 3) << 2);
@ -189,7 +190,7 @@ void s3_out(uint16_t addr, uint8_t val, void *p)
{
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
{
fullchange = changeframecount;
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}

View file

@ -160,7 +160,7 @@ void s3_virge_out(uint16_t addr, uint8_t val, void *p)
{
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
{
fullchange = changeframecount;
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}

View file

@ -298,7 +298,10 @@ void svga_recalctimings(svga_t *svga)
svga->render = svga_render_4bpp_highres;
break;
case 0x20: /*4 colours*/
if (svga->seqregs[1] & 8) /*Low res (320)*/
svga->render = svga_render_2bpp_lowres;
else
svga->render = svga_render_2bpp_highres;
break;
case 0x40: case 0x60: /*256+ colours*/
switch (svga->bpp)
@ -497,7 +500,7 @@ void svga_poll(void *p)
svga->fullchange = 2;
svga->blink++;
for (x = 0; x < 2048; x++)
for (x = 0; x < (svga->vram_limit >> 10); x++)
{
if (svga->changedvram[x])
svga->changedvram[x]--;

View file

@ -37,8 +37,9 @@ void svga_render_text_40(svga_t *svga)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
if (fullchange)
if (svga->fullchange)
{
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[32];
int x, xx;
int drawcursor;
uint8_t chr, attr, dat;
@ -74,21 +75,22 @@ void svga_render_text_40(svga_t *svga)
dat = svga->vram[charaddr + (svga->sc << 2)];
if (svga->seqregs[1] & 1)
{
for (xx = 0; xx < 8; xx++)
((uint32_t *)buffer32->line[svga->displine])[(x + 32 + (xx << 1)) & 2047] = ((uint32_t *)buffer32->line[svga->displine])[(x + 33 + (xx << 1)) & 2047] = (dat & (0x80 >> xx)) ? fg : bg;
for (xx = 0; xx < 16; xx += 2)
p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg;
}
else
{
for (xx = 0; xx < 8; xx++)
((uint32_t *)buffer32->line[svga->displine])[(x + 32 + (xx << 1)) & 2047] = ((uint32_t *)buffer32->line[svga->displine])[(x + 33 + (xx << 1)) & 2047] = (dat & (0x80 >> xx)) ? fg : bg;
for (xx = 0; xx < 16; xx += 2)
p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg;
if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4))
((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 16) & 2047] = ((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 17) & 2047] = bg;
p[16] = p[17] = bg;
else
((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 16) & 2047] = ((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 17) & 2047] = (dat & 1) ? fg : bg;
p[16] = p[17] = (dat & 1) ? fg : bg;
}
svga->ma += 4;
svga->ma &= svga->vrammask;
p += xinc;
}
svga->ma &= svga->vrammask;
}
}
@ -98,8 +100,9 @@ void svga_render_text_80(svga_t *svga)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
if (fullchange)
if (svga->fullchange)
{
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[32];
int x, xx;
int drawcursor;
uint8_t chr, attr, dat;
@ -136,293 +139,399 @@ void svga_render_text_80(svga_t *svga)
if (svga->seqregs[1] & 1)
{
for (xx = 0; xx < 8; xx++)
((uint32_t *)buffer32->line[svga->displine])[(x + 32 + xx) & 2047] = (dat & (0x80 >> xx)) ? fg : bg;
p[xx] = (dat & (0x80 >> xx)) ? fg : bg;
}
else
{
for (xx = 0; xx < 8; xx++)
((uint32_t *)buffer32->line[svga->displine])[(x + 32 + xx) & 2047] = (dat & (0x80 >> xx)) ? fg : bg;
p[xx] = (dat & (0x80 >> xx)) ? fg : bg;
if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4))
((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 8) & 2047] = bg;
p[8] = bg;
else
((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 8) & 2047] = (dat & 1) ? fg : bg;
p[8] = (dat & 1) ? fg : bg;
}
svga->ma += 4;
p += xinc;
}
svga->ma &= svga->vrammask;
}
}
void svga_render_2bpp_lowres(svga_t *svga)
{
int changed_offset;
if (svga->sc & 1 && !(svga->crtc[0x17] & 1))
changed_offset = (svga->ma << 1) >> 10;
else
changed_offset = ((svga->ma << 1) + 0x8000) >> 10;
if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange)
{
int x;
int offset = ((8 - svga->scrollcache) << 1) + 16;
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x += 16)
{
uint8_t dat[2];
if (svga->sc & 1 && !(svga->crtc[0x17] & 1))
{
dat[0] = svga->vram[(svga->ma << 1) + 0x8000];
dat[1] = svga->vram[(svga->ma << 1) + 0x8004];
}
else
{
dat[0] = svga->vram[(svga->ma << 1)];
dat[1] = svga->vram[(svga->ma << 1) + 4];
}
svga->ma += 4;
svga->ma &= svga->vrammask;
p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]];
p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]];
p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]];
p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]];
p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]];
p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]];
p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]];
p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]];
p += 16;
}
}
}
void svga_render_2bpp_highres(svga_t *svga)
{
int changed_offset;
if (svga->sc & 1 && !(svga->crtc[0x17] & 1))
changed_offset = ((svga->ma << 1) | 0x8000) >> 10;
else
changed_offset = (svga->ma << 1) >> 10;
if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange)
{
int x;
int offset = (8 - svga->scrollcache) + 24;
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x += 8)
{
uint8_t dat[2];
if (svga->sc & 1 && !(svga->crtc[0x17] & 1))
{
dat[0] = svga->vram[(svga->ma << 1) + 0x8000];
dat[1] = svga->vram[(svga->ma << 1) + 0x8004];
}
else
{
dat[0] = svga->vram[(svga->ma << 1)];
dat[1] = svga->vram[(svga->ma << 1) + 4];
}
svga->ma += 4;
svga->ma &= svga->vrammask;
p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]];
p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]];
p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]];
p[3] = svga->pallook[svga->egapal[dat[0] & 3]];
p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]];
p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]];
p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]];
p[7] = svga->pallook[svga->egapal[dat[1] & 3]];
p += 8;
}
}
}
void svga_render_4bpp_lowres(svga_t *svga)
{
int x, offset;
uint8_t edat[4], dat;
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || svga->fullchange)
{
int x;
int offset = ((8 - svga->scrollcache) << 1) + 16;
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
offset = ((8 - svga->scrollcache) << 1) + 16;
for (x = 0; x <= svga->hdisp; x += 16)
{
edat[0] = svga->vram[svga->ma];
edat[1] = svga->vram[svga->ma | 0x1];
edat[2] = svga->vram[svga->ma | 0x2];
edat[3] = svga->vram[svga->ma | 0x3];
uint8_t edat[4];
uint8_t dat;
*(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma]);
svga->ma += 4;
svga->ma &= svga->vrammask;
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
((uint32_t *)buffer32->line[svga->displine])[x + 14 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 15 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
((uint32_t *)buffer32->line[svga->displine])[x + 12 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 13 + offset] = svga->pallook[svga->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[svga->displine])[x + 10 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 11 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
((uint32_t *)buffer32->line[svga->displine])[x + 8 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 9 + offset] = svga->pallook[svga->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[svga->displine])[x + 6 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 7 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
((uint32_t *)buffer32->line[svga->displine])[x + 4 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 5 + offset] = svga->pallook[svga->egapal[dat >> 4]];
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
((uint32_t *)buffer32->line[svga->displine])[x + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = svga->pallook[svga->egapal[dat >> 4]];
p[0] = p[1] = svga->pallook[svga->egapal[dat >> 4]];
p[2] = p[3] = svga->pallook[svga->egapal[dat & 0xf]];
dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
p[4] = p[5] = svga->pallook[svga->egapal[dat >> 4]];
p[6] = p[7] = svga->pallook[svga->egapal[dat & 0xf]];
dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
p[8] = p[9] = svga->pallook[svga->egapal[dat >> 4]];
p[10] = p[11] = svga->pallook[svga->egapal[dat & 0xf]];
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
p[12] = p[13] = svga->pallook[svga->egapal[dat >> 4]];
p[14] = p[15] = svga->pallook[svga->egapal[dat & 0xf]];
p += 16;
}
}
}
void svga_render_4bpp_highres(svga_t *svga)
{
int x, offset;
uint8_t edat[4], dat;
int changed_offset;
if (svga->sc & 1 && !(svga->crtc[0x17] & 1))
changed_offset = (svga->ma | 0x8000) >> 10;
else
changed_offset = svga->ma >> 10;
if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->changedvram[changed_offset + 2] || svga->fullchange)
{
int x;
int offset = (8 - svga->scrollcache) + 24;
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
offset = (8 - svga->scrollcache) + 24;
for (x = 0; x <= svga->hdisp; x += 8)
{
edat[0] = svga->vram[svga->ma];
edat[1] = svga->vram[svga->ma | 0x1];
edat[2] = svga->vram[svga->ma | 0x2];
edat[3] = svga->vram[svga->ma | 0x3];
uint8_t edat[4];
uint8_t dat;
if (svga->sc & 1 && !(svga->crtc[0x17] & 1))
*(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma | 0x8000]);
else
*(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma]);
svga->ma += 4;
svga->ma &= svga->vrammask;
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
((uint32_t *)buffer32->line[svga->displine])[x + 7 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
((uint32_t *)buffer32->line[svga->displine])[x + 6 + offset] = svga->pallook[svga->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[svga->displine])[x + 5 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
((uint32_t *)buffer32->line[svga->displine])[x + 4 + offset] = svga->pallook[svga->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[svga->displine])[x + 3 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = svga->pallook[svga->egapal[dat >> 4]];
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
((uint32_t *)buffer32->line[svga->displine])[x + offset] = svga->pallook[svga->egapal[dat >> 4]];
p[0] = svga->pallook[svga->egapal[dat >> 4]];
p[1] = svga->pallook[svga->egapal[dat & 0xf]];
dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
p[2] = svga->pallook[svga->egapal[dat >> 4]];
p[3] = svga->pallook[svga->egapal[dat & 0xf]];
dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
p[4] = svga->pallook[svga->egapal[dat >> 4]];
p[5] = svga->pallook[svga->egapal[dat & 0xf]];
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
p[6] = svga->pallook[svga->egapal[dat >> 4]];
p[7] = svga->pallook[svga->egapal[dat & 0xf]];
p += 8;
}
}
void svga_render_2bpp_lowres(svga_t *svga)
{
int x, offset;
uint8_t edat[2], dat;
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
offset = ((8 - svga->scrollcache) << 1) + 16;
/*Low res (320) only, though high res (640) should be possible*/
for (x = 0; x <= svga->hdisp; x += 16)
{
if (svga->sc & 1 && !(svga->crtc[0x17] & 1))
{
edat[0] = svga->vram[(svga->ma << 1) + 0x8000];
edat[1] = svga->vram[(svga->ma << 1) + 0x8004];
}
else
{
edat[0] = svga->vram[(svga->ma << 1)];
edat[1] = svga->vram[(svga->ma << 1) + 4];
}
svga->ma += 4; svga->ma &= svga->vrammask;
((uint32_t *)buffer32->line[svga->displine])[x + 14 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 15 + offset] = svga->pallook[svga->egapal[edat[1] & 3]];
((uint32_t *)buffer32->line[svga->displine])[x + 12 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 13 + offset] = svga->pallook[svga->egapal[(edat[1] >> 2) & 3]];
((uint32_t *)buffer32->line[svga->displine])[x + 10 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 11 + offset] = svga->pallook[svga->egapal[(edat[1] >> 4) & 3]];
((uint32_t *)buffer32->line[svga->displine])[x + 8 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 9 + offset] = svga->pallook[svga->egapal[(edat[1] >> 6) & 3]];
((uint32_t *)buffer32->line[svga->displine])[x + 6 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 7 + offset] = svga->pallook[svga->egapal[edat[0] & 3]];
((uint32_t *)buffer32->line[svga->displine])[x + 4 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 5 + offset] = svga->pallook[svga->egapal[(edat[0] >> 2) & 3]];
((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = svga->pallook[svga->egapal[(edat[0] >> 4) & 3]];
((uint32_t *)buffer32->line[svga->displine])[x + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = svga->pallook[svga->egapal[(edat[0] >> 6) & 3]];
}
}
void svga_render_8bpp_lowres(svga_t *svga)
{
int x, offset;
uint8_t edat[4];
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || svga->fullchange)
{
int x;
int offset = (8 - (svga->scrollcache & 6)) + 24;
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
offset = (8 - (svga->scrollcache & 6)) + 24;
for (x = 0; x <= svga->hdisp; x += 8)
{
edat[0] = svga->vram[svga->ma];
edat[1] = svga->vram[svga->ma | 0x1];
edat[2] = svga->vram[svga->ma | 0x2];
edat[3] = svga->vram[svga->ma | 0x3];
uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vrammask]);
p[0] = p[1] = svga->pallook[dat & 0xff];
p[2] = p[3] = svga->pallook[(dat >> 8) & 0xff];
p[4] = p[5] = svga->pallook[(dat >> 16) & 0xff];
p[6] = p[7] = svga->pallook[(dat >> 24) & 0xff];
svga->ma += 4;
svga->ma &= svga->vrammask;
((uint32_t *)buffer32->line[svga->displine])[x + 6 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 7 + offset] = svga->pallook[edat[3]];
((uint32_t *)buffer32->line[svga->displine])[x + 4 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 5 + offset] = svga->pallook[edat[2]];
((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = svga->pallook[edat[1]];
((uint32_t *)buffer32->line[svga->displine])[x + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = svga->pallook[edat[0]];
p += 8;
}
svga->ma &= svga->vrammask;
}
}
void svga_render_8bpp_highres(svga_t *svga)
{
int x, offset;
uint8_t edat[4];
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || svga->fullchange)
{
int x;
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
for (x = 0; x <= svga->hdisp; x += 8)
{
edat[0] = svga->vram[svga->ma];
edat[1] = svga->vram[svga->ma | 0x1];
edat[2] = svga->vram[svga->ma | 0x2];
edat[3] = svga->vram[svga->ma | 0x3];
svga->ma += 4;
svga->ma &= svga->vrammask;
((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = svga->pallook[edat[3]];
((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = svga->pallook[edat[2]];
((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = svga->pallook[edat[1]];
((uint32_t *)buffer32->line[svga->displine])[x + offset] = svga->pallook[edat[0]];
uint32_t dat;
dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vrammask]);
p[0] = svga->pallook[dat & 0xff];
p[1] = svga->pallook[(dat >> 8) & 0xff];
p[2] = svga->pallook[(dat >> 16) & 0xff];
p[3] = svga->pallook[(dat >> 24) & 0xff];
edat[0] = svga->vram[svga->ma];
edat[1] = svga->vram[svga->ma | 0x1];
edat[2] = svga->vram[svga->ma | 0x2];
edat[3] = svga->vram[svga->ma | 0x3];
svga->ma += 4;
svga->ma &= svga->vrammask;
((uint32_t *)buffer32->line[svga->displine])[x + 7 + offset] = svga->pallook[edat[3]];
((uint32_t *)buffer32->line[svga->displine])[x + 6 + offset] = svga->pallook[edat[2]];
((uint32_t *)buffer32->line[svga->displine])[x + 5 + offset] = svga->pallook[edat[1]];
((uint32_t *)buffer32->line[svga->displine])[x + 4 + offset] = svga->pallook[edat[0]];
dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vrammask]);
p[4] = svga->pallook[dat & 0xff];
p[5] = svga->pallook[(dat >> 8) & 0xff];
p[6] = svga->pallook[(dat >> 16) & 0xff];
p[7] = svga->pallook[(dat >> 24) & 0xff];
svga->ma += 8;
p += 8;
}
svga->ma &= svga->vrammask;
}
}
void svga_render_15bpp_lowres(svga_t *svga)
{
int x, offset;
uint16_t fg, bg;
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || svga->fullchange)
{
int x;
int offset = (8 - (svga->scrollcache & 6)) + 24;
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
offset = (8 - (svga->scrollcache & 6)) + 24;
for (x = 0; x <= svga->hdisp; x += 4)
{
fg = svga->vram[svga->ma] | (svga->vram[svga->ma | 0x1] << 8);
bg = svga->vram[svga->ma | 0x2] | (svga->vram[svga->ma | 0x3] << 8);
svga->ma += 4;
svga->ma &= svga->vrammask;
((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = ((bg & 31) << 3) | (((bg >> 5) & 31) << 11) | (((bg >> 10) & 31) << 19);
((uint32_t *)buffer32->line[svga->displine])[x + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = ((fg & 31) << 3) | (((fg >> 5) & 31) << 11) | (((fg >> 10) & 31) << 19);
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vrammask]);
p[x] = video_15to32[dat & 0xffff];
p[x + 1] = video_15to32[dat >> 16];
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vrammask]);
p[x] = video_15to32[dat & 0xffff];
p[x + 1] = video_15to32[dat >> 16];
}
svga->ma += x << 1;
svga->ma &= svga->vrammask;
}
}
void svga_render_15bpp_highres(svga_t *svga)
{
int x, offset;
uint16_t fg, bg;
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || svga->fullchange)
{
int x;
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
for (x = 0; x <= svga->hdisp; x += 2)
for (x = 0; x <= svga->hdisp; x += 8)
{
fg = svga->vram[svga->ma] | (svga->vram[svga->ma | 0x1] << 8);
bg = svga->vram[svga->ma | 0x2] | (svga->vram[svga->ma | 0x3] << 8);
svga->ma += 4;
svga->ma &= svga->vrammask;
((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = ((bg & 31) << 3) | (((bg >> 5) & 31) << 11) | (((bg >> 10) & 31) << 19);
((uint32_t *)buffer32->line[svga->displine])[x + offset] = ((fg & 31) << 3) | (((fg >> 5) & 31) << 11) | (((fg >> 10) & 31) << 19);
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vrammask]);
p[x] = video_15to32[dat & 0xffff];
p[x + 1] = video_15to32[dat >> 16];
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vrammask]);
p[x + 2] = video_15to32[dat & 0xffff];
p[x + 3] = video_15to32[dat >> 16];
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vrammask]);
p[x + 4] = video_15to32[dat & 0xffff];
p[x + 5] = video_15to32[dat >> 16];
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vrammask]);
p[x + 6] = video_15to32[dat & 0xffff];
p[x + 7] = video_15to32[dat >> 16];
}
svga->ma += x << 1;
svga->ma &= svga->vrammask;
}
}
void svga_render_16bpp_lowres(svga_t *svga)
{
int x, offset;
uint16_t fg, bg;
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || svga->fullchange)
{
int x;
int offset = (8 - (svga->scrollcache & 6)) + 24;
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
offset = (8 - (svga->scrollcache & 6)) + 24;
for (x = 0; x <= svga->hdisp; x += 4)
{
fg = svga->vram[svga->ma] | (svga->vram[svga->ma | 0x1] << 8);
bg = svga->vram[svga->ma | 0x2] | (svga->vram[svga->ma | 0x3] << 8);
svga->ma += 4;
svga->ma &= svga->vrammask;
((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = ((bg & 31) << 3) | (((bg >> 5) & 63) << 10) | (((bg >> 11) & 31) << 19);
((uint32_t *)buffer32->line[svga->displine])[x + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = ((fg & 31) << 3) | (((fg >> 5) & 63) << 10) | (((fg >> 11) & 31) << 19);
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vrammask]);
p[x] = video_16to32[dat & 0xffff];
p[x + 1] = video_16to32[dat >> 16];
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vrammask]);
p[x] = video_16to32[dat & 0xffff];
p[x + 1] = video_16to32[dat >> 16];
}
svga->ma += x << 1;
svga->ma &= svga->vrammask;
}
}
void svga_render_16bpp_highres(svga_t *svga)
{
int x, offset;
uint16_t fg, bg;
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || svga->fullchange)
{
int x;
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
for (x = 0; x <= svga->hdisp; x += 2)
for (x = 0; x <= svga->hdisp; x += 8)
{
fg = svga->vram[svga->ma] | (svga->vram[svga->ma | 0x1] << 8);
bg = svga->vram[svga->ma | 0x2] | (svga->vram[svga->ma | 0x3] << 8);
svga->ma += 4;
svga->ma &= svga->vrammask;
((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = ((bg & 31) << 3) | (((bg >> 5) & 63) << 10) | (((bg >> 11) & 31) << 19);
((uint32_t *)buffer32->line[svga->displine])[x + offset] = ((fg & 31) << 3) | (((fg >> 5) & 63) << 10) | (((fg >> 11) & 31) << 19);
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vrammask]);
p[x] = video_16to32[dat & 0xffff];
p[x + 1] = video_16to32[dat >> 16];
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vrammask]);
p[x + 2] = video_16to32[dat & 0xffff];
p[x + 3] = video_16to32[dat >> 16];
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vrammask]);
p[x + 4] = video_16to32[dat & 0xffff];
p[x + 5] = video_16to32[dat >> 16];
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vrammask]);
p[x + 6] = video_16to32[dat & 0xffff];
p[x + 7] = video_16to32[dat >> 16];
}
svga->ma += x << 1;
svga->ma &= svga->vrammask;
}
}
@ -431,7 +540,7 @@ void svga_render_24bpp_lowres(svga_t *svga)
int x, offset;
uint32_t fg;
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || svga->fullchange)
{
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
@ -451,24 +560,33 @@ void svga_render_24bpp_lowres(svga_t *svga)
void svga_render_24bpp_highres(svga_t *svga)
{
int x, offset;
uint32_t fg;
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || svga->fullchange)
{
int x;
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
for (x = 0; x <= svga->hdisp; x++)
for (x = 0; x <= svga->hdisp; x += 4)
{
fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16);
svga->ma += 3;
svga->ma &= svga->vrammask;
((uint32_t *)buffer32->line[svga->displine])[x + offset] = fg;
uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vrammask]);
p[x] = dat & 0xffffff;
dat = *(uint32_t *)(&svga->vram[(svga->ma + 3) & svga->vrammask]);
p[x + 1] = dat & 0xffffff;
dat = *(uint32_t *)(&svga->vram[(svga->ma + 6) & svga->vrammask]);
p[x + 2] = dat & 0xffffff;
dat = *(uint32_t *)(&svga->vram[(svga->ma + 9) & svga->vrammask]);
p[x + 3] = dat & 0xffffff;
svga->ma += 12;
}
svga->ma &= svga->vrammask;
}
}
@ -477,7 +595,7 @@ void svga_render_32bpp_lowres(svga_t *svga)
int x, offset;
uint32_t fg;
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || svga->fullchange)
{
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
@ -495,26 +613,27 @@ void svga_render_32bpp_lowres(svga_t *svga)
}
}
/*72%
91%*/
void svga_render_32bpp_highres(svga_t *svga)
{
int x, offset;
uint32_t fg;
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || svga->fullchange)
{
int x;
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
for (x = 0; x <= svga->hdisp; x++)
{
fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16);
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vrammask]);
p[x] = dat & 0xffffff;
}
svga->ma += 4;
svga->ma &= svga->vrammask;
((uint32_t *)buffer32->line[svga->displine])[x + offset] = fg;
}
}
}

View file

@ -14,6 +14,7 @@ void svga_render_text_40(svga_t *svga);
void svga_render_text_80(svga_t *svga);
void svga_render_2bpp_lowres(svga_t *svga);
void svga_render_2bpp_highres(svga_t *svga);
void svga_render_4bpp_lowres(svga_t *svga);
void svga_render_4bpp_highres(svga_t *svga);
void svga_render_8bpp_lowres(svga_t *svga);

View file

@ -140,7 +140,7 @@ void tvga_out(uint16_t addr, uint8_t val, void *p)
{
if (svga->crtcreg < 0xE || svga->crtcreg > 0x10)
{
fullchange = changeframecount;
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}

View file

@ -36,7 +36,7 @@ void vga_out(uint16_t addr, uint8_t val, void *p)
{
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
{
fullchange = changeframecount;
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}

View file

@ -1,3 +1,4 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "ibm.h"
@ -30,6 +31,8 @@
#include "vid_tvga.h"
#include "vid_vga.h"
uint32_t *video_15to32, *video_16to32;
int egareads=0,egawrites=0;
int changeframecount=2;
@ -380,9 +383,21 @@ void initvideo()
// printf("Edat %i,%i now %02X\n",c,d,edatlookup[c][d]);
}
}
video_15to32 = malloc(4 * 65536);
for (c = 0; c < 65536; c++)
video_15to32[c] = ((c & 31) << 3) | (((c >> 5) & 31) << 11) | (((c >> 10) & 31) << 19);
video_16to32 = malloc(4 * 65536);
for (c = 0; c < 65536; c++)
video_16to32[c] = ((c & 31) << 3) | (((c >> 5) & 63) << 10) | (((c >> 11) & 31) << 19);
}
void closevideo()
{
free(video_15to32);
free(video_16to32);
destroy_bitmap(buffer);
destroy_bitmap(buffer32);
}

View file

@ -19,6 +19,8 @@ BITMAP *create_bitmap(int w, int h);
extern uint8_t fontdat[256][8];
extern uint8_t fontdatm[256][16];
extern uint32_t *video_15to32, *video_16to32;
extern int xsize,ysize;
typedef struct