Fixed EGA graphics modes and ported EGA 2bpp/4bpp word mode and 4bpp odd/even functionality to (S)VGA which should also support it.

This commit is contained in:
OBattler
2019-10-20 17:25:30 +02:00
parent d829f80236
commit 9c42abf2bf
5 changed files with 278 additions and 111 deletions

View File

@@ -102,7 +102,8 @@ ega_out(uint16_t addr, uint8_t val, void *p)
ega->overscan_color = ega->vres ? pallook16[val & 0x0f] : pallook64[val & 0x3f];
if (o != val)
ega_recalctimings(ega);
}
} else if (ega->attraddr == 0x12)
ega->plane_mask = val & 0xf;
}
ega->attrff ^= 1;
break;
@@ -320,7 +321,10 @@ ega_recalctimings(ega_t *ega)
ega->render = ega_render_4bpp_highres;
break;
case 0x20:
ega->render = ega_render_2bpp;
if (ega->seqregs[1] & 8)
ega->render = ega_render_2bpp_lowres;
else
ega->render = ega_render_2bpp_highres;
break;
}
}
@@ -379,29 +383,29 @@ ega_poll(void *p)
video_wait_for_buffer();
}
ega_render_overscan_left(ega);
if (ega->scrblank || fullchange) {
if (ega->firstline_draw == 2000)
ega->firstline_draw = ega->displine;
ega->lastline_draw = ega->displine;
if (ega->vres) {
old_ma = ega->ma;
if (ega->vres) {
old_ma = ega->ma;
ega->displine <<= 1;
ega->y_add <<= 1;
ega->displine <<= 1;
ega->y_add <<= 1;
ega->render(ega);
ega->displine++;
ega_render_overscan_left(ega);
ega->render(ega);
ega_render_overscan_right(ega);
ega->displine++;
ega->ma = old_ma;
ega->render(ega);
ega->ma = old_ma;
ega_render_overscan_left(ega);
ega->render(ega);
ega_render_overscan_right(ega);
ega->y_add >>= 1;
ega->displine >>= 1;
} else
ega->render(ega);
ega->y_add >>= 1;
ega->displine >>= 1;
} else {
ega_render_overscan_left(ega);
ega->render(ega);
ega_render_overscan_right(ega);
}
ega_render_overscan_right(ega);
if (ega->lastline < ega->displine)
ega->lastline = ega->displine;

View File

@@ -30,7 +30,8 @@ typedef struct ega_t {
uint8_t crtcreg, gdcaddr, attraddr, attrff,
attr_palette_enable, seqaddr, miscout,
writemask, la, lb, lc, ld,
stat, colourcompare, colournocare, scrblank;
stat, colourcompare, colournocare, scrblank,
plane_mask, pad, pad0, pad1;
uint8_t crtc[32];
uint8_t gdcreg[16];
uint8_t attrregs[32];

View File

@@ -225,16 +225,22 @@ ega_render_text_80(ega_t *ega)
void
ega_render_2bpp(ega_t *ega)
ega_render_2bpp_lowres(ega_t *ega)
{
int x, dl = ega->displine + ega->y_add;
uint8_t edat[2];
uint32_t addr;
int x;
uint8_t dat[2];
uint32_t addr, *p;
if ((ega->displine + ega->y_add) < 0)
return;
for (x = 0; x <= ega->hdisp; x++) {
p = &buffer32->line[ega->displine + ega->y_add][ega->x_add];
if (ega->firstline_draw == 2000)
ega->firstline_draw = ega->displine;
ega->lastline_draw = ega->displine;
for (x = 0; x <= ega->hdisp; x += 16) {
addr = ega->ma;
if (!(ega->crtc[0x17] & 0x40)) {
@@ -254,8 +260,8 @@ ega_render_2bpp(ega_t *ega)
if (!(ega->crtc[0x17] & 0x02))
addr = (addr & ~0x10000) | ((ega->sc & 2) ? 0x10000 : 0);
edat[0] = ega->vram[addr];
edat[1] = ega->vram[addr | 0x1];
dat[0] = ega->vram[addr];
dat[1] = ega->vram[addr | 0x1];
if (ega->seqregs[1] & 4)
ega->ma += 2;
else
@@ -263,22 +269,75 @@ ega_render_2bpp(ega_t *ega)
ega->ma &= ega->vrammask;
buffer32->line[dl][(x << 4) + 14 + ega->x_add] =
buffer32->line[dl][(x << 4) + 15 + ega->x_add] = ega->pallook[ega->egapal[edat[1] & 3]];
buffer32->line[dl][(x << 4) + 12 + ega->x_add] =
buffer32->line[dl][(x << 4) + 13 + ega->x_add] = ega->pallook[ega->egapal[(edat[1] >> 2) & 3]];
buffer32->line[dl][(x << 4) + 10 + ega->x_add] =
buffer32->line[dl][(x << 4) + 11 + ega->x_add] = ega->pallook[ega->egapal[(edat[1] >> 4) & 3]];
buffer32->line[dl][(x << 4) + 8 + ega->x_add] =
buffer32->line[dl][(x << 4) + 9 + ega->x_add] = ega->pallook[ega->egapal[(edat[1] >> 6) & 3]];
buffer32->line[dl][(x << 4) + 6 + ega->x_add] =
buffer32->line[dl][(x << 4) + 7 + ega->x_add] = ega->pallook[ega->egapal[(edat[0] >> 0) & 3]];
buffer32->line[dl][(x << 4) + 4 + ega->x_add] =
buffer32->line[dl][(x << 4) + 5 + ega->x_add] = ega->pallook[ega->egapal[(edat[0] >> 2) & 3]];
buffer32->line[dl][(x << 4) + 2 + ega->x_add] =
buffer32->line[dl][(x << 4) + 3 + ega->x_add] = ega->pallook[ega->egapal[(edat[0] >> 4) & 3]];
buffer32->line[dl][(x << 4) + ega->x_add] =
buffer32->line[dl][(x << 4) + 1 + ega->x_add] = ega->pallook[ega->egapal[(edat[0] >> 6) & 3]];
p[0] = p[1] = ega->pallook[ega->egapal[(dat[0] >> 6) & 3]];
p[2] = p[3] = ega->pallook[ega->egapal[(dat[0] >> 4) & 3]];
p[4] = p[5] = ega->pallook[ega->egapal[(dat[0] >> 2) & 3]];
p[6] = p[7] = ega->pallook[ega->egapal[dat[0] & 3]];
p[8] = p[9] = ega->pallook[ega->egapal[(dat[1] >> 6) & 3]];
p[10] = p[11] = ega->pallook[ega->egapal[(dat[1] >> 4) & 3]];
p[12] = p[13] = ega->pallook[ega->egapal[(dat[1] >> 2) & 3]];
p[14] = p[15] = ega->pallook[ega->egapal[dat[1] & 3]];
p += 16;
}
}
void
ega_render_2bpp_highres(ega_t *ega)
{
int x;
uint8_t dat[2];
uint32_t addr, *p;
if ((ega->displine + ega->y_add) < 0)
return;
p = &buffer32->line[ega->displine + ega->y_add][ega->x_add];
if (ega->firstline_draw == 2000)
ega->firstline_draw = ega->displine;
ega->lastline_draw = ega->displine;
for (x = 0; x <= ega->hdisp; x += 8) {
addr = ega->ma;
if (!(ega->crtc[0x17] & 0x40)) {
addr = (addr << 1) & ega->vrammask;
addr &= ~7;
if ((ega->crtc[0x17] & 0x20) && (ega->ma & 0x20000))
addr |= 4;
if (!(ega->crtc[0x17] & 0x20) && (ega->ma & 0x8000))
addr |= 4;
}
if (!(ega->crtc[0x17] & 0x01))
addr = (addr & ~0x8000) | ((ega->sc & 1) ? 0x8000 : 0);
if (!(ega->crtc[0x17] & 0x02))
addr = (addr & ~0x10000) | ((ega->sc & 2) ? 0x10000 : 0);
dat[0] = ega->vram[addr];
dat[1] = ega->vram[addr | 0x1];
if (ega->seqregs[1] & 4)
ega->ma += 2;
else
ega->ma += 4;
ega->ma &= ega->vrammask;
p[0] = ega->pallook[ega->egapal[(dat[0] >> 6) & 3]];
p[1] = ega->pallook[ega->egapal[(dat[0] >> 4) & 3]];
p[2] = ega->pallook[ega->egapal[(dat[0] >> 2) & 3]];
p[3] = ega->pallook[ega->egapal[dat[0] & 3]];
p[4] = ega->pallook[ega->egapal[(dat[1] >> 6) & 3]];
p[5] = ega->pallook[ega->egapal[(dat[1] >> 4) & 3]];
p[6] = ega->pallook[ega->egapal[(dat[1] >> 2) & 3]];
p[7] = ega->pallook[ega->egapal[dat[1] & 3]];
p += 8;
}
}
@@ -286,15 +345,20 @@ ega_render_2bpp(ega_t *ega)
void
ega_render_4bpp_lowres(ega_t *ega)
{
int dl = ega->displine + ega->y_add;
int x, oddeven;
uint8_t dat, edat[4];
uint32_t addr;
uint32_t addr, *p;
if ((ega->displine + ega->y_add) < 0)
return;
for (x = 0; x <= ega->hdisp; x++) {
p = &buffer32->line[ega->displine + ega->y_add][ega->x_add];
if (ega->firstline_draw == 2000)
ega->firstline_draw = ega->displine;
ega->lastline_draw = ega->displine;
for (x = 0; x <= ega->hdisp; x += 16) {
addr = ega->ma;
oddeven = 0;
@@ -333,29 +397,20 @@ ega_render_4bpp_lowres(ega_t *ega)
ega->ma &= ega->vrammask;
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
buffer32->line[dl][(x << 4) + 14 + ega->x_add] =
buffer32->line[dl][(x << 4) + 15 + ega->x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]];
buffer32->line[dl][(x << 4) + 12 + ega->x_add] =
buffer32->line[dl][(x << 4) + 13 + ega->x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]];
dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
buffer32->line[dl][(x << 4) + 10 + ega->x_add] =
buffer32->line[dl][(x << 4) + 11 + ega->x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]];
buffer32->line[dl][(x << 4) + 8 + ega->x_add] =
buffer32->line[dl][(x << 4) + 9 + ega->x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]];
dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
buffer32->line[dl][(x << 4) + 6 + ega->x_add] =
buffer32->line[dl][(x << 4) + 7 + ega->x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]];
buffer32->line[dl][(x << 4) + 4 + ega->x_add] =
buffer32->line[dl][(x << 4) + 5 + ega->x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]];
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
buffer32->line[dl][(x << 4) + 2 + ega->x_add] =
buffer32->line[dl][(x << 4) + 3 + ega->x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]];
buffer32->line[dl][(x << 4) + ega->x_add] =
buffer32->line[dl][(x << 4) + 1 + ega->x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]];
p[0] = p[1] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
p[2] = p[3] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
p[4] = p[5] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
p[6] = p[7] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
p[8] = p[9] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
p[10] = p[11] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
p[12] = p[13] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
p[14] = p[15] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
p += 16;
}
}
@@ -363,15 +418,20 @@ ega_render_4bpp_lowres(ega_t *ega)
void
ega_render_4bpp_highres(ega_t *ega)
{
int dl = ega->displine + ega->y_add;
int x, oddeven;
uint8_t dat, edat[4];
uint32_t addr;
uint32_t addr, *p;
if ((ega->displine + ega->y_add) < 0)
return;
for (x = 0; x <= ega->hdisp; x++) {
p = &buffer32->line[ega->displine + ega->y_add][ega->x_add];
if (ega->firstline_draw == 2000)
ega->firstline_draw = ega->displine;
ega->lastline_draw = ega->displine;
for (x = 0; x <= ega->hdisp; x += 8) {
addr = ega->ma;
oddeven = 0;
@@ -400,28 +460,24 @@ ega_render_4bpp_highres(ega_t *ega)
edat[1] = edat[3] = 0;
ega->ma += 2;
} else {
edat[0] = ega->vram[addr];
edat[1] = ega->vram[addr | 0x1];
edat[2] = ega->vram[addr | 0x2];
edat[3] = ega->vram[addr | 0x3];
*(uint32_t *)(&edat[0]) = *(uint32_t *)(&ega->vram[addr]);
ega->ma += 4;
}
ega->ma &= ega->vrammask;
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
buffer32->line[dl][(x << 3) + 7 + ega->x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]];
buffer32->line[dl][(x << 3) + 6 + ega->x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]];
dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
buffer32->line[dl][(x << 3) + 5 + ega->x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]];
buffer32->line[dl][(x << 3) + 4 + ega->x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]];
dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
buffer32->line[dl][(x << 3) + 3 + ega->x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]];
buffer32->line[dl][(x << 3) + 2 + ega->x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]];
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
buffer32->line[dl][(x << 3) + 1 + ega->x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]];
buffer32->line[dl][(x << 3) + ega->x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]];
p[0] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
p[1] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
p[2] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
p[3] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
p[4] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
p[5] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
p[6] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
p[7] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
p += 8;
}
}

View File

@@ -35,7 +35,8 @@ void ega_render_overscan_right(ega_t *ega);
void ega_render_text_40(ega_t *ega);
void ega_render_text_80(ega_t *ega);
void ega_render_2bpp(ega_t *ega);
void ega_render_2bpp_lowres(ega_t *ega);
void ega_render_2bpp_highres(ega_t *ega);
void ega_render_4bpp_lowres(ega_t *ega);
void ega_render_4bpp_highres(ega_t *ega);

View File

@@ -333,8 +333,8 @@ void
svga_render_2bpp_lowres(svga_t *svga)
{
int changed_offset, x;
uint32_t *p;
uint8_t dat[2];
uint32_t addr, *p;
if ((svga->displine + svga->y_add) < 0)
return;
@@ -349,10 +349,33 @@ svga_render_2bpp_lowres(svga_t *svga)
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x += 16) {
dat[0] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000];
dat[1] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000 + 1];
svga->ma += 4;
svga->ma &= svga->vram_display_mask;
addr = svga->ma;
if (!(svga->crtc[0x17] & 0x40)) {
addr = (addr << 1) & svga->vram_mask;
addr &= ~7;
if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000))
addr |= 4;
if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000))
addr |= 4;
}
if (!(svga->crtc[0x17] & 0x01))
addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0);
if (!(svga->crtc[0x17] & 0x02))
addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0);
dat[0] = svga->vram[addr];
dat[1] = svga->vram[addr | 0x1];
if (svga->seqregs[1] & 4)
svga->ma += 2;
else
svga->ma += 4;
svga->ma &= svga->vram_mask;
p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]];
p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]];
@@ -373,8 +396,8 @@ void
svga_render_2bpp_highres(svga_t *svga)
{
int changed_offset, x;
uint32_t *p;
uint8_t dat[2];
uint32_t addr, *p;
if ((svga->displine + svga->y_add) < 0)
return;
@@ -384,15 +407,38 @@ svga_render_2bpp_highres(svga_t *svga)
if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) {
p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
if (svga->firstline_draw == 2000)
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x += 8) {
dat[0] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000];
dat[1] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000 + 1];
svga->ma += 4;
svga->ma &= svga->vram_display_mask;
addr = svga->ma;
if (!(svga->crtc[0x17] & 0x40)) {
addr = (addr << 1) & svga->vram_mask;
addr &= ~7;
if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000))
addr |= 4;
if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000))
addr |= 4;
}
if (!(svga->crtc[0x17] & 0x01))
addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0);
if (!(svga->crtc[0x17] & 0x02))
addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0);
dat[0] = svga->vram[addr];
dat[1] = svga->vram[addr | 0x1];
if (svga->seqregs[1] & 4)
svga->ma += 2;
else
svga->ma += 4;
svga->ma &= svga->vram_mask;
p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]];
p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]];
@@ -412,8 +458,8 @@ svga_render_2bpp_highres(svga_t *svga)
void
svga_render_4bpp_lowres(svga_t *svga)
{
int x;
uint32_t *p;
int x, oddeven;
uint32_t addr, *p;
uint8_t edat[4];
uint8_t dat;
@@ -428,9 +474,38 @@ svga_render_4bpp_lowres(svga_t *svga)
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x += 16) {
*(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma]);
svga->ma += 4;
svga->ma &= svga->vram_display_mask;
addr = svga->ma;
oddeven = 0;
if (!(svga->crtc[0x17] & 0x40)) {
addr = (addr << 1) & svga->vram_mask;
if (svga->seqregs[1] & 4)
oddeven = (addr & 4) ? 1 : 0;
addr &= ~7;
if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000))
addr |= 4;
if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000))
addr |= 4;
}
if (!(svga->crtc[0x17] & 0x01))
addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0);
if (!(svga->crtc[0x17] & 0x02))
addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0);
if (svga->seqregs[1] & 4) {
edat[0] = svga->vram[addr | oddeven];
edat[2] = svga->vram[addr | oddeven | 0x2];
edat[1] = edat[3] = 0;
svga->ma += 2;
} else {
*(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]);
svga->ma += 4;
}
svga->ma &= svga->vram_mask;
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
p[0] = p[1] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
@@ -455,7 +530,8 @@ void
svga_render_4bpp_highres(svga_t *svga)
{
int changed_offset, x;
uint32_t *p;
int oddeven;
uint32_t addr, *p;
uint8_t edat[4];
uint8_t dat;
@@ -472,9 +548,38 @@ svga_render_4bpp_highres(svga_t *svga)
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x += 8) {
*(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma | ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000]);
svga->ma += 4;
svga->ma &= svga->vram_display_mask;
addr = svga->ma;
oddeven = 0;
if (!(svga->crtc[0x17] & 0x40)) {
addr = (addr << 1) & svga->vram_mask;
if (svga->seqregs[1] & 4)
oddeven = (addr & 4) ? 1 : 0;
addr &= ~7;
if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000))
addr |= 4;
if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000))
addr |= 4;
}
if (!(svga->crtc[0x17] & 0x01))
addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0);
if (!(svga->crtc[0x17] & 0x02))
addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0);
if (svga->seqregs[1] & 4) {
edat[0] = svga->vram[addr | oddeven];
edat[2] = svga->vram[addr | oddeven | 0x2];
edat[1] = edat[3] = 0;
svga->ma += 2;
} else {
*(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]);
svga->ma += 4;
}
svga->ma &= svga->vram_mask;
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];