From 54b400aa056323cbcca79c32f6f4133d2bea9d77 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 21 Feb 2018 12:58:35 +0100 Subject: [PATCH] Corrected interlacing in the TVGA8900CL/D and Oak OTI cards. Removed leftover code from PCem-X in the TVGA8900CL/D and ET4000AX cards. Added correct Cirrus Logic GD5434 PCI/VLB code. --- src/video/vid_cl54xx.c | 446 ++++++++++++++++++++++++++++------------- src/video/vid_cl54xx.h | 2 + src/video/vid_et4000.c | 13 -- src/video/vid_oti067.c | 8 +- src/video/vid_table.c | 2 + src/video/vid_tvga.c | 24 +-- src/video/video.h | 8 +- 7 files changed, 318 insertions(+), 185 deletions(-) diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index d3f545400..5ec90d34b 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -6,8 +6,8 @@ * * This file is part of the 86Box distribution. * - * Emulation of select Cirrus Logic cards (currently only - * CL-GD 5428, 5429 and 5430 are fully supported). + * Emulation of select Cirrus Logic cards (currently + * CL-GD 5428, 5429, 5430 and 5434 are supported). * * Version: @(#)vid_cl_54xx.c 1.0.1 2018/02/19 * @@ -41,13 +41,16 @@ #define BIOS_GD5428_ISA_PATH L"roms/video/cirruslogic/5428.bin" #define BIOS_GD5428_VLB_PATH L"roms/video/cirruslogic/Diamond SpeedStar PRO VLB (Cirrus Logic 5428)_v3.04.bin" -#define BIOS_GD5429_PATH L"roms/video/cirruslogic/5429.vbi" +#define BIOS_GD5429_PATH L"roms/video/cirruslogic/5429.vbi" #define BIOS_GD5430_VLB_PATH L"roms/video/cirruslogic/diamondvlbus.bin" #define BIOS_GD5430_PCI_PATH L"roms/video/cirruslogic/pci.bin" +#define BIOS_GD5434_PATH L"roms/video/cirruslogic/gd5434.bin" #define CIRRUS_ID_CLGD5428 0x98 #define CIRRUS_ID_CLGD5429 0x9c #define CIRRUS_ID_CLGD5430 0xa0 +#define CIRRUS_ID_CLGD5434 0xa8 +#define CIRRUS_ID_CLGD5446 0xb8 /* sequencer 0x07 */ #define CIRRUS_SR7_BPP_VGA 0x00 @@ -99,11 +102,10 @@ typedef struct gd54xx_t struct { uint8_t state; int ctrl; - PALETTE pal; } ramdac; struct { - uint16_t fg_col, bg_col; + uint32_t fg_col, bg_col; uint16_t width, height; uint16_t dst_pitch, src_pitch; uint32_t dst_addr, src_addr; @@ -186,7 +188,7 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) svga->hwcursor.ena = val & 1; break; case 0x13: - svga->hwcursor.addr = (0x1fc000 + ((val & 0x3f) * 256)); + svga->hwcursor.addr = ((gd54xx->vram_size << 20)-0x4000) + ((val & 0x3f) * 256); break; case 0x07: svga->set_reset_disabled = svga->seqregs[7] & 1; @@ -202,58 +204,11 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) if (gd54xx->ramdac.state == 4) { gd54xx->ramdac.state = 0; gd54xx->ramdac.ctrl = val; - - if (svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) { - switch (svga->seqregs[0x07] & CIRRUS_SR7_BPP_MASK) { - case CIRRUS_SR7_BPP_8: - svga->bpp = 8; - break; - case CIRRUS_SR7_BPP_16_DOUBLEVCLK: - case CIRRUS_SR7_BPP_16: - if (gd54xx->ramdac.ctrl & 0x01) - svga->bpp = 16; - else - svga->bpp = 15; - break; - case CIRRUS_SR7_BPP_24: - svga->bpp = 24; - break; - case CIRRUS_SR7_BPP_32: - svga->bpp = 32; - break; - } - } svga_recalctimings(svga); return; } gd54xx->ramdac.state = 0; break; - case 0x3C7: case 0x3C8: - gd54xx->ramdac.state = 0; - break; - case 0x3C9: - if (svga->seqregs[0x12] & CIRRUS_CURSOR_HIDDENPEL) { - gd54xx->ramdac.state = 0; - svga->fullchange = changeframecount; - switch (svga->dac_pos) { - case 0: - gd54xx->ramdac.pal[svga->dac_write & 0xf].r = val & 63; - svga->dac_pos++; - break; - case 1: - gd54xx->ramdac.pal[svga->dac_write & 0xf].g = val & 63; - svga->dac_pos++; - break; - case 2: - gd54xx->ramdac.pal[svga->dac_write & 0xf].b = val & 63; - svga->dac_pos = 0; - svga->dac_write = (svga->dac_write + 1) & 255; - break; - } - return; - } - gd54xx->ramdac.state = 0; - break; case 0x3cf: if (svga->gdcaddr == 0) gd543x_mmio_write(0x00, val, gd54xx); @@ -287,6 +242,18 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) case 0x11: gd543x_mmio_write(0x05, val, gd54xx); break; + case 0x12: + gd543x_mmio_write(0x02, val, gd54xx); + break; + case 0x13: + gd543x_mmio_write(0x06, val, gd54xx); + break; + case 0x14: + gd543x_mmio_write(0x03, val, gd54xx); + break; + case 0x15: + gd543x_mmio_write(0x07, val, gd54xx); + break; case 0x20: gd543x_mmio_write(0x08, val, gd54xx); @@ -412,27 +379,6 @@ gd54xx_in(uint16_t addr, void *p) } gd54xx->ramdac.state++; break; - case 0x3C7: case 0x3C8: - gd54xx->ramdac.state = 0; - break; - case 0x3C9: - if (svga->seqregs[0x12] & CIRRUS_CURSOR_HIDDENPEL) { - gd54xx->ramdac.state = 0; - switch (svga->dac_pos) { - case 0: - svga->dac_pos++; - return gd54xx->ramdac.pal[svga->dac_read & 0xf].r; - case 1: - svga->dac_pos++; - return gd54xx->ramdac.pal[svga->dac_read & 0xf].g; - case 2: - svga->dac_pos=0; - svga->dac_read = (svga->dac_read + 1) & 255; - return gd54xx->ramdac.pal[(svga->dac_read - 1) & 15].b; - } - } - gd54xx->ramdac.state = 0; - break; case 0x3cf: if (svga->gdcaddr > 8) { return svga->gdcreg[svga->gdcaddr & 0x3f]; @@ -467,13 +413,13 @@ gd54xx_recalc_banking(gd54xx_t *gd54xx) svga_t *svga = &gd54xx->svga; if (svga->gdcreg[0xb] & 0x20) - gd54xx->bank[0] = svga->gdcreg[0x09] << 14; + gd54xx->bank[0] = (svga->gdcreg[0x09] & 0xff) << 14; else gd54xx->bank[0] = svga->gdcreg[0x09] << 12; if (svga->gdcreg[0xb] & 0x01) { if (svga->gdcreg[0xb] & 0x20) - gd54xx->bank[1] = svga->gdcreg[0x0a] << 14; + gd54xx->bank[1] = (svga->gdcreg[0x0a] & 0xff) << 14; else gd54xx->bank[1] = svga->gdcreg[0x0a] << 12; } else @@ -497,7 +443,7 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) mem_mapping_disable(&gd54xx->linear_mapping); switch (svga->gdcreg[6] & 0x0C) { case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); mem_mapping_disable(&gd54xx->mmio_mapping); svga->banked_mask = 0xffff; break; @@ -550,35 +496,48 @@ gd54xx_recalctimings(svga_t *svga) { gd54xx_t *gd54xx = (gd54xx_t *)svga->p; uint8_t clocksel; - - svga->rowoffset = (svga->crtc[0x13]) | ((svga->crtc[0x1b] & 0x10) << 4); + + svga->rowoffset = (svga->crtc[0x13]) | ((svga->crtc[0x1b] & 0x10) << 4); + + svga->interlace = (svga->crtc[0x1a] & 0x01); svga->ma_latch = (svga->crtc[0x0c] << 8) - + svga->crtc[0x0d] - + ((svga->crtc[0x1b] & 0x01) << 16) - + ((svga->crtc[0x1b] & 0x0c) << 15) - + ((svga->crtc[0x1d] & 0x80) << 12); - - svga->interlace = (svga->crtc[0x1a] & 0x01); - - if (svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) { - switch (svga->bpp) { - case 8: - svga->render = svga_render_8bpp_highres; - break; - case 15: - svga->render = svga_render_15bpp_highres; - break; - case 16: - svga->render = svga_render_16bpp_highres; - break; - case 24: - svga->render = svga_render_24bpp_highres; - break; - case 32: - svga->render = svga_render_32bpp_highres; - break; - } + | svga->crtc[0x0d] + | ((svga->crtc[0x1b] & 0x01) << 16) + | ((svga->crtc[0x1b] & 0x0c) << 15) + | ((svga->crtc[0x1d] & 0x80) << 12); + + if (svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) + { + switch (svga->seqregs[0x07] & CIRRUS_SR7_BPP_MASK) + { + case CIRRUS_SR7_BPP_8: + svga->bpp = 8; + svga->render = svga_render_8bpp_highres; + break; + case CIRRUS_SR7_BPP_16_DOUBLEVCLK: + case CIRRUS_SR7_BPP_16: + if (gd54xx->ramdac.ctrl & 0x01) + { + svga->bpp = 16; + svga->render = svga_render_16bpp_highres; + } + else + { + svga->bpp = 15; + svga->render = svga_render_15bpp_highres; + } + break; + case CIRRUS_SR7_BPP_24: + svga->bpp = 24; + svga->render = svga_render_24bpp_highres; + break; + case CIRRUS_SR7_BPP_32: + svga->bpp = 32; + svga->render = svga_render_32bpp_highres; + svga->rowoffset *= 2; + break; + } } clocksel = (svga->miscout >> 2) & 3; @@ -590,6 +549,15 @@ gd54xx_recalctimings(svga_t *svga) int d = (gd54xx->vclk_d[clocksel] & 0x3e) >> 1; int m = gd54xx->vclk_d[clocksel] & 0x01 ? 2 : 1; float freq = (14318184.0 * ((float)n / ((float)d * m))); + switch (svga->seqregs[7] & ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5434) ? 0xe : 6)) + { + case 2: + freq /= 2.0; + break; + case 4: + freq /= 3.0; + break; + } svga->clock = cpuclock / freq; } @@ -1130,20 +1098,49 @@ static void gd543x_mmio_write(uint32_t addr, uint8_t val, void *p) { gd54xx_t *gd54xx = (gd54xx_t *)p; + svga_t *svga = &gd54xx->svga; switch (addr & 0xff) { case 0x00: - gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0xff00) | val; + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5434) + gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0xffffff00) | val; + else + gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0xff00) | val; break; case 0x01: - gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0x00ff) | (val << 8); + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5434) + gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0xffff00ff) | (val << 8); + else + gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0x00ff) | (val << 8); + break; + case 0x02: + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5434) + gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0xff00ffff) | (val << 16); + break; + case 0x03: + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5434) + gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0x00ffffff) | (val << 24); break; case 0x04: - gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0xff00) | val; + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5434) + gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0xffffff00) | val; + else + gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0xff00) | val; break; case 0x05: - gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0x00ff) | (val << 8); + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5434) + gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0xffff00ff) | (val << 8); + else + gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0x00ff) | (val << 8); + break; + case 0x06: + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5434) + gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0xff00ffff) | (val << 16); + break; + case 0x07: + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5434) + gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0x00ffffff) | (val << 24); break; case 0x08: @@ -1151,12 +1148,17 @@ gd543x_mmio_write(uint32_t addr, uint8_t val, void *p) break; case 0x09: gd54xx->blt.width = (gd54xx->blt.width & 0x00ff) | (val << 8); + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5434) + gd54xx->blt.width &= 0x1fff; + else + gd54xx->blt.width &= 0x07ff; break; case 0x0a: gd54xx->blt.height = (gd54xx->blt.height & 0xff00) | val; break; case 0x0b: gd54xx->blt.height = (gd54xx->blt.height & 0x00ff) | (val << 8); + gd54xx->blt.height &= 0x03ff; break; case 0x0c: gd54xx->blt.dst_pitch = (gd54xx->blt.dst_pitch & 0xff00) | val; @@ -1179,6 +1181,10 @@ gd543x_mmio_write(uint32_t addr, uint8_t val, void *p) break; case 0x12: gd54xx->blt.dst_addr = (gd54xx->blt.dst_addr & 0x00ffff) | (val << 16); + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5434) + gd54xx->blt.dst_addr &= 0x3fffff; + else + gd54xx->blt.dst_addr &= 0x1fffff; break; case 0x14: @@ -1189,6 +1195,10 @@ gd543x_mmio_write(uint32_t addr, uint8_t val, void *p) break; case 0x16: gd54xx->blt.src_addr = (gd54xx->blt.src_addr & 0x00ffff) | (val << 16); + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5434) + gd54xx->blt.src_addr &= 0x3fffff; + else + gd54xx->blt.src_addr &= 0x1fffff; break; case 0x17: @@ -1212,7 +1222,7 @@ gd543x_mmio_write(uint32_t addr, uint8_t val, void *p) gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr; gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr; } else - gd54xx_start_blit(0, -1, gd54xx, &gd54xx->svga); + gd54xx_start_blit(0, -1, gd54xx, svga); } break; } @@ -1234,9 +1244,22 @@ static void gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) { int blt_mask = gd54xx->blt.mask & 7; + int x_max = 0; - if (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTH16) - blt_mask *= 2; + switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) + { + case CIRRUS_BLTMODE_PIXELWIDTH8: + x_max = 8; + break; + case CIRRUS_BLTMODE_PIXELWIDTH16: + x_max = 16; + blt_mask *= 2; + break; + case CIRRUS_BLTMODE_PIXELWIDTH32: + x_max = 32; + blt_mask *= 4; + break; + } if (count == -1) { gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr; @@ -1284,15 +1307,41 @@ gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) if (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSSRC) { if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) { - if ((gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTH16) && (gd54xx->blt.x_count & 1)) - src = (cpu_dat & 0x80) ? (gd54xx->blt.fg_col >> 8) : (gd54xx->blt.bg_col >> 8); - else - src = (cpu_dat & 0x80) ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; mask = cpu_dat & 0x80; - if (!(gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTH16) || (gd54xx->blt.x_count & 1)) + + switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { + case CIRRUS_BLTMODE_PIXELWIDTH8: + src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; cpu_dat <<= 1; count--; + break; + case CIRRUS_BLTMODE_PIXELWIDTH16: + if (gd54xx->blt.x_count & 1) + src = mask ? (gd54xx->blt.fg_col >> 8) : (gd54xx->blt.bg_col >> 8); + else + src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; + if (gd54xx->blt.x_count & 1) + { + cpu_dat <<= 1; + count--; + } + break; + case CIRRUS_BLTMODE_PIXELWIDTH32: + if ((gd54xx->blt.x_count & 3) == 3) + src = mask ? (gd54xx->blt.fg_col >> 24) : (gd54xx->blt.bg_col >> 24); + else if ((gd54xx->blt.x_count & 3) == 2) + src = mask ? (gd54xx->blt.fg_col >> 16) : (gd54xx->blt.bg_col >> 16); + else if ((gd54xx->blt.x_count & 3) == 1) + src = mask ? (gd54xx->blt.fg_col >> 8) : (gd54xx->blt.bg_col >> 8); + else + src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; + if ((gd54xx->blt.x_count & 3) == 3) + { + cpu_dat <<= 1; + count--; + } + break; } } } else { @@ -1303,34 +1352,72 @@ gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) mask = 1; break; case CIRRUS_BLTMODE_PATTERNCOPY: - if (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTH16) - src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~3)) + (gd54xx->blt.y_count << 4) + (gd54xx->blt.x_count & 15)]; - else - src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~7)) + (gd54xx->blt.y_count << 3) + (gd54xx->blt.x_count & 7)]; + switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) + { + case CIRRUS_BLTMODE_PIXELWIDTH8: + src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~7)) + (gd54xx->blt.y_count << 3) + (gd54xx->blt.x_count & 7)]; + break; + case CIRRUS_BLTMODE_PIXELWIDTH16: + src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~3)) + (gd54xx->blt.y_count << 4) + (gd54xx->blt.x_count & 15)]; + break; + case CIRRUS_BLTMODE_PIXELWIDTH32: + src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~3)) + (gd54xx->blt.y_count << 5) + (gd54xx->blt.x_count & 31)]; + break; + } mask = 1; break; case CIRRUS_BLTMODE_COLOREXPAND: - if (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTH16) { - mask = svga->vram[gd54xx->blt.src_addr & svga->vram_mask] & (0x80 >> (gd54xx->blt.x_count >> 1)); - if (gd54xx->blt.dst_addr & 1) - src = mask ? (gd54xx->blt.fg_col >> 8) : (gd54xx->blt.bg_col >> 8); - else + switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) + { + case CIRRUS_BLTMODE_PIXELWIDTH8: + mask = svga->vram[gd54xx->blt.src_addr & svga->vram_mask] & (0x80 >> gd54xx->blt.x_count); src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; - } else { - mask = svga->vram[gd54xx->blt.src_addr & svga->vram_mask] & (0x80 >> gd54xx->blt.x_count); - src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; + break; + case CIRRUS_BLTMODE_PIXELWIDTH16: + mask = svga->vram[gd54xx->blt.src_addr & svga->vram_mask] & (0x80 >> (gd54xx->blt.x_count >> 1)); + if (gd54xx->blt.dst_addr & 1) + src = mask ? (gd54xx->blt.fg_col >> 8) : (gd54xx->blt.bg_col >> 8); + else + src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; + break; + case CIRRUS_BLTMODE_PIXELWIDTH32: + mask = svga->vram[gd54xx->blt.src_addr & svga->vram_mask] & (0x80 >> (gd54xx->blt.x_count >> 2)); + if ((gd54xx->blt.dst_addr & 3) == 3) + src = mask ? (gd54xx->blt.fg_col >> 24) : (gd54xx->blt.bg_col >> 24); + else if ((gd54xx->blt.dst_addr & 3) == 2) + src = mask ? (gd54xx->blt.fg_col >> 16) : (gd54xx->blt.bg_col >> 16); + else if ((gd54xx->blt.dst_addr & 3) == 1) + src = mask ? (gd54xx->blt.fg_col >> 8) : (gd54xx->blt.bg_col >> 8); + else + src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; + break; } break; case CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND: - if (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTH16) { - mask = svga->vram[(gd54xx->blt.src_addr & svga->vram_mask & ~7) | gd54xx->blt.y_count] & (0x80 >> (gd54xx->blt.x_count >> 1)); - if (gd54xx->blt.dst_addr & 1) - src = mask ? (gd54xx->blt.fg_col >> 8) : (gd54xx->blt.bg_col >> 8); - else + switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) + { + case CIRRUS_BLTMODE_PIXELWIDTH8: + mask = svga->vram[(gd54xx->blt.src_addr & svga->vram_mask & ~7) | gd54xx->blt.y_count] & (0x80 >> gd54xx->blt.x_count); src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; - } else { - mask = svga->vram[(gd54xx->blt.src_addr & svga->vram_mask & ~7) | gd54xx->blt.y_count] & (0x80 >> gd54xx->blt.x_count); - src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; + break; + case CIRRUS_BLTMODE_PIXELWIDTH16: + mask = svga->vram[(gd54xx->blt.src_addr & svga->vram_mask & ~7) | gd54xx->blt.y_count] & (0x80 >> (gd54xx->blt.x_count >> 1)); + if (gd54xx->blt.dst_addr & 1) + src = mask ? (gd54xx->blt.fg_col >> 8) : (gd54xx->blt.bg_col >> 8); + else + src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; + break; + case CIRRUS_BLTMODE_PIXELWIDTH32: + mask = svga->vram[(gd54xx->blt.src_addr & svga->vram_mask & ~7) | gd54xx->blt.y_count] & (0x80 >> (gd54xx->blt.x_count >> 2)); + if ((gd54xx->blt.dst_addr & 3) == 3) + src = mask ? (gd54xx->blt.fg_col >> 24) : (gd54xx->blt.bg_col >> 24); + else if ((gd54xx->blt.dst_addr & 3) == 2) + src = mask ? (gd54xx->blt.fg_col >> 16) : (gd54xx->blt.bg_col >> 16); + else if ((gd54xx->blt.dst_addr & 3) == 1) + src = mask ? (gd54xx->blt.fg_col >> 8) : (gd54xx->blt.bg_col >> 8); + else + src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; + break; } break; } @@ -1365,7 +1452,7 @@ gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) gd54xx->blt.dst_addr += ((gd54xx->blt.mode & CIRRUS_BLTMODE_BACKWARDS) ? -1 : 1); gd54xx->blt.x_count++; - if (gd54xx->blt.x_count == ((gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTH16) ? 16 : 8)) { + if (gd54xx->blt.x_count == x_max) { gd54xx->blt.x_count = 0; if ((gd54xx->blt.mode & (CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND)) == CIRRUS_BLTMODE_COLOREXPAND) gd54xx->blt.src_addr++; @@ -1434,6 +1521,8 @@ cl_pci_read(int func, int addr, void *p) switch (svga->crtc[0x27]) { case CIRRUS_ID_CLGD5430: return 0xa0; + case CIRRUS_ID_CLGD5434: + return 0xa8; } return 0xff; case 0x03: return 0x00; @@ -1528,9 +1617,13 @@ static void romfn = BIOS_GD5430_PCI_PATH; else romfn = BIOS_GD5430_VLB_PATH; - break; - } + break; + case CIRRUS_ID_CLGD5434: + romfn = BIOS_GD5434_PATH; + break; + } + gd54xx->vram_size = device_get_config_int("memory"); gd54xx->vram_mask = (gd54xx->vram_size << 20) - 1; @@ -1548,17 +1641,23 @@ static void io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); - if (gd54xx->vram_size == 2) { + if (gd54xx->vram_size == 4) { + gd54xx->vram_code = 4; + svga->seqregs[0x0f] = 0x98; /*4MB of memory*/ + svga->seqregs[0x17] = 0x38; /*ISA, win3.1 drivers require so, even for PCI in the case of the GD5430*/ + svga->seqregs[0x1f] = 0x2d; + } + else if (gd54xx->vram_size == 2) { gd54xx->vram_code = 3; svga->seqregs[0x0f] = 0x18; /*2MB of memory*/ svga->seqregs[0x17] = 0x38; /*ISA, win3.1 drivers require so, even for PCI in the case of the GD5430*/ svga->seqregs[0x1f] = 0x22; - } else { + } else { gd54xx->vram_code = 2; svga->seqregs[0x0f] = 0x10; /*1MB of memory*/ svga->seqregs[0x17] = 0x38; /*ISA, win3.1 drivers require so, even for PCI in the case of the GD5430*/ svga->seqregs[0x1f] = 0x22; - } + } svga->hwcursor.yoff = 32; svga->hwcursor.xoff = 0; @@ -1617,6 +1716,11 @@ gd5430_pci_available(void) return rom_present(BIOS_GD5430_PCI_PATH); } +static int +gd5434_available(void) +{ + return rom_present(BIOS_GD5434_PATH); +} void gd54xx_close(void *p) @@ -1683,6 +1787,33 @@ static device_config_t gd542x_config[] = } }; +static device_config_t gd5434_config[] = +{ + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "2 MB", + .value = 2 + }, + { + .description = "4 MB", + .value = 4 + }, + { + .description = "" + } + }, + .default_int = 4 + }, + { + .type = -1 + } +}; + device_t gd5428_isa_device = { @@ -1762,3 +1893,34 @@ device_t gd5430_pci_device = gd54xx_add_status_info, gd542x_config }; + +device_t gd5434_vlb_device = +{ + "Cirrus Logic GD5434 (VLB)", + DEVICE_VLB, + CIRRUS_ID_CLGD5434, + gd54xx_init, + gd54xx_close, + NULL, + gd5434_available, + gd54xx_speed_changed, + gd54xx_force_redraw, + gd54xx_add_status_info, + gd5434_config +}; + + +device_t gd5434_pci_device = +{ + "Cirrus Logic GD5434 (PCI)", + DEVICE_PCI, + CIRRUS_ID_CLGD5434, + gd54xx_init, + gd54xx_close, + NULL, + gd5434_available, + gd54xx_speed_changed, + gd54xx_force_redraw, + gd54xx_add_status_info, + gd5434_config +}; diff --git a/src/video/vid_cl54xx.h b/src/video/vid_cl54xx.h index 946657428..1480ac8d6 100644 --- a/src/video/vid_cl54xx.h +++ b/src/video/vid_cl54xx.h @@ -6,3 +6,5 @@ extern device_t gd5428_vlb_device; extern device_t gd5429_device; extern device_t gd5430_vlb_device; extern device_t gd5430_pci_device; +extern device_t gd5434_vlb_device; +extern device_t gd5434_pci_device; diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 831868483..d3aa90572 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -45,18 +45,6 @@ typedef struct et4000_t uint8_t banking; } et4000_t; -static uint8_t crtc_mask[0x40] = -{ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - void et4000_out(uint16_t addr, uint8_t val, void *p) { et4000_t *et4000 = (et4000_t *)p; @@ -87,7 +75,6 @@ void et4000_out(uint16_t addr, uint8_t val, void *p) if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) val = (svga->crtc[7] & ~0x10) | (val & 0x10); old = svga->crtc[svga->crtcreg]; - val &= crtc_mask[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; if (old != val) { diff --git a/src/video/vid_oti067.c b/src/video/vid_oti067.c index 70e6c6f5c..420571b4f 100644 --- a/src/video/vid_oti067.c +++ b/src/video/vid_oti067.c @@ -186,13 +186,7 @@ oti_recalctimings(svga_t *svga) if (oti->regs[0x0d] & 0x0c) svga->rowoffset <<= 1; - if (oti->regs[0x14] & 0x80) { - svga->vtotal *= 2; - svga->dispend *= 2; - svga->vblankstart *= 2; - svga->vsyncstart *=2; - svga->split *= 2; - } + svga->interlace = oti->regs[0x14] & 0x80; } diff --git a/src/video/vid_table.c b/src/video/vid_table.c index e687173ea..ef3872e03 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -119,6 +119,7 @@ video_cards[] = { {"[PCI] ATI Video Xpression (Mach64 VT2)", "mach64vt2", &mach64vt2_device, GFX_MACH64VT2, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, {"[PCI] Cardex Tseng ET4000/w32p", "et4000w32p_pci", &et4000w32p_cardex_pci_device, GFX_ET4000W32_CARDEX_PCI, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, {"[PCI] Cirrus Logic CL-GD 5430", "cl_gd5430_pci", &gd5430_pci_device, GFX_CL_GD5430_PCI, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, + {"[PCI] Cirrus Logic CL-GD 5434", "cl_gd5434_pci", &gd5434_pci_device, GFX_CL_GD5434_PCI, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, #if defined(DEV_BRANCH) && defined(USE_STEALTH32) {"[PCI] Diamond Stealth 32 (Tseng ET4000/w32p)","stealth32_pci", &et4000w32p_pci_device, GFX_ET4000W32_PCI, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, #endif @@ -141,6 +142,7 @@ video_cards[] = { {"[VLB] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_vlb", &mach64gx_vlb_device, GFX_MACH64GX_VLB, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, {"[VLB] Cardex Tseng ET4000/w32p", "et4000w32p_vlb", &et4000w32p_cardex_vlb_device, GFX_ET4000W32_CARDEX_VLB, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, {"[VLB] Cirrus Logic CL-GD 5429", "cl_gd5429_vlb", &gd5429_device, GFX_CL_GD5429, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, + {"[VLB] Cirrus Logic CL-GD 5434", "cl_gd5434_vlb", &gd5434_vlb_device, GFX_CL_GD5434_VLB, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, #if defined(DEV_BRANCH) && defined(USE_STEALTH32) {"[VLB] Diamond Stealth 32 (Tseng ET4000/w32p)","stealth32_vlb", &et4000w32p_vlb_device, GFX_ET4000W32_VLB, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, #endif diff --git a/src/video/vid_tvga.c b/src/video/vid_tvga.c index 94bac6a97..b7792e7cd 100644 --- a/src/video/vid_tvga.c +++ b/src/video/vid_tvga.c @@ -52,18 +52,6 @@ typedef struct tvga_t uint32_t vram_mask; } tvga_t; -static uint8_t crtc_mask[0x40] = -{ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x7f, 0xff, 0x3f, 0x7f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xef, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x7f, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - static void tvga_recalcbanking(tvga_t *tvga); void tvga_out(uint16_t addr, uint8_t val, void *p) { @@ -135,7 +123,6 @@ void tvga_out(uint16_t addr, uint8_t val, void *p) if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) val = (svga->crtc[7] & ~0x10) | (val & 0x10); old = svga->crtc[svga->crtcreg]; - val &= crtc_mask[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; if (old != val) { @@ -252,15 +239,10 @@ void tvga_recalctimings(svga_t *svga) svga->hdisp_time *= 2; } - if (svga->crtc[0x1e] & 4) - { + svga->interlace = (svga->crtc[0x1e] & 4); + + if (svga->interlace) svga->rowoffset >>= 1; - svga->vtotal *= 2; - svga->dispend *= 2; - svga->vblankstart *= 2; - svga->vsyncstart *= 2; - svga->split *= 2; - } switch (((svga->miscout >> 2) & 3) | ((tvga->newctrl2 << 2) & 4)) { diff --git a/src/video/video.h b/src/video/video.h index 16913c640..a078121a5 100644 --- a/src/video/video.h +++ b/src/video/video.h @@ -56,8 +56,8 @@ enum { GFX_N9_9FX_VLB, /* S3 764/Trio64 (Number Nine 9FX) VLB */ GFX_N9_9FX_PCI, /* S3 764/Trio64 (Number Nine 9FX) PCI */ GFX_TGUI9400CXI, /* Trident TGUI9400CXi VLB */ - GFX_TGUI9440_VLB, /* Trident TGUI9440 VLB */ - GFX_TGUI9440_PCI, /* Trident TGUI9440 PCI */ + GFX_TGUI9440_VLB, /* Trident TGUI9440AGi VLB */ + GFX_TGUI9440_PCI, /* Trident TGUI9440AGi PCI */ GFX_VGA88, /* ATI VGA-88 (18800-1) */ GFX_VGAEDGE16, /* ATI VGA Edge-16 (18800-1) */ GFX_VGACHARGER, /* ATI VGA Charger (28800-5) */ @@ -70,11 +70,15 @@ enum { GFX_MACH64GX_VLB, /* ATI Graphics Pro Turbo (Mach64) VLB */ GFX_MACH64GX_PCI, /* ATI Graphics Pro Turbo (Mach64) PCI */ GFX_MACH64VT2, /* ATI Mach64 VT2 */ + GFX_CL_GD5422, /* Cirrus Logic CL-GD 5422 ISA */ GFX_CL_GD5428_ISA, /* Cirrus Logic CL-GD 5428 ISA */ GFX_CL_GD5428_VLB, /* Diamond SpeedStar PRO (Cirrus Logic CL-GD 5428) VLB */ GFX_CL_GD5429, /* Cirrus Logic CL-GD 5429 VLB */ GFX_CL_GD5430_VLB, /* Diamond SpeedStar PRO SE (Cirrus Logic CL-GD 5430) PCI */ GFX_CL_GD5430_PCI, /* Cirrus Logic CL-GD 5430 PCI */ + GFX_CL_GD5434_VLB, /* Cirrus Logic CL-GD 5434 VLB */ + GFX_CL_GD5434_PCI, /* Cirrus Logic CL-GD 5434 PCI */ + GFX_CL_GD5446, /* Cirrus Logic CL-GD 5446 PCI (coming) */ #if defined(DEV_BRANCH) && defined(USE_RIVA) GFX_RIVATNT, /* nVidia Riva TNT */ GFX_RIVATNT2, /* nVidia Riva TNT2 */