diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c
index cef1e83d2..a48488030 100644
--- a/src/video/vid_cl54xx.c
+++ b/src/video/vid_cl54xx.c
@@ -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.25 2018/10/04
+ * Version: @(#)vid_cl_54xx.c 1.0.26 2018/10/21
*
* Authors: Sarah Walker,
* Barry Rodewald,
@@ -1009,8 +1009,13 @@ gd54xx_write(uint32_t addr, uint8_t val, void *p)
{
gd54xx_t *gd54xx = (gd54xx_t *)p;
svga_t *svga = &gd54xx->svga;
-
- if (gd54xx->blt.sys_tx) {
+
+ if ((svga->seqregs[0x07] & 0x01) == 0) {
+ svga_write(addr, val, svga);
+ return;
+ }
+
+ if (gd54xx->blt.sys_tx) {
if (gd54xx->blt.mode == CIRRUS_BLTMODE_MEMSYSSRC) {
gd54xx->blt.sys_buf &= ~(0xff << (gd54xx->blt.sys_cnt * 8));
gd54xx->blt.sys_buf |= (val << (gd54xx->blt.sys_cnt * 8));
@@ -1021,7 +1026,7 @@ gd54xx_write(uint32_t addr, uint8_t val, void *p)
}
}
return;
- }
+ }
addr &= svga->banked_mask;
addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1];
@@ -1035,14 +1040,18 @@ gd54xx_writew(uint32_t addr, uint16_t val, void *p)
{
gd54xx_t *gd54xx = (gd54xx_t *)p;
svga_t *svga = &gd54xx->svga;
-
- if (gd54xx->blt.sys_tx)
- {
- gd54xx_write(addr, val, gd54xx);
- gd54xx_write(addr+1, val >> 8, gd54xx);
- return;
- }
-
+
+ if ((svga->seqregs[0x07] & 0x01) == 0) {
+ svga_writew(addr, val, svga);
+ return;
+ }
+
+ if (gd54xx->blt.sys_tx) {
+ gd54xx_write(addr, val, gd54xx);
+ gd54xx_write(addr+1, val >> 8, gd54xx);
+ return;
+ }
+
addr &= svga->banked_mask;
addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1];
@@ -1061,14 +1070,18 @@ gd54xx_writel(uint32_t addr, uint32_t val, void *p)
gd54xx_t *gd54xx = (gd54xx_t *)p;
svga_t *svga = &gd54xx->svga;
- if (gd54xx->blt.sys_tx)
- {
- gd54xx_write(addr, val, gd54xx);
- gd54xx_write(addr+1, val >> 8, gd54xx);
- gd54xx_write(addr+2, val >> 16, gd54xx);
- gd54xx_write(addr+3, val >> 24, gd54xx);
- return;
- }
+ if ((svga->seqregs[0x07] & 0x01) == 0) {
+ svga_writel(addr, val, svga);
+ return;
+ }
+
+ if (gd54xx->blt.sys_tx) {
+ gd54xx_write(addr, val, gd54xx);
+ gd54xx_write(addr+1, val >> 8, gd54xx);
+ gd54xx_write(addr+2, val >> 16, gd54xx);
+ gd54xx_write(addr+3, val >> 24, gd54xx);
+ return;
+ }
addr &= svga->banked_mask;
addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1];
@@ -1525,6 +1538,10 @@ gd54xx_read(uint32_t addr, void *p)
{
gd54xx_t *gd54xx = (gd54xx_t *)p;
svga_t *svga = &gd54xx->svga;
+
+ if ((svga->seqregs[0x07] & 0x01) == 0)
+ return svga_read(addr, svga);
+
addr &= svga->banked_mask;
addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1];
return svga_read_linear(addr, svga);
@@ -1537,6 +1554,9 @@ gd54xx_readw(uint32_t addr, void *p)
gd54xx_t *gd54xx = (gd54xx_t *)p;
svga_t *svga = &gd54xx->svga;
+ if ((svga->seqregs[0x07] & 0x01) == 0)
+ return svga_readw(addr, svga);
+
addr &= svga->banked_mask;
addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1];
return svga_readw_linear(addr, svga);
@@ -1549,6 +1569,9 @@ gd54xx_readl(uint32_t addr, void *p)
gd54xx_t *gd54xx = (gd54xx_t *)p;
svga_t *svga = &gd54xx->svga;
+ if ((svga->seqregs[0x07] & 0x01) == 0)
+ return svga_readl(addr, svga);
+
addr &= svga->banked_mask;
addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1];
return svga_readl_linear(addr, svga);
diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c
index c259d77db..55ac34bb0 100644
--- a/src/video/vid_svga.c
+++ b/src/video/vid_svga.c
@@ -11,7 +11,7 @@
* This is intended to be used by another SVGA driver,
* and not as a card in it's own right.
*
- * Version: @(#)vid_svga.c 1.0.34 2018/10/07
+ * Version: @(#)vid_svga.c 1.0.35 2018/10/21
*
* Authors: Sarah Walker,
* Miran Grca,
@@ -829,6 +829,7 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
svga_t *svga = (svga_t *)p;
int func_select, writemask2 = svga->writemask;
+ int memory_map_mode;
uint32_t write_mask, bit_mask, set_mask, val32 = (uint32_t) val;
egawrites++;
@@ -836,8 +837,30 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
cycles -= video_timing_write_b;
if (!linear) {
- addr &= svga->banked_mask;
- addr += svga->write_bank;
+ memory_map_mode = (svga->gdcreg[6] >> 2) & 3;
+
+ addr &= 0x1ffff;
+
+ switch (memory_map_mode) {
+ case 0:
+ break;
+ case 1:
+ if (addr >= 0x10000)
+ return;
+ addr += svga->write_bank;
+ break;
+ case 2:
+ addr -= 0x10000;
+ if (addr >= 0x8000)
+ return;
+ break;
+ default:
+ case 3:
+ addr -= 0x18000;
+ if (addr >= 0x8000)
+ return;
+ break;
+ }
}
if (!(svga->gdcreg[6] & 1))
@@ -962,16 +985,37 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p)
{
svga_t *svga = (svga_t *)p;
uint32_t latch_addr = 0, ret;
- int readplane = svga->readplane;
- uint8_t ret8;
+ int memory_map_mode, readplane = svga->readplane;
cycles -= video_timing_read_b;
egareads++;
if (!linear) {
- addr &= svga->banked_mask;
- addr += svga->read_bank;
+ memory_map_mode = (svga->gdcreg[6] >> 2) & 3;
+
+ addr &= 0x1ffff;
+
+ switch(memory_map_mode) {
+ case 0:
+ break;
+ case 1:
+ if (addr >= 0x10000)
+ return 0xff;
+ addr += svga->read_bank;
+ break;
+ case 2:
+ addr -= 0x10000;
+ if (addr >= 0x8000)
+ return 0xff;
+ break;
+ default:
+ case 3:
+ addr -= 0x18000;
+ if (addr >= 0x8000)
+ return 0xff;
+ break;
+ }
latch_addr = (addr << 2) & svga->decode_mask;
}
@@ -985,6 +1029,12 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p)
readplane = (readplane & 2) | (addr & 1);
addr &= ~1;
addr <<= 2;
+ addr |= readplane;
+ addr &= svga->decode_mask;
+ if (addr >= svga->vram_max)
+ return 0xff;
+ addr &= svga->vram_mask;
+ return svga->vram[addr];
} else
addr <<= 2;
@@ -1014,15 +1064,14 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p)
if (!(svga->gdcreg[5] & 8)) {
/* read mode 0 */
- return svga->vram[addr | readplane];
+ return (svga->latch >> (readplane * 8)) & 0xff;
} else {
/* read mode 1 */
ret = (svga->latch ^ mask16[svga->colourcompare & 0x0f]) & mask16[svga->colournocare & 0x0f];
- ret8 = (ret & 0xff);
- ret8 |= ((ret >> 24) & 0xff);
- ret8 |= ((ret >> 16) & 0xff);
- ret8 |= ((ret >> 8) & 0xff);
- return(~ret8);
+ ret |= ret >> 16;
+ ret |= ret >> 8;
+ ret = (~ret) & 0xff;
+ return(ret);
}
}