diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index d53a8404f..09e70bbe6 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -7,9 +7,9 @@ * This file is part of the 86Box distribution. * * Emulation of select Cirrus Logic cards (CL-GD 5428, - * CL-GD 5429, 5430, 5434 and 5436 are supported). + * CL-GD 5429, CL-GD 5430, CL-GD 5434 and CL-GD 5436 are supported). * - * Version: @(#)vid_cl_54xx.c 1.0.11 2018/03/08 + * Version: @(#)vid_cl_54xx.c 1.0.9 2018/03/02 * * Authors: Sarah Walker, * Barry Rodewald, @@ -40,8 +40,8 @@ #include "vid_cl54xx.h" #define BIOS_GD5424_PATH L"roms/video/cirruslogic/cl5424.bin" -#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_GD5426_PATH L"roms/video/cirruslogic/Diamond SpeedStar PRO VLB v3.04.bin" +#define BIOS_GD5428_PATH L"roms/video/cirruslogic/vlbusjapan.BIN" #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" @@ -49,6 +49,7 @@ #define BIOS_GD5436_PATH L"roms/video/cirruslogic/5436.vbi" #define CIRRUS_ID_CLGD5424 0x94 +#define CIRRUS_ID_CLGD5426 0x90 #define CIRRUS_ID_CLGD5428 0x98 #define CIRRUS_ID_CLGD5429 0x9c #define CIRRUS_ID_CLGD5430 0xa0 @@ -77,9 +78,13 @@ #define CIRRUS_BUSTYPE_VLBSLOW 0x30 #define CIRRUS_BUSTYPE_ISA 0x38 #define CIRRUS_MMIO_ENABLE 0x04 -#define CIRRUS_MMIO_USE_PCIADDR 0x40 // 0xb8000 if cleared. +#define CIRRUS_MMIO_USE_PCIADDR 0x40 /* 0xb8000 if cleared. */ #define CIRRUS_MEMSIZEEXT_DOUBLE 0x80 +// control 0x0b +#define CIRRUS_BANKING_DUAL 0x01 +#define CIRRUS_BANKING_GRANULARITY_16K 0x20 /* set:16k, clear:4k */ + /* control 0x30 */ #define CIRRUS_BLTMODE_BACKWARDS 0x01 #define CIRRUS_BLTMODE_MEMSYSDEST 0x02 @@ -93,6 +98,13 @@ #define CIRRUS_BLTMODE_PIXELWIDTH24 0x20 #define CIRRUS_BLTMODE_PIXELWIDTH32 0x30 +// control 0x31 +#define CIRRUS_BLT_BUSY 0x01 +#define CIRRUS_BLT_START 0x02 +#define CIRRUS_BLT_RESET 0x04 +#define CIRRUS_BLT_FIFOUSED 0x10 +#define CIRRUS_BLT_AUTOSTART 0x80 + // control 0x33 #define CIRRUS_BLTMODEEXT_SOLIDFILL 0x04 #define CIRRUS_BLTMODEEXT_COLOREXPINV 0x02 @@ -134,7 +146,7 @@ typedef struct gd54xx_t uint32_t dst_addr, src_addr; uint8_t mask, mode, rop; uint8_t modeext; - uint8_t bltstart; + uint8_t status; uint16_t trans_col, trans_mask; uint32_t dst_addr_backup, src_addr_backup; @@ -199,7 +211,7 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) if (svga->seqaddr > 5) { svga->seqregs[svga->seqaddr & 0x1f] = val; switch (svga->seqaddr & 0x1f) { - case 6: /* cirrus unlock extensions */ + case 6: val &= 0x17; if (val == 0x12) svga->seqregs[6] = 0x12; @@ -214,22 +226,30 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) break; 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); + svga->hwcursor.x = (val << 3) | (svga->seqaddr >> 5); 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); + svga->hwcursor.y = (val << 3) | (svga->seqaddr >> 5); break; case 0x12: - svga->hwcursor.ena = val & 1; + svga->hwcursor.ena = val & CIRRUS_CURSOR_SHOW; + svga->hwcursor.xsize = svga->hwcursor.ysize = (val & CIRRUS_CURSOR_LARGE) ? 64 : 32; + svga->hwcursor.yoff = 0; + if (val & CIRRUS_CURSOR_LARGE) + svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((svga->seqregs[0x13] & 0x3c) * 256)); + else + svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((svga->seqregs[0x13] & 0x3f) * 256)); break; case 0x13: - svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((val & 0x3f) * 256)); + if (svga->seqregs[0x12] & CIRRUS_CURSOR_LARGE) + svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((val & 0x3c) * 256)); + else + svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((val & 0x3f) * 256)); break; case 0x07: svga->set_reset_disabled = svga->seqregs[7] & 1; case 0x17: - /* svga->seqregs[0x17] = (svga->seqregs[0x17] & 0x38) | (val & 0xc7); */ gd543x_recalc_mapping(gd54xx); break; } @@ -394,8 +414,7 @@ gd54xx_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]; - if ((svga->crtcreg != 0x27) && (svga->crtcreg != 0x28)) - svga->crtc[svga->crtcreg] = val; + svga->crtc[svga->crtcreg] = val; if (old != val) { if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { @@ -421,18 +440,31 @@ gd54xx_in(uint16_t addr, void *p) addr ^= 0x60; switch (addr) { + case 0x3c4: + if ((svga->seqregs[6] & 0x17) == 0x12) + { + temp = svga->seqaddr; + if ((temp & 0x1e) == 0x10) + { + if (temp & 1) + temp = ((svga->hwcursor.y & 7) << 5) | 0x11; + else + temp = ((svga->hwcursor.x & 7) << 5) | 0x10; + } + return temp; + } + return svga->seqaddr; + case 0x3c5: if (svga->seqaddr > 5) { switch (svga->seqaddr) { case 6: - return ((svga->seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f; + return ((svga->seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f; case 0x0b: case 0x0c: case 0x0d: case 0x0e: - return gd54xx->vclk_n[svga->seqaddr-0x0b]; - case 0x0f: - return svga->seqregs[0x0f]; + return gd54xx->vclk_n[svga->seqaddr-0x0b]; case 0x17: temp = svga->gdcreg[0x17] & ~(7 << 3); - if (svga->crtc[0x27] < CIRRUS_ID_CLGD5430) { + if (svga->crtc[0x27] <= CIRRUS_ID_CLGD5429) { if (gd54xx->vlb) temp |= (CL_GD5429_SYSTEM_BUS_VESA << 3); else @@ -448,8 +480,6 @@ gd54xx_in(uint16_t addr, void *p) return temp; case 0x1b: case 0x1c: case 0x1d: case 0x1e: return gd54xx->vclk_d[svga->seqaddr-0x1b]; - case 0x1f: - return svga->seqregs[0x1f]; } return svga->seqregs[svga->seqaddr & 0x3f]; } @@ -473,7 +503,7 @@ gd54xx_in(uint16_t addr, void *p) case 0x24: /*Attribute controller toggle readback (R)*/ return svga->attrff << 7; case 0x26: /*Attribute controller index readback (R)*/ - return svga->attraddr & 0x3f; + return svga->attraddr & 0x3f; case 0x27: /*ID*/ return svga->crtc[0x27]; /*GD542x/GD543x*/ case 0x28: /*Class ID*/ @@ -492,13 +522,13 @@ gd54xx_recalc_banking(gd54xx_t *gd54xx) { svga_t *svga = &gd54xx->svga; - if (svga->gdcreg[0xb] & 0x20) + if (svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) gd54xx->bank[0] = svga->gdcreg[0x09] << 14; else gd54xx->bank[0] = svga->gdcreg[0x09] << 12; - if (svga->gdcreg[0xb] & 0x01) { - if (svga->gdcreg[0xb] & 0x20) + if (svga->gdcreg[0x0b] & CIRRUS_BANKING_DUAL) { + if (svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) gd54xx->bank[1] = svga->gdcreg[0x0a] << 14; else gd54xx->bank[1] = svga->gdcreg[0x0a] << 12; @@ -523,7 +553,7 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) if (!(svga->seqregs[7] & 0xf0)) { mem_mapping_disable(&gd54xx->linear_mapping); - switch (svga->gdcreg[6] & 0x0C) { + switch (svga->gdcreg[6] & 0x0c) { case 0x0: /*128k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); svga->banked_mask = 0xffff; @@ -534,12 +564,10 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) break; case 0x8: /*32k at B0000*/ mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - mem_mapping_disable(&gd54xx->mmio_mapping); svga->banked_mask = 0x7fff; break; case 0xC: /*32k at B8000*/ mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - mem_mapping_disable(&gd54xx->mmio_mapping); svga->banked_mask = 0x7fff; gd54xx->mmio_vram_overlap = 1; break; @@ -552,7 +580,7 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) uint32_t base, size; if (svga->crtc[0x27] <= CIRRUS_ID_CLGD5429 || (!gd54xx->pci && !gd54xx->vlb)) { - if (svga->gdcreg[0xb] & 0x20) { + if (svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) { base = (svga->seqregs[7] & 0xf0) << 16; size = 1 * 1024 * 1024; } else { @@ -577,7 +605,7 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) mem_mapping_set_addr(&gd54xx->linear_mapping, base, size); svga->linear_base = base; if (svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) { - if (svga->seqregs[0x17] & 0x40) { + if (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR) { if (size >= (4 * 1024 * 1024)) mem_mapping_disable(&gd54xx->mmio_mapping); /* MMIO is handled in the linear read/write functions */ else { @@ -602,45 +630,85 @@ gd54xx_recalctimings(svga_t *svga) svga->interlace = (svga->crtc[0x1a] & 0x01); - if (svga->seqregs[7] & 0x01) { - svga->render = svga_render_8bpp_highres; - svga->bpp = 8; - } else if (svga->gdcreg[5] & 0x40) { - svga->render = svga_render_8bpp_lowres; - svga->bpp = 8; - } - svga->ma_latch |= ((svga->crtc[0x1b] & 0x01) << 16) | ((svga->crtc[0x1b] & 0xc) << 15); - if (gd54xx->ramdac.ctrl & 0x80) { - if (gd54xx->ramdac.ctrl & 0x40) { - switch (gd54xx->ramdac.ctrl & 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: - if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5434) && (svga->seqregs[7] & 8)) { - svga->render = svga_render_32bpp_highres; - svga->bpp = 32; - if (svga->crtc[0x27] < CIRRUS_ID_CLGD5436) - svga->rowoffset *= 2; - } else { - svga->render = svga_render_24bpp_highres; - svga->bpp = 24; - } - break; - } - } else { - svga->render = svga_render_15bpp_highres; - svga->bpp = 15; + if (svga->seqregs[7] & CIRRUS_SR7_BPP_SVGA) + { + svga->bpp = 8; + svga->render = svga_render_8bpp_highres; } + else if (svga->gdcreg[5] & 0x40) + { + svga->bpp = 8; + svga->render = svga_render_8bpp_lowres; } - + + if (gd54xx->ramdac.ctrl & 0x80) + { + if (gd54xx->ramdac.ctrl & 0x40) + { + switch (gd54xx->ramdac.ctrl & 0xf) + { + case 0: + svga->bpp = 15; + svga->render = svga_render_15bpp_highres; + break; + + case 1: + svga->bpp = 16; + svga->render = svga_render_16bpp_highres; + break; + + case 5: + if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5434) && (svga->seqregs[7] & CIRRUS_SR7_BPP_32)) + { + svga->bpp = 32; + svga->render = svga_render_32bpp_highres; + if (svga->crtc[0x27] < CIRRUS_ID_CLGD5436) + svga->rowoffset *= 2; + } + else + { + svga->bpp = 24; + svga->render = svga_render_24bpp_highres; + } + break; + + case 0xf: + switch (svga->seqregs[7] & CIRRUS_SR7_BPP_MASK) + { + case CIRRUS_SR7_BPP_32: + svga->bpp = 32; + svga->render = svga_render_32bpp_highres; + svga->rowoffset *= 2; + break; + + case CIRRUS_SR7_BPP_24: + svga->bpp = 24; + svga->render = svga_render_24bpp_highres; + break; + + case CIRRUS_SR7_BPP_16: + case CIRRUS_SR7_BPP_16_DOUBLEVCLK: + svga->bpp = 16; + svga->render = svga_render_16bpp_highres; + break; + + case CIRRUS_SR7_BPP_8: + svga->bpp = 8; + svga->render = svga_render_8bpp_highres; + break; + } + break; + } + } + else + { + svga->bpp = 15; + svga->render = svga_render_15bpp_highres; + } + } + clocksel = (svga->miscout >> 2) & 3; if (!gd54xx->vclk_n[clocksel] || !gd54xx->vclk_d[clocksel]) @@ -656,7 +724,7 @@ gd54xx_recalctimings(svga_t *svga) freq /= 2.0; break; case 4: - if (svga->crtc[0x27] < CIRRUS_ID_CLGD5436) + if (svga->crtc[0x27] <= CIRRUS_ID_CLGD5434) freq /= 3.0; break; } @@ -666,47 +734,50 @@ gd54xx_recalctimings(svga_t *svga) svga->vram_display_mask = (svga->crtc[0x1b] & 2) ? gd54xx->vram_mask : 0x3ffff; } - -static void -gd54xx_hwcursor_draw(svga_t *svga, int displine) +static +void gd54xx_hwcursor_draw(svga_t *svga, int displine) { - int x; - uint8_t dat[2]; - int xx; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - int largecur = (svga->seqregs[0x12] & CIRRUS_CURSOR_LARGE); - int cursize = (largecur) ? 64 : 32; - int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; - int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; - - if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 4; - - for (x = 0; x < cursize; x += 8) { + int x; + uint8_t dat[2]; + int xx; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; + int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; + int pitch = (svga->hwcursor.xsize == 64) ? 16 : 4; + + if (svga->interlace && svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += pitch; + + for (x = 0; x < svga->hwcursor.xsize; x += 8) { dat[0] = svga->vram[svga->hwcursor_latch.addr]; - dat[1] = svga->vram[svga->hwcursor_latch.addr + 0x80]; + if (svga->hwcursor.xsize == 64) + dat[1] = svga->vram[svga->hwcursor_latch.addr + 0x08]; + else + dat[1] = svga->vram[svga->hwcursor_latch.addr + 0x80]; for (xx = 0; xx < 8; xx++) { if (offset >= svga->hwcursor_latch.x) { if (dat[1] & 0x80) - ((uint32_t *)buffer32->line[displine + y_add])[offset + cursize + x_add] = 0; + ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = 0; if (dat[0] & 0x80) - ((uint32_t *)buffer32->line[displine + y_add])[offset + cursize + x_add] ^= 0xffffff; + ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] ^= 0xffffff; } - + offset++; dat[0] <<= 1; dat[1] <<= 1; } svga->hwcursor_latch.addr++; - } - - if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 4; + } + + if (svga->hwcursor.xsize == 64) + svga->hwcursor_latch.addr += 8; + + if (svga->interlace && !svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += pitch; } - static void -gd5428_copy_pixel(gd54xx_t *gd54xx, svga_t *svga, uint8_t src, uint8_t dst) +gd54xx_memsrc_rop(gd54xx_t *gd54xx, svga_t *svga, uint8_t src, uint8_t dst) { uint8_t res = src; svga->changedvram[(gd54xx->blt.dst_addr_backup & svga->vram_mask) >> 12] = changeframecount; @@ -751,7 +822,7 @@ gd54xx_blit_dword(gd54xx_t *gd54xx, svga_t *svga) for (x=0;x<32;x+=8) { pixel = ((gd54xx->blt.sys_buf & (0xff << x)) >> x); if(gd54xx->blt.pixel_cnt <= gd54xx->blt.width) - gd5428_copy_pixel(gd54xx, svga, pixel, svga->vram[gd54xx->blt.dst_addr_backup & svga->vram_mask]); + gd54xx_memsrc_rop(gd54xx, svga, pixel, svga->vram[gd54xx->blt.dst_addr_backup & svga->vram_mask]); gd54xx->blt.dst_addr_backup++; gd54xx->blt.pixel_cnt++; } @@ -1123,7 +1194,7 @@ gd54xx_readb_linear(uint32_t addr, void *p) } if ((addr & 0x003fff00) == 0x003fff00) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & 0x40)) + if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) return gd543x_mmio_read(addr & 0x000000ff, gd54xx); } @@ -1143,7 +1214,7 @@ gd54xx_readw_linear(uint32_t addr, void *p) addr &= 0x003fffff; /* 4 MB mask */ if ((addr & 0x003fff00) == 0x003fff00) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & 0x40)) { + if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { if (ap == 2) addr ^= 0x00000002; @@ -1199,7 +1270,7 @@ gd54xx_readl_linear(uint32_t addr, void *p) addr &= 0x003fffff; /* 4 MB mask */ if ((addr & 0x003fff00) == 0x003fff00) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & 0x40)) { + if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { temp = gd543x_mmio_readl(addr & 0x000000ff, gd54xx); switch(ap) { @@ -1286,7 +1357,7 @@ gd54xx_writeb_linear(uint32_t addr, uint8_t val, void *p) } if ((addr & 0x003fff00) == 0x003fff00) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & 0x40)) + if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) gd543x_mmio_write(addr & 0x000000ff, val, gd54xx); } @@ -1320,7 +1391,7 @@ gd54xx_writew_linear(uint32_t addr, uint16_t val, void *p) uint16_t temp; if ((addr & 0x003fff00) == 0x003fff00) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & 0x40)) { + if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { switch(ap) { case 0: default: @@ -1394,7 +1465,7 @@ gd54xx_writel_linear(uint32_t addr, uint32_t val, void *p) uint32_t temp; if ((addr & 0x003fff00) == 0x003fff00) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & 0x40)) { + if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { switch(ap) { case 0: default: @@ -1520,7 +1591,7 @@ gd54xx_readl(uint32_t addr, void *p) static int gd543x_do_mmio(svga_t *svga, uint32_t addr) { - if (svga->seqregs[0x17] & 0x40) + if (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR) return 1; else return ((addr & ~0xff) == 0xb8000); @@ -1620,7 +1691,7 @@ gd543x_mmio_write(uint32_t addr, uint8_t val, void *p) else gd54xx->blt.dst_addr &= 0x1fffff; - if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) && (gd54xx->blt.bltstart & 0x80)) { + if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5436) && (gd54xx->blt.status & CIRRUS_BLT_AUTOSTART)) { if (gd54xx->blt.mode == CIRRUS_BLTMODE_MEMSYSSRC) { gd54xx->blt.sys_tx = 1; gd54xx->blt.sys_cnt = 0; @@ -1659,7 +1730,7 @@ gd543x_mmio_write(uint32_t addr, uint8_t val, void *p) break; case 0x1b: - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) + if (svga->crtc[0x27] == CIRRUS_ID_CLGD5436) gd54xx->blt.modeext = val; break; @@ -1680,8 +1751,8 @@ gd543x_mmio_write(uint32_t addr, uint8_t val, void *p) break; case 0x40: - gd54xx->blt.bltstart = val; - if (gd54xx->blt.bltstart & 0x02) { + gd54xx->blt.status = val; + if (gd54xx->blt.status & CIRRUS_BLT_START) { if (gd54xx->blt.mode == CIRRUS_BLTMODE_MEMSYSSRC) { gd54xx->blt.sys_tx = 1; gd54xx->blt.sys_cnt = 0; @@ -1799,7 +1870,7 @@ gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) blt_mask *= 2; break; case CIRRUS_BLTMODE_PIXELWIDTH24: - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) + if (svga->crtc[0x27] == CIRRUS_ID_CLGD5436) { x_max = 24; if (gd54xx->blt.mode & CIRRUS_BLTMODE_PATTERNCOPY) @@ -1853,7 +1924,7 @@ gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) } else { - mem_mapping_set_handler(&gd54xx->linear_mapping, svga_read_linear, svga_readw_linear, svga_readl_linear, gd54xx_writeb_linear, gd54xx_writew_linear, gd54xx_writel_linear); + mem_mapping_set_handler(&gd54xx->linear_mapping, svga_readb_linear, svga_readw_linear, svga_readl_linear, gd54xx_writeb_linear, gd54xx_writew_linear, gd54xx_writel_linear); mem_mapping_set_p(&gd54xx->linear_mapping, svga); } gd543x_recalc_mapping(gd54xx); @@ -1892,7 +1963,7 @@ gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) } break; case CIRRUS_BLTMODE_PIXELWIDTH24: - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) + if (svga->crtc[0x27] == CIRRUS_ID_CLGD5436) { if ((gd54xx->blt.x_count % 3) == 2) src = mask ? (gd54xx->blt.fg_col >> 16) : (gd54xx->blt.bg_col >> 16); @@ -1941,8 +2012,7 @@ gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) 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_PIXELWIDTH24: - pclog("Pattern copy\n"); - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) + if (svga->crtc[0x27] == CIRRUS_ID_CLGD5436) src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~3)) + (gd54xx->blt.y_count << 5) + (gd54xx->blt.x_count % 24)]; break; case CIRRUS_BLTMODE_PIXELWIDTH32: @@ -1966,7 +2036,7 @@ gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; break; case CIRRUS_BLTMODE_PIXELWIDTH24: - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) + if (svga->crtc[0x27] == CIRRUS_ID_CLGD5436) { mask = svga->vram[gd54xx->blt.src_addr & svga->vram_mask] & (0x80 >> (gd54xx->blt.x_count / 3)); if ((gd54xx->blt.dst_addr % 3) == 2) @@ -2039,7 +2109,7 @@ gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; break; case CIRRUS_BLTMODE_PIXELWIDTH24: - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) + if (svga->crtc[0x27] == CIRRUS_ID_CLGD5436) { mask = svga->vram[(gd54xx->blt.src_addr & svga->vram_mask & ~7) | gd54xx->blt.y_count] & (0x80 >> (gd54xx->blt.x_count / 3)); if ((gd54xx->blt.dst_addr % 3) == 2) @@ -2074,7 +2144,7 @@ gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) switch (gd54xx->blt.rop) { case 0x00: dst = 0; break; case 0x05: dst = src & dst; break; - case 0x06: /* dst = dst; */ break; + case 0x06: dst = dst; break; case 0x09: dst = src & ~dst; break; case 0x0b: dst = ~ dst; break; case 0x0d: dst = src; break; @@ -2146,7 +2216,7 @@ gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) } else { - mem_mapping_set_handler(&gd54xx->linear_mapping, svga_read_linear, svga_readw_linear, svga_readl_linear, gd54xx_writeb_linear, gd54xx_writew_linear, gd54xx_writel_linear); + mem_mapping_set_handler(&gd54xx->linear_mapping, svga_readb_linear, svga_readw_linear, svga_readl_linear, gd54xx_writeb_linear, gd54xx_writew_linear, gd54xx_writel_linear); mem_mapping_set_p(&gd54xx->linear_mapping, svga); } gd543x_recalc_mapping(gd54xx); @@ -2172,16 +2242,9 @@ cl_pci_read(int func, int addr, void *p) case 0x01: return 0x10; case 0x02: - switch (svga->crtc[0x27]) { - case CIRRUS_ID_CLGD5430: - return 0xa0; - case CIRRUS_ID_CLGD5434: - return 0xa8; - case CIRRUS_ID_CLGD5436: - return 0xac; - } - return 0xff; + return svga->crtc[0x27]; case 0x03: return 0x00; + case PCI_REG_COMMAND: return gd54xx->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ @@ -2198,10 +2261,10 @@ cl_pci_read(int func, int addr, void *p) case 0x12: return 0x00; case 0x13: return gd54xx->lfb_base >> 24; - case 0x30: return (gd54xx->has_bios) ? (gd54xx->pci_regs[0x30] & 0x01) : 0x00; /*BIOS ROM address*/ + case 0x30: return (gd54xx->pci_regs[0x30] & 0x01); /*BIOS ROM address*/ case 0x31: return 0x00; - case 0x32: return (gd54xx->has_bios) ? gd54xx->pci_regs[0x32] : 0x00; - case 0x33: return (gd54xx->has_bios) ? gd54xx->pci_regs[0x33] : 0x00; + case 0x32: return gd54xx->pci_regs[0x32]; + case 0x33: return gd54xx->pci_regs[0x33]; case 0x3c: return gd54xx->int_line; case 0x3d: return PCI_INTA; @@ -2230,8 +2293,6 @@ cl_pci_write(int func, int addr, uint8_t val, void *p) break; case 0x30: case 0x32: case 0x33: - if (!(gd54xx->has_bios)) - return; gd54xx->pci_regs[addr] = val; if (gd54xx->pci_regs[0x30] & 0x01) { uint32_t addr = (gd54xx->pci_regs[0x32] << 16) | (gd54xx->pci_regs[0x33] << 24); @@ -2252,21 +2313,20 @@ static void { gd54xx_t *gd54xx = malloc(sizeof(gd54xx_t)); svga_t *svga = &gd54xx->svga; - int id = info->local & 0x7FFF; + int id = info->local; wchar_t *romfn = NULL; memset(gd54xx, 0, sizeof(gd54xx_t)); - gd54xx->has_bios = !(info->local & 0x8000); - gd54xx->pci = !!(info->flags & DEVICE_PCI); gd54xx->vlb = !!(info->flags & DEVICE_VLB); switch (id) { + case CIRRUS_ID_CLGD5426: + romfn = BIOS_GD5426_PATH; + break; + case CIRRUS_ID_CLGD5428: - if (gd54xx->vlb) - romfn = BIOS_GD5428_VLB_PATH; - else - romfn = BIOS_GD5428_ISA_PATH; + romfn = BIOS_GD5428_PATH; break; case CIRRUS_ID_CLGD5429: @@ -2292,7 +2352,6 @@ static void gd54xx->vram_size = device_get_config_int("memory"); gd54xx->vram_mask = (gd54xx->vram_size << 20) - 1; - if (gd54xx->has_bios) rom_init(&gd54xx->bios_rom, romfn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); svga_init(&gd54xx->svga, gd54xx, gd54xx->vram_size << 20, @@ -2307,23 +2366,6 @@ static void io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); - svga->decode_mask = (4 << 20) - 1; - - switch (gd54xx->vram_size) { - case 1: /*1MB*/ - svga->vram_mask = (1 << 20) - 1; - svga->vram_max = 1 << 20; - break; - case 2: /*2MB*/ - svga->vram_mask = (2 << 20) - 1; - svga->vram_max = 2 << 20; - break; - case 4: /*4MB*/ - svga->vram_mask = (4 << 20) - 1; - svga->vram_max = 4 << 20; - break; - } - svga->hwcursor.yoff = 32; svga->hwcursor.xoff = 0; @@ -2334,10 +2376,10 @@ static void gd54xx->bank[1] = 0x8000; - if ((info->flags & DEVICE_PCI) && id >= CIRRUS_ID_CLGD5430) + if (gd54xx->pci && id >= CIRRUS_ID_CLGD5430) pci_add_card(PCI_ADD_VIDEO, cl_pci_read, cl_pci_write, gd54xx); - gd54xx->pci_regs[0x04] = 7; + gd54xx->pci_regs[PCI_REG_COMMAND] = 7; gd54xx->pci_regs[0x30] = 0x00; gd54xx->pci_regs[0x32] = 0x0c; @@ -2349,19 +2391,17 @@ static void } static int -gd5428_isa_available(void) +gd5426_available(void) { - return rom_present(BIOS_GD5428_ISA_PATH); + return rom_present(BIOS_GD5426_PATH); } - static int -gd5428_vlb_available(void) +gd5428_available(void) { - return rom_present(BIOS_GD5428_VLB_PATH); + return rom_present(BIOS_GD5428_PATH); } - static int gd5429_available(void) { @@ -2396,7 +2436,7 @@ void gd54xx_close(void *p) { gd54xx_t *gd54xx = (gd54xx_t *)p; - + svga_close(&gd54xx->svga); free(gd54xx); @@ -2484,6 +2524,20 @@ static device_config_t gd5434_config[] = } }; +device_t gd5426_vlb_device = +{ + "Cirrus Logic CL-GD 5426 (VLB)", + DEVICE_VLB, + CIRRUS_ID_CLGD5426, + gd54xx_init, + gd54xx_close, + NULL, + gd5426_available, + gd54xx_speed_changed, + gd54xx_force_redraw, + gd54xx_add_status_info, + gd5428_config +}; device_t gd5428_isa_device = { @@ -2493,7 +2547,7 @@ device_t gd5428_isa_device = gd54xx_init, gd54xx_close, NULL, - gd5428_isa_available, + gd5428_available, gd54xx_speed_changed, gd54xx_force_redraw, gd54xx_add_status_info, @@ -2508,7 +2562,7 @@ device_t gd5428_vlb_device = gd54xx_init, gd54xx_close, NULL, - gd5428_vlb_available, + gd5428_available, gd54xx_speed_changed, gd54xx_force_redraw, gd54xx_add_status_info, diff --git a/src/video/vid_cl54xx.h b/src/video/vid_cl54xx.h index 2bf9e6aaf..472d8316b 100644 --- a/src/video/vid_cl54xx.h +++ b/src/video/vid_cl54xx.h @@ -1,6 +1,7 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ +extern device_t gd5426_vlb_device; extern device_t gd5428_isa_device; extern device_t gd5428_vlb_device; extern device_t gd5429_isa_device; diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 56800e09d..b4b239697 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -158,6 +158,7 @@ video_cards[] = { #if defined(DEV_BRANCH) && defined(USE_STEALTH32) {"[VLB] Diamond Stealth 32 (Tseng ET4000/w32p)","stealth32_vlb", &et4000w32p_vlb_device, GFX_ET4000W32_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, #endif + {"[VLB] Diamond SpeedStar PRO (CL-GD5426)", "cl_gd5426_vlb", &gd5426_vlb_device, GFX_CL_GD5426_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, {"[VLB] Diamond SpeedStar PRO SE (CL-GD5430)", "cl_gd5430_vlb", &gd5430_vlb_device, GFX_CL_GD5430_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, {"[VLB] Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000_vlb",&s3_virge_vlb_device, GFX_VIRGE_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, {"[VLB] Diamond Stealth 3D 3000 (S3 ViRGE/VX)", "stealth3d_3000_vlb",&s3_virge_988_vlb_device, GFX_VIRGEVX_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 4, 26, 26, 42}}, diff --git a/src/video/video.h b/src/video/video.h index 7b2fadd1a..33d92106c 100644 --- a/src/video/video.h +++ b/src/video/video.h @@ -76,11 +76,12 @@ enum { GFX_MACH64VT2, /* ATI Mach64 VT2 */ GFX_CL_GD5424_ISA, /* Cirrus Logic CL-GD 5424 ISA */ GFX_CL_GD5424_VLB, /* Cirrus Logic CL-GD 5424 VLB */ + GFX_CL_GD5426_VLB, /* Diamond SpeedStar PRO (Cirrus Logic CL-GD 5426) VLB */ 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_GD5428_VLB, /* Cirrus Logic CL-GD 5428 VLB */ GFX_CL_GD5429_ISA, /* Cirrus Logic CL-GD 5429 ISA */ GFX_CL_GD5429_VLB, /* Cirrus Logic CL-GD 5429 VLB */ - GFX_CL_GD5430_VLB, /* Diamond SpeedStar PRO SE (Cirrus Logic CL-GD 5430) PCI */ + GFX_CL_GD5430_VLB, /* Diamond SpeedStar PRO SE (Cirrus Logic CL-GD 5430) VLB */ GFX_CL_GD5430_PCI, /* Cirrus Logic CL-GD 5430 PCI */ GFX_CL_GD5434_ISA, /* Cirrus Logic CL-GD 5434 ISA */ GFX_CL_GD5434_VLB, /* Cirrus Logic CL-GD 5434 VLB */