From 93d0db4d9b0cf07896c7d03ff1f2c2dff5ccf5e6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 15 Feb 2018 21:00:12 +0000 Subject: [PATCH] CL-GD5429 improvements : - Support >8 bpp on RAMDAC - Support 16-bit pixel depth on blitter - Support 16-bit pixel depth on write modes 4/5 - Support blitter on PIO - Support interlaced modes - Extended size of graphics controller register array to prevent out-of-bounds accesses --- src/vid_cl5429.c | 378 +++++++++++++++++++++++++++++++++++++++-------- src/vid_svga.c | 2 +- src/vid_svga.h | 2 +- 3 files changed, 318 insertions(+), 64 deletions(-) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 914a330..d3e0b81 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -35,6 +35,8 @@ typedef struct gd5429_t int x_count; } blt; + uint8_t hidden_dac_reg; + int dac_3c6_count; } gd5429_t; void gd5429_write(uint32_t addr, uint8_t val, void *p); @@ -74,20 +76,22 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) case 0x10: case 0x30: case 0x50: case 0x70: case 0x90: case 0xb0: case 0xd0: case 0xf0: svga->hwcursor.x = (val << 3) | ((svga->seqaddr >> 5) & 7); - pclog("svga->hwcursor.x = %i\n", svga->hwcursor.x); +// pclog("svga->hwcursor.x = %i\n", svga->hwcursor.x); break; case 0x11: case 0x31: case 0x51: case 0x71: case 0x91: case 0xb1: case 0xd1: case 0xf1: svga->hwcursor.y = (val << 3) | ((svga->seqaddr >> 5) & 7); - pclog("svga->hwcursor.y = %i\n", svga->hwcursor.y); +// pclog("svga->hwcursor.y = %i\n", svga->hwcursor.y); break; case 0x12: svga->hwcursor.ena = val & 1; - pclog("svga->hwcursor.ena = %i\n", svga->hwcursor.ena); + svga->hwcursor.ysize = (val & 4) ? 64 : 32; + svga->hwcursor.yoff = 0; +// pclog("svga->hwcursor.ena = %i\n", svga->hwcursor.ena); break; case 0x13: svga->hwcursor.addr = 0x1fc000 + ((val & 0x3f) * 256); - pclog("svga->hwcursor.addr = %x\n", svga->hwcursor.addr); +// pclog("svga->hwcursor.addr = %x\n", svga->hwcursor.addr); break; case 0x17: @@ -98,7 +102,24 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) } break; + case 0x3c6: +// pclog("CL write 3c6 %02x %i\n", val, gd5429->dac_3c6_count); + if (gd5429->dac_3c6_count == 4) + { + gd5429->dac_3c6_count = 0; + gd5429->hidden_dac_reg = val; + svga_recalctimings(svga); + return; + } + gd5429->dac_3c6_count = 0; + break; + case 0x3cf: +// pclog("Write GDC %02x %02x\n", svga->gdcaddr, val); + if (svga->gdcaddr == 0) + gd5429_mmio_write(0x00, val, gd5429); + if (svga->gdcaddr == 1) + gd5429_mmio_write(0x04, val, gd5429); if (svga->gdcaddr == 5) { svga->gdcreg[5] = val; @@ -133,6 +154,73 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) else svga->writemode = svga->gdcreg[5] & 3; break; + + case 0x10: + gd5429_mmio_write(0x01, val, gd5429); + break; + case 0x11: + gd5429_mmio_write(0x05, val, gd5429); + break; + + case 0x20: + gd5429_mmio_write(0x08, val, gd5429); + break; + case 0x21: + gd5429_mmio_write(0x09, val, gd5429); + break; + case 0x22: + gd5429_mmio_write(0x0a, val, gd5429); + break; + case 0x23: + gd5429_mmio_write(0x0b, val, gd5429); + break; + case 0x24: + gd5429_mmio_write(0x0c, val, gd5429); + break; + case 0x25: + gd5429_mmio_write(0x0d, val, gd5429); + break; + case 0x26: + gd5429_mmio_write(0x0e, val, gd5429); + break; + case 0x27: + gd5429_mmio_write(0x0f, val, gd5429); + break; + + case 0x28: + gd5429_mmio_write(0x10, val, gd5429); + break; + case 0x29: + gd5429_mmio_write(0x11, val, gd5429); + break; + case 0x2a: + gd5429_mmio_write(0x12, val, gd5429); + break; + + case 0x2c: + gd5429_mmio_write(0x14, val, gd5429); + break; + case 0x2d: + gd5429_mmio_write(0x15, val, gd5429); + break; + case 0x2e: + gd5429_mmio_write(0x16, val, gd5429); + break; + + case 0x2f: + gd5429_mmio_write(0x17, val, gd5429); + break; + case 0x30: + gd5429_mmio_write(0x18, val, gd5429); + break; + + case 0x32: + gd5429_mmio_write(0x1a, val, gd5429); + break; + + case 0x31: + gd5429_mmio_write(0x40, val, gd5429); + break; } return; } @@ -185,6 +273,16 @@ uint8_t gd5429_in(uint16_t addr, void *p) return svga->seqregs[svga->seqaddr & 0x3f]; } break; + + case 0x3c6: +// pclog("CL read 3c6 %i\n", gd5429->dac_3c6_count); + if (gd5429->dac_3c6_count == 4) + { + gd5429->dac_3c6_count = 0; + return gd5429->hidden_dac_reg; + } + gd5429->dac_3c6_count++; + break; case 0x3cf: if (svga->gdcaddr > 8) @@ -230,7 +328,7 @@ void gd5429_recalc_mapping(gd5429_t *gd5429) { svga_t *svga = &gd5429->svga; - pclog("Write mapping %02X %i\n", svga->gdcreg[6], svga->seqregs[0x17] & 0x04); +// pclog("Write mapping %02X %i\n", svga->gdcreg[6], svga->seqregs[0x17] & 0x04); switch (svga->gdcreg[6] & 0x0C) { case 0x0: /*128k at A0000*/ @@ -259,15 +357,45 @@ void gd5429_recalc_mapping(gd5429_t *gd5429) void gd5429_recalctimings(svga_t *svga) { -// gd5429_t *gd5429 = (gd5429_t *)svga->p; + gd5429_t *gd5429 = (gd5429_t *)svga->p; + + if (!svga->rowoffset) + svga->rowoffset = 0x100; + + svga->interlace = svga->crtc[0x1a] & 1; if (svga->seqregs[7] & 0x01) { svga->render = svga_render_8bpp_highres; + svga->bpp = 8; } svga->ma_latch |= ((svga->crtc[0x1b] & 0x01) << 16) | ((svga->crtc[0x1b] & 0xc) << 15); - pclog("MA now %05X %02X\n", svga->ma_latch, svga->crtc[0x1b]); +// pclog("MA now %05X %02X\n", svga->ma_latch, svga->crtc[0x1b]); + + if (gd5429->hidden_dac_reg & 0x80) + { + if (gd5429->hidden_dac_reg & 0x40) + { + switch (gd5429->hidden_dac_reg & 0xf) + { + case 0x0: + svga->render = svga_render_15bpp_highres; + svga->bpp = 15; + break; + case 0x1: + svga->render = svga_render_16bpp_highres; + svga->bpp = 16; + break; + case 0x5: + svga->render = svga_render_24bpp_highres; + svga->bpp = 24; + break; + } + } + else + svga->render = svga_render_15bpp_highres; + } } void gd5429_hwcursor_draw(svga_t *svga, int displine) @@ -276,8 +404,10 @@ void gd5429_hwcursor_draw(svga_t *svga, int displine) uint8_t dat[2]; int xx; int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - - pclog("HWcursor %i %i %i %i %x %02X %02X\n", svga->hwcursor_latch.x, svga->hwcursor_latch.y, offset, displine, svga->hwcursor_latch.addr, svga->vram[svga->hwcursor_latch.addr], svga->vram[svga->hwcursor_latch.addr + 0x80]); + + if (svga->interlace && svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 4; + for (x = 0; x < 32; x += 8) { dat[0] = svga->vram[svga->hwcursor_latch.addr]; @@ -298,6 +428,9 @@ void gd5429_hwcursor_draw(svga_t *svga, int displine) } svga->hwcursor_latch.addr++; } + + if (svga->interlace && !svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 4; } @@ -369,41 +502,117 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) switch (svga->writemode) { case 4: - pclog("Writemode 4 : %X ", addr); - addr <<= 1; - svga->changedvram[addr >> 12] = changeframecount; - pclog("%X %X\n", addr, val); - if (val & 0x80) - svga->vram[addr + 0] = svga->gdcreg[1]; - if (val & 0x40) - svga->vram[addr + 1] = svga->gdcreg[1]; - if (val & 0x20) - svga->vram[addr + 2] = svga->gdcreg[1]; - if (val & 0x10) - svga->vram[addr + 3] = svga->gdcreg[1]; - if (val & 0x08) - svga->vram[addr + 4] = svga->gdcreg[1]; - if (val & 0x04) - svga->vram[addr + 5] = svga->gdcreg[1]; - if (val & 0x02) - svga->vram[addr + 6] = svga->gdcreg[1]; - if (val & 0x01) - svga->vram[addr + 7] = svga->gdcreg[1]; + if (svga->gdcreg[0xb] & 0x10) + { +// pclog("Writemode 4 : %X ", addr); + addr <<= 2; + svga->changedvram[addr >> 12] = changeframecount; +// pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]); + if (val & 0x80) + { + svga->vram[addr + 0] = svga->gdcreg[1]; + svga->vram[addr + 1] = svga->gdcreg[0x11]; + } + if (val & 0x40) + { + svga->vram[addr + 2] = svga->gdcreg[1]; + svga->vram[addr + 3] = svga->gdcreg[0x11]; + } + if (val & 0x20) + { + svga->vram[addr + 4] = svga->gdcreg[1]; + svga->vram[addr + 5] = svga->gdcreg[0x11]; + } + if (val & 0x10) + { + svga->vram[addr + 6] = svga->gdcreg[1]; + svga->vram[addr + 7] = svga->gdcreg[0x11]; + } + if (val & 0x08) + { + svga->vram[addr + 8] = svga->gdcreg[1]; + svga->vram[addr + 9] = svga->gdcreg[0x11]; + } + if (val & 0x04) + { + svga->vram[addr + 10] = svga->gdcreg[1]; + svga->vram[addr + 11] = svga->gdcreg[0x11]; + } + if (val & 0x02) + { + svga->vram[addr + 12] = svga->gdcreg[1]; + svga->vram[addr + 13] = svga->gdcreg[0x11]; + } + if (val & 0x01) + { + svga->vram[addr + 14] = svga->gdcreg[1]; + svga->vram[addr + 15] = svga->gdcreg[0x11]; + } + } + else + { +// pclog("Writemode 4 : %X ", addr); + addr <<= 1; + svga->changedvram[addr >> 12] = changeframecount; +// pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]); + if (val & 0x80) + svga->vram[addr + 0] = svga->gdcreg[1]; + if (val & 0x40) + svga->vram[addr + 1] = svga->gdcreg[1]; + if (val & 0x20) + svga->vram[addr + 2] = svga->gdcreg[1]; + if (val & 0x10) + svga->vram[addr + 3] = svga->gdcreg[1]; + if (val & 0x08) + svga->vram[addr + 4] = svga->gdcreg[1]; + if (val & 0x04) + svga->vram[addr + 5] = svga->gdcreg[1]; + if (val & 0x02) + svga->vram[addr + 6] = svga->gdcreg[1]; + if (val & 0x01) + svga->vram[addr + 7] = svga->gdcreg[1]; + } break; case 5: - pclog("Writemode 5 : %X ", addr); - addr <<= 1; - svga->changedvram[addr >> 12] = changeframecount; - pclog("%X %X\n", addr, val); - svga->vram[addr + 0] = (val & 0x80) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 1] = (val & 0x40) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 2] = (val & 0x20) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 3] = (val & 0x10) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 4] = (val & 0x08) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 5] = (val & 0x04) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 6] = (val & 0x02) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 7] = (val & 0x01) ? svga->gdcreg[1] : svga->gdcreg[0]; + if (svga->gdcreg[0xb] & 0x10) + { +// pclog("Writemode 5 : %X ", addr); + addr <<= 2; + svga->changedvram[addr >> 12] = changeframecount; +// pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]); + svga->vram[addr + 0] = (val & 0x80) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 1] = (val & 0x80) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + svga->vram[addr + 2] = (val & 0x40) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 3] = (val & 0x40) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + svga->vram[addr + 4] = (val & 0x20) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 5] = (val & 0x20) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + svga->vram[addr + 6] = (val & 0x10) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 7] = (val & 0x10) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + svga->vram[addr + 8] = (val & 0x08) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 9] = (val & 0x08) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + svga->vram[addr + 10] = (val & 0x04) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 11] = (val & 0x04) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + svga->vram[addr + 12] = (val & 0x02) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 13] = (val & 0x02) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + svga->vram[addr + 14] = (val & 0x01) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 15] = (val & 0x01) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + } + else + { +// pclog("Writemode 5 : %X ", addr); + addr <<= 1; + svga->changedvram[addr >> 12] = changeframecount; +// pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]); + svga->vram[addr + 0] = (val & 0x80) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 1] = (val & 0x40) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 2] = (val & 0x20) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 3] = (val & 0x10) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 4] = (val & 0x08) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 5] = (val & 0x04) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 6] = (val & 0x02) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 7] = (val & 0x01) ? svga->gdcreg[1] : svga->gdcreg[0]; + } break; case 1: @@ -415,7 +624,7 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) case 0: if (svga->gdcreg[3] & 7) val = svga_rotate[svga->gdcreg[3] & 7][val]; - if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) + if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || (svga->seqregs[7] & 1))) { if (writemask2 & 1) svga->vram[addr] = val; if (writemask2 & 2) svga->vram[addr | 0x1] = val; @@ -552,8 +761,12 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) { gd5429_t *gd5429 = (gd5429_t *)p; svga_t *svga = &gd5429->svga; + int blt_mask = gd5429->blt.mask & 7; - pclog("gd5429_start_blit %i\n", count); + if (gd5429->blt.mode & 0x10) + blt_mask *= 2; + +// pclog("gd5429_start_blit %i\n", count); if (count == -1) { gd5429->blt.dst_addr_backup = gd5429->blt.dst_addr; @@ -561,7 +774,9 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) gd5429->blt.width_backup = gd5429->blt.width; gd5429->blt.height_internal = gd5429->blt.height; gd5429->blt.x_count = gd5429->blt.mask & 7; - pclog("gd5429_start_blit : size %i, %i\n", gd5429->blt.width, gd5429->blt.height); + if (gd5429->blt.mode & 0x10) + gd5429->blt.x_count *= 2; +// pclog("gd5429_start_blit : size %i, %i %i\n", gd5429->blt.width, gd5429->blt.height, gd5429->blt.x_count); if (gd5429->blt.mode & 0x04) { @@ -577,6 +792,8 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) gd5429_recalc_mapping(gd5429); } } + else if (gd5429->blt.height_internal == 0xffff) + return; while (count) { @@ -587,6 +804,8 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) { if (gd5429->blt.mode & 0x80) { + if (gd5429->blt.mode & 0x10) + fatal("Here blt.mode & 0x10\n"); src = (cpu_dat & 0x80) ? gd5429->blt.fg_col : gd5429->blt.bg_col; mask = cpu_dat & 0x80; cpu_dat <<= 1; @@ -610,22 +829,54 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) mask = 1; break; case 0x40: - src = svga->vram[(gd5429->blt.src_addr & (svga->vram_mask & ~7)) | (gd5429->blt.dst_addr & 7)]; + if (gd5429->blt.mode & 0x10) + src = svga->vram[(gd5429->blt.src_addr & (svga->vram_mask & ~15)) | (gd5429->blt.dst_addr & 15)]; + else + src = svga->vram[(gd5429->blt.src_addr & (svga->vram_mask & ~7)) | (gd5429->blt.dst_addr & 7)]; mask = 1; break; case 0x80: - mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> gd5429->blt.x_count); - src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; - gd5429->blt.x_count++; - if (gd5429->blt.x_count == 8) + if (gd5429->blt.mode & 0x10) { - gd5429->blt.x_count = 0; - gd5429->blt.src_addr++; + mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> (gd5429->blt.x_count >> 1)); + if (gd5429->blt.dst_addr & 1) + src = mask ? (gd5429->blt.fg_col >> 8) : (gd5429->blt.bg_col >> 8); + else + src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; +// pclog(" src=%02x mask=%i fg_col=%04x bg_col=%04x %i %08x\n", src, mask, gd5429->blt.fg_col, gd5429->blt.bg_col, gd5429->blt.x_count, gd5429->blt.src_addr); + gd5429->blt.x_count++; + if (gd5429->blt.x_count == 16) + { + gd5429->blt.x_count = 0; + gd5429->blt.src_addr++; + } + } + else + { + mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> gd5429->blt.x_count); + src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; + gd5429->blt.x_count++; + if (gd5429->blt.x_count == 8) + { + gd5429->blt.x_count = 0; + gd5429->blt.src_addr++; + } } break; - case 0xc0: - mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> (gd5429->blt.dst_addr & 7)); - src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; + case 0xc0: + if (gd5429->blt.mode & 0x10) + { + mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> ((gd5429->blt.dst_addr >> 1) & 7)); + if (gd5429->blt.dst_addr & 1) + src = mask ? (gd5429->blt.fg_col >> 8) : (gd5429->blt.bg_col >> 8); + else + src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; + } + else + { + mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> (gd5429->blt.dst_addr & 7)); + src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; + } break; } count--; @@ -633,7 +884,7 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) dst = svga->vram[gd5429->blt.dst_addr & svga->vram_mask]; svga->changedvram[(gd5429->blt.dst_addr & svga->vram_mask) >> 12] = changeframecount; - pclog("Blit %i,%i %06X %06X %06X %02X %02X %02X %02X ", gd5429->blt.width, gd5429->blt.height_internal, gd5429->blt.src_addr, gd5429->blt.dst_addr, gd5429->blt.src_addr & svga->vram_mask, svga->vram[gd5429->blt.src_addr & svga->vram_mask], 0x80 >> (gd5429->blt.dst_addr & 7), src, dst); +// pclog("Blit %i,%i %06X %06X %06X %02X %02X %02X %02X ", gd5429->blt.width, gd5429->blt.height_internal, gd5429->blt.src_addr, gd5429->blt.dst_addr, gd5429->blt.src_addr & svga->vram_mask, svga->vram[gd5429->blt.src_addr & svga->vram_mask], 0x80 >> (gd5429->blt.dst_addr & 7), src, dst); switch (gd5429->blt.rop) { case 0x00: dst = 0; break; @@ -653,9 +904,9 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) case 0xd6: dst = ~src | dst; break; case 0xda: dst = ~(src & dst); break; } - pclog("%02X %02X\n", dst, mask); + //pclog("%02X %02X\n", dst, mask); - if ((gd5429->blt.width_backup - gd5429->blt.width) >= (gd5429->blt.mask & 7) && + if ((gd5429->blt.width_backup - gd5429->blt.width) >= blt_mask && !((gd5429->blt.mode & 0x08) && !mask)) svga->vram[gd5429->blt.dst_addr & svga->vram_mask] = dst; @@ -675,7 +926,10 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) gd5429->blt.src_addr = gd5429->blt.src_addr_backup = gd5429->blt.src_addr_backup + ((gd5429->blt.mode & 0x01) ? -gd5429->blt.src_pitch : gd5429->blt.src_pitch); break; case 0x40: - gd5429->blt.src_addr = ((gd5429->blt.src_addr + ((gd5429->blt.mode & 0x01) ? -8 : 8)) & 0x38) | (gd5429->blt.src_addr & ~0x38); + if (gd5429->blt.mode & 0x10) + gd5429->blt.src_addr = ((gd5429->blt.src_addr + ((gd5429->blt.mode & 0x01) ? -16 : 16)) & 0x70) | (gd5429->blt.src_addr & ~0x70); + else + gd5429->blt.src_addr = ((gd5429->blt.src_addr + ((gd5429->blt.mode & 0x01) ? -8 : 8)) & 0x38) | (gd5429->blt.src_addr & ~0x38); break; case 0x80: if (gd5429->blt.x_count != 0) @@ -711,7 +965,7 @@ void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p) { gd5429_t *gd5429 = (gd5429_t *)p; - pclog("MMIO write %08X %02X\n", addr, val); +// pclog("MMIO write %08X %02X\n", addr, val); switch (addr & 0xff) { case 0x00: @@ -795,7 +1049,7 @@ uint8_t gd5429_mmio_read(uint32_t addr, void *p) { // gd5429_t *gd5429 = (gd5429_t *)p; - pclog("MMIO read %08X\n", addr); +// pclog("MMIO read %08X\n", addr); switch (addr & 0xff) { case 0x40: /*BLT status*/ @@ -806,7 +1060,7 @@ uint8_t gd5429_mmio_read(uint32_t addr, void *p) void gd5429_blt_write_w(uint32_t addr, uint16_t val, void *p) { - pclog("gd5429_blt_write_w %08X %08X\n", addr, val); +// pclog("gd5429_blt_write_w %08X %08X\n", addr, val); gd5429_start_blit(val, 16, p); } @@ -814,7 +1068,7 @@ void gd5429_blt_write_l(uint32_t addr, uint32_t val, void *p) { gd5429_t *gd5429 = (gd5429_t *)p; - pclog("gd5429_blt_write_l %08X %08X %04X %04X\n", addr, val, ((val >> 8) & 0x00ff) | ((val << 8) & 0xff00), ((val >> 24) & 0x00ff) | ((val >> 8) & 0xff00)); +// pclog("gd5429_blt_write_l %08X %08X %04X %04X\n", addr, val, ((val >> 8) & 0x00ff) | ((val << 8) & 0xff00), ((val >> 24) & 0x00ff) | ((val >> 8) & 0xff00)); if ((gd5429->blt.mode & 0x84) == 0x84) { gd5429_start_blit( val & 0xff, 8, p); diff --git a/src/vid_svga.c b/src/vid_svga.c index 8817ca9..b98f460 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -501,7 +501,7 @@ void svga_poll(void *p) } if (svga->hwcursor_on || svga->overlay_on) - svga->changedvram[svga->ma >> 12] = svga->changedvram[(svga->ma >> 12) + 1] = 2; + svga->changedvram[svga->ma >> 12] = svga->changedvram[(svga->ma >> 12) + 1] = svga->interlace ? 3 : 2; if (!svga->override) svga->render(svga); diff --git a/src/vid_svga.h b/src/vid_svga.h index f3455a3..5c89483 100644 --- a/src/vid_svga.h +++ b/src/vid_svga.h @@ -4,7 +4,7 @@ typedef struct svga_t uint8_t crtcreg; uint8_t crtc[128]; - uint8_t gdcreg[16]; + uint8_t gdcreg[64]; int gdcaddr; uint8_t attrregs[32]; int attraddr, attrff;