Adding Cirrus Logic GD5402 & GD5420

Some Cirrus cards fixes : HW Cursor for 512Kb VRAM and Hi-Res SVGA 16 colors display.
This commit is contained in:
Altheos
2019-01-08 16:53:52 +01:00
parent aa23448b00
commit 7a542a0146
4 changed files with 158 additions and 34 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, 5430, 5434 and 5436 are supported). * CL-GD 5429, 5430, 5434 and 5436 are supported).
* *
* Version: @(#)vid_cl54xx.c 1.0.23 2018/10/22 * Version: @(#)vid_cl54xx.c 1.0.24 2019/01/07
* *
* Authors: Fred N. van Kempen, <decwiz@yahoo.com> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -58,6 +58,8 @@
#include "vid_svga_render.h" #include "vid_svga_render.h"
#define BIOS_GD5420_PATH L"video/cirruslogic/5420.vbi"
#define BIOS_GD5422_PATH L"video/cirruslogic/cl5422.bin" #define BIOS_GD5422_PATH L"video/cirruslogic/cl5422.bin"
#define BIOS_GD5426_PATH L"video/cirruslogic/diamond speedstar pro vlb v3.04.bin" #define BIOS_GD5426_PATH L"video/cirruslogic/diamond speedstar pro vlb v3.04.bin"
#define BIOS_GD5428_ISA_PATH L"video/cirruslogic/gd5428.bin" #define BIOS_GD5428_ISA_PATH L"video/cirruslogic/gd5428.bin"
@@ -73,7 +75,9 @@
#define BIOS_GD5480_PATH L"video/cirruslogic/gd5480.rom" #define BIOS_GD5480_PATH L"video/cirruslogic/gd5480.rom"
#define CIRRUS_ID_CLGD5420 0x88
#define CIRRUS_ID_CLGD5402 0x89
#define CIRRUS_ID_CLGD5420 0x8a
#define CIRRUS_ID_CLGD5422 0x8c #define CIRRUS_ID_CLGD5422 0x8c
#define CIRRUS_ID_CLGD5424 0x94 #define CIRRUS_ID_CLGD5424 0x94
#define CIRRUS_ID_CLGD5426 0x90 #define CIRRUS_ID_CLGD5426 0x90
@@ -87,6 +91,7 @@
#define CIRRUS_ID_CLGD5480 0xbc #define CIRRUS_ID_CLGD5480 0xbc
/* sequencer 0x07 */ /* sequencer 0x07 */
#define CIRRUS_SR7_BPP_VGA 0x00 #define CIRRUS_SR7_BPP_VGA 0x00
#define CIRRUS_SR7_BPP_SVGA 0x01 #define CIRRUS_SR7_BPP_SVGA 0x01
@@ -223,6 +228,15 @@ static void gd543x_recalc_mapping(gd54xx_t *gd54xx);
static void gd54xx_start_blit(uint32_t cpu_dat, int count, static void gd54xx_start_blit(uint32_t cpu_dat, int count,
gd54xx_t *gd54xx, svga_t *svga); gd54xx_t *gd54xx, svga_t *svga);
/* Returns 1 if the card is a 5422+ */
static int
gd54xx_is_5422(svga_t *svga)
{
if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5422)
return 1;
else
return 0;
}
/* Returns 1 if the card is a 5434, 5436/46, or 5480. */ /* Returns 1 if the card is a 5434, 5436/46, or 5480. */
static int static int
@@ -298,13 +312,14 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p)
if (svga->seqaddr > 5) { if (svga->seqaddr > 5) {
o = svga->seqregs[svga->seqaddr & 0x1f]; o = svga->seqregs[svga->seqaddr & 0x1f];
svga->seqregs[svga->seqaddr & 0x1f] = val; svga->seqregs[svga->seqaddr & 0x1f] = val;
switch (svga->seqaddr & 0x1f) { switch (svga->seqaddr) {
case 0x06: case 0x06:
val &= 0x17; val &= 0x17;
if (val == 0x12) if (val == 0x12)
svga->seqregs[6] = 0x12; svga->seqregs[6] = 0x12;
else else
svga->seqregs[6] = 0x0f; svga->seqregs[6] = 0x0f;
break;
case 0x08: // Todo EEPROM case 0x08: // Todo EEPROM
@@ -388,9 +403,17 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p)
return; return;
break; break;
case 0x07: case 0x07:
if (!gd54xx_is_5422(svga)) {
svga->seqregs[svga->seqaddr] &= 0x0f;
gd543x_recalc_mapping(gd54xx);
}
if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429)
svga->set_reset_disabled = svga->seqregs[7] & 1; svga->set_reset_disabled = svga->seqregs[7] & 1;
case 0x17: case 0x17:
if (gd54xx_is_5422(svga))
gd543x_recalc_mapping(gd54xx); gd543x_recalc_mapping(gd54xx);
else
return;
break; break;
} }
return; return;
@@ -732,6 +755,15 @@ gd54xx_recalc_banking(gd54xx_t *gd54xx)
{ {
svga_t *svga = &gd54xx->svga; svga_t *svga = &gd54xx->svga;
if (!gd54xx_is_5422(svga)) {
gd54xx->bank[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) if (svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K)
gd54xx->bank[0] = svga->gdcreg[0x09] << 14; gd54xx->bank[0] = svga->gdcreg[0x09] << 14;
else else
@@ -742,8 +774,11 @@ gd54xx_recalc_banking(gd54xx_t *gd54xx)
gd54xx->bank[1] = svga->gdcreg[0x0a] << 14; gd54xx->bank[1] = svga->gdcreg[0x0a] << 14;
else else
gd54xx->bank[1] = svga->gdcreg[0x0a] << 12; gd54xx->bank[1] = svga->gdcreg[0x0a] << 12;
} else }
else
gd54xx->bank[1] = gd54xx->bank[0] + 0x8000; gd54xx->bank[1] = gd54xx->bank[0] + 0x8000;
}
} }
@@ -927,6 +962,7 @@ gd54xx_recalctimings(svga_t *svga)
int d = (gd54xx->vclk_d[clocksel] & 0x3e) >> 1; int d = (gd54xx->vclk_d[clocksel] & 0x3e) >> 1;
int m = gd54xx->vclk_d[clocksel] & 0x01 ? 2 : 1; int m = gd54xx->vclk_d[clocksel] & 0x01 ? 2 : 1;
float freq = ((float)14318184.0 * ((float)n / ((float)d * m))); float freq = ((float)14318184.0 * ((float)n / ((float)d * m)));
if (gd54xx_is_5422(svga)) {
switch (svga->seqregs[7] & (gd54xx_is_5434(svga) ? 0xe : 6)) { switch (svga->seqregs[7] & (gd54xx_is_5434(svga) ? 0xe : 6)) {
case 2: case 2:
freq /= 2.0; freq /= 2.0;
@@ -936,10 +972,16 @@ gd54xx_recalctimings(svga_t *svga)
freq /= 3.0; freq /= 3.0;
break; break;
} }
}
svga->clock = cpuclock / freq; svga->clock = cpuclock / freq;
} }
if (gd54xx->vram_size == (1 << 19)) /* Note : why 512Kb VRAM cards does not wrap */
svga->vram_display_mask = gd54xx->vram_mask;
else
svga->vram_display_mask = (svga->crtc[0x1b] & 2) ? gd54xx->vram_mask : 0x3ffff; svga->vram_display_mask = (svga->crtc[0x1b] & 2) ? gd54xx->vram_mask : 0x3ffff;
} }
static static
@@ -1095,6 +1137,13 @@ gd54xx_write(uint32_t addr, uint8_t val, void *p)
gd54xx_t *gd54xx = (gd54xx_t *)p; gd54xx_t *gd54xx = (gd54xx_t *)p;
svga_t *svga = &gd54xx->svga; svga_t *svga = &gd54xx->svga;
if (svga->gdcreg[0x0b] & 1) {
svga->write_bank = gd54xx->bank[(addr >> 15) & 1];
addr = addr & 0x7fff;
}
else
svga->write_bank = gd54xx->bank[0];
if ((svga->seqregs[0x07] & 0x01) == 0) { if ((svga->seqregs[0x07] & 0x01) == 0) {
svga_write(addr, val, svga); svga_write(addr, val, svga);
return; return;
@@ -1127,6 +1176,13 @@ gd54xx_writew(uint32_t addr, uint16_t val, void *p)
gd54xx_t *gd54xx = (gd54xx_t *)p; gd54xx_t *gd54xx = (gd54xx_t *)p;
svga_t *svga = &gd54xx->svga; svga_t *svga = &gd54xx->svga;
if (svga->gdcreg[0x0b] & 1) {
svga->write_bank = gd54xx->bank[(addr >> 15) & 1];
addr = addr & 0x7fff;
}
else
svga->write_bank = gd54xx->bank[0];
if ((svga->seqregs[0x07] & 0x01) == 0) { if ((svga->seqregs[0x07] & 0x01) == 0) {
svga_writew(addr, val, svga); svga_writew(addr, val, svga);
return; return;
@@ -1635,6 +1691,8 @@ gd54xx_read(uint32_t addr, void *p)
addr &= svga->vram_mask; addr &= svga->vram_mask;
return svga_read_linear(addr, svga); return svga_read_linear(addr, svga);
} }
@@ -2323,6 +2381,10 @@ gd54xx_init(const device_t *info)
gd54xx->has_bios = 1; gd54xx->has_bios = 1;
switch (id) { switch (id) {
case CIRRUS_ID_CLGD5402:
case CIRRUS_ID_CLGD5420:
romfn = BIOS_GD5420_PATH;
break;
case CIRRUS_ID_CLGD5422: case CIRRUS_ID_CLGD5422:
case CIRRUS_ID_CLGD5424: case CIRRUS_ID_CLGD5424:
romfn = BIOS_GD5422_PATH; romfn = BIOS_GD5422_PATH;
@@ -2381,11 +2443,14 @@ gd54xx_init(const device_t *info)
break; break;
} }
if (id >= CIRRUS_ID_CLGD5420)
vram = device_get_config_int("memory"); vram = device_get_config_int("memory");
else
vram = 0;
if (vram) if (vram)
gd54xx->vram_size = vram << 20; gd54xx->vram_size = vram << 20;
else else
gd54xx->vram_size = 512 << 10; gd54xx->vram_size = 1 << 19;
gd54xx->vram_mask = gd54xx->vram_size - 1; gd54xx->vram_mask = gd54xx->vram_size - 1;
if (romfn) if (romfn)
@@ -2407,10 +2472,26 @@ gd54xx_init(const device_t *info)
svga->hwcursor.yoff = 32; svga->hwcursor.yoff = 32;
svga->hwcursor.xoff = 0; svga->hwcursor.xoff = 0;
if (id >= CIRRUS_ID_CLGD5420) {
gd54xx->vclk_n[0] = 0x4a; gd54xx->vclk_n[0] = 0x4a;
gd54xx->vclk_d[0] = 0x2b; gd54xx->vclk_d[0] = 0x2b;
gd54xx->vclk_n[1] = 0x5b; gd54xx->vclk_n[1] = 0x5b;
gd54xx->vclk_d[1] = 0x2f; 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;
}
else {
gd54xx->vclk_n[0] = 0x66;
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->bank[1] = 0x8000; gd54xx->bank[1] = 0x8000;
@@ -2460,6 +2541,11 @@ gd54xx_force_redraw(void *p)
gd54xx->svga.fullchange = changeframecount; gd54xx->svga.fullchange = changeframecount;
} }
static int
gd5420_available(void)
{
return rom_present(BIOS_GD5420_PATH);
}
static int static int
gd5422_available(void) gd5422_available(void)
@@ -2628,12 +2714,40 @@ static const video_timings_t cl_gd_isa_timing = {VID_ISA,3,3,6,8,8,12};
static const video_timings_t cl_gd_vlb_timing = {VID_BUS,4,4,8,10,10,20}; static const video_timings_t cl_gd_vlb_timing = {VID_BUS,4,4,8,10,10,20};
static const video_timings_t cl_gd_pci_timing = {VID_BUS,4,4,8,10,10,20}; static const video_timings_t cl_gd_pci_timing = {VID_BUS,4,4,8,10,10,20};
const device_t gd5402_isa_device =
{
"Cirrus Logic GD-5402 (ACUMOS AVGA2)",
DEVICE_AT | DEVICE_ISA,
CIRRUS_ID_CLGD5402,
gd54xx_init, gd54xx_close,
NULL,
gd5420_available, /* Common BIOS between 5402 and 5420 */
gd54xx_speed_changed,
gd54xx_force_redraw,
&cl_gd_isa_timing,
NULL,
};
const device_t gd5420_isa_device =
{
"Cirrus Logic GD-5420",
DEVICE_AT | DEVICE_ISA,
CIRRUS_ID_CLGD5420,
gd54xx_init, gd54xx_close,
NULL,
gd5420_available, /* Common BIOS between 5402 and 5420 */
gd54xx_speed_changed,
gd54xx_force_redraw,
&cl_gd_isa_timing,
gd5422_config,
};
const device_t gd5422_isa_device = { const device_t gd5422_isa_device = {
"Cirrus Logic GD-5422", "Cirrus Logic GD-5422",
DEVICE_AT | DEVICE_ISA, DEVICE_AT | DEVICE_ISA,
CIRRUS_ID_CLGD5422, CIRRUS_ID_CLGD5422,
gd54xx_init, gd54xx_close, NULL, gd54xx_init, gd54xx_close,
gd5422_available, NULL,
gd5422_available, /* Common BIOS between 5422 and 5424 */
gd54xx_speed_changed, gd54xx_speed_changed,
gd54xx_force_redraw, gd54xx_force_redraw,
&cl_gd_isa_timing, &cl_gd_isa_timing,
@@ -2644,8 +2758,9 @@ const device_t gd5424_vlb_device = {
"Cirrus Logic GD-5424", "Cirrus Logic GD-5424",
DEVICE_VLB, DEVICE_VLB,
CIRRUS_ID_CLGD5424, CIRRUS_ID_CLGD5424,
gd54xx_init, gd54xx_close, NULL, gd54xx_init, gd54xx_close,
gd5422_available, NULL,
gd5422_available, /* Common BIOS between 5422 and 5424 */
gd54xx_speed_changed, gd54xx_speed_changed,
gd54xx_force_redraw, gd54xx_force_redraw,
&cl_gd_vlb_timing, &cl_gd_vlb_timing,

View File

@@ -11,7 +11,7 @@
* This is intended to be used by another SVGA driver, * This is intended to be used by another SVGA driver,
* and not as a card in it's own right. * and not as a card in it's own right.
* *
* Version: @(#)vid_svga.c 1.0.14 2018/10/21 * Version: @(#)vid_svga.c 1.0.15 2019/01/08
* *
* Authors: Fred N. van Kempen, <decwiz@yahoo.com> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -883,29 +883,34 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
if (! linear) { if (! linear) {
memory_map_mode = (svga->gdcreg[6] >> 2) & 3; memory_map_mode = (svga->gdcreg[6] >> 2) & 3;
addr &= 0x1ffff; //addr &= 0x1ffff;
switch (memory_map_mode) { switch (memory_map_mode) {
case 0: case 0:
addr &= svga->banked_mask;
break; break;
case 1: case 1:
if (addr >= 0x10000) //if (addr >= 0x10000)
return; //return;
addr &= svga->banked_mask;
addr += svga->write_bank; addr += svga->write_bank;
break; break;
case 2: case 2:
addr -= 0x10000; //addr -= 0x10000;
if (addr >= 0x8000) //if (addr >= 0x8000)
return; // return;
addr &= svga->banked_mask;
break; break;
default: default:
case 3: case 3:
addr -= 0x18000; //addr -= 0x18000;
if (addr >= 0x8000) //if (addr >= 0x8000)
return; // return;
addr &= svga->banked_mask;
addr += svga->write_bank;
break; break;
} }
} }

View File

@@ -8,7 +8,7 @@
* *
* Definitions for the video controller module. * Definitions for the video controller module.
* *
* Version: @(#)video.h 1.0.23 2018/11/20 * Version: @(#)video.h 1.0.24 2019/01/08
* *
* Authors: Fred N. van Kempen, <decwiz@yahoo.com> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -171,6 +171,8 @@ extern const device_t cga_device;
/* Cirrus Logic GD-series cards. */ /* Cirrus Logic GD-series cards. */
#if defined(DEV_BRANCH) #if defined(DEV_BRANCH)
extern const device_t gd5402_isa_device;
extern const device_t gd5420_isa_device;
extern const device_t gd5422_isa_device; extern const device_t gd5422_isa_device;
extern const device_t gd5424_vlb_device; extern const device_t gd5424_vlb_device;
#endif #endif

View File

@@ -12,7 +12,7 @@
* "extern" reference to its device into the video.h file, * "extern" reference to its device into the video.h file,
* and add an entry for it into the table here. * and add an entry for it into the table here.
* *
* Version: @(#)video_dev.c 1.0.28 2018/11/20 * Version: @(#)video_dev.c 1.0.29 2019/01/08
* *
* Authors: Fred N. van Kempen, <decwiz@yahoo.com> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -85,6 +85,8 @@ static const struct {
#endif #endif
{ "superega", &sega_device }, { "superega", &sega_device },
#if defined(DEV_BRANCH) #if defined(DEV_BRANCH)
{ "cl_gd5402_isa", &gd5402_isa_device },
{ "cl_gd5420_isa", &gd5420_isa_device },
{ "cl_gd5422_isa", &gd5422_isa_device }, { "cl_gd5422_isa", &gd5422_isa_device },
#endif #endif
{ "cl_gd5428_isa", &gd5428_isa_device }, { "cl_gd5428_isa", &gd5428_isa_device },