From 633447710e3a194b615c62f35d224c188dc03aee Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 7 Aug 2022 20:48:20 +0300 Subject: [PATCH] Fix wrong 24-bit/32-bit colors in hardware emulated RTG board that swap R and B color channels in hardware. --- pcem/vid_svga.cpp | 10 +++ pcem/vid_svga_render.cpp | 167 ++++++++++++++++++++++++++++++++++++++- pcem/vid_svga_render.h | 4 + 3 files changed, 179 insertions(+), 2 deletions(-) diff --git a/pcem/vid_svga.cpp b/pcem/vid_svga.cpp index c2a55226..f01681ba 100644 --- a/pcem/vid_svga.cpp +++ b/pcem/vid_svga.cpp @@ -498,6 +498,16 @@ void svga_recalctimings(svga_t *svga) if (svga->render == svga_render_32bpp_highres) svga->render = svga_render_32bpp_lowres; } + if (svga->swaprb) { + if (svga->render == svga_render_24bpp_lowres) + svga->render = svga_render_24bpp_lowres_swaprb; + if (svga->render == svga_render_24bpp_highres) + svga->render = svga_render_24bpp_highres_swaprb; + if (svga->render == svga_render_32bpp_lowres) + svga->render = svga_render_32bpp_lowres_swaprb; + if (svga->render == svga_render_32bpp_highres) + svga->render = svga_render_32bpp_highres_swaprb; + } } crtcconst = svga->clock * svga->char_width; diff --git a/pcem/vid_svga_render.cpp b/pcem/vid_svga_render.cpp index a3514c99..19578df0 100644 --- a/pcem/vid_svga_render.cpp +++ b/pcem/vid_svga_render.cpp @@ -844,6 +844,49 @@ void svga_render_24bpp_lowres(svga_t *svga) } } +void svga_render_24bpp_lowres_swaprb(svga_t *svga) +{ + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || 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 == 4000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) + { + for (x = 0; x <= svga->hdisp << svga->horizontal_linedbl; x++) + { + uint32_t fg = svga->vram[svga->ma + 2] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 0] << 16); + svga->ma += 3; + svga->ma &= svga->vram_display_mask; + p[0] = p[1] = fg; + p += 2; + } + } + else + { + for (x = 0; x <= svga->hdisp << svga->horizontal_linedbl; x++) + { + uint32_t addr; + + addr = svga->remap_func(svga, svga->ma); + uint32_t fg = svga->vram[addr + 2] | (svga->vram[addr + 1] << 8) | (svga->vram[addr + 0] << 16); + svga->ma += 3; + svga->ma &= svga->vram_display_mask; + p[0] = p[1] = fg; + p += 2; + } + } + } +} + + void svga_render_24bpp_highres(svga_t *svga) { uint32_t changed_addr = svga->remap_func(svga, svga->ma); @@ -900,6 +943,45 @@ void svga_render_24bpp_highres(svga_t *svga) } } +void svga_render_24bpp_highres_swaprb(svga_t *svga) +{ + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || 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 == 4000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) + { + for (x = 0; x <= svga->hdisp; x++) + { + uint32_t fg = svga->vram[svga->ma + 2] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 0] << 16); + svga->ma += 3; + svga->ma &= svga->vram_display_mask; + *p++ = fg; + } + } + else + { + for (x = 0; x <= svga->hdisp; x += 4) + { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t fg = svga->vram[addr + 2] | (svga->vram[addr + 1] << 8) | (svga->vram[addr + 0] << 16); + svga->ma += 3; + svga->ma &= svga->vram_display_mask; + *p++ = fg; + } + } + svga->ma &= svga->vram_display_mask; + } +} + void svga_render_32bpp_lowres(svga_t *svga) { uint32_t changed_addr = svga->remap_func(svga, svga->ma); @@ -939,8 +1021,48 @@ void svga_render_32bpp_lowres(svga_t *svga) } } -/*72% - 91%*/ +void svga_render_32bpp_lowres_swaprb(svga_t *svga) +{ + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || 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 == 4000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) + { + for (x = 0; x <= svga->hdisp << svga->horizontal_linedbl; x++) + { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + dat = ((dat & 0xff0000) >> 16) | ((dat & 0x0000ff) << 16) | ((dat & 0x00ff00)); + *p++ = dat & 0xffffff; + *p++ = dat & 0xffffff; + } + svga->ma += x * 4; + } + else + { + for (x = 0; x <= svga->hdisp << svga->horizontal_linedbl; x++) + { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr]); + dat = ((dat & 0xff0000) >> 16) | ((dat & 0x0000ff) << 16) | ((dat & 0x00ff00)); + *p++ = dat & 0xffffff; + *p++ = dat & 0xffffff; + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; + } +} + + void svga_render_32bpp_highres(svga_t *svga) { uint32_t changed_addr = svga->remap_func(svga, svga->ma); @@ -979,6 +1101,47 @@ void svga_render_32bpp_highres(svga_t *svga) } } +void svga_render_32bpp_highres_swaprb(svga_t *svga) +{ + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || 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 == 4000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) + { + for (x = 0; x <= svga->hdisp; x++) + { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + dat = ((dat & 0xff0000) >> 16) | ((dat & 0x0000ff) << 16) | ((dat & 0x00ff00)); + *p++ = dat & 0xffffff; + } + svga->ma += x * 4; + } + else + { + for (x = 0; x <= svga->hdisp; x++) + { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + dat = ((dat & 0xff0000) >> 16) | ((dat & 0x0000ff) << 16) | ((dat & 0x00ff00)); + *p++ = dat & 0xffffff; + svga->ma += 4; + } + } + + svga->ma &= svga->vram_display_mask; + } +} + + void svga_render_ABGR8888_highres(svga_t *svga) { uint32_t changed_addr = svga->remap_func(svga, svga->ma); diff --git a/pcem/vid_svga_render.h b/pcem/vid_svga_render.h index e0f81e5e..2a94c57f 100644 --- a/pcem/vid_svga_render.h +++ b/pcem/vid_svga_render.h @@ -28,9 +28,13 @@ void svga_render_15bpp_highres(svga_t *svga); void svga_render_16bpp_lowres(svga_t *svga); void svga_render_16bpp_highres(svga_t *svga); void svga_render_24bpp_lowres(svga_t *svga); +void svga_render_24bpp_lowres_swaprb(svga_t *svga); void svga_render_24bpp_highres(svga_t *svga); +void svga_render_24bpp_highres_swaprb(svga_t *svga); void svga_render_32bpp_lowres(svga_t *svga); +void svga_render_32bpp_lowres_swaprb(svga_t *svga); void svga_render_32bpp_highres(svga_t *svga); +void svga_render_32bpp_highres_swaprb(svga_t *svga); void svga_render_ABGR8888_highres(svga_t *svga); void svga_render_RGBA8888_highres(svga_t *svga); -- 2.47.3