The Cirrus Logic graphics cards now support the 8-byte latches, fixes 16 colors drivers;

The Cirrus Logic graphics cards now support the 15 bpp/palette mix, 8 bpp grayscale, and 8 bpp 3:3:2 RGB modes;
The makefiles now do -funroll_loops.
This commit is contained in:
OBattler
2019-10-01 15:14:51 +02:00
parent b114b62695
commit 591cd2e019
11 changed files with 673 additions and 156 deletions

View File

@@ -36,8 +36,10 @@
#include "vid_svga_render.h"
#include "vid_cl54xx.h"
#define BIOS_GD5420_PATH L"video/cirruslogic/5420.vbi"
#define BIOS_GD5422_PATH L"video/cirruslogic/cl5422.bin"
#if defined(DEV_BRANCH) && defined(USE_CL5422)
#define BIOS_GD5420_PATH L"roms/video/cirruslogic/5420.vbi"
#define BIOS_GD5422_PATH L"roms/video/cirruslogic/cl5422.bin"
#endif
#define BIOS_GD5426_PATH L"roms/video/cirruslogic/Diamond SpeedStar PRO VLB v3.04.bin"
#define BIOS_GD5428_ISA_PATH L"roms/video/cirruslogic/5428.bin"
#define BIOS_GD5428_PATH L"roms/video/cirruslogic/vlbusjapan.BIN"
@@ -145,7 +147,6 @@ typedef struct gd54xx_t
uint8_t vclk_n[4];
uint8_t vclk_d[4];
uint32_t bank[2];
struct {
uint8_t state;
@@ -179,7 +180,7 @@ typedef struct gd54xx_t
int countminusone;
uint8_t pci_regs[256];
uint8_t int_line;
uint8_t int_line, unlocked;
uint8_t fc; /* Feature Connector */
@@ -316,6 +317,14 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p)
svga->seqaddr = val;
break;
case 0x3c5:
if ((svga->seqaddr == 2) && !gd54xx->unlocked) {
o = svga->seqregs[svga->seqaddr & 0x1f];
svga_out(addr, val, svga);
svga->seqregs[svga->seqaddr & 0x1f] = (o & 0xf0) | (val & 0x0f);
return;
} else if ((svga->seqaddr > 6) && !gd54xx->unlocked)
return;
if (svga->seqaddr > 5) {
o = svga->seqregs[svga->seqaddr & 0x1f];
svga->seqregs[svga->seqaddr & 0x1f] = val;
@@ -326,6 +335,8 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p)
svga->seqregs[6] = 0x12;
else
svga->seqregs[6] = 0x0f;
if (svga->crtc[0x27] < CIRRUS_ID_CLGD5429)
gd54xx->unlocked = (svga->seqregs[6] == 0x12);
break;
case 0x0a:
@@ -365,21 +376,26 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p)
break;
case 0x12:
svga->ext_overscan = !!(val & 0x80);
if (svga->ext_overscan)
if (svga->ext_overscan && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5426))
svga->overscan_color = gd54xx->extpallook[2];
else
svga->overscan_color = svga->pallook[svga->attrregs[0x11]];
svga_recalctimings(svga);
svga->hwcursor.ena = val & CIRRUS_CURSOR_SHOW;
svga->hwcursor.xsize = svga->hwcursor.ysize = (val & CIRRUS_CURSOR_LARGE) ? 64 : 32;
if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5422)
svga->hwcursor.xsize = svga->hwcursor.ysize =
((val & CIRRUS_CURSOR_LARGE) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5422)) ? 64 : 32;
else
svga->hwcursor.xsize = 32;
svga->hwcursor.yoff = (svga->hwcursor.ysize == 32) ? 32 : 0;
if (val & CIRRUS_CURSOR_LARGE)
// (svga->crtc[0x1b] & 2)
if ((svga->seqregs[0x12] & CIRRUS_CURSOR_LARGE) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5422))
svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + ((svga->seqregs[0x13] & 0x3c) * 256));
else
svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + ((svga->seqregs[0x13] & 0x3f) * 256));
break;
case 0x13:
if (svga->seqregs[0x12] & CIRRUS_CURSOR_LARGE)
if ((svga->seqregs[0x12] & CIRRUS_CURSOR_LARGE) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5422))
svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + ((val & 0x3c) * 256));
else
svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + ((val & 0x3f) * 256));
@@ -421,7 +437,9 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p)
return;
}
break;
case 0x3C6:
case 0x3c6:
if (!gd54xx->unlocked)
break;
if (gd54xx->ramdac.state == 4) {
gd54xx->ramdac.state = 0;
gd54xx->ramdac.ctrl = val;
@@ -430,7 +448,7 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p)
}
gd54xx->ramdac.state = 0;
break;
case 0x3C9:
case 0x3c9:
svga->dac_status = 0;
svga->fullchange = changeframecount;
switch (svga->dac_pos) {
@@ -472,8 +490,16 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p)
svga->gdcaddr = val/* & 0x3f*/;
return;
case 0x3cf:
if ((svga->gdcaddr > 0x1f) && ((svga->crtc[0x27] <= CIRRUS_ID_CLGD5422) ||
(svga->crtc[0x27] == CIRRUS_ID_CLGD5424)))
return;
o = svga->gdcreg[svga->gdcaddr];
svga->gdcreg[svga->gdcaddr] = val;
if ((svga->gdcaddr < 2) && !gd54xx->unlocked)
svga->gdcreg[svga->gdcaddr] = (svga->gdcreg[svga->gdcaddr] & 0xf0) | (val & 0x0f);
else if ((svga->gdcaddr <= 8) || gd54xx->unlocked)
svga->gdcreg[svga->gdcaddr] = val;
if (svga->gdcaddr <= 8) {
switch (svga->gdcaddr) {
@@ -508,17 +534,22 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p)
svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) &&
!svga->gdcreg[1]) && svga->chain4;
if ((svga->gdcaddr == 5 && (val ^ o) & 0x70) ||
(svga->gdcaddr == 6 && (val ^ o) & 1))
if (((svga->gdcaddr == 5) && ((val ^ o) & 0x70)) ||
((svga->gdcaddr == 6) && ((val ^ o) & 1)))
svga_recalctimings(svga);
} else {
switch (svga->gdcaddr) {
case 0x09: case 0x0a: case 0x0b:
case 0x09: case 0x0a: /* case 0x0b: */
gd54xx_recalc_banking(gd54xx);
if (svga->gdcreg[0xb] & 0x04)
svga->writemode = svga->gdcreg[5] & 7;
else
svga->writemode = svga->gdcreg[5] & 3;
svga->adv_flags = FLAG_EXTRA_BANKS;
if (svga->gdcreg[0xb] & 0x02)
svga->adv_flags |= FLAG_ADDR_BY8;
if (svga->gdcreg[0xb] & 0x08)
svga->adv_flags |= FLAG_LATCH8;
break;
case 0x10:
@@ -622,10 +653,15 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p)
}
}
return;
case 0x3D4:
case 0x3d4:
svga->crtcreg = val & 0x3f;
return;
case 0x3D5:
case 0x3d5:
if (((svga->crtcreg == 0x19) || (svga->crtcreg == 0x1a) ||
(svga->crtcreg == 0x1b) || (svga->crtcreg == 0x1d) ||
(svga->crtcreg == 0x25) || (svga->crtcreg == 0x27)) &&
!gd54xx->unlocked)
return;
if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80))
return;
if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80))
@@ -658,27 +694,30 @@ gd54xx_in(uint16_t addr, void *p)
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;
if (gd54xx->unlocked) {
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 temp;
}
return svga->seqaddr;
return svga->seqaddr;
case 0x3c5:
if ((svga->seqaddr == 2) && !gd54xx->unlocked)
return svga_in(addr, svga) & 0x0f;
else if ((svga->seqaddr > 6) && !gd54xx->unlocked)
return 0xff;
if (svga->seqaddr > 5) {
switch (svga->seqaddr) {
case 6:
return ((svga->seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f;
return svga->seqregs[6];
case 0x0b: case 0x0c: case 0x0d: case 0x0e:
return gd54xx->vclk_n[svga->seqaddr-0x0b];
return gd54xx->vclk_n[svga->seqaddr-0x0b];
case 0x17:
temp = svga->gdcreg[0x17] & ~(7 << 3);
if (svga->crtc[0x27] <= CIRRUS_ID_CLGD5429) {
@@ -701,6 +740,15 @@ gd54xx_in(uint16_t addr, void *p)
return svga->seqregs[svga->seqaddr & 0x3f];
}
break;
case 0x3c6:
if (!gd54xx->unlocked)
break;
if (gd54xx->ramdac.state == 4) {
gd54xx->ramdac.state = 0;
return gd54xx->ramdac.ctrl;
}
gd54xx->ramdac.state++;
break;
case 0x3c9:
svga->dac_status = 3;
index = (svga->dac_addr - 1) & 0xff;
@@ -728,17 +776,15 @@ gd54xx_in(uint16_t addr, void *p)
return svga->vgapal[index].b & 0x3f;
}
return 0xFF;
case 0x3C6:
if (gd54xx->ramdac.state == 4) {
gd54xx->ramdac.state = 0;
return gd54xx->ramdac.ctrl;
}
gd54xx->ramdac.state++;
break;
case 0x3ce:
return svga->gdcaddr & 0x3f;
case 0x3cf:
if (svga->gdcaddr >= 0x10) {
if ((svga->gdcaddr > 8) && !gd54xx->unlocked)
return 0xff;
if ((svga->gdcaddr > 0x1f) && ((svga->crtc[0x27] <= CIRRUS_ID_CLGD5422) ||
(svga->crtc[0x27] == CIRRUS_ID_CLGD5424)))
return 0xff;
switch (svga->gdcaddr) {
case 0x10:
temp = gd543x_mmio_read(0xb8001, gd54xx);
@@ -843,13 +889,25 @@ gd54xx_in(uint16_t addr, void *p)
temp = 0xff;
break;
}
} else
temp = svga->gdcreg[svga->gdcaddr];
} else {
if ((svga->gdcaddr < 2) && !gd54xx->unlocked)
temp = (svga->gdcreg[svga->gdcaddr] & 0x0f);
else
temp = svga->gdcreg[svga->gdcaddr];
}
return temp;
case 0x3D4:
case 0x3d4:
return svga->crtcreg;
case 0x3D5:
case 0x3d5:
if (((svga->crtcreg == 0x19) || (svga->crtcreg == 0x1a) ||
(svga->crtcreg == 0x1b) || (svga->crtcreg == 0x1d) ||
(svga->crtcreg == 0x25) || (svga->crtcreg == 0x27)) &&
!gd54xx->unlocked)
return 0xff;
switch (svga->crtcreg) {
case 0x22: /*Graphis Data Latches Readback Register*/
/*Should this be & 7 if 8 byte latch is enabled? */
return (svga->latch >> ((svga->gdcreg[4] & 3) << 3)) & 0xff;
case 0x24: /*Attribute controller toggle readback (R)*/
return svga->attrff << 7;
case 0x26: /*Attribute controller index readback (R)*/
@@ -872,38 +930,37 @@ gd54xx_recalc_banking(gd54xx_t *gd54xx)
{
svga_t *svga = &gd54xx->svga;
if (!gd54xx_is_5422(svga)) {
gd54xx->bank[0] = (svga->gdcreg[0x09] & 0x7f) << 12;
if (!gd54xx_is_5422(svga)) {
svga->extra_banks[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)
gd54xx->bank[0] = svga->gdcreg[0x09] << 14;
else
gd54xx->bank[0] = svga->gdcreg[0x09] << 12;
if (svga->gdcreg[0x0b] & CIRRUS_BANKING_DUAL) {
if (svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K)
gd54xx->bank[1] = svga->gdcreg[0x0a] << 14;
if (svga->gdcreg[0x0b] & CIRRUS_BANKING_DUAL)
svga->extra_banks[1] = (svga->gdcreg[0x0a] & 0x7f) << 12;
else
gd54xx->bank[1] = svga->gdcreg[0x0a] << 12;
}
svga->extra_banks[1] = svga->extra_banks[0] + 0x8000;
} else {
if ((svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) &&
(svga->crtc[0x27] >= CIRRUS_ID_CLGD5426) && (svga->crtc[0x27] != CIRRUS_ID_CLGD5424))
svga->extra_banks[0] = svga->gdcreg[0x09] << 14;
else
svga->extra_banks[0] = svga->gdcreg[0x09] << 12;
if (svga->gdcreg[0x0b] & CIRRUS_BANKING_DUAL) {
if ((svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) &&
(svga->crtc[0x27] >= CIRRUS_ID_CLGD5426) && (svga->crtc[0x27] != CIRRUS_ID_CLGD5424))
svga->extra_banks[1] = svga->gdcreg[0x0a] << 14;
else
gd54xx->bank[1] = gd54xx->bank[0] + 0x8000;
}
svga->extra_banks[1] = svga->gdcreg[0x0a] << 12;
} else
svga->extra_banks[1] = svga->extra_banks[0] + 0x8000;
}
}
static void
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)) {
mem_mapping_disable(&svga->mapping);
@@ -936,7 +993,9 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx)
gd54xx->mmio_vram_overlap = 1;
break;
}
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)) {
if (gd54xx->mmio_vram_overlap) {
mem_mapping_disable(&svga->mapping);
mem_mapping_set_addr(&gd54xx->mmio_mapping, 0xb8000, 0x08000);
@@ -945,9 +1004,7 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx)
} else
mem_mapping_disable(&gd54xx->mmio_mapping);
} else {
uint32_t base, size;
if (svga->crtc[0x27] <= CIRRUS_ID_CLGD5429 || (!gd54xx->pci && !gd54xx->vlb)) {
if ((svga->crtc[0x27] <= CIRRUS_ID_CLGD5429) || (!gd54xx->pci && !gd54xx->vlb)) {
if (svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) {
base = (svga->seqregs[7] & 0xf0) << 16;
size = 1 * 1024 * 1024;
@@ -971,7 +1028,8 @@ 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) {
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_USE_PCIADDR)
mem_mapping_disable(&gd54xx->mmio_mapping); /* MMIO is handled in the linear read/write functions */
else
@@ -993,7 +1051,7 @@ static void
gd54xx_recalctimings(svga_t *svga)
{
gd54xx_t *gd54xx = (gd54xx_t *)svga->p;
uint8_t clocksel;
uint8_t clocksel, rdmask;
svga->rowoffset = (svga->crtc[0x13]) | ((svga->crtc[0x1b] & 0x10) << 4);
@@ -1010,10 +1068,18 @@ gd54xx_recalctimings(svga_t *svga)
if (gd54xx->ramdac.ctrl & 0x80) {
if (gd54xx->ramdac.ctrl & 0x40) {
switch (gd54xx->ramdac.ctrl & 0xf) {
if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5428) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5426))
rdmask = 0xf;
else
rdmask = 0x7;
switch (gd54xx->ramdac.ctrl & rdmask) {
case 0:
svga->bpp = 15;
svga->render = svga_render_15bpp_highres;
if (gd54xx->ramdac.ctrl & 0x80)
svga->render = svga_render_15bpp_mix_highres;
else
svga->render = svga_render_15bpp_highres;
break;
case 1:
@@ -1033,12 +1099,24 @@ gd54xx_recalctimings(svga_t *svga)
}
break;
case 8:
svga->bpp = 8;
svga->render = svga_render_8bpp_gs_highres;
break;
case 9:
svga->bpp = 8;
svga->render = svga_render_8bpp_rgb_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;
if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5430) {
svga->bpp = 32;
svga->render = svga_render_32bpp_highres;
svga->rowoffset *= 2;
}
break;
case CIRRUS_SR7_BPP_24:
@@ -1047,6 +1125,12 @@ gd54xx_recalctimings(svga_t *svga)
break;
case CIRRUS_SR7_BPP_16:
if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5428) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5426)) {
svga->bpp = 16;
svga->render = svga_render_16bpp_highres;
}
break;
case CIRRUS_SR7_BPP_16_DOUBLEVCLK:
svga->bpp = 16;
svga->render = svga_render_16bpp_highres;
@@ -1061,7 +1145,10 @@ gd54xx_recalctimings(svga_t *svga)
}
} else {
svga->bpp = 15;
svga->render = svga_render_15bpp_highres;
if (gd54xx->ramdac.ctrl & 0x80)
svga->render = svga_render_15bpp_mix_highres;
else
svga->render = svga_render_15bpp_highres;
}
}
@@ -1242,8 +1329,7 @@ gd54xx_write(uint32_t addr, uint8_t val, void *p)
return;
}
addr &= svga->banked_mask;
addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1];
addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1];
svga_write_linear(addr, val, svga);
}
@@ -1267,8 +1353,7 @@ gd54xx_writew(uint32_t addr, uint16_t val, void *p)
return;
}
addr &= svga->banked_mask;
addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1];
addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1];
if (svga->writemode < 4)
svga_writew_linear(addr, val, svga);
@@ -1299,8 +1384,7 @@ gd54xx_writel(uint32_t addr, uint32_t val, void *p)
return;
}
addr &= svga->banked_mask;
addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1];
addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1];
if (svga->writemode < 4)
svga_writel_linear(addr, val, svga);
@@ -1317,7 +1401,7 @@ gd54xx_writel(uint32_t addr, uint32_t val, void *p)
static void
gd54xx_write_modes45(svga_t *svga, uint8_t val, uint32_t addr)
{
uint32_t i, j;
uint32_t i;
switch (svga->writemode) {
case 4:
@@ -1345,21 +1429,22 @@ gd54xx_write_modes45(svga_t *svga, uint8_t val, uint32_t addr)
addr <<= 2;
for (i = 0; i < 8; i++) {
j = (0x80 >> i);
if (svga->seqregs[2] & j) {
svga->vram[addr + (i << 1)] = (val & j) ?
svga->gdcreg[1] : svga->gdcreg[0];
svga->vram[addr + (i << 1) + 1] = (val & j) ?
svga->gdcreg[0x11] : svga->gdcreg[0x10];
if (val & svga->seqregs[2] & (0x80 >> i)) {
svga->vram[addr + (i << 1)] = svga->gdcreg[1];
svga->vram[addr + (i << 1) + 1] = svga->gdcreg[0x11];
} else {
svga->vram[addr + (i << 1)] = svga->gdcreg[0];
svga->vram[addr + (i << 1) + 1] = svga->gdcreg[0x10];
}
}
} else {
addr <<= 1;
for (i = 0; i < 8; i++) {
j = (0x80 >> i);
if (svga->seqregs[2] & j)
svga->vram[addr + i] = (val & j) ? svga->gdcreg[1] : svga->gdcreg[0];
if (val & svga->seqregs[2] & (0x80 >> i))
svga->vram[addr + i] = svga->gdcreg[1];
else
svga->vram[addr + i] = svga->gdcreg[0];
}
}
break;
@@ -1846,8 +1931,7 @@ gd54xx_read(uint32_t addr, void *p)
!(gd54xx->blt.status & CIRRUS_BLT_PAUSED))
return gd54xx_mem_sys_dest_read(gd54xx);
addr &= svga->banked_mask;
addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1];
addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1];
return svga_read_linear(addr, svga);
}
@@ -1869,8 +1953,7 @@ gd54xx_readw(uint32_t addr, void *p)
return ret;
}
addr &= svga->banked_mask;
addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1];
addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1];
return svga_readw_linear(addr, svga);
}
@@ -1894,8 +1977,7 @@ gd54xx_readl(uint32_t addr, void *p)
return ret;
}
addr &= svga->banked_mask;
addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1];
addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1];
return svga_readl_linear(addr, svga);
}
@@ -2870,6 +2952,7 @@ static void
gd54xx->has_bios = 1;
switch (id) {
#if defined(DEV_BRANCH) && defined(USE_CL5422)
case CIRRUS_ID_CLGD5402:
case CIRRUS_ID_CLGD5420:
romfn = BIOS_GD5420_PATH;
@@ -2878,6 +2961,7 @@ static void
case CIRRUS_ID_CLGD5424:
romfn = BIOS_GD5422_PATH;
break;
#endif
case CIRRUS_ID_CLGD5426:
romfn = BIOS_GD5426_PATH;
@@ -2956,6 +3040,8 @@ static void
gd54xx_recalctimings, gd54xx_in, gd54xx_out,
gd54xx_hwcursor_draw, NULL);
svga->ven_write = gd54xx_write_modes45;
if (vram <= 1)
svga->decode_mask = gd54xx->vram_mask;
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);
@@ -2981,6 +3067,7 @@ static void
svga->hwcursor.yoff = 32;
svga->hwcursor.xoff = 0;
#if defined(DEV_BRANCH) && defined(USE_CL5422)
if (id >= CIRRUS_ID_CLGD5420) {
gd54xx->vclk_n[0] = 0x4a;
gd54xx->vclk_d[0] = 0x2b;
@@ -2995,13 +3082,23 @@ static void
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->vclk_n[2] = 0x45;
gd54xx->vclk_d[2] = 0x2c;
gd54xx->vclk_n[3] = 0x7e;
gd54xx->vclk_d[3] = 0x33;
}
#else
gd54xx->vclk_n[0] = 0x4a;
gd54xx->vclk_d[0] = 0x2b;
gd54xx->vclk_n[1] = 0x5b;
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;
#endif
gd54xx->bank[1] = 0x8000;
svga->extra_banks[1] = 0x8000;
if (gd54xx->pci && id >= CIRRUS_ID_CLGD5430)
pci_add_card(PCI_ADD_VIDEO, cl_pci_read, cl_pci_write, gd54xx);
@@ -3013,10 +3110,16 @@ static void
gd54xx->pci_regs[0x33] = 0x00;
svga->crtc[0x27] = id;
svga->adv_flags = FLAG_EXTRA_BANKS;
svga->seqregs[6] = 0x0f;
if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429)
gd54xx->unlocked = 1;
return gd54xx;
}
#if defined(DEV_BRANCH) && defined(USE_CL5422)
static int
gd5420_available(void)
{
@@ -3028,6 +3131,7 @@ gd5422_available(void)
{
return rom_present(BIOS_GD5422_PATH);
}
#endif
static int
gd5426_available(void)
@@ -3106,6 +3210,10 @@ gd54xx_close(void *p)
{
gd54xx_t *gd54xx = (gd54xx_t *)p;
FILE *f = fopen("d:\\queen\\86boxnew\\vram.dmp", "wb");
fwrite(gd54xx->svga.vram, 1, gd54xx->vram_size, f);
fclose(f);
svga_close(&gd54xx->svga);
free(gd54xx);
@@ -3129,6 +3237,7 @@ gd54xx_force_redraw(void *p)
gd54xx->svga.fullchange = changeframecount;
}
#if defined(DEV_BRANCH) && defined(USE_CL5422)
static const device_config_t gd5422_config[] =
{
{
@@ -3149,6 +3258,7 @@ static const device_config_t gd5422_config[] =
"","",-1
}
};
#endif
static const device_config_t gd5428_config[] =
{
@@ -3231,6 +3341,7 @@ static const device_config_t gd5434_config[] =
}
};
#if defined(DEV_BRANCH) && defined(USE_CL5422)
const device_t gd5402_isa_device =
{
"Cirrus Logic GD-5402 (ACUMOS AVGA2)",
@@ -3280,6 +3391,7 @@ const device_t gd5424_vlb_device = {
gd54xx_force_redraw,
gd5422_config,
};
#endif
const device_t gd5426_vlb_device =
{

View File

@@ -1,7 +1,7 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
#if defined(DEV_BRANCH)
#if defined(DEV_BRANCH) && defined(USE_CL5422)
extern const device_t gd5402_isa_device;
extern const device_t gd5420_isa_device;
extern const device_t gd5422_isa_device;

View File

@@ -47,7 +47,7 @@ extern uint8_t edatlookup[4][4];
uint8_t svga_rotate[8][256];
static const uint32_t mask16[16] = {
static const uint64_t mask16[16] = {
0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff,
@@ -153,7 +153,7 @@ svga_out(uint16_t addr, uint8_t val, void *p)
svga_recalctimings(svga);
break;
case 2:
svga->writemask = val & 0xf;
svga->writemask = val & 0xf;
break;
case 3:
svga->charsetb = (((val >> 2) & 3) * 0x10000) + 2;
@@ -167,7 +167,7 @@ svga_out(uint16_t addr, uint8_t val, void *p)
svga->chain2_write = !(val & 4);
svga->chain4 = val & 8;
svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) &&
!svga->gdcreg[1]) && svga->chain4;
!svga->gdcreg[1]) && svga->chain4 && !(svga->adv_flags & FLAG_ADDR_BY8);
break;
}
break;
@@ -212,7 +212,7 @@ svga_out(uint16_t addr, uint8_t val, void *p)
o = svga->gdcreg[svga->gdcaddr & 15];
switch (svga->gdcaddr & 15) {
case 2:
svga->colourcompare=val;
svga->colourcompare = val;
break;
case 4:
svga->readplane = val & 3;
@@ -245,7 +245,7 @@ svga_out(uint16_t addr, uint8_t val, void *p)
}
break;
case 7:
svga->colournocare=val;
svga->colournocare = val;
break;
}
svga->gdcreg[svga->gdcaddr & 15] = val;
@@ -839,7 +839,10 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
int func_select, writemask2 = svga->writemask;
int memory_map_mode;
uint32_t write_mask, bit_mask, set_mask, val32 = (uint32_t) val;
uint64_t write_mask, bit_mask, set_mask, mask0, la, val32 = (uint64_t) val;
if (svga->adv_flags & FLAG_ADDR_BY8)
writemask2 = svga->seqregs[2];
egawrites++;
@@ -856,7 +859,10 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
case 1:
if (addr >= 0x10000)
return;
addr += svga->write_bank;
else if (svga->adv_flags & FLAG_EXTRA_BANKS)
addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1];
else
addr += svga->write_bank;
break;
case 2:
addr -= 0x10000;
@@ -875,17 +881,28 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
if (!(svga->gdcreg[6] & 1))
svga->fullchange = 2;
if ((svga->chain4 || svga->fb_only) && (svga->writemode < 4)) {
if ((svga->adv_flags & FLAG_ADDR_BY8) && (svga->writemode < 4)) {
if (svga->fb_only)
fatal("BY8 write in fb_only\n");
if (svga->chain2_write)
fatal("BY8 write in chain2\n");
addr <<= 3;
} else if ((svga->chain4 || svga->fb_only) && (svga->writemode < 4)) {
writemask2 = 1 << (addr & 3);
addr &= ~3;
if (svga->writemode >= 4)
fatal("write mode %i in chain4 mode\n", svga->writemode);
} else if (svga->chain2_write) {
writemask2 &= ~0xa;
if (addr & 1)
writemask2 <<= 1;
addr &= ~1;
addr <<= 2;
if (svga->writemode >= 4)
fatal("write mode %i in chain odd/even\n", svga->writemode);
} else
addr <<= 2;
addr &= svga->decode_mask;
if (addr >= svga->vram_max)
@@ -909,33 +926,61 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
val32 |= (val32 << 8);
val32 |= (val32 << 16);
if (svga->adv_flags & FLAG_ADDR_BY8)
val32 |= (val32 << 32);
if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) &&
(!svga->gdcreg[1] || svga->set_reset_disabled)) {
/* mask data according to sr[2] */
write_mask = mask16[writemask2 & 0x0f];
addr >>= 2;
if (svga->adv_flags & FLAG_ADDR_BY8) {
write_mask |= (mask16[(writemask2 & 0xf0) >> 4] << 32);
addr >>= 3;
((uint32_t *)(svga->vram))[addr] &= ~write_mask;
((uint32_t *)(svga->vram))[addr] |= (val32 & write_mask);
((uint64_t *)(svga->vram))[addr] &= ~write_mask;
((uint64_t *)(svga->vram))[addr] |= (val32 & write_mask);
} else {
addr >>= 2;
((uint32_t *)(svga->vram))[addr] &= ~write_mask;
((uint32_t *)(svga->vram))[addr] |= (val32 & write_mask);
}
return;
}
set_mask = mask16[svga->gdcreg[1] & 0x0f];
val32 = (val32 & ~set_mask) | (mask16[svga->gdcreg[0] & 0x0f] & set_mask);
if (svga->adv_flags & FLAG_ADDR_BY8)
set_mask |= (mask16[(svga->gdcreg[1] & 0xf0) >> 4] << 32);
mask0 = mask16[svga->gdcreg[0] & 0x0f];
if (svga->adv_flags & FLAG_ADDR_BY8)
mask0 |= (mask16[(svga->gdcreg[0] & 0xf0) >> 4] << 32);
val32 = (val32 & ~set_mask) | (mask0 & set_mask);
break;
case 1:
val32 = svga->latch;
/* mask data according to sr[2] */
write_mask = mask16[writemask2 & 0x0f];
addr >>= 2;
if (svga->adv_flags & FLAG_ADDR_BY8) {
write_mask |= (mask16[(writemask2 & 0xf0) >> 4] << 32);
addr >>= 3;
((uint32_t *)(svga->vram))[addr] &= ~write_mask;
((uint32_t *)(svga->vram))[addr] |= (val32 & write_mask);
((uint64_t *)(svga->vram))[addr] &= ~write_mask;
((uint64_t *)(svga->vram))[addr] |= (val32 & write_mask);
} else {
addr >>= 2;
((uint32_t *)(svga->vram))[addr] &= ~write_mask;
((uint32_t *)(svga->vram))[addr] |= (val32 & write_mask);
}
return;
case 2:
val32 = mask16[val32 & 0x0f];
mask0 = mask16[val32 & 0x0f];
if (svga->adv_flags & FLAG_ADDR_BY8)
mask0 |= (mask16[(val32 & 0xf0) >> 4] << 32);
val32 = mask0;
bit_mask = svga->gdcreg[8];
if (!(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled))
@@ -948,6 +993,8 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
bit_mask = svga->gdcreg[8] & val32;
val32 = mask16[svga->gdcreg[0] & 0x0f];
if (svga->adv_flags & FLAG_ADDR_BY8)
val32 |= (mask16[(svga->gdcreg[0] & 0xf0) >> 4] << 32);
break;
default:
if (svga->ven_write)
@@ -958,6 +1005,12 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
/* apply bit mask */
bit_mask |= bit_mask << 8;
bit_mask |= bit_mask << 16;
if (svga->adv_flags & FLAG_ADDR_BY8)
bit_mask |= bit_mask << 32;
la = svga->latch;
if (!(svga->adv_flags & FLAG_LATCH8))
la &= 0xffffffff;
/* apply logical operation */
switch(func_select) {
@@ -965,30 +1018,36 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
default:
/* set */
val32 &= bit_mask;
val32 |= (svga->latch & ~bit_mask);
val32 |= (la & ~bit_mask);
break;
case 1:
/* and */
val32 |= ~bit_mask;
val32 &= svga->latch;
val32 &= la;
break;
case 2:
/* or */
val32 &= bit_mask;
val32 |= svga->latch;
val32 |= la;
break;
case 3:
/* xor */
val32 &= bit_mask;
val32 ^= svga->latch;
val32 ^= la;
break;
}
/* mask data according to sr[2] */
write_mask = mask16[writemask2 & 0x0f];
addr >>= 2;
if (svga->adv_flags & FLAG_ADDR_BY8)
write_mask |= (mask16[(writemask2 & 0xf0) >> 4] << 32);
((uint32_t *)(svga->vram))[addr] = (((uint32_t *)(svga->vram))[addr] & ~write_mask) | (val32 & write_mask);
addr >>= ((svga->adv_flags & FLAG_ADDR_BY8) ? 3 : 2);
if (svga->adv_flags & FLAG_ADDR_BY8)
((uint64_t *)(svga->vram))[addr] = (((uint64_t *)(svga->vram))[addr] & ~write_mask) | (val32 & write_mask);
else
((uint32_t *)(svga->vram))[addr] = (((uint32_t *)(svga->vram))[addr] & ~write_mask) | (val32 & write_mask);
}
@@ -996,8 +1055,13 @@ uint8_t
svga_read_common(uint32_t addr, uint8_t linear, void *p)
{
svga_t *svga = (svga_t *)p;
uint32_t latch_addr = 0, ret;
uint32_t latch_addr = 0;
int memory_map_mode, readplane = svga->readplane;
uint32_t mask0, mask1;
uint64_t ret;
if (svga->adv_flags & FLAG_ADDR_BY8)
readplane = svga->gdcreg[4] & 7;
sub_cycles(video_timing_read_b);
@@ -1014,7 +1078,10 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p)
case 1:
if (addr >= 0x10000)
return 0xff;
addr += svga->read_bank;
else if (svga->adv_flags & FLAG_EXTRA_BANKS)
addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1];
else
addr += svga->read_bank;
break;
case 2:
addr -= 0x10000;
@@ -1029,10 +1096,19 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p)
break;
}
latch_addr = (addr << 2) & svga->decode_mask;
if (svga->adv_flags & FLAG_ADDR_BY8)
latch_addr = (addr << 3) & svga->decode_mask;
else
latch_addr = (addr << 2) & svga->decode_mask;
}
if (svga->chain4 || svga->fb_only) {
if (svga->adv_flags & FLAG_ADDR_BY8) {
if (svga->fb_only)
fatal("BY8 read in fb_only\n");
if (svga->chain2_read)
fatal("BY8 read in chain2\n");
addr <<= 3;
} else if (svga->chain4 || svga->fb_only) {
addr &= svga->decode_mask;
if (addr >= svga->vram_max)
return 0xff;
@@ -1059,13 +1135,28 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p)
addr &= svga->vram_mask;
svga->latch = ((uint32_t *)(svga->vram))[addr >> 2];
if (svga->adv_flags & FLAG_ADDR_BY8) {
if (svga->adv_flags & FLAG_LATCH8)
svga->latch = ((uint64_t *)(svga->vram))[addr >> 3];
else
svga->latch = (svga->latch & 0xffffffff00000000ULL) | (((uint64_t *)(svga->vram))[addr >> 3] & 0xffffffff);
} else
svga->latch = (svga->latch & 0xffffffff00000000ULL) | ((uint32_t *)(svga->vram))[addr >> 2];
} else {
if (latch_addr > svga->vram_max)
svga->latch = 0xffffffff;
if (svga->adv_flags & FLAG_LATCH8)
svga->latch = 0xffffffffffffffffULL;
else
svga->latch = (svga->latch & 0xffffffff00000000ULL) | 0xffffffff;
else {
latch_addr &= svga->vram_mask;
svga->latch = ((uint32_t *)(svga->vram))[latch_addr >> 2];
if (svga->adv_flags & FLAG_ADDR_BY8) {
if (svga->adv_flags & FLAG_LATCH8)
svga->latch = ((uint64_t *)(svga->vram))[latch_addr >> 3];
else
svga->latch = (svga->latch & 0xffffffff00000000ULL) | (((uint64_t *)(svga->vram))[latch_addr >> 3] & 0xffffffff);
} else
svga->latch = (svga->latch & 0xffffffff00000000ULL) | ((uint32_t *)(svga->vram))[latch_addr >> 2];
}
if (addr >= svga->vram_max)
@@ -1079,7 +1170,13 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p)
return (svga->latch >> (readplane * 8)) & 0xff;
} else {
/* read mode 1 */
ret = (svga->latch ^ mask16[svga->colourcompare & 0x0f]) & mask16[svga->colournocare & 0x0f];
if (svga->adv_flags & FLAG_LATCH8) {
mask0 = mask16[svga->colourcompare & 0x0f] | (mask16[(svga->colourcompare & 0xf0) >> 4] << 32);
mask1 = mask16[svga->colournocare & 0x0f] | (mask16[(svga->colournocare & 0xf0) >> 4] << 32);
ret = (svga->latch ^ mask0) & mask1;
ret |= ret >> 32;
} else
ret = (svga->latch ^ mask16[svga->colourcompare & 0x0f]) & mask16[svga->colournocare & 0x0f];
ret |= ret >> 16;
ret |= ret >> 8;
ret = (~ret) & 0xff;
@@ -1213,6 +1310,7 @@ void
svga_writew_common(uint32_t addr, uint16_t val, uint8_t linear, void *p)
{
svga_t *svga = (svga_t *)p;
int memory_map_mode;
if (!svga->fast) {
svga_write_common(addr, val, linear, p);
@@ -1224,8 +1322,14 @@ svga_writew_common(uint32_t addr, uint16_t val, uint8_t linear, void *p)
sub_cycles(video_timing_write_w);
if (!linear)
addr = (addr & svga->banked_mask) + svga->write_bank;
if (!linear) {
memory_map_mode = (svga->gdcreg[6] >> 2) & 3;
if ((memory_map_mode == 1) && (svga->adv_flags & FLAG_EXTRA_BANKS))
addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1];
else
addr = (addr & svga->banked_mask) + svga->write_bank;
}
addr &= svga->decode_mask;
if (addr >= svga->vram_max)
return;
@@ -1254,6 +1358,7 @@ void
svga_writel_common(uint32_t addr, uint32_t val, uint8_t linear, void *p)
{
svga_t *svga = (svga_t *)p;
int memory_map_mode;
if (!svga->fast) {
svga_write_common(addr, val, linear, p);
@@ -1267,8 +1372,14 @@ svga_writel_common(uint32_t addr, uint32_t val, uint8_t linear, void *p)
sub_cycles(video_timing_write_l);
if (!linear)
addr = (addr & svga->banked_mask) + svga->write_bank;
if (!linear) {
memory_map_mode = (svga->gdcreg[6] >> 2) & 3;
if ((memory_map_mode == 1) && (svga->adv_flags & FLAG_EXTRA_BANKS))
addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1];
else
addr = (addr & svga->banked_mask) + svga->write_bank;
}
addr &= svga->decode_mask;
if (addr >= svga->vram_max)
return;

View File

@@ -17,6 +17,12 @@
* Copyright 2016-2018 Miran Grca.
*/
#define FLAG_EXTRA_BANKS 1
#define FLAG_ADDR_BY8 2
#define FLAG_LATCH8 4
typedef struct {
int ena,
x, y, xoff, yoff, xsize, ysize,
@@ -58,17 +64,20 @@ typedef struct svga_t
uint32_t decode_mask, vram_max,
vram_mask,
charseta, charsetb,
latch, ma_latch,
adv_flags, ma_latch,
ma, maback,
write_bank, read_bank,
extra_banks[2],
banked_mask,
ca, overscan_color,
pallook[256];
PALETTE vgapal;
uint64_t dispontime, dispofftime;
pc_timer_t timer;
uint64_t latch,
dispontime, dispofftime;
pc_timer_t timer;
double clock;

View File

@@ -560,6 +560,142 @@ void svga_render_8bpp_highres(svga_t *svga)
}
}
void svga_render_8bpp_gs_lowres(svga_t *svga)
{
int y_add = enable_overscan ? (overscan_y >> 1) : 0;
int x_add = enable_overscan ? 8 : 0;
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
{
int x;
int offset = (8 - (svga->scrollcache & 6)) + 24;
uint32_t *p = &buffer32->line[svga->displine + y_add][offset + x_add];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x += 8)
{
uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
p[0] = p[1] = video_8togs[dat & 0xff];
p[2] = p[3] = video_8togs[(dat >> 8) & 0xff];
p[4] = p[5] = video_8togs[(dat >> 16) & 0xff];
p[6] = p[7] = video_8togs[(dat >> 24) & 0xff];
svga->ma += 4;
p += 8;
}
svga->ma &= svga->vram_display_mask;
}
}
void svga_render_8bpp_gs_highres(svga_t *svga)
{
int y_add = enable_overscan ? (overscan_y >> 1) : 0;
int x_add = enable_overscan ? 8 : 0;
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
{
int x;
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
uint32_t *p = &buffer32->line[svga->displine + y_add][offset + x_add];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x += 8)
{
uint32_t dat;
dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
p[0] = video_8togs[dat & 0xff];
p[1] = video_8togs[(dat >> 8) & 0xff];
p[2] = video_8togs[(dat >> 16) & 0xff];
p[3] = video_8togs[(dat >> 24) & 0xff];
dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]);
p[4] = video_8togs[dat & 0xff];
p[5] = video_8togs[(dat >> 8) & 0xff];
p[6] = video_8togs[(dat >> 16) & 0xff];
p[7] = video_8togs[(dat >> 24) & 0xff];
svga->ma += 8;
p += 8;
}
svga->ma &= svga->vram_display_mask;
}
}
void svga_render_8bpp_rgb_lowres(svga_t *svga)
{
int y_add = enable_overscan ? (overscan_y >> 1) : 0;
int x_add = enable_overscan ? 8 : 0;
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
{
int x;
int offset = (8 - (svga->scrollcache & 6)) + 24;
uint32_t *p = &buffer32->line[svga->displine + y_add][offset + x_add];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x += 8)
{
uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
p[0] = p[1] = video_8to32[dat & 0xff];
p[2] = p[3] = video_8to32[(dat >> 8) & 0xff];
p[4] = p[5] = video_8to32[(dat >> 16) & 0xff];
p[6] = p[7] = video_8to32[(dat >> 24) & 0xff];
svga->ma += 4;
p += 8;
}
svga->ma &= svga->vram_display_mask;
}
}
void svga_render_8bpp_rgb_highres(svga_t *svga)
{
int y_add = enable_overscan ? (overscan_y >> 1) : 0;
int x_add = enable_overscan ? 8 : 0;
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
{
int x;
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
uint32_t *p = &buffer32->line[svga->displine + y_add][offset + x_add];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x += 8)
{
uint32_t dat;
dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
p[0] = video_8to32[dat & 0xff];
p[1] = video_8to32[(dat >> 8) & 0xff];
p[2] = video_8to32[(dat >> 16) & 0xff];
p[3] = video_8to32[(dat >> 24) & 0xff];
dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]);
p[4] = video_8to32[dat & 0xff];
p[5] = video_8to32[(dat >> 8) & 0xff];
p[6] = video_8to32[(dat >> 16) & 0xff];
p[7] = video_8to32[(dat >> 24) & 0xff];
svga->ma += 8;
p += 8;
}
svga->ma &= svga->vram_display_mask;
}
}
void svga_render_15bpp_lowres(svga_t *svga)
{
int y_add = enable_overscan ? (overscan_y >> 1) : 0;
@@ -630,6 +766,82 @@ void svga_render_15bpp_highres(svga_t *svga)
}
}
void svga_render_15bpp_mix_lowres(svga_t *svga)
{
int y_add = enable_overscan ? (overscan_y >> 1) : 0;
int x_add = enable_overscan ? 8 : 0;
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
{
int x;
int offset = (8 - (svga->scrollcache & 6)) + 24;
uint32_t *p = &buffer32->line[svga->displine + y_add][offset + x_add];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x += 4)
{
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
p[x] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff];
dat >>= 16;
p[x + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff];
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
p[x + 2] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff];
dat >>= 16;
p[x + 3] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff];
}
svga->ma += x << 1;
svga->ma &= svga->vram_display_mask;
}
}
void svga_render_15bpp_mix_highres(svga_t *svga)
{
int y_add = enable_overscan ? (overscan_y >> 1) : 0;
int x_add = enable_overscan ? 8 : 0;
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
{
int x;
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
uint32_t *p = &buffer32->line[svga->displine + y_add][offset + x_add];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= svga->hdisp; x += 8)
{
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
p[x] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff];
dat >>= 16;
p[x + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff];
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
p[x + 2] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff];
dat >>= 16;
p[x + 3] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff];
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]);
p[x + 4] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff];
dat >>= 16;
p[x + 5] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff];
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]);
p[x + 6] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff];
dat >>= 16;
p[x + 7] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff];
}
svga->ma += x << 1;
svga->ma &= svga->vram_display_mask;
}
}
void svga_render_16bpp_lowres(svga_t *svga)
{
int y_add = enable_overscan ? (overscan_y >> 1) : 0;

View File

@@ -38,8 +38,14 @@ void svga_render_4bpp_lowres(svga_t *svga);
void svga_render_4bpp_highres(svga_t *svga);
void svga_render_8bpp_lowres(svga_t *svga);
void svga_render_8bpp_highres(svga_t *svga);
void svga_render_8bpp_gs_lowres(svga_t *svga);
void svga_render_8bpp_gs_highres(svga_t *svga);
void svga_render_8bpp_rgb_lowres(svga_t *svga);
void svga_render_8bpp_rgb_highres(svga_t *svga);
void svga_render_15bpp_lowres(svga_t *svga);
void svga_render_15bpp_highres(svga_t *svga);
void svga_render_15bpp_mix_lowres(svga_t *svga);
void svga_render_15bpp_mix_highres(svga_t *svga);
void svga_render_16bpp_lowres(svga_t *svga);
void svga_render_16bpp_highres(svga_t *svga);
void svga_render_24bpp_lowres(svga_t *svga);

View File

@@ -92,7 +92,7 @@ video_cards[] = {
#endif
{ "[ISA] CGA", "cga", &cga_device },
{ "[ISA] Chips & Technologies SuperEGA", "superega", &sega_device },
#if defined(DEV_BRANCH)
#if defined(DEV_BRANCH) && defined(USE_CL5422)
{ "[ISA] Cirrus Logic CL-GD 5402", "cl_gd5402_isa", &gd5402_isa_device },
{ "[ISA] Cirrus Logic CL-GD 5420", "cl_gd5420_isa", &gd5420_isa_device },
{ "[ISA] Cirrus Logic CL-GD 5422", "cl_gd5422_isa", &gd5422_isa_device },
@@ -160,9 +160,9 @@ video_cards[] = {
{ "[PCI] Trident TGUI9440", "tgui9440_pci", &tgui9440_pci_device },
{ "[VLB] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_vlb", &mach64gx_vlb_device },
{ "[VLB] Cardex Tseng ET4000/w32p", "et4000w32p_vlb", &et4000w32p_cardex_vlb_device },
#if defined(DEV_BRANCH)
#if defined(DEV_BRANCH) && defined(USE_CL5422)
{ "[VLB] Cirrus Logic CL-GD 5424", "cl_gd5424_vlb", &gd5424_vlb_device },
#endif
#endif
{ "[VLB] Cirrus Logic CL-GD 5428", "cl_gd5428_vlb", &gd5428_vlb_device },
{ "[VLB] Cirrus Logic CL-GD 5429", "cl_gd5429_vlb", &gd5429_vlb_device },
{ "[VLB] Cirrus Logic CL-GD 5434", "cl_gd5434_vlb", &gd5434_vlb_device },

View File

@@ -80,6 +80,8 @@ int xsize = 1,
int cga_palette = 0,
herc_blend = 0;
uint32_t *video_6to8 = NULL,
*video_8togs = NULL,
*video_8to32 = NULL,
*video_15to32 = NULL,
*video_16to32 = NULL;
int egareads = 0,
@@ -517,6 +519,26 @@ calc_6to8(int c)
}
int
calc_8to32(int c)
{
int b, g, r;
double db, dg, dr;
b = (c & 3);
g = ((c >> 2) & 7);
r = ((c >> 5) & 7);
db = (((double) b) / 3.0) * 255.0;
dg = (((double) g) / 7.0) * 255.0;
dr = (((double) r) / 7.0) * 255.0;
b = (int) db;
g = ((int) dg) << 8;
r = ((int) dr) << 16;
return(b | g | r);
}
int
calc_15to32(int c)
{
@@ -666,19 +688,20 @@ video_init(void)
video_6to8 = malloc(4 * 256);
for (c = 0; c < 256; c++)
video_6to8[c] = calc_6to8(c);
video_8togs = malloc(4 * 256);
for (c = 0; c < 256; c++)
video_8togs[c] = c | (c << 16) | (c << 24);
video_8to32 = malloc(4 * 256);
for (c = 0; c < 256; c++)
video_8to32[c] = calc_8to32(c);
video_15to32 = malloc(4 * 65536);
#if 0
for (c = 0; c < 65536; c++)
video_15to32[c] = ((c & 31) << 3) | (((c >> 5) & 31) << 11) | (((c >> 10) & 31) << 19);
#endif
for (c = 0; c < 65536; c++)
video_15to32[c] = calc_15to32(c);
video_16to32 = malloc(4 * 65536);
#if 0
for (c = 0; c < 65536; c++)
video_16to32[c] = ((c & 31) << 3) | (((c >> 5) & 63) << 10) | (((c >> 11) & 31) << 19);
#endif
for (c = 0; c < 65536; c++)
video_16to32[c] = calc_16to32(c);
@@ -697,9 +720,11 @@ video_close(void)
thread_destroy_event(blit_data.blit_complete);
thread_destroy_event(blit_data.wake_blit_thread);
free(video_6to8);
free(video_15to32);
free(video_16to32);
free(video_15to32);
free(video_8to32);
free(video_8togs);
free(video_6to8);
destroy_bitmap(buffer32);

View File

@@ -99,6 +99,8 @@ extern uint8_t fontdat12x18[256][36];
extern dbcs_font_t *fontdatksc5601;
extern dbcs_font_t *fontdatksc5601_user;
extern uint32_t *video_6to8,
*video_8togs,
*video_8to32,
*video_15to32,
*video_16to32;
extern int xsize,ysize;

View File

@@ -41,6 +41,9 @@ ifeq ($(DEV_BUILD), y)
ifndef AMD_K
AMD_K := y
endif
ifndef CL5422
CL5422 := y
endif
ifndef CRASHDUMP
CRASHDUMP := y
endif
@@ -71,6 +74,9 @@ ifeq ($(DEV_BUILD), y)
ifndef PS2M70T4
PS2M70T4 := y
endif
ifndef TI
TI := y
endif
ifndef TC430HX
TC430HX := y
endif
@@ -96,6 +102,9 @@ else
ifndef AMD_K
AMD_K := n
endif
ifndef CL5422
CL5422 := n
endif
ifndef CRASHDUMP
CRASHDUMP := n
endif
@@ -126,6 +135,9 @@ else
ifndef PS2M70T4
PS2M70T4 := n
endif
ifndef TI
TI := n
endif
ifndef TC430HX
TC430HX := n
endif
@@ -436,6 +448,10 @@ ifeq ($(AMD_K), y)
OPTS += -DUSE_AMD_K
endif
ifeq ($(CL5422), y)
OPTS += -DUSE_CL5422
endif
ifeq ($(CRASHDUMPOBJ), y)
OPTS += -DUSE_CRASHDUMP
DEVBROBJ += win_crashdump.o
@@ -476,6 +492,10 @@ ifeq ($(PS2M70T4), y)
OPTS += -DUSE_PS2M70T4
endif
ifeq ($(TI), y)
OPTS += -DUSE_TI
endif
ifeq ($(TC430HX), y)
OPTS += -DUSE_TC430HX
endif
@@ -504,7 +524,7 @@ endif
# Final versions of the toolchain flags.
CFLAGS := $(WX_FLAGS) $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) \
$(AFLAGS) -fomit-frame-pointer -mstackrealign -Wall \
-fno-strict-aliasing
-fno-strict-aliasing -funroll-loops
# Add freetyp2 references through pkgconfig
CFLAGS := $(CFLAGS) `pkg-config.exe --cflags freetype2`

View File

@@ -41,6 +41,9 @@ ifeq ($(DEV_BUILD), y)
ifndef AMD_K
AMD_K := y
endif
ifndef CL5422
CL5422 := y
endif
ifndef CRASHDUMP
CRASHDUMP := y
endif
@@ -71,6 +74,9 @@ ifeq ($(DEV_BUILD), y)
ifndef PS2M70T4
PS2M70T4 := y
endif
ifndef TI
TI := y
endif
ifndef TC430HX
TC430HX := y
endif
@@ -96,6 +102,9 @@ else
ifndef AMD_K
AMD_K := n
endif
ifndef CL5422
CL5422 := n
endif
ifndef CRASHDUMP
CRASHDUMP := n
endif
@@ -126,6 +135,9 @@ else
ifndef PS2M70T4
PS2M70T4 := n
endif
ifndef TI
TI := n
endif
ifndef TC430HX
TC430HX := n
endif
@@ -442,6 +454,10 @@ ifeq ($(AMD_K), y)
OPTS += -DUSE_AMD_K
endif
ifeq ($(CL5422), y)
OPTS += -DUSE_CL5422
endif
ifeq ($(CRASHDUMPOBJ), y)
OPTS += -DUSE_CRASHDUMP
DEVBROBJ += win_crashdump.o
@@ -482,6 +498,10 @@ ifeq ($(PS2M70T4), y)
OPTS += -DUSE_PS2M70T4
endif
ifeq ($(TI), y)
OPTS += -DUSE_TI
endif
ifeq ($(TC430HX), y)
OPTS += -DUSE_TC430HX
endif
@@ -510,7 +530,7 @@ endif
# Final versions of the toolchain flags.
CFLAGS := $(WX_FLAGS) $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) \
$(AFLAGS) -fomit-frame-pointer -mstackrealign -Wall \
-fno-strict-aliasing
-fno-strict-aliasing -funroll-loops
# Add freetyp2 references through pkgconfig
CFLAGS := $(CFLAGS) `pkg-config.exe --cflags freetype2`