TC1995's port of MCA CL-GD 5428.

This commit is contained in:
OBattler
2020-03-24 01:03:59 +01:00
parent 1640d48be6
commit 3020ec48ce
3 changed files with 113 additions and 38 deletions

View File

@@ -9,7 +9,7 @@
* Emulation of select Cirrus Logic cards (CL-GD 5428, * Emulation of select Cirrus Logic cards (CL-GD 5428,
* CL-GD 5429, CL-GD 5430, CL-GD 5434 and CL-GD 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.33 2020/01/22 * Version: @(#)vid_cl_54xx.c 1.0.34 2020/03/23
* *
* Authors: TheCollector1995, * Authors: TheCollector1995,
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -127,6 +127,10 @@
#define CIRRUS_BLTMODEEXT_COLOREXPINV 0x02 #define CIRRUS_BLTMODEEXT_COLOREXPINV 0x02
#define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01 #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_VESA 5
#define CL_GD5429_SYSTEM_BUS_ISA 7 #define CL_GD5429_SYSTEM_BUS_ISA 7
@@ -179,7 +183,7 @@ typedef struct gd54xx_t
int unlock_special; int unlock_special;
} blt; } blt;
int pci, vlb; int pci, vlb, mca;
int countminusone; int countminusone;
uint8_t pci_regs[256]; uint8_t pci_regs[256];
@@ -188,6 +192,9 @@ typedef struct gd54xx_t
uint8_t fc; /* Feature Connector */ uint8_t fc; /* Feature Connector */
int card; int card;
uint8_t pos_regs[8];
svga_t *mb_vga;
uint32_t lfb_base; uint32_t lfb_base;
@@ -690,10 +697,19 @@ gd54xx_in(uint16_t addr, void *p)
case 0x17: case 0x17:
ret = svga->gdcreg[0x17] & ~(7 << 3); ret = svga->gdcreg[0x17] & ~(7 << 3);
if (svga->crtc[0x27] <= CIRRUS_ID_CLGD5429) { if (svga->crtc[0x27] <= CIRRUS_ID_CLGD5429) {
if (gd54xx->vlb) if (svga->crtc[0x27] == CIRRUS_ID_CLGD5428) {
ret |= (CL_GD5429_SYSTEM_BUS_VESA << 3); if (gd54xx->vlb)
else ret |= (CL_GD5428_SYSTEM_BUS_VESA << 3);
ret |= (CL_GD5429_SYSTEM_BUS_ISA << 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 { } else {
if (gd54xx->pci) if (gd54xx->pci)
ret |= (CL_GD543X_SYSTEM_BUS_PCI << 3); ret |= (CL_GD543X_SYSTEM_BUS_PCI << 3);
@@ -878,8 +894,14 @@ gd54xx_in(uint16_t addr, void *p)
} else { } else {
if ((svga->gdcaddr < 2) && !gd54xx->unlocked) if ((svga->gdcaddr < 2) && !gd54xx->unlocked)
ret = (svga->gdcreg[svga->gdcaddr] & 0x0f); ret = (svga->gdcreg[svga->gdcaddr] & 0x0f);
else else {
ret = svga->gdcreg[svga->gdcaddr]; 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; break;
case 0x3d4: case 0x3d4:
@@ -893,7 +915,7 @@ gd54xx_in(uint16_t addr, void *p)
!gd54xx->unlocked) !gd54xx->unlocked)
ret = 0xff; ret = 0xff;
else switch (svga->crtcreg) { 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? */ /*Should this be & 7 if 8 byte latch is enabled? */
ret = svga->latch.b[svga->gdcreg[4] & 3]; ret = svga->latch.b[svga->gdcreg[4] & 3];
break; break;
@@ -959,8 +981,9 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx)
{ {
svga_t *svga = &gd54xx->svga; svga_t *svga = &gd54xx->svga;
uint32_t base, size; 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(&svga->mapping);
mem_mapping_disable(&gd54xx->linear_mapping); mem_mapping_disable(&gd54xx->linear_mapping);
mem_mapping_disable(&gd54xx->mmio_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) && 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) { if (gd54xx->mmio_vram_overlap) {
mem_mapping_disable(&svga->mapping); mem_mapping_disable(&svga->mapping);
mem_mapping_set_addr(&gd54xx->mmio_mapping, 0xb8000, 0x08000); mem_mapping_set_addr(&gd54xx->mmio_mapping, 0xb8000, 0x08000);
@@ -1016,7 +1039,7 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx)
size = 16 * 1024 * 1024; size = 16 * 1024 * 1024;
else else
size = 4 * 1024 * 1024; size = 4 * 1024 * 1024;
} else { /*VLB*/ } else { /*VLB/ISA/MCA*/
base = 128*1024*1024; base = 128*1024*1024;
if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436)
size = 16 * 1024 * 1024; size = 16 * 1024 * 1024;
@@ -1026,8 +1049,7 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx)
mem_mapping_disable(&svga->mapping); mem_mapping_disable(&svga->mapping);
mem_mapping_set_addr(&gd54xx->linear_mapping, base, size); mem_mapping_set_addr(&gd54xx->linear_mapping, base, size);
if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5426) && if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429)) {
(svga->crtc[0x27] != CIRRUS_ID_CLGD5424)) {
if (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR) if (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)
mem_mapping_disable(&gd54xx->mmio_mapping); /* MMIO is handled in the linear read/write functions */ mem_mapping_disable(&gd54xx->mmio_mapping); /* MMIO is handled in the linear read/write functions */
else 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 static void
*gd54xx_init(const device_t *info) *gd54xx_init(const device_t *info)
@@ -2903,7 +2952,8 @@ static void
memset(gd54xx, 0, sizeof(gd54xx_t)); memset(gd54xx, 0, sizeof(gd54xx_t));
gd54xx->pci = !!(info->flags & DEVICE_PCI); 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->rev = 0;
gd54xx->has_bios = 1; gd54xx->has_bios = 1;
@@ -2979,16 +3029,21 @@ static void
romfn = BIOS_GD5480_PATH; romfn = BIOS_GD5480_PATH;
break; break;
} }
if (id >= CIRRUS_ID_CLGD5420) if (info->flags & DEVICE_MCA) {
vram = device_get_config_int("memory"); vram = 1;
else gd54xx->vram_size = 1 << 20;
vram = 0; } else {
if (id >= CIRRUS_ID_CLGD5420)
if (vram) vram = device_get_config_int("memory");
gd54xx->vram_size = vram << 20; else
else vram = 0;
gd54xx->vram_size = 1 << 19;
if (vram)
gd54xx->vram_size = vram << 20;
else
gd54xx->vram_size = 1 << 19;
}
gd54xx->vram_mask = gd54xx->vram_size - 1; 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_handler(&svga->mapping, gd54xx_read, gd54xx_readw, gd54xx_readl, gd54xx_write, gd54xx_writew, gd54xx_writel);
mem_mapping_set_p(&svga->mapping, gd54xx); mem_mapping_set_p(&svga->mapping, gd54xx);
mem_mapping_add(&gd54xx->mmio_mapping, 0, 0, mem_mapping_add(&gd54xx->mmio_mapping, 0, 0,
gd543x_mmio_read, gd543x_mmio_readw, gd543x_mmio_readl, gd543x_mmio_read, gd543x_mmio_readw, gd543x_mmio_readl,
gd543x_mmio_writeb, gd543x_mmio_writew, gd543x_mmio_writel, gd543x_mmio_writeb, gd543x_mmio_writew, gd543x_mmio_writel,
NULL, MEM_MAPPING_EXTERNAL, gd54xx); NULL, MEM_MAPPING_EXTERNAL, gd54xx);
mem_mapping_disable(&gd54xx->mmio_mapping); mem_mapping_disable(&gd54xx->mmio_mapping);
mem_mapping_add(&gd54xx->linear_mapping, 0, 0, mem_mapping_add(&gd54xx->linear_mapping, 0, 0,
gd54xx_readb_linear, gd54xx_readw_linear, gd54xx_readl_linear, gd54xx_readb_linear, gd54xx_readw_linear, gd54xx_readl_linear,
gd54xx_writeb_linear, gd54xx_writew_linear, gd54xx_writel_linear, gd54xx_writeb_linear, gd54xx_writew_linear, gd54xx_writel_linear,
NULL, MEM_MAPPING_EXTERNAL, gd54xx); NULL, MEM_MAPPING_EXTERNAL, gd54xx);
mem_mapping_disable(&gd54xx->linear_mapping); mem_mapping_disable(&gd54xx->linear_mapping);
mem_mapping_add(&gd54xx->aperture2_mapping, 0, 0, mem_mapping_add(&gd54xx->aperture2_mapping, 0, 0,
gd5436_aperture2_readb, gd5436_aperture2_readw, gd5436_aperture2_readl, gd5436_aperture2_readb, gd5436_aperture2_readw, gd5436_aperture2_readl,
gd5436_aperture2_writeb, gd5436_aperture2_writew, gd5436_aperture2_writel, gd5436_aperture2_writeb, gd5436_aperture2_writew, gd5436_aperture2_writel,
NULL, MEM_MAPPING_EXTERNAL, gd54xx); NULL, MEM_MAPPING_EXTERNAL, gd54xx);
mem_mapping_disable(&gd54xx->aperture2_mapping); mem_mapping_disable(&gd54xx->aperture2_mapping);
io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx);
svga->hwcursor.yoff = 32; svga->hwcursor.yoff = 32;
svga->hwcursor.xoff = 0; svga->hwcursor.xoff = 0;
@@ -3068,6 +3123,12 @@ static void
if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429) if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429)
gd54xx->unlocked = 1; 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; return gd54xx;
} }
@@ -3400,6 +3461,20 @@ const device_t gd5428_vlb_device =
gd5428_config 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 = const device_t gd5429_isa_device =
{ {
"Cirrus Logic CL-GD 5429 (ISA)", "Cirrus Logic CL-GD 5429 (ISA)",

View File

@@ -1 +0,0 @@
LOL

View File

@@ -221,6 +221,7 @@ extern const device_t gd5424_vlb_device;
extern const device_t gd5426_vlb_device; extern const device_t gd5426_vlb_device;
extern const device_t gd5428_isa_device; extern const device_t gd5428_isa_device;
extern const device_t gd5428_vlb_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_isa_device;
extern const device_t gd5429_vlb_device; extern const device_t gd5429_vlb_device;
extern const device_t gd5430_vlb_device; extern const device_t gd5430_vlb_device;