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,
* 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, <mgrca8@gmail.com>
@@ -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)",

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 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;