From 3020ec48ce64a7c384df2176efae0ec70cafef27 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 24 Mar 2020 01:03:59 +0100 Subject: [PATCH] TC1995's port of MCA CL-GD 5428. --- src/video/vid_cl54xx.c | 149 +++++++++++++++++++++++++++++++---------- src/video/vid_cl54xx.h | 1 - src/video/video.h | 1 + 3 files changed, 113 insertions(+), 38 deletions(-) delete mode 100644 src/video/vid_cl54xx.h diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 8749fa0d9..ae575f2b7 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -9,7 +9,7 @@ * Emulation of select Cirrus Logic cards (CL-GD 5428, * CL-GD 5429, CL-GD 5430, CL-GD 5434 and CL-GD 5436 are supported). * - * Version: @(#)vid_cl_54xx.c 1.0.33 2020/01/22 + * Version: @(#)vid_cl_54xx.c 1.0.34 2020/03/23 * * Authors: TheCollector1995, * Miran Grca, @@ -127,6 +127,10 @@ #define CIRRUS_BLTMODEEXT_COLOREXPINV 0x02 #define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01 +#define CL_GD5428_SYSTEM_BUS_MCA 5 +#define CL_GD5428_SYSTEM_BUS_VESA 6 +#define CL_GD5428_SYSTEM_BUS_ISA 7 + #define CL_GD5429_SYSTEM_BUS_VESA 5 #define CL_GD5429_SYSTEM_BUS_ISA 7 @@ -179,7 +183,7 @@ typedef struct gd54xx_t int unlock_special; } blt; - int pci, vlb; + int pci, vlb, mca; int countminusone; uint8_t pci_regs[256]; @@ -188,6 +192,9 @@ typedef struct gd54xx_t uint8_t fc; /* Feature Connector */ int card; + + uint8_t pos_regs[8]; + svga_t *mb_vga; uint32_t lfb_base; @@ -690,10 +697,19 @@ gd54xx_in(uint16_t addr, void *p) case 0x17: ret = svga->gdcreg[0x17] & ~(7 << 3); if (svga->crtc[0x27] <= CIRRUS_ID_CLGD5429) { - if (gd54xx->vlb) - ret |= (CL_GD5429_SYSTEM_BUS_VESA << 3); - else - ret |= (CL_GD5429_SYSTEM_BUS_ISA << 3); + if (svga->crtc[0x27] == CIRRUS_ID_CLGD5428) { + if (gd54xx->vlb) + ret |= (CL_GD5428_SYSTEM_BUS_VESA << 3); + else if (gd54xx->mca) + ret |= (CL_GD5428_SYSTEM_BUS_MCA << 3); + else + ret |= (CL_GD5428_SYSTEM_BUS_ISA << 3); + } else { + if (gd54xx->vlb) + ret |= (CL_GD5429_SYSTEM_BUS_VESA << 3); + else + ret |= (CL_GD5429_SYSTEM_BUS_ISA << 3); + } } else { if (gd54xx->pci) ret |= (CL_GD543X_SYSTEM_BUS_PCI << 3); @@ -878,8 +894,14 @@ gd54xx_in(uint16_t addr, void *p) } else { if ((svga->gdcaddr < 2) && !gd54xx->unlocked) ret = (svga->gdcreg[svga->gdcaddr] & 0x0f); - else - ret = svga->gdcreg[svga->gdcaddr]; + else { + if (svga->gdcaddr == 0) + ret = gd543x_mmio_read(0xb8000, gd54xx); + else if (svga->gdcaddr == 1) + ret = gd543x_mmio_read(0xb8004, gd54xx); + else + ret = svga->gdcreg[svga->gdcaddr]; + } } break; case 0x3d4: @@ -893,7 +915,7 @@ gd54xx_in(uint16_t addr, void *p) !gd54xx->unlocked) ret = 0xff; else switch (svga->crtcreg) { - case 0x22: /*Graphis Data Latches Readback Register*/ + case 0x22: /*Graphics Data Latches Readback Register*/ /*Should this be & 7 if 8 byte latch is enabled? */ ret = svga->latch.b[svga->gdcreg[4] & 3]; break; @@ -959,8 +981,9 @@ 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)) { + + if ((gd54xx->pci && (!(gd54xx->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM))) || + (gd54xx->mca && (!(gd54xx->pos_regs[2] & 1)))) { mem_mapping_disable(&svga->mapping); mem_mapping_disable(&gd54xx->linear_mapping); mem_mapping_disable(&gd54xx->mmio_mapping); @@ -993,7 +1016,7 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) } if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x07] & 0x01) && - (svga->crtc[0x27] >= CIRRUS_ID_CLGD5426) && (svga->crtc[0x27] != CIRRUS_ID_CLGD5424)) { + (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429)) { if (gd54xx->mmio_vram_overlap) { mem_mapping_disable(&svga->mapping); mem_mapping_set_addr(&gd54xx->mmio_mapping, 0xb8000, 0x08000); @@ -1016,7 +1039,7 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) size = 16 * 1024 * 1024; else size = 4 * 1024 * 1024; - } else { /*VLB*/ + } else { /*VLB/ISA/MCA*/ base = 128*1024*1024; if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) size = 16 * 1024 * 1024; @@ -1026,8 +1049,7 @@ 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) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5426) && - (svga->crtc[0x27] != CIRRUS_ID_CLGD5424)) { + if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429)) { if (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR) mem_mapping_disable(&gd54xx->mmio_mapping); /* MMIO is handled in the linear read/write functions */ else @@ -2891,6 +2913,33 @@ cl_pci_write(int func, int addr, uint8_t val, void *p) } } +static uint8_t +gd5428_mca_read(int port, void *p) +{ + gd54xx_t *gd54xx = (gd54xx_t *)p; + + return gd54xx->pos_regs[port & 7]; +} + +static void +gd5428_mca_write(int port, uint8_t val, void *p) +{ + gd54xx_t *gd54xx = (gd54xx_t *)p; + + if (port < 0x102) + return; + + gd54xx->pos_regs[port & 7] = val; + gd543x_recalc_mapping(gd54xx); +} + +static uint8_t +gd5428_mca_feedb(void *p) +{ + gd54xx_t *gd54xx = (gd54xx_t *)p; + + return gd54xx->pos_regs[2] & 1; +} static void *gd54xx_init(const device_t *info) @@ -2903,7 +2952,8 @@ static void memset(gd54xx, 0, sizeof(gd54xx_t)); gd54xx->pci = !!(info->flags & DEVICE_PCI); - gd54xx->vlb = !!(info->flags & DEVICE_VLB); + gd54xx->vlb = !!(info->flags & DEVICE_VLB); + gd54xx->mca = !!(info->flags & DEVICE_MCA); gd54xx->rev = 0; gd54xx->has_bios = 1; @@ -2979,16 +3029,21 @@ static void romfn = BIOS_GD5480_PATH; break; } - - if (id >= CIRRUS_ID_CLGD5420) - vram = device_get_config_int("memory"); - else - vram = 0; - - if (vram) - gd54xx->vram_size = vram << 20; - else - gd54xx->vram_size = 1 << 19; + + if (info->flags & DEVICE_MCA) { + vram = 1; + gd54xx->vram_size = 1 << 20; + } else { + if (id >= CIRRUS_ID_CLGD5420) + vram = device_get_config_int("memory"); + else + vram = 0; + + if (vram) + gd54xx->vram_size = vram << 20; + else + gd54xx->vram_size = 1 << 19; + } gd54xx->vram_mask = gd54xx->vram_size - 1; @@ -3009,25 +3064,25 @@ static void 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); - + mem_mapping_add(&gd54xx->mmio_mapping, 0, 0, - gd543x_mmio_read, gd543x_mmio_readw, gd543x_mmio_readl, - gd543x_mmio_writeb, gd543x_mmio_writew, gd543x_mmio_writel, - NULL, MEM_MAPPING_EXTERNAL, gd54xx); + gd543x_mmio_read, gd543x_mmio_readw, gd543x_mmio_readl, + gd543x_mmio_writeb, gd543x_mmio_writew, gd543x_mmio_writel, + NULL, MEM_MAPPING_EXTERNAL, gd54xx); mem_mapping_disable(&gd54xx->mmio_mapping); mem_mapping_add(&gd54xx->linear_mapping, 0, 0, - gd54xx_readb_linear, gd54xx_readw_linear, gd54xx_readl_linear, - gd54xx_writeb_linear, gd54xx_writew_linear, gd54xx_writel_linear, - NULL, MEM_MAPPING_EXTERNAL, gd54xx); + gd54xx_readb_linear, gd54xx_readw_linear, gd54xx_readl_linear, + gd54xx_writeb_linear, gd54xx_writew_linear, gd54xx_writel_linear, + NULL, MEM_MAPPING_EXTERNAL, gd54xx); mem_mapping_disable(&gd54xx->linear_mapping); mem_mapping_add(&gd54xx->aperture2_mapping, 0, 0, - gd5436_aperture2_readb, gd5436_aperture2_readw, gd5436_aperture2_readl, - gd5436_aperture2_writeb, gd5436_aperture2_writew, gd5436_aperture2_writel, - NULL, MEM_MAPPING_EXTERNAL, gd54xx); + gd5436_aperture2_readb, gd5436_aperture2_readw, gd5436_aperture2_readl, + gd5436_aperture2_writeb, gd5436_aperture2_writew, gd5436_aperture2_writel, + NULL, MEM_MAPPING_EXTERNAL, gd54xx); mem_mapping_disable(&gd54xx->aperture2_mapping); io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); - + svga->hwcursor.yoff = 32; svga->hwcursor.xoff = 0; @@ -3068,6 +3123,12 @@ static void if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429) gd54xx->unlocked = 1; + if (gd54xx->mca) { + gd54xx->pos_regs[0] = 0x7b; + gd54xx->pos_regs[1] = 0x91; + mca_add(gd5428_mca_read, gd5428_mca_write, gd5428_mca_feedb, NULL, gd54xx); + } + return gd54xx; } @@ -3400,6 +3461,20 @@ const device_t gd5428_vlb_device = gd5428_config }; +const device_t gd5428_mca_device = +{ + "Cirrus Logic CL-GD 5428 (IBM SVGA Adapter/A)", + DEVICE_MCA, + CIRRUS_ID_CLGD5428, + gd54xx_init, + gd54xx_close, + NULL, + gd5428_available, + gd54xx_speed_changed, + gd54xx_force_redraw, + NULL +}; + const device_t gd5429_isa_device = { "Cirrus Logic CL-GD 5429 (ISA)", diff --git a/src/video/vid_cl54xx.h b/src/video/vid_cl54xx.h deleted file mode 100644 index 7e49e634b..000000000 --- a/src/video/vid_cl54xx.h +++ /dev/null @@ -1 +0,0 @@ -LOL \ No newline at end of file diff --git a/src/video/video.h b/src/video/video.h index b27e29862..fad5359d4 100644 --- a/src/video/video.h +++ b/src/video/video.h @@ -221,6 +221,7 @@ extern const device_t gd5424_vlb_device; extern const device_t gd5426_vlb_device; extern const device_t gd5428_isa_device; extern const device_t gd5428_vlb_device; +extern const device_t gd5428_mca_device; extern const device_t gd5429_isa_device; extern const device_t gd5429_vlb_device; extern const device_t gd5430_vlb_device;