Reworked the cursor emulation of the Cirrus cards and added additional fixes to make the OS/2 SVGA detection happy.

Added a GD5426-based Diamond SpeedStar Pro card to the table.
This commit is contained in:
TC1995
2018-03-15 20:32:34 +01:00
parent a51bcfc77d
commit 47d2ff142d
4 changed files with 222 additions and 165 deletions

View File

@@ -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, <http://pcem-emulator.co.uk/>
* 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,

View File

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

View File

@@ -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}},

View File

@@ -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 */