diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index d42f67ea9..284b3342d 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -36,8 +36,10 @@ #include "vid_svga_render.h" #include "vid_cl54xx.h" -#define BIOS_GD5420_PATH L"video/cirruslogic/5420.vbi" -#define BIOS_GD5422_PATH L"video/cirruslogic/cl5422.bin" +#if defined(DEV_BRANCH) && defined(USE_CL5422) +#define BIOS_GD5420_PATH L"roms/video/cirruslogic/5420.vbi" +#define BIOS_GD5422_PATH L"roms/video/cirruslogic/cl5422.bin" +#endif #define BIOS_GD5426_PATH L"roms/video/cirruslogic/Diamond SpeedStar PRO VLB v3.04.bin" #define BIOS_GD5428_ISA_PATH L"roms/video/cirruslogic/5428.bin" #define BIOS_GD5428_PATH L"roms/video/cirruslogic/vlbusjapan.BIN" @@ -145,7 +147,6 @@ typedef struct gd54xx_t uint8_t vclk_n[4]; uint8_t vclk_d[4]; - uint32_t bank[2]; struct { uint8_t state; @@ -179,7 +180,7 @@ typedef struct gd54xx_t int countminusone; uint8_t pci_regs[256]; - uint8_t int_line; + uint8_t int_line, unlocked; uint8_t fc; /* Feature Connector */ @@ -316,6 +317,14 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) svga->seqaddr = val; break; case 0x3c5: + if ((svga->seqaddr == 2) && !gd54xx->unlocked) { + o = svga->seqregs[svga->seqaddr & 0x1f]; + svga_out(addr, val, svga); + svga->seqregs[svga->seqaddr & 0x1f] = (o & 0xf0) | (val & 0x0f); + return; + } else if ((svga->seqaddr > 6) && !gd54xx->unlocked) + return; + if (svga->seqaddr > 5) { o = svga->seqregs[svga->seqaddr & 0x1f]; svga->seqregs[svga->seqaddr & 0x1f] = val; @@ -326,6 +335,8 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) svga->seqregs[6] = 0x12; else svga->seqregs[6] = 0x0f; + if (svga->crtc[0x27] < CIRRUS_ID_CLGD5429) + gd54xx->unlocked = (svga->seqregs[6] == 0x12); break; case 0x0a: @@ -365,21 +376,26 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) break; case 0x12: svga->ext_overscan = !!(val & 0x80); - if (svga->ext_overscan) + if (svga->ext_overscan && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5426)) svga->overscan_color = gd54xx->extpallook[2]; else svga->overscan_color = svga->pallook[svga->attrregs[0x11]]; svga_recalctimings(svga); svga->hwcursor.ena = val & CIRRUS_CURSOR_SHOW; - svga->hwcursor.xsize = svga->hwcursor.ysize = (val & CIRRUS_CURSOR_LARGE) ? 64 : 32; + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5422) + svga->hwcursor.xsize = svga->hwcursor.ysize = + ((val & CIRRUS_CURSOR_LARGE) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5422)) ? 64 : 32; + else + svga->hwcursor.xsize = 32; svga->hwcursor.yoff = (svga->hwcursor.ysize == 32) ? 32 : 0; - if (val & CIRRUS_CURSOR_LARGE) + // (svga->crtc[0x1b] & 2) + if ((svga->seqregs[0x12] & CIRRUS_CURSOR_LARGE) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5422)) svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + ((svga->seqregs[0x13] & 0x3c) * 256)); else svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + ((svga->seqregs[0x13] & 0x3f) * 256)); break; case 0x13: - if (svga->seqregs[0x12] & CIRRUS_CURSOR_LARGE) + if ((svga->seqregs[0x12] & CIRRUS_CURSOR_LARGE) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5422)) svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + ((val & 0x3c) * 256)); else svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + ((val & 0x3f) * 256)); @@ -421,7 +437,9 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) return; } break; - case 0x3C6: + case 0x3c6: + if (!gd54xx->unlocked) + break; if (gd54xx->ramdac.state == 4) { gd54xx->ramdac.state = 0; gd54xx->ramdac.ctrl = val; @@ -430,7 +448,7 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) } gd54xx->ramdac.state = 0; break; - case 0x3C9: + case 0x3c9: svga->dac_status = 0; svga->fullchange = changeframecount; switch (svga->dac_pos) { @@ -472,8 +490,16 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) svga->gdcaddr = val/* & 0x3f*/; return; case 0x3cf: + if ((svga->gdcaddr > 0x1f) && ((svga->crtc[0x27] <= CIRRUS_ID_CLGD5422) || + (svga->crtc[0x27] == CIRRUS_ID_CLGD5424))) + return; + o = svga->gdcreg[svga->gdcaddr]; - svga->gdcreg[svga->gdcaddr] = val; + + if ((svga->gdcaddr < 2) && !gd54xx->unlocked) + svga->gdcreg[svga->gdcaddr] = (svga->gdcreg[svga->gdcaddr] & 0xf0) | (val & 0x0f); + else if ((svga->gdcaddr <= 8) || gd54xx->unlocked) + svga->gdcreg[svga->gdcaddr] = val; if (svga->gdcaddr <= 8) { switch (svga->gdcaddr) { @@ -508,17 +534,22 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && svga->chain4; - if ((svga->gdcaddr == 5 && (val ^ o) & 0x70) || - (svga->gdcaddr == 6 && (val ^ o) & 1)) + if (((svga->gdcaddr == 5) && ((val ^ o) & 0x70)) || + ((svga->gdcaddr == 6) && ((val ^ o) & 1))) svga_recalctimings(svga); } else { switch (svga->gdcaddr) { - case 0x09: case 0x0a: case 0x0b: + case 0x09: case 0x0a: /* case 0x0b: */ gd54xx_recalc_banking(gd54xx); if (svga->gdcreg[0xb] & 0x04) svga->writemode = svga->gdcreg[5] & 7; else svga->writemode = svga->gdcreg[5] & 3; + svga->adv_flags = FLAG_EXTRA_BANKS; + if (svga->gdcreg[0xb] & 0x02) + svga->adv_flags |= FLAG_ADDR_BY8; + if (svga->gdcreg[0xb] & 0x08) + svga->adv_flags |= FLAG_LATCH8; break; case 0x10: @@ -622,10 +653,15 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) } } return; - case 0x3D4: + case 0x3d4: svga->crtcreg = val & 0x3f; return; - case 0x3D5: + case 0x3d5: + if (((svga->crtcreg == 0x19) || (svga->crtcreg == 0x1a) || + (svga->crtcreg == 0x1b) || (svga->crtcreg == 0x1d) || + (svga->crtcreg == 0x25) || (svga->crtcreg == 0x27)) && + !gd54xx->unlocked) + return; if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) return; if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) @@ -658,27 +694,30 @@ gd54xx_in(uint16_t addr, void *p) 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; + if (gd54xx->unlocked) { + 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 temp; - } - return svga->seqaddr; - + return svga->seqaddr; + case 0x3c5: + if ((svga->seqaddr == 2) && !gd54xx->unlocked) + return svga_in(addr, svga) & 0x0f; + else if ((svga->seqaddr > 6) && !gd54xx->unlocked) + return 0xff; + if (svga->seqaddr > 5) { switch (svga->seqaddr) { case 6: - return ((svga->seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f; + return svga->seqregs[6]; case 0x0b: case 0x0c: case 0x0d: case 0x0e: - return gd54xx->vclk_n[svga->seqaddr-0x0b]; + return gd54xx->vclk_n[svga->seqaddr-0x0b]; case 0x17: temp = svga->gdcreg[0x17] & ~(7 << 3); if (svga->crtc[0x27] <= CIRRUS_ID_CLGD5429) { @@ -701,6 +740,15 @@ gd54xx_in(uint16_t addr, void *p) return svga->seqregs[svga->seqaddr & 0x3f]; } break; + case 0x3c6: + if (!gd54xx->unlocked) + break; + if (gd54xx->ramdac.state == 4) { + gd54xx->ramdac.state = 0; + return gd54xx->ramdac.ctrl; + } + gd54xx->ramdac.state++; + break; case 0x3c9: svga->dac_status = 3; index = (svga->dac_addr - 1) & 0xff; @@ -728,17 +776,15 @@ gd54xx_in(uint16_t addr, void *p) return svga->vgapal[index].b & 0x3f; } return 0xFF; - case 0x3C6: - if (gd54xx->ramdac.state == 4) { - gd54xx->ramdac.state = 0; - return gd54xx->ramdac.ctrl; - } - gd54xx->ramdac.state++; - break; case 0x3ce: return svga->gdcaddr & 0x3f; case 0x3cf: if (svga->gdcaddr >= 0x10) { + if ((svga->gdcaddr > 8) && !gd54xx->unlocked) + return 0xff; + if ((svga->gdcaddr > 0x1f) && ((svga->crtc[0x27] <= CIRRUS_ID_CLGD5422) || + (svga->crtc[0x27] == CIRRUS_ID_CLGD5424))) + return 0xff; switch (svga->gdcaddr) { case 0x10: temp = gd543x_mmio_read(0xb8001, gd54xx); @@ -843,13 +889,25 @@ gd54xx_in(uint16_t addr, void *p) temp = 0xff; break; } - } else - temp = svga->gdcreg[svga->gdcaddr]; + } else { + if ((svga->gdcaddr < 2) && !gd54xx->unlocked) + temp = (svga->gdcreg[svga->gdcaddr] & 0x0f); + else + temp = svga->gdcreg[svga->gdcaddr]; + } return temp; - case 0x3D4: + case 0x3d4: return svga->crtcreg; - case 0x3D5: + case 0x3d5: + if (((svga->crtcreg == 0x19) || (svga->crtcreg == 0x1a) || + (svga->crtcreg == 0x1b) || (svga->crtcreg == 0x1d) || + (svga->crtcreg == 0x25) || (svga->crtcreg == 0x27)) && + !gd54xx->unlocked) + return 0xff; switch (svga->crtcreg) { + case 0x22: /*Graphis Data Latches Readback Register*/ + /*Should this be & 7 if 8 byte latch is enabled? */ + return (svga->latch >> ((svga->gdcreg[4] & 3) << 3)) & 0xff; case 0x24: /*Attribute controller toggle readback (R)*/ return svga->attrff << 7; case 0x26: /*Attribute controller index readback (R)*/ @@ -872,38 +930,37 @@ gd54xx_recalc_banking(gd54xx_t *gd54xx) { svga_t *svga = &gd54xx->svga; - if (!gd54xx_is_5422(svga)) { - gd54xx->bank[0] = (svga->gdcreg[0x09] & 0x7f) << 12; + if (!gd54xx_is_5422(svga)) { + svga->extra_banks[0] = (svga->gdcreg[0x09] & 0x7f) << 12; - if (svga->gdcreg[0x0b] & CIRRUS_BANKING_DUAL) - gd54xx->bank[1] = (svga->gdcreg[0x0a] & 0x7f) << 12; - else - gd54xx->bank[1] = gd54xx->bank[0] + 0x8000; - } - else { - 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[0x0b] & CIRRUS_BANKING_DUAL) { - if (svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) - gd54xx->bank[1] = svga->gdcreg[0x0a] << 14; + if (svga->gdcreg[0x0b] & CIRRUS_BANKING_DUAL) + svga->extra_banks[1] = (svga->gdcreg[0x0a] & 0x7f) << 12; else - gd54xx->bank[1] = svga->gdcreg[0x0a] << 12; - } + svga->extra_banks[1] = svga->extra_banks[0] + 0x8000; + } else { + if ((svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) && + (svga->crtc[0x27] >= CIRRUS_ID_CLGD5426) && (svga->crtc[0x27] != CIRRUS_ID_CLGD5424)) + svga->extra_banks[0] = svga->gdcreg[0x09] << 14; + else + svga->extra_banks[0] = svga->gdcreg[0x09] << 12; + + if (svga->gdcreg[0x0b] & CIRRUS_BANKING_DUAL) { + if ((svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) && + (svga->crtc[0x27] >= CIRRUS_ID_CLGD5426) && (svga->crtc[0x27] != CIRRUS_ID_CLGD5424)) + svga->extra_banks[1] = svga->gdcreg[0x0a] << 14; else - - gd54xx->bank[1] = gd54xx->bank[0] + 0x8000; - } + svga->extra_banks[1] = svga->gdcreg[0x0a] << 12; + } else + svga->extra_banks[1] = svga->extra_banks[0] + 0x8000; + } } - static void gd543x_recalc_mapping(gd54xx_t *gd54xx) { svga_t *svga = &gd54xx->svga; + uint32_t base, size; if (!(gd54xx->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { mem_mapping_disable(&svga->mapping); @@ -936,7 +993,9 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) gd54xx->mmio_vram_overlap = 1; break; } - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x07] & 0x01)) { + + if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x07] & 0x01) && + (svga->crtc[0x27] >= CIRRUS_ID_CLGD5426) && (svga->crtc[0x27] != CIRRUS_ID_CLGD5424)) { if (gd54xx->mmio_vram_overlap) { mem_mapping_disable(&svga->mapping); mem_mapping_set_addr(&gd54xx->mmio_mapping, 0xb8000, 0x08000); @@ -945,9 +1004,7 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) } else mem_mapping_disable(&gd54xx->mmio_mapping); } else { - uint32_t base, size; - - if (svga->crtc[0x27] <= CIRRUS_ID_CLGD5429 || (!gd54xx->pci && !gd54xx->vlb)) { + if ((svga->crtc[0x27] <= CIRRUS_ID_CLGD5429) || (!gd54xx->pci && !gd54xx->vlb)) { if (svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) { base = (svga->seqregs[7] & 0xf0) << 16; size = 1 * 1024 * 1024; @@ -971,7 +1028,8 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) mem_mapping_disable(&svga->mapping); mem_mapping_set_addr(&gd54xx->linear_mapping, base, size); - if (svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) { + if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5426) && + (svga->crtc[0x27] != CIRRUS_ID_CLGD5424)) { if (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR) mem_mapping_disable(&gd54xx->mmio_mapping); /* MMIO is handled in the linear read/write functions */ else @@ -993,7 +1051,7 @@ static void gd54xx_recalctimings(svga_t *svga) { gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - uint8_t clocksel; + uint8_t clocksel, rdmask; svga->rowoffset = (svga->crtc[0x13]) | ((svga->crtc[0x1b] & 0x10) << 4); @@ -1010,10 +1068,18 @@ gd54xx_recalctimings(svga_t *svga) if (gd54xx->ramdac.ctrl & 0x80) { if (gd54xx->ramdac.ctrl & 0x40) { - switch (gd54xx->ramdac.ctrl & 0xf) { + if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5428) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5426)) + rdmask = 0xf; + else + rdmask = 0x7; + + switch (gd54xx->ramdac.ctrl & rdmask) { case 0: svga->bpp = 15; - svga->render = svga_render_15bpp_highres; + if (gd54xx->ramdac.ctrl & 0x80) + svga->render = svga_render_15bpp_mix_highres; + else + svga->render = svga_render_15bpp_highres; break; case 1: @@ -1033,12 +1099,24 @@ gd54xx_recalctimings(svga_t *svga) } break; + case 8: + svga->bpp = 8; + svga->render = svga_render_8bpp_gs_highres; + break; + + case 9: + svga->bpp = 8; + svga->render = svga_render_8bpp_rgb_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; + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5430) { + svga->bpp = 32; + svga->render = svga_render_32bpp_highres; + svga->rowoffset *= 2; + } break; case CIRRUS_SR7_BPP_24: @@ -1047,6 +1125,12 @@ gd54xx_recalctimings(svga_t *svga) break; case CIRRUS_SR7_BPP_16: + if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5428) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5426)) { + svga->bpp = 16; + svga->render = svga_render_16bpp_highres; + } + break; + case CIRRUS_SR7_BPP_16_DOUBLEVCLK: svga->bpp = 16; svga->render = svga_render_16bpp_highres; @@ -1061,7 +1145,10 @@ gd54xx_recalctimings(svga_t *svga) } } else { svga->bpp = 15; - svga->render = svga_render_15bpp_highres; + if (gd54xx->ramdac.ctrl & 0x80) + svga->render = svga_render_15bpp_mix_highres; + else + svga->render = svga_render_15bpp_highres; } } @@ -1242,8 +1329,7 @@ gd54xx_write(uint32_t addr, uint8_t val, void *p) return; } - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; + addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; svga_write_linear(addr, val, svga); } @@ -1267,8 +1353,7 @@ gd54xx_writew(uint32_t addr, uint16_t val, void *p) return; } - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; + addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; if (svga->writemode < 4) svga_writew_linear(addr, val, svga); @@ -1299,8 +1384,7 @@ gd54xx_writel(uint32_t addr, uint32_t val, void *p) return; } - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; + addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; if (svga->writemode < 4) svga_writel_linear(addr, val, svga); @@ -1317,7 +1401,7 @@ gd54xx_writel(uint32_t addr, uint32_t val, void *p) static void gd54xx_write_modes45(svga_t *svga, uint8_t val, uint32_t addr) { - uint32_t i, j; + uint32_t i; switch (svga->writemode) { case 4: @@ -1345,21 +1429,22 @@ gd54xx_write_modes45(svga_t *svga, uint8_t val, uint32_t addr) addr <<= 2; for (i = 0; i < 8; i++) { - j = (0x80 >> i); - if (svga->seqregs[2] & j) { - svga->vram[addr + (i << 1)] = (val & j) ? - svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + (i << 1) + 1] = (val & j) ? - svga->gdcreg[0x11] : svga->gdcreg[0x10]; + if (val & svga->seqregs[2] & (0x80 >> i)) { + svga->vram[addr + (i << 1)] = svga->gdcreg[1]; + svga->vram[addr + (i << 1) + 1] = svga->gdcreg[0x11]; + } else { + svga->vram[addr + (i << 1)] = svga->gdcreg[0]; + svga->vram[addr + (i << 1) + 1] = svga->gdcreg[0x10]; } } } else { addr <<= 1; for (i = 0; i < 8; i++) { - j = (0x80 >> i); - if (svga->seqregs[2] & j) - svga->vram[addr + i] = (val & j) ? svga->gdcreg[1] : svga->gdcreg[0]; + if (val & svga->seqregs[2] & (0x80 >> i)) + svga->vram[addr + i] = svga->gdcreg[1]; + else + svga->vram[addr + i] = svga->gdcreg[0]; } } break; @@ -1846,8 +1931,7 @@ gd54xx_read(uint32_t addr, void *p) !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) return gd54xx_mem_sys_dest_read(gd54xx); - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; + addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; return svga_read_linear(addr, svga); } @@ -1869,8 +1953,7 @@ gd54xx_readw(uint32_t addr, void *p) return ret; } - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; + addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; return svga_readw_linear(addr, svga); } @@ -1894,8 +1977,7 @@ gd54xx_readl(uint32_t addr, void *p) return ret; } - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; + addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; return svga_readl_linear(addr, svga); } @@ -2870,6 +2952,7 @@ static void gd54xx->has_bios = 1; switch (id) { +#if defined(DEV_BRANCH) && defined(USE_CL5422) case CIRRUS_ID_CLGD5402: case CIRRUS_ID_CLGD5420: romfn = BIOS_GD5420_PATH; @@ -2878,6 +2961,7 @@ static void case CIRRUS_ID_CLGD5424: romfn = BIOS_GD5422_PATH; break; +#endif case CIRRUS_ID_CLGD5426: romfn = BIOS_GD5426_PATH; @@ -2956,6 +3040,8 @@ static void gd54xx_recalctimings, gd54xx_in, gd54xx_out, gd54xx_hwcursor_draw, NULL); svga->ven_write = gd54xx_write_modes45; + if (vram <= 1) + svga->decode_mask = gd54xx->vram_mask; mem_mapping_set_handler(&svga->mapping, gd54xx_read, gd54xx_readw, gd54xx_readl, gd54xx_write, gd54xx_writew, gd54xx_writel); mem_mapping_set_p(&svga->mapping, gd54xx); @@ -2981,6 +3067,7 @@ static void svga->hwcursor.yoff = 32; svga->hwcursor.xoff = 0; +#if defined(DEV_BRANCH) && defined(USE_CL5422) if (id >= CIRRUS_ID_CLGD5420) { gd54xx->vclk_n[0] = 0x4a; gd54xx->vclk_d[0] = 0x2b; @@ -2995,13 +3082,23 @@ static void gd54xx->vclk_d[0] = 0x3b; gd54xx->vclk_n[1] = 0x5b; gd54xx->vclk_d[1] = 0x2f; - gd54xx->vclk_n[1] = 0x45; - gd54xx->vclk_d[1] = 0x2c; - gd54xx->vclk_n[1] = 0x7e; - gd54xx->vclk_d[1] = 0x33; + gd54xx->vclk_n[2] = 0x45; + gd54xx->vclk_d[2] = 0x2c; + gd54xx->vclk_n[3] = 0x7e; + gd54xx->vclk_d[3] = 0x33; } +#else + gd54xx->vclk_n[0] = 0x4a; + gd54xx->vclk_d[0] = 0x2b; + gd54xx->vclk_n[1] = 0x5b; + gd54xx->vclk_d[1] = 0x2f; + gd54xx->vclk_n[2] = 0x45; + gd54xx->vclk_d[2] = 0x30; + gd54xx->vclk_n[3] = 0x7e; + gd54xx->vclk_d[3] = 0x33; +#endif - gd54xx->bank[1] = 0x8000; + svga->extra_banks[1] = 0x8000; if (gd54xx->pci && id >= CIRRUS_ID_CLGD5430) pci_add_card(PCI_ADD_VIDEO, cl_pci_read, cl_pci_write, gd54xx); @@ -3013,10 +3110,16 @@ static void gd54xx->pci_regs[0x33] = 0x00; svga->crtc[0x27] = id; + svga->adv_flags = FLAG_EXTRA_BANKS; + + svga->seqregs[6] = 0x0f; + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429) + gd54xx->unlocked = 1; return gd54xx; } +#if defined(DEV_BRANCH) && defined(USE_CL5422) static int gd5420_available(void) { @@ -3028,6 +3131,7 @@ gd5422_available(void) { return rom_present(BIOS_GD5422_PATH); } +#endif static int gd5426_available(void) @@ -3106,6 +3210,10 @@ gd54xx_close(void *p) { gd54xx_t *gd54xx = (gd54xx_t *)p; + FILE *f = fopen("d:\\queen\\86boxnew\\vram.dmp", "wb"); + fwrite(gd54xx->svga.vram, 1, gd54xx->vram_size, f); + fclose(f); + svga_close(&gd54xx->svga); free(gd54xx); @@ -3129,6 +3237,7 @@ gd54xx_force_redraw(void *p) gd54xx->svga.fullchange = changeframecount; } +#if defined(DEV_BRANCH) && defined(USE_CL5422) static const device_config_t gd5422_config[] = { { @@ -3149,6 +3258,7 @@ static const device_config_t gd5422_config[] = "","",-1 } }; +#endif static const device_config_t gd5428_config[] = { @@ -3231,6 +3341,7 @@ static const device_config_t gd5434_config[] = } }; +#if defined(DEV_BRANCH) && defined(USE_CL5422) const device_t gd5402_isa_device = { "Cirrus Logic GD-5402 (ACUMOS AVGA2)", @@ -3280,6 +3391,7 @@ const device_t gd5424_vlb_device = { gd54xx_force_redraw, gd5422_config, }; +#endif const device_t gd5426_vlb_device = { diff --git a/src/video/vid_cl54xx.h b/src/video/vid_cl54xx.h index 7c8c9dc51..b777d28dc 100644 --- a/src/video/vid_cl54xx.h +++ b/src/video/vid_cl54xx.h @@ -1,7 +1,7 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ -#if defined(DEV_BRANCH) +#if defined(DEV_BRANCH) && defined(USE_CL5422) extern const device_t gd5402_isa_device; extern const device_t gd5420_isa_device; extern const device_t gd5422_isa_device; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 3324b8023..002d1dfe7 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -47,7 +47,7 @@ extern uint8_t edatlookup[4][4]; uint8_t svga_rotate[8][256]; -static const uint32_t mask16[16] = { +static const uint64_t mask16[16] = { 0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff, 0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff, 0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff, @@ -153,7 +153,7 @@ svga_out(uint16_t addr, uint8_t val, void *p) svga_recalctimings(svga); break; case 2: - svga->writemask = val & 0xf; + svga->writemask = val & 0xf; break; case 3: svga->charsetb = (((val >> 2) & 3) * 0x10000) + 2; @@ -167,7 +167,7 @@ svga_out(uint16_t addr, uint8_t val, void *p) svga->chain2_write = !(val & 4); svga->chain4 = val & 8; svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && - !svga->gdcreg[1]) && svga->chain4; + !svga->gdcreg[1]) && svga->chain4 && !(svga->adv_flags & FLAG_ADDR_BY8); break; } break; @@ -212,7 +212,7 @@ svga_out(uint16_t addr, uint8_t val, void *p) o = svga->gdcreg[svga->gdcaddr & 15]; switch (svga->gdcaddr & 15) { case 2: - svga->colourcompare=val; + svga->colourcompare = val; break; case 4: svga->readplane = val & 3; @@ -245,7 +245,7 @@ svga_out(uint16_t addr, uint8_t val, void *p) } break; case 7: - svga->colournocare=val; + svga->colournocare = val; break; } svga->gdcreg[svga->gdcaddr & 15] = val; @@ -839,7 +839,10 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) int func_select, writemask2 = svga->writemask; int memory_map_mode; - uint32_t write_mask, bit_mask, set_mask, val32 = (uint32_t) val; + uint64_t write_mask, bit_mask, set_mask, mask0, la, val32 = (uint64_t) val; + + if (svga->adv_flags & FLAG_ADDR_BY8) + writemask2 = svga->seqregs[2]; egawrites++; @@ -856,7 +859,10 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) case 1: if (addr >= 0x10000) return; - addr += svga->write_bank; + else if (svga->adv_flags & FLAG_EXTRA_BANKS) + addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; + else + addr += svga->write_bank; break; case 2: addr -= 0x10000; @@ -875,17 +881,28 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) if (!(svga->gdcreg[6] & 1)) svga->fullchange = 2; - if ((svga->chain4 || svga->fb_only) && (svga->writemode < 4)) { + if ((svga->adv_flags & FLAG_ADDR_BY8) && (svga->writemode < 4)) { + if (svga->fb_only) + fatal("BY8 write in fb_only\n"); + if (svga->chain2_write) + fatal("BY8 write in chain2\n"); + addr <<= 3; + } else if ((svga->chain4 || svga->fb_only) && (svga->writemode < 4)) { writemask2 = 1 << (addr & 3); addr &= ~3; + if (svga->writemode >= 4) + fatal("write mode %i in chain4 mode\n", svga->writemode); } else if (svga->chain2_write) { writemask2 &= ~0xa; if (addr & 1) writemask2 <<= 1; addr &= ~1; addr <<= 2; + if (svga->writemode >= 4) + fatal("write mode %i in chain odd/even\n", svga->writemode); } else addr <<= 2; + addr &= svga->decode_mask; if (addr >= svga->vram_max) @@ -909,33 +926,61 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) val32 |= (val32 << 8); val32 |= (val32 << 16); + if (svga->adv_flags & FLAG_ADDR_BY8) + val32 |= (val32 << 32); if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { /* mask data according to sr[2] */ write_mask = mask16[writemask2 & 0x0f]; - addr >>= 2; + if (svga->adv_flags & FLAG_ADDR_BY8) { + write_mask |= (mask16[(writemask2 & 0xf0) >> 4] << 32); + addr >>= 3; - ((uint32_t *)(svga->vram))[addr] &= ~write_mask; - ((uint32_t *)(svga->vram))[addr] |= (val32 & write_mask); + ((uint64_t *)(svga->vram))[addr] &= ~write_mask; + ((uint64_t *)(svga->vram))[addr] |= (val32 & write_mask); + } else { + addr >>= 2; + + ((uint32_t *)(svga->vram))[addr] &= ~write_mask; + ((uint32_t *)(svga->vram))[addr] |= (val32 & write_mask); + } return; } set_mask = mask16[svga->gdcreg[1] & 0x0f]; - val32 = (val32 & ~set_mask) | (mask16[svga->gdcreg[0] & 0x0f] & set_mask); + if (svga->adv_flags & FLAG_ADDR_BY8) + set_mask |= (mask16[(svga->gdcreg[1] & 0xf0) >> 4] << 32); + + mask0 = mask16[svga->gdcreg[0] & 0x0f]; + if (svga->adv_flags & FLAG_ADDR_BY8) + mask0 |= (mask16[(svga->gdcreg[0] & 0xf0) >> 4] << 32); + + val32 = (val32 & ~set_mask) | (mask0 & set_mask); break; case 1: val32 = svga->latch; /* mask data according to sr[2] */ write_mask = mask16[writemask2 & 0x0f]; - addr >>= 2; + if (svga->adv_flags & FLAG_ADDR_BY8) { + write_mask |= (mask16[(writemask2 & 0xf0) >> 4] << 32); + addr >>= 3; - ((uint32_t *)(svga->vram))[addr] &= ~write_mask; - ((uint32_t *)(svga->vram))[addr] |= (val32 & write_mask); + ((uint64_t *)(svga->vram))[addr] &= ~write_mask; + ((uint64_t *)(svga->vram))[addr] |= (val32 & write_mask); + } else { + addr >>= 2; + + ((uint32_t *)(svga->vram))[addr] &= ~write_mask; + ((uint32_t *)(svga->vram))[addr] |= (val32 & write_mask); + } return; case 2: - val32 = mask16[val32 & 0x0f]; + mask0 = mask16[val32 & 0x0f]; + if (svga->adv_flags & FLAG_ADDR_BY8) + mask0 |= (mask16[(val32 & 0xf0) >> 4] << 32); + val32 = mask0; bit_mask = svga->gdcreg[8]; if (!(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) @@ -948,6 +993,8 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) bit_mask = svga->gdcreg[8] & val32; val32 = mask16[svga->gdcreg[0] & 0x0f]; + if (svga->adv_flags & FLAG_ADDR_BY8) + val32 |= (mask16[(svga->gdcreg[0] & 0xf0) >> 4] << 32); break; default: if (svga->ven_write) @@ -958,6 +1005,12 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) /* apply bit mask */ bit_mask |= bit_mask << 8; bit_mask |= bit_mask << 16; + if (svga->adv_flags & FLAG_ADDR_BY8) + bit_mask |= bit_mask << 32; + + la = svga->latch; + if (!(svga->adv_flags & FLAG_LATCH8)) + la &= 0xffffffff; /* apply logical operation */ switch(func_select) { @@ -965,30 +1018,36 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) default: /* set */ val32 &= bit_mask; - val32 |= (svga->latch & ~bit_mask); + val32 |= (la & ~bit_mask); break; case 1: /* and */ val32 |= ~bit_mask; - val32 &= svga->latch; + val32 &= la; break; case 2: /* or */ val32 &= bit_mask; - val32 |= svga->latch; + val32 |= la; break; case 3: /* xor */ val32 &= bit_mask; - val32 ^= svga->latch; + val32 ^= la; break; } /* mask data according to sr[2] */ write_mask = mask16[writemask2 & 0x0f]; - addr >>= 2; + if (svga->adv_flags & FLAG_ADDR_BY8) + write_mask |= (mask16[(writemask2 & 0xf0) >> 4] << 32); - ((uint32_t *)(svga->vram))[addr] = (((uint32_t *)(svga->vram))[addr] & ~write_mask) | (val32 & write_mask); + addr >>= ((svga->adv_flags & FLAG_ADDR_BY8) ? 3 : 2); + + if (svga->adv_flags & FLAG_ADDR_BY8) + ((uint64_t *)(svga->vram))[addr] = (((uint64_t *)(svga->vram))[addr] & ~write_mask) | (val32 & write_mask); + else + ((uint32_t *)(svga->vram))[addr] = (((uint32_t *)(svga->vram))[addr] & ~write_mask) | (val32 & write_mask); } @@ -996,8 +1055,13 @@ uint8_t svga_read_common(uint32_t addr, uint8_t linear, void *p) { svga_t *svga = (svga_t *)p; - uint32_t latch_addr = 0, ret; + uint32_t latch_addr = 0; int memory_map_mode, readplane = svga->readplane; + uint32_t mask0, mask1; + uint64_t ret; + + if (svga->adv_flags & FLAG_ADDR_BY8) + readplane = svga->gdcreg[4] & 7; sub_cycles(video_timing_read_b); @@ -1014,7 +1078,10 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p) case 1: if (addr >= 0x10000) return 0xff; - addr += svga->read_bank; + else if (svga->adv_flags & FLAG_EXTRA_BANKS) + addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; + else + addr += svga->read_bank; break; case 2: addr -= 0x10000; @@ -1029,10 +1096,19 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p) break; } - latch_addr = (addr << 2) & svga->decode_mask; + if (svga->adv_flags & FLAG_ADDR_BY8) + latch_addr = (addr << 3) & svga->decode_mask; + else + latch_addr = (addr << 2) & svga->decode_mask; } - if (svga->chain4 || svga->fb_only) { + if (svga->adv_flags & FLAG_ADDR_BY8) { + if (svga->fb_only) + fatal("BY8 read in fb_only\n"); + if (svga->chain2_read) + fatal("BY8 read in chain2\n"); + addr <<= 3; + } else if (svga->chain4 || svga->fb_only) { addr &= svga->decode_mask; if (addr >= svga->vram_max) return 0xff; @@ -1059,13 +1135,28 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p) addr &= svga->vram_mask; - svga->latch = ((uint32_t *)(svga->vram))[addr >> 2]; + if (svga->adv_flags & FLAG_ADDR_BY8) { + if (svga->adv_flags & FLAG_LATCH8) + svga->latch = ((uint64_t *)(svga->vram))[addr >> 3]; + else + svga->latch = (svga->latch & 0xffffffff00000000ULL) | (((uint64_t *)(svga->vram))[addr >> 3] & 0xffffffff); + } else + svga->latch = (svga->latch & 0xffffffff00000000ULL) | ((uint32_t *)(svga->vram))[addr >> 2]; } else { if (latch_addr > svga->vram_max) - svga->latch = 0xffffffff; + if (svga->adv_flags & FLAG_LATCH8) + svga->latch = 0xffffffffffffffffULL; + else + svga->latch = (svga->latch & 0xffffffff00000000ULL) | 0xffffffff; else { latch_addr &= svga->vram_mask; - svga->latch = ((uint32_t *)(svga->vram))[latch_addr >> 2]; + if (svga->adv_flags & FLAG_ADDR_BY8) { + if (svga->adv_flags & FLAG_LATCH8) + svga->latch = ((uint64_t *)(svga->vram))[latch_addr >> 3]; + else + svga->latch = (svga->latch & 0xffffffff00000000ULL) | (((uint64_t *)(svga->vram))[latch_addr >> 3] & 0xffffffff); + } else + svga->latch = (svga->latch & 0xffffffff00000000ULL) | ((uint32_t *)(svga->vram))[latch_addr >> 2]; } if (addr >= svga->vram_max) @@ -1079,7 +1170,13 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p) return (svga->latch >> (readplane * 8)) & 0xff; } else { /* read mode 1 */ - ret = (svga->latch ^ mask16[svga->colourcompare & 0x0f]) & mask16[svga->colournocare & 0x0f]; + if (svga->adv_flags & FLAG_LATCH8) { + mask0 = mask16[svga->colourcompare & 0x0f] | (mask16[(svga->colourcompare & 0xf0) >> 4] << 32); + mask1 = mask16[svga->colournocare & 0x0f] | (mask16[(svga->colournocare & 0xf0) >> 4] << 32); + ret = (svga->latch ^ mask0) & mask1; + ret |= ret >> 32; + } else + ret = (svga->latch ^ mask16[svga->colourcompare & 0x0f]) & mask16[svga->colournocare & 0x0f]; ret |= ret >> 16; ret |= ret >> 8; ret = (~ret) & 0xff; @@ -1213,6 +1310,7 @@ void svga_writew_common(uint32_t addr, uint16_t val, uint8_t linear, void *p) { svga_t *svga = (svga_t *)p; + int memory_map_mode; if (!svga->fast) { svga_write_common(addr, val, linear, p); @@ -1224,8 +1322,14 @@ svga_writew_common(uint32_t addr, uint16_t val, uint8_t linear, void *p) sub_cycles(video_timing_write_w); - if (!linear) - addr = (addr & svga->banked_mask) + svga->write_bank; + if (!linear) { + memory_map_mode = (svga->gdcreg[6] >> 2) & 3; + if ((memory_map_mode == 1) && (svga->adv_flags & FLAG_EXTRA_BANKS)) + addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; + else + addr = (addr & svga->banked_mask) + svga->write_bank; + } + addr &= svga->decode_mask; if (addr >= svga->vram_max) return; @@ -1254,6 +1358,7 @@ void svga_writel_common(uint32_t addr, uint32_t val, uint8_t linear, void *p) { svga_t *svga = (svga_t *)p; + int memory_map_mode; if (!svga->fast) { svga_write_common(addr, val, linear, p); @@ -1267,8 +1372,14 @@ svga_writel_common(uint32_t addr, uint32_t val, uint8_t linear, void *p) sub_cycles(video_timing_write_l); - if (!linear) - addr = (addr & svga->banked_mask) + svga->write_bank; + if (!linear) { + memory_map_mode = (svga->gdcreg[6] >> 2) & 3; + if ((memory_map_mode == 1) && (svga->adv_flags & FLAG_EXTRA_BANKS)) + addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; + else + addr = (addr & svga->banked_mask) + svga->write_bank; + } + addr &= svga->decode_mask; if (addr >= svga->vram_max) return; diff --git a/src/video/vid_svga.h b/src/video/vid_svga.h index 6d941932a..5bca424da 100644 --- a/src/video/vid_svga.h +++ b/src/video/vid_svga.h @@ -17,6 +17,12 @@ * Copyright 2016-2018 Miran Grca. */ + +#define FLAG_EXTRA_BANKS 1 +#define FLAG_ADDR_BY8 2 +#define FLAG_LATCH8 4 + + typedef struct { int ena, x, y, xoff, yoff, xsize, ysize, @@ -58,17 +64,20 @@ typedef struct svga_t uint32_t decode_mask, vram_max, vram_mask, charseta, charsetb, - latch, ma_latch, + adv_flags, ma_latch, ma, maback, write_bank, read_bank, + extra_banks[2], banked_mask, ca, overscan_color, pallook[256]; PALETTE vgapal; - uint64_t dispontime, dispofftime; - pc_timer_t timer; + uint64_t latch, + dispontime, dispofftime; + + pc_timer_t timer; double clock; diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index bd6773e2d..1350ae51a 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -560,6 +560,142 @@ void svga_render_8bpp_highres(svga_t *svga) } } +void svga_render_8bpp_gs_lowres(svga_t *svga) +{ + int y_add = enable_overscan ? (overscan_y >> 1) : 0; + int x_add = enable_overscan ? 8 : 0; + + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + { + int x; + int offset = (8 - (svga->scrollcache & 6)) + 24; + uint32_t *p = &buffer32->line[svga->displine + y_add][offset + x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + for (x = 0; x <= svga->hdisp; x += 8) + { + uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + + p[0] = p[1] = video_8togs[dat & 0xff]; + p[2] = p[3] = video_8togs[(dat >> 8) & 0xff]; + p[4] = p[5] = video_8togs[(dat >> 16) & 0xff]; + p[6] = p[7] = video_8togs[(dat >> 24) & 0xff]; + + svga->ma += 4; + p += 8; + } + svga->ma &= svga->vram_display_mask; + } +} + +void svga_render_8bpp_gs_highres(svga_t *svga) +{ + int y_add = enable_overscan ? (overscan_y >> 1) : 0; + int x_add = enable_overscan ? 8 : 0; + + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + { + int x; + int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; + uint32_t *p = &buffer32->line[svga->displine + y_add][offset + x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + for (x = 0; x <= svga->hdisp; x += 8) + { + uint32_t dat; + dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + p[0] = video_8togs[dat & 0xff]; + p[1] = video_8togs[(dat >> 8) & 0xff]; + p[2] = video_8togs[(dat >> 16) & 0xff]; + p[3] = video_8togs[(dat >> 24) & 0xff]; + + dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + p[4] = video_8togs[dat & 0xff]; + p[5] = video_8togs[(dat >> 8) & 0xff]; + p[6] = video_8togs[(dat >> 16) & 0xff]; + p[7] = video_8togs[(dat >> 24) & 0xff]; + + svga->ma += 8; + p += 8; + } + svga->ma &= svga->vram_display_mask; + } +} + +void svga_render_8bpp_rgb_lowres(svga_t *svga) +{ + int y_add = enable_overscan ? (overscan_y >> 1) : 0; + int x_add = enable_overscan ? 8 : 0; + + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + { + int x; + int offset = (8 - (svga->scrollcache & 6)) + 24; + uint32_t *p = &buffer32->line[svga->displine + y_add][offset + x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + for (x = 0; x <= svga->hdisp; x += 8) + { + uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + + p[0] = p[1] = video_8to32[dat & 0xff]; + p[2] = p[3] = video_8to32[(dat >> 8) & 0xff]; + p[4] = p[5] = video_8to32[(dat >> 16) & 0xff]; + p[6] = p[7] = video_8to32[(dat >> 24) & 0xff]; + + svga->ma += 4; + p += 8; + } + svga->ma &= svga->vram_display_mask; + } +} + +void svga_render_8bpp_rgb_highres(svga_t *svga) +{ + int y_add = enable_overscan ? (overscan_y >> 1) : 0; + int x_add = enable_overscan ? 8 : 0; + + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + { + int x; + int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; + uint32_t *p = &buffer32->line[svga->displine + y_add][offset + x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + for (x = 0; x <= svga->hdisp; x += 8) + { + uint32_t dat; + dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + p[0] = video_8to32[dat & 0xff]; + p[1] = video_8to32[(dat >> 8) & 0xff]; + p[2] = video_8to32[(dat >> 16) & 0xff]; + p[3] = video_8to32[(dat >> 24) & 0xff]; + + dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + p[4] = video_8to32[dat & 0xff]; + p[5] = video_8to32[(dat >> 8) & 0xff]; + p[6] = video_8to32[(dat >> 16) & 0xff]; + p[7] = video_8to32[(dat >> 24) & 0xff]; + + svga->ma += 8; + p += 8; + } + svga->ma &= svga->vram_display_mask; + } +} + void svga_render_15bpp_lowres(svga_t *svga) { int y_add = enable_overscan ? (overscan_y >> 1) : 0; @@ -630,6 +766,82 @@ void svga_render_15bpp_highres(svga_t *svga) } } +void svga_render_15bpp_mix_lowres(svga_t *svga) +{ + int y_add = enable_overscan ? (overscan_y >> 1) : 0; + int x_add = enable_overscan ? 8 : 0; + + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + { + int x; + int offset = (8 - (svga->scrollcache & 6)) + 24; + uint32_t *p = &buffer32->line[svga->displine + y_add][offset + x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + for (x = 0; x <= svga->hdisp; x += 4) + { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + p[x] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + + dat >>= 16; + p[x + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + p[x + 2] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + + dat >>= 16; + p[x + 3] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + } + svga->ma += x << 1; + svga->ma &= svga->vram_display_mask; + } +} + +void svga_render_15bpp_mix_highres(svga_t *svga) +{ + int y_add = enable_overscan ? (overscan_y >> 1) : 0; + int x_add = enable_overscan ? 8 : 0; + + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + { + int x; + int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; + uint32_t *p = &buffer32->line[svga->displine + y_add][offset + x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + for (x = 0; x <= svga->hdisp; x += 8) + { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + p[x] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + dat >>= 16; + p[x + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + p[x + 2] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + dat >>= 16; + p[x + 3] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); + p[x + 4] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + dat >>= 16; + p[x + 5] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); + p[x + 6] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + dat >>= 16; + p[x + 7] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + } + svga->ma += x << 1; + svga->ma &= svga->vram_display_mask; + } +} + void svga_render_16bpp_lowres(svga_t *svga) { int y_add = enable_overscan ? (overscan_y >> 1) : 0; diff --git a/src/video/vid_svga_render.h b/src/video/vid_svga_render.h index 4bbc43272..f619d3520 100644 --- a/src/video/vid_svga_render.h +++ b/src/video/vid_svga_render.h @@ -38,8 +38,14 @@ void svga_render_4bpp_lowres(svga_t *svga); void svga_render_4bpp_highres(svga_t *svga); void svga_render_8bpp_lowres(svga_t *svga); void svga_render_8bpp_highres(svga_t *svga); +void svga_render_8bpp_gs_lowres(svga_t *svga); +void svga_render_8bpp_gs_highres(svga_t *svga); +void svga_render_8bpp_rgb_lowres(svga_t *svga); +void svga_render_8bpp_rgb_highres(svga_t *svga); void svga_render_15bpp_lowres(svga_t *svga); void svga_render_15bpp_highres(svga_t *svga); +void svga_render_15bpp_mix_lowres(svga_t *svga); +void svga_render_15bpp_mix_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); diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 9d7cca6b0..c1f4882db 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -92,7 +92,7 @@ video_cards[] = { #endif { "[ISA] CGA", "cga", &cga_device }, { "[ISA] Chips & Technologies SuperEGA", "superega", &sega_device }, -#if defined(DEV_BRANCH) +#if defined(DEV_BRANCH) && defined(USE_CL5422) { "[ISA] Cirrus Logic CL-GD 5402", "cl_gd5402_isa", &gd5402_isa_device }, { "[ISA] Cirrus Logic CL-GD 5420", "cl_gd5420_isa", &gd5420_isa_device }, { "[ISA] Cirrus Logic CL-GD 5422", "cl_gd5422_isa", &gd5422_isa_device }, @@ -160,9 +160,9 @@ video_cards[] = { { "[PCI] Trident TGUI9440", "tgui9440_pci", &tgui9440_pci_device }, { "[VLB] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_vlb", &mach64gx_vlb_device }, { "[VLB] Cardex Tseng ET4000/w32p", "et4000w32p_vlb", &et4000w32p_cardex_vlb_device }, -#if defined(DEV_BRANCH) +#if defined(DEV_BRANCH) && defined(USE_CL5422) { "[VLB] Cirrus Logic CL-GD 5424", "cl_gd5424_vlb", &gd5424_vlb_device }, -#endif +#endif { "[VLB] Cirrus Logic CL-GD 5428", "cl_gd5428_vlb", &gd5428_vlb_device }, { "[VLB] Cirrus Logic CL-GD 5429", "cl_gd5429_vlb", &gd5429_vlb_device }, { "[VLB] Cirrus Logic CL-GD 5434", "cl_gd5434_vlb", &gd5434_vlb_device }, diff --git a/src/video/video.c b/src/video/video.c index aeb4cf7c1..9a513ae9d 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -80,6 +80,8 @@ int xsize = 1, int cga_palette = 0, herc_blend = 0; uint32_t *video_6to8 = NULL, + *video_8togs = NULL, + *video_8to32 = NULL, *video_15to32 = NULL, *video_16to32 = NULL; int egareads = 0, @@ -517,6 +519,26 @@ calc_6to8(int c) } +int +calc_8to32(int c) +{ + int b, g, r; + double db, dg, dr; + + b = (c & 3); + g = ((c >> 2) & 7); + r = ((c >> 5) & 7); + db = (((double) b) / 3.0) * 255.0; + dg = (((double) g) / 7.0) * 255.0; + dr = (((double) r) / 7.0) * 255.0; + b = (int) db; + g = ((int) dg) << 8; + r = ((int) dr) << 16; + + return(b | g | r); +} + + int calc_15to32(int c) { @@ -666,19 +688,20 @@ video_init(void) video_6to8 = malloc(4 * 256); for (c = 0; c < 256; c++) video_6to8[c] = calc_6to8(c); + + video_8togs = malloc(4 * 256); + for (c = 0; c < 256; c++) + video_8togs[c] = c | (c << 16) | (c << 24); + + video_8to32 = malloc(4 * 256); + for (c = 0; c < 256; c++) + video_8to32[c] = calc_8to32(c); + video_15to32 = malloc(4 * 65536); -#if 0 - for (c = 0; c < 65536; c++) - video_15to32[c] = ((c & 31) << 3) | (((c >> 5) & 31) << 11) | (((c >> 10) & 31) << 19); -#endif for (c = 0; c < 65536; c++) video_15to32[c] = calc_15to32(c); video_16to32 = malloc(4 * 65536); -#if 0 - for (c = 0; c < 65536; c++) - video_16to32[c] = ((c & 31) << 3) | (((c >> 5) & 63) << 10) | (((c >> 11) & 31) << 19); -#endif for (c = 0; c < 65536; c++) video_16to32[c] = calc_16to32(c); @@ -697,9 +720,11 @@ video_close(void) thread_destroy_event(blit_data.blit_complete); thread_destroy_event(blit_data.wake_blit_thread); - free(video_6to8); - free(video_15to32); free(video_16to32); + free(video_15to32); + free(video_8to32); + free(video_8togs); + free(video_6to8); destroy_bitmap(buffer32); diff --git a/src/video/video.h b/src/video/video.h index 3d66bf58e..77a3a5733 100644 --- a/src/video/video.h +++ b/src/video/video.h @@ -99,6 +99,8 @@ extern uint8_t fontdat12x18[256][36]; extern dbcs_font_t *fontdatksc5601; extern dbcs_font_t *fontdatksc5601_user; extern uint32_t *video_6to8, + *video_8togs, + *video_8to32, *video_15to32, *video_16to32; extern int xsize,ysize; diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 36f66cdf0..ce8fd696e 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -41,6 +41,9 @@ ifeq ($(DEV_BUILD), y) ifndef AMD_K AMD_K := y endif + ifndef CL5422 + CL5422 := y + endif ifndef CRASHDUMP CRASHDUMP := y endif @@ -71,6 +74,9 @@ ifeq ($(DEV_BUILD), y) ifndef PS2M70T4 PS2M70T4 := y endif + ifndef TI + TI := y + endif ifndef TC430HX TC430HX := y endif @@ -96,6 +102,9 @@ else ifndef AMD_K AMD_K := n endif + ifndef CL5422 + CL5422 := n + endif ifndef CRASHDUMP CRASHDUMP := n endif @@ -126,6 +135,9 @@ else ifndef PS2M70T4 PS2M70T4 := n endif + ifndef TI + TI := n + endif ifndef TC430HX TC430HX := n endif @@ -436,6 +448,10 @@ ifeq ($(AMD_K), y) OPTS += -DUSE_AMD_K endif +ifeq ($(CL5422), y) +OPTS += -DUSE_CL5422 +endif + ifeq ($(CRASHDUMPOBJ), y) OPTS += -DUSE_CRASHDUMP DEVBROBJ += win_crashdump.o @@ -476,6 +492,10 @@ ifeq ($(PS2M70T4), y) OPTS += -DUSE_PS2M70T4 endif +ifeq ($(TI), y) +OPTS += -DUSE_TI +endif + ifeq ($(TC430HX), y) OPTS += -DUSE_TC430HX endif @@ -504,7 +524,7 @@ endif # Final versions of the toolchain flags. CFLAGS := $(WX_FLAGS) $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) \ $(AFLAGS) -fomit-frame-pointer -mstackrealign -Wall \ - -fno-strict-aliasing + -fno-strict-aliasing -funroll-loops # Add freetyp2 references through pkgconfig CFLAGS := $(CFLAGS) `pkg-config.exe --cflags freetype2` diff --git a/src/win/Makefile_ndr.mingw b/src/win/Makefile_ndr.mingw index 93ec085d5..78854ae40 100644 --- a/src/win/Makefile_ndr.mingw +++ b/src/win/Makefile_ndr.mingw @@ -41,6 +41,9 @@ ifeq ($(DEV_BUILD), y) ifndef AMD_K AMD_K := y endif + ifndef CL5422 + CL5422 := y + endif ifndef CRASHDUMP CRASHDUMP := y endif @@ -71,6 +74,9 @@ ifeq ($(DEV_BUILD), y) ifndef PS2M70T4 PS2M70T4 := y endif + ifndef TI + TI := y + endif ifndef TC430HX TC430HX := y endif @@ -96,6 +102,9 @@ else ifndef AMD_K AMD_K := n endif + ifndef CL5422 + CL5422 := n + endif ifndef CRASHDUMP CRASHDUMP := n endif @@ -126,6 +135,9 @@ else ifndef PS2M70T4 PS2M70T4 := n endif + ifndef TI + TI := n + endif ifndef TC430HX TC430HX := n endif @@ -442,6 +454,10 @@ ifeq ($(AMD_K), y) OPTS += -DUSE_AMD_K endif +ifeq ($(CL5422), y) +OPTS += -DUSE_CL5422 +endif + ifeq ($(CRASHDUMPOBJ), y) OPTS += -DUSE_CRASHDUMP DEVBROBJ += win_crashdump.o @@ -482,6 +498,10 @@ ifeq ($(PS2M70T4), y) OPTS += -DUSE_PS2M70T4 endif +ifeq ($(TI), y) +OPTS += -DUSE_TI +endif + ifeq ($(TC430HX), y) OPTS += -DUSE_TC430HX endif @@ -510,7 +530,7 @@ endif # Final versions of the toolchain flags. CFLAGS := $(WX_FLAGS) $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) \ $(AFLAGS) -fomit-frame-pointer -mstackrealign -Wall \ - -fno-strict-aliasing + -fno-strict-aliasing -funroll-loops # Add freetyp2 references through pkgconfig CFLAGS := $(CFLAGS) `pkg-config.exe --cflags freetype2`