diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 20fd9ac35..fac75e163 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -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; diff --git a/src/video/vid_ega.h b/src/video/vid_ega.h index 841d86ced..f64da0a01 100644 --- a/src/video/vid_ega.h +++ b/src/video/vid_ega.h @@ -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]; diff --git a/src/video/vid_ega_render.c b/src/video/vid_ega_render.c index 46b0948ea..e5bcc9fb0 100644 --- a/src/video/vid_ega_render.c +++ b/src/video/vid_ega_render.c @@ -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; } } diff --git a/src/video/vid_ega_render.h b/src/video/vid_ega_render.h index 3a0c8f092..a905fc5dd 100644 --- a/src/video/vid_ega_render.h +++ b/src/video/vid_ega_render.h @@ -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); diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 4e02268d3..04a1f7219 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -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]];