From 86616cd5fb5a650897715de624ae006c11849195 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 21 Oct 2018 20:07:00 +0200 Subject: [PATCH] Slight fixes to CL-GD 54xx and generic (S)VGA memory read/write code - fixes E-Ten 24x24 driver (and probably more) on CL-GD and even the Tridents (though the second half of the screen is glitched on Tridents, which is an interlace bug and needs to be looked into). --- src/video/vid_cl54xx.c | 63 ++++++++++++++++++++++++----------- src/video/vid_svga.c | 75 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 105 insertions(+), 33 deletions(-) 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); } }