Rework (S)VGA memory addressing. Support correct chain-4 mapping, as well
as MA13/14 remapping for non-CGA modes. Fixes corruption on Windows 3.x when using Paradise drivers, also fixes corruption in Titan.
This commit is contained in:
parent
f9cdcfa6b6
commit
092be3e9d4
12 changed files with 740 additions and 239 deletions
51
src/vid_s3.c
51
src/vid_s3.c
|
|
@ -1010,6 +1010,7 @@ void s3_out(uint16_t addr, uint8_t val, void *p)
|
|||
{
|
||||
case 0x31:
|
||||
s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4);
|
||||
svga->force_dword_mode = val & 0x08;
|
||||
break;
|
||||
case 0x32:
|
||||
svga->vram_display_mask = (val & 0x40) ? 0x3ffff : s3->vram_mask;
|
||||
|
|
@ -1662,15 +1663,35 @@ static void polygon_setup(s3_t *s3)
|
|||
}
|
||||
}
|
||||
|
||||
#define READ_SRC(addr, dat) if (s3->bpp == 0) dat = svga->vram[ (addr) & s3->vram_mask]; \
|
||||
else if (s3->bpp == 1) dat = vram_w[(addr) & (s3->vram_mask >> 1)]; \
|
||||
else dat = vram_l[(addr) & (s3->vram_mask >> 2)]; \
|
||||
/*Remap address for chain-4/doubleword style layout*/
|
||||
static inline uint32_t dword_remap(uint32_t in_addr)
|
||||
{
|
||||
return ((in_addr << 2) & 0x3fff0) |
|
||||
((in_addr >> 14) & 0xc) |
|
||||
(in_addr & ~0x3fffc);
|
||||
}
|
||||
static inline uint32_t dword_remap_w(uint32_t in_addr)
|
||||
{
|
||||
return ((in_addr << 2) & 0x1fff8) |
|
||||
((in_addr >> 14) & 0x6) |
|
||||
(in_addr & ~0x1fffe);
|
||||
}
|
||||
static inline uint32_t dword_remap_l(uint32_t in_addr)
|
||||
{
|
||||
return ((in_addr << 2) & 0xfffc) |
|
||||
((in_addr >> 14) & 0x3) |
|
||||
(in_addr & ~0xffff);
|
||||
}
|
||||
|
||||
#define READ_SRC(addr, dat) if (s3->bpp == 0) dat = svga->vram[ dword_remap(addr) & s3->vram_mask]; \
|
||||
else if (s3->bpp == 1) dat = vram_w[dword_remap_w(addr) & (s3->vram_mask >> 1)]; \
|
||||
else dat = vram_l[dword_remap_l(addr) & (s3->vram_mask >> 2)]; \
|
||||
if (vram_mask) \
|
||||
dat = ((dat & rd_mask) == rd_mask);
|
||||
|
||||
#define READ_DST(addr, dat) if (s3->bpp == 0) dat = svga->vram[ (addr) & s3->vram_mask]; \
|
||||
else if (s3->bpp == 1) dat = vram_w[(addr) & (s3->vram_mask >> 1)]; \
|
||||
else dat = vram_l[(addr) & (s3->vram_mask >> 2)];
|
||||
#define READ_DST(addr, dat) if (s3->bpp == 0) dat = svga->vram[ dword_remap(addr) & s3->vram_mask]; \
|
||||
else if (s3->bpp == 1) dat = vram_w[dword_remap_w(addr) & (s3->vram_mask >> 1)]; \
|
||||
else dat = vram_l[dword_remap_l(addr) & (s3->vram_mask >> 2)];
|
||||
|
||||
#define MIX { \
|
||||
uint32_t old_dest_dat = dest_dat; \
|
||||
|
|
@ -1699,18 +1720,18 @@ static void polygon_setup(s3_t *s3)
|
|||
|
||||
#define WRITE(addr) if (s3->bpp == 0) \
|
||||
{ \
|
||||
svga->vram[(addr) & s3->vram_mask] = dest_dat; \
|
||||
svga->changedvram[((addr) & s3->vram_mask) >> 12] = changeframecount; \
|
||||
svga->vram[dword_remap(addr) & s3->vram_mask] = dest_dat; \
|
||||
svga->changedvram[(dword_remap(addr) & s3->vram_mask) >> 12] = changeframecount; \
|
||||
} \
|
||||
else if (s3->bpp == 1) \
|
||||
{ \
|
||||
vram_w[(addr) & (s3->vram_mask >> 1)] = dest_dat; \
|
||||
svga->changedvram[((addr) & (s3->vram_mask >> 1)) >> 11] = changeframecount; \
|
||||
vram_w[dword_remap_w(addr) & (s3->vram_mask >> 1)] = dest_dat; \
|
||||
svga->changedvram[(dword_remap_w(addr) & (s3->vram_mask >> 1)) >> 11] = changeframecount; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
vram_l[(addr) & (s3->vram_mask >> 2)] = dest_dat; \
|
||||
svga->changedvram[((addr) & (s3->vram_mask >> 2)) >> 10] = changeframecount; \
|
||||
vram_l[dword_remap_l(addr) & (s3->vram_mask >> 2)] = dest_dat; \
|
||||
svga->changedvram[(dword_remap_l(addr) & (s3->vram_mask >> 2)) >> 10] = changeframecount; \
|
||||
}
|
||||
|
||||
void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3)
|
||||
|
|
@ -2520,8 +2541,10 @@ void s3_hwcursor_draw(svga_t *svga, int displine)
|
|||
// pclog("HWcursor %i %i\n", svga->hwcursor_latch.x, svga->hwcursor_latch.y);
|
||||
for (x = 0; x < 64; x += 16)
|
||||
{
|
||||
dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 8) | svga->vram[svga->hwcursor_latch.addr + 1];
|
||||
dat[1] = (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3];
|
||||
uint32_t remapped_addr = dword_remap(svga->hwcursor_latch.addr);
|
||||
|
||||
dat[0] = (svga->vram[remapped_addr] << 8) | svga->vram[remapped_addr + 1];
|
||||
dat[1] = (svga->vram[remapped_addr + 2] << 8) | svga->vram[remapped_addr + 3];
|
||||
for (xx = 0; xx < 16; xx++)
|
||||
{
|
||||
if (offset >= svga->hwcursor_latch.x)
|
||||
|
|
|
|||
Loading…
Reference in a new issue