Fixed EGA and (S)VGA pel panning, fixes games like Supaplex.

This commit is contained in:
OBattler
2019-11-19 19:18:44 +01:00
parent 3cc320d2b2
commit ac0a1ee327
4 changed files with 61 additions and 45 deletions

View File

@@ -9,7 +9,7 @@
* Emulation of the EGA and Chips & Technologies SuperEGA
* graphics cards.
*
* Version: @(#)vid_ega.c 1.0.22 2019/10/03
* Version: @(#)vid_ega.c 1.0.23 2019/11/19
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -389,9 +389,13 @@ ega_poll(void *p)
ega->displine <<= 1;
ega->y_add <<= 1;
ega_render_overscan_left(ega);
ega->render(ega);
ega->x_add = (overscan_x >> 1);
ega_render_overscan_left(ega);
ega_render_overscan_right(ega);
ega->x_add = (overscan_x >> 1) - ega->scrollcache;
ega->displine++;
ega->ma = old_ma;
@@ -454,8 +458,10 @@ ega_poll(void *p)
if (ega->vc == ega->split) {
ega->ma = ega->maback = 0;
ega->sc = 0;
if (ega->attrregs[0x10] & 0x20)
if (ega->attrregs[0x10] & 0x20) {
ega->scrollcache = 0;
ega->x_add = (overscan_x >> 1);
}
}
if (ega->vc == ega->dispend) {
ega->dispon = 0;

View File

@@ -8,7 +8,7 @@
*
* EGA renderers.
*
* Version: @(#)vid_ega_render.c 1.0.6 2019/10/03
* Version: @(#)vid_ega_render.c 1.0.7 2019/11/19
*
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -53,7 +53,7 @@ ega_render_blank(ega_t *ega)
if ((ega->displine + ega->y_add) < 0)
return;
for (x = 0; x < ega->hdisp; x++) {
for (x = 0; x < (ega->hdisp + ega->scrollcache); x++) {
switch (ega->seqregs[1] & 9) {
case 0:
for (xx = 0; xx < 9; xx++) buffer32->line[ega->displine + ega->y_add][ega->x_add + (x * 9) + xx] = 0;
@@ -120,7 +120,7 @@ ega_render_text_40(ega_t *ega)
p = &buffer32->line[ega->displine + ega->y_add][ega->x_add];
xinc = (ega->seqregs[1] & 1) ? 16 : 18;
for (x = 0; x < ega->hdisp; x += xinc) {
for (x = 0; x < (ega->hdisp + ega->scrollcache); x += xinc) {
drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron);
chr = ega->vram[(ega->ma << 1) & ega->vrammask];
attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask];
@@ -183,7 +183,7 @@ ega_render_text_80(ega_t *ega)
p = &buffer32->line[ega->displine + ega->y_add][ega->x_add];
xinc = (ega->seqregs[1] & 1) ? 8 : 9;
for (x = 0; x < ega->hdisp; x += xinc) {
for (x = 0; x < (ega->hdisp + ega->scrollcache); x += xinc) {
drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron);
chr = ega->vram[(ega->ma << 1) & ega->vrammask];
attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask];
@@ -240,7 +240,7 @@ ega_render_2bpp_lowres(ega_t *ega)
ega->firstline_draw = ega->displine;
ega->lastline_draw = ega->displine;
for (x = 0; x <= ega->hdisp; x += 16) {
for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 16) {
addr = ega->ma;
if (!(ega->crtc[0x17] & 0x40)) {
@@ -299,7 +299,7 @@ ega_render_2bpp_highres(ega_t *ega)
ega->firstline_draw = ega->displine;
ega->lastline_draw = ega->displine;
for (x = 0; x <= ega->hdisp; x += 8) {
for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 8) {
addr = ega->ma;
if (!(ega->crtc[0x17] & 0x40)) {
@@ -358,7 +358,7 @@ ega_render_4bpp_lowres(ega_t *ega)
ega->firstline_draw = ega->displine;
ega->lastline_draw = ega->displine;
for (x = 0; x <= ega->hdisp; x += 16) {
for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 16) {
addr = ega->ma;
oddeven = 0;
@@ -431,7 +431,7 @@ ega_render_4bpp_highres(ega_t *ega)
ega->firstline_draw = ega->displine;
ega->lastline_draw = ega->displine;
for (x = 0; x <= ega->hdisp; x += 8) {
for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 8) {
addr = ega->ma;
oddeven = 0;

View File

@@ -11,7 +11,7 @@
* This is intended to be used by another SVGA driver,
* and not as a card in it's own right.
*
* Version: @(#)vid_svga.c 1.0.37 2019/10/21
* Version: @(#)vid_svga.c 1.0.38 2019/11/19
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -530,10 +530,13 @@ svga_recalctimings(svga_t *svga)
overscan_y = 16;
}
overscan_x = (svga->seqregs[1] & 1) ? 16 : 18;
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) {
overscan_x = (svga->seqregs[1] & 1) ? 16 : 18;
if (svga->seqregs[1] & 8)
overscan_x <<= 1;
if (svga->seqregs[1] & 8)
overscan_x <<= 1;
} else
overscan_x = 16;
if (svga->recalctimings_ex)
svga->recalctimings_ex(svga);
@@ -553,6 +556,7 @@ svga_recalctimings(svga_t *svga)
disptime *= 2;
_dispontime *= 2;
}
_dispofftime = disptime - _dispontime;
_dispontime *= crtcconst;
_dispofftime *= crtcconst;
@@ -572,6 +576,7 @@ svga_poll(void *p)
svga_t *svga = (svga_t *)p;
uint32_t x, blink_delay;
int wx, wy;
int skip = (svga->crtc[8] >> 5) & 0x03;
if (!svga->linepos) {
if (svga->displine == svga->hwcursor_latch.y && svga->hwcursor_latch.ena) {
@@ -625,9 +630,12 @@ svga_poll(void *p)
}
if (!svga->override) {
svga_render_overscan_left(svga);
svga->render(svga);
svga->x_add = (overscan_x >> 1);
svga_render_overscan_left(svga);
svga_render_overscan_right(svga);
svga->x_add = (overscan_x >> 1) - svga->scrollcache;
}
if (svga->overlay_on) {
@@ -702,8 +710,10 @@ svga_poll(void *p)
if (svga->vc == svga->split) {
svga->ma = svga->maback = 0;
svga->sc = 0;
if (svga->attrregs[0x10] & 0x20)
if (svga->attrregs[0x10] & 0x20) {
svga->scrollcache = 0;
svga->x_add = (overscan_x >> 1);
}
}
if (svga->vc == svga->dispend) {
if (svga->vblank_start)
@@ -761,9 +771,9 @@ svga_poll(void *p)
svga->ma = svga->maback = svga->ma_latch;
svga->ca = (svga->crtc[0xe] << 8) | svga->crtc[0xf];
svga->ma <<= 2;
svga->maback <<= 2;
svga->ca <<= 2;
svga->ma = (svga->ma << 2) + (skip << 2);
svga->maback = (svga->maback << 2) + (skip << 2);
svga->ca = (svga->ca << 2) + (skip << 2);
}
if (svga->vc == svga->vtotal) {
svga->vc = 0;
@@ -786,7 +796,7 @@ svga_poll(void *p)
else
svga->scrollcache = (svga->scrollcache & 0x06) >> 1;
if (svga->seqregs[1] & 8)
if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres))
svga->scrollcache <<= 1;
svga->x_add = (overscan_x >> 1) - svga->scrollcache;

View File

@@ -8,7 +8,7 @@
*
* SVGA renderers.
*
* Version: @(#)vid_svga_render.c 1.0.13 2019/03/08
* Version: @(#)vid_svga_render.c 1.0.14 2019/11/19
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -40,7 +40,7 @@ svga_render_blank(svga_t *svga)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x < svga->hdisp; x++) {
for (x = 0; x < (svga->hdisp + svga->scrollcache); x++) {
switch (svga->seqregs[1] & 9) {
case 0:
for (xx = 0; xx < 9; xx++)
@@ -84,7 +84,7 @@ svga_render_overscan_right(svga_t *svga)
if (svga->scrblank || (svga->hdisp == 0))
return;
right = (overscan_x >> 1) + svga->scrollcache;
right = (overscan_x >> 1);
for (i = 0; i < right; i++)
buffer32->line[svga->displine + svga->y_add][svga->x_add + svga->hdisp + i] = svga->overscan_color;
}
@@ -111,7 +111,7 @@ svga_render_text_40(svga_t *svga)
p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
xinc = (svga->seqregs[1] & 1) ? 16 : 18;
for (x = 0; x < svga->hdisp; x += xinc) {
for (x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) {
drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask];
attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask];
@@ -174,7 +174,7 @@ svga_render_text_80(svga_t *svga)
p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
xinc = (svga->seqregs[1] & 1) ? 8 : 9;
for (x = 0; x < svga->hdisp; x += xinc) {
for (x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) {
drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask];
attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask];
@@ -237,7 +237,7 @@ svga_render_text_80_ksc5601(svga_t *svga)
xinc = (svga->seqregs[1] & 1) ? 8 : 9;
for (x = 0; x < svga->hdisp; x += xinc) {
for (x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) {
drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask];
nextchr = svga->vram[((svga->ma + 4) << 1) & svga->vram_display_mask];
@@ -348,7 +348,7 @@ svga_render_2bpp_lowres(svga_t *svga)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x += 16) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) {
addr = svga->ma;
if (!(svga->crtc[0x17] & 0x40)) {
@@ -411,7 +411,7 @@ svga_render_2bpp_highres(svga_t *svga)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x += 8) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
addr = svga->ma;
if (!(svga->crtc[0x17] & 0x40)) {
@@ -473,7 +473,7 @@ svga_render_4bpp_lowres(svga_t *svga)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x += 16) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) {
addr = svga->ma;
oddeven = 0;
@@ -547,7 +547,7 @@ svga_render_4bpp_highres(svga_t *svga)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x += 8) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
addr = svga->ma;
oddeven = 0;
@@ -617,7 +617,7 @@ svga_render_8bpp_lowres(svga_t *svga)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x += 8) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
p[0] = p[1] = svga->map8[dat & 0xff];
@@ -650,7 +650,7 @@ svga_render_8bpp_highres(svga_t *svga)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x += 8) {
for (x = 0; x <= (svga->hdisp/* + svga->scrollcache*/); x += 8) {
dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
p[0] = svga->map8[dat & 0xff];
p[1] = svga->map8[(dat >> 8) & 0xff];
@@ -688,7 +688,7 @@ svga_render_15bpp_lowres(svga_t *svga)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x += 4) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) {
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
p[(x << 1)] = p[(x << 1) + 1] = video_15to32[dat & 0xffff];
@@ -724,7 +724,7 @@ svga_render_15bpp_highres(svga_t *svga)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x += 8) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
p[x] = video_15to32[dat & 0xffff];
p[x + 1] = video_15to32[dat >> 16];
@@ -764,7 +764,7 @@ svga_render_15bpp_mix_lowres(svga_t *svga)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x += 4) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) {
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
p[(x << 1)] = p[(x << 1) + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff];
@@ -800,7 +800,7 @@ svga_render_15bpp_mix_highres(svga_t *svga)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x += 8) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
p[x] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff];
dat >>= 16;
@@ -844,7 +844,7 @@ svga_render_16bpp_lowres(svga_t *svga)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x += 4) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) {
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
p[(x << 1)] = p[(x << 1) + 1] = video_16to32[dat & 0xffff];
p[(x << 1) + 2] = p[(x << 1) + 3] = video_16to32[dat >> 16];
@@ -875,7 +875,7 @@ svga_render_16bpp_highres(svga_t *svga)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x += 8) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
p[x] = video_16to32[dat & 0xffff];
p[x + 1] = video_16to32[dat >> 16];
@@ -912,7 +912,7 @@ svga_render_24bpp_lowres(svga_t *svga)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x++) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16);
svga->ma += 3;
svga->ma &= svga->vram_display_mask;
@@ -940,7 +940,7 @@ svga_render_24bpp_highres(svga_t *svga)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x += 4) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) {
dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
p[x] = dat & 0xffffff;
@@ -974,7 +974,7 @@ svga_render_32bpp_lowres(svga_t *svga)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x++) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16);
svga->ma += 4;
svga->ma &= svga->vram_display_mask;
@@ -1002,7 +1002,7 @@ svga_render_32bpp_highres(svga_t *svga)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x++) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
p[x] = dat & 0xffffff;
}
@@ -1029,7 +1029,7 @@ svga_render_ABGR8888_highres(svga_t *svga)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x++) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
p[x] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16);
}
@@ -1056,7 +1056,7 @@ svga_render_RGBA8888_highres(svga_t *svga)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x++) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
p[x] = dat >> 8;
}