Rework video memory handling to cater for open bus and VRAM address wrapping. Fixes more hangs with Trio64 and Windows 95.

This commit is contained in:
SarahW 2017-10-22 12:41:10 +01:00
commit 39a68d757b
10 changed files with 174 additions and 117 deletions

View file

@ -468,12 +468,12 @@ void mach64_recalctimings(svga_t *svga)
break; break;
} }
svga->vrammask = mach64->vram_mask; svga->vram_display_mask = mach64->vram_mask;
// pclog("mach64_recalctimings : frame %i,%i disp %i,%i vsync at %i rowoffset %i pixel clock %f MA %08X\n", svga->htotal, svga->vtotal, svga->hdisp, svga->dispend, svga->vsyncstart, svga->rowoffset, svga->clock, svga->ma); // pclog("mach64_recalctimings : frame %i,%i disp %i,%i vsync at %i rowoffset %i pixel clock %f MA %08X\n", svga->htotal, svga->vtotal, svga->hdisp, svga->dispend, svga->vsyncstart, svga->rowoffset, svga->clock, svga->ma);
} }
else else
{ {
svga->vrammask = (mach64->regs[0x36] & 0x01) ? mach64->vram_mask : 0x3ffff; svga->vram_display_mask = (mach64->regs[0x36] & 0x01) ? mach64->vram_mask : 0x3ffff;
} }
} }

View file

@ -350,9 +350,10 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p)
{ {
addr <<= 2; addr <<= 2;
} }
addr &= 0x7fffff; addr &= svga->decode_mask;
if (addr >= svga->vram_limit) if (addr >= svga->vram_max)
return; return;
addr &= svga->vram_mask;
// if (svga_output) pclog("%08X\n", addr); // if (svga_output) pclog("%08X\n", addr);
svga->changedvram[addr >> 12] = changeframecount; svga->changedvram[addr >> 12] = changeframecount;
@ -595,16 +596,16 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p)
switch (gd5429->blt.mode & 0xc0) switch (gd5429->blt.mode & 0xc0)
{ {
case 0x00: case 0x00:
src = svga->vram[gd5429->blt.src_addr & svga->vrammask]; src = svga->vram[gd5429->blt.src_addr & svga->vram_mask];
gd5429->blt.src_addr += ((gd5429->blt.mode & 0x01) ? -1 : 1); gd5429->blt.src_addr += ((gd5429->blt.mode & 0x01) ? -1 : 1);
mask = 1; mask = 1;
break; break;
case 0x40: case 0x40:
src = svga->vram[(gd5429->blt.src_addr & (svga->vrammask & ~7)) | (gd5429->blt.dst_addr & 7)]; src = svga->vram[(gd5429->blt.src_addr & (svga->vram_mask & ~7)) | (gd5429->blt.dst_addr & 7)];
mask = 1; mask = 1;
break; break;
case 0x80: case 0x80:
mask = svga->vram[gd5429->blt.src_addr & svga->vrammask] & (0x80 >> gd5429->blt.x_count); mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> gd5429->blt.x_count);
src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col;
gd5429->blt.x_count++; gd5429->blt.x_count++;
if (gd5429->blt.x_count == 8) if (gd5429->blt.x_count == 8)
@ -614,16 +615,16 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p)
} }
break; break;
case 0xc0: case 0xc0:
mask = svga->vram[gd5429->blt.src_addr & svga->vrammask] & (0x80 >> (gd5429->blt.dst_addr & 7)); mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> (gd5429->blt.dst_addr & 7));
src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col;
break; break;
} }
count--; count--;
} }
dst = svga->vram[gd5429->blt.dst_addr & svga->vrammask]; dst = svga->vram[gd5429->blt.dst_addr & svga->vram_mask];
svga->changedvram[(gd5429->blt.dst_addr & svga->vrammask) >> 12] = changeframecount; svga->changedvram[(gd5429->blt.dst_addr & svga->vram_mask) >> 12] = changeframecount;
pclog("Blit %i,%i %06X %06X %06X %02X %02X %02X %02X ", gd5429->blt.width, gd5429->blt.height_internal, gd5429->blt.src_addr, gd5429->blt.dst_addr, gd5429->blt.src_addr & svga->vrammask, svga->vram[gd5429->blt.src_addr & svga->vrammask], 0x80 >> (gd5429->blt.dst_addr & 7), src, dst); pclog("Blit %i,%i %06X %06X %06X %02X %02X %02X %02X ", gd5429->blt.width, gd5429->blt.height_internal, gd5429->blt.src_addr, gd5429->blt.dst_addr, gd5429->blt.src_addr & svga->vram_mask, svga->vram[gd5429->blt.src_addr & svga->vram_mask], 0x80 >> (gd5429->blt.dst_addr & 7), src, dst);
switch (gd5429->blt.rop) switch (gd5429->blt.rop)
{ {
case 0x00: dst = 0; break; case 0x00: dst = 0; break;
@ -647,7 +648,7 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p)
if ((gd5429->blt.width_backup - gd5429->blt.width) >= (gd5429->blt.mask & 7) && if ((gd5429->blt.width_backup - gd5429->blt.width) >= (gd5429->blt.mask & 7) &&
!((gd5429->blt.mode & 0x08) && !mask)) !((gd5429->blt.mode & 0x08) && !mask))
svga->vram[gd5429->blt.dst_addr & svga->vrammask] = dst; svga->vram[gd5429->blt.dst_addr & svga->vram_mask] = dst;
gd5429->blt.dst_addr += ((gd5429->blt.mode & 0x01) ? -1 : 1); gd5429->blt.dst_addr += ((gd5429->blt.mode & 0x01) ? -1 : 1);

View file

@ -554,7 +554,7 @@ void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p)
} }
else else
{ {
if ((addr&0x1fff) + et4000->mmu.base[bank] < svga->vram_limit) if ((addr&0x1fff) + et4000->mmu.base[bank] < svga->vram_max)
{ {
svga->vram[(addr & 0x1fff) + et4000->mmu.base[bank]] = val; svga->vram[(addr & 0x1fff) + et4000->mmu.base[bank]] = val;
svga->changedvram[((addr & 0x1fff) + et4000->mmu.base[bank]) >> 12] = changeframecount; svga->changedvram[((addr & 0x1fff) + et4000->mmu.base[bank]) >> 12] = changeframecount;
@ -614,7 +614,7 @@ uint8_t et4000w32p_mmu_read(uint32_t addr, void *p)
/*???*/ /*???*/
return temp; return temp;
} }
if ((addr&0x1fff) + et4000->mmu.base[bank] >= svga->vram_limit) if ((addr&0x1fff) + et4000->mmu.base[bank] >= svga->vram_max)
return 0xff; return 0xff;
return svga->vram[(addr&0x1fff) + et4000->mmu.base[bank]]; return svga->vram[(addr&0x1fff) + et4000->mmu.base[bank]];

View file

@ -65,13 +65,13 @@ void oti067_out(uint16_t addr, uint8_t val, void *p)
switch (oti067->index) switch (oti067->index)
{ {
case 0xD: case 0xD:
svga->vrammask = (val & 0xc) ? oti067->vram_mask : 0x3ffff; svga->vram_display_mask = (val & 0xc) ? oti067->vram_mask : 0x3ffff;
if ((val & 0x80) && oti067->vram_size == 256) if ((val & 0x80) && oti067->vram_size == 256)
mem_mapping_disable(&svga->mapping); mem_mapping_disable(&svga->mapping);
else else
mem_mapping_enable(&svga->mapping); mem_mapping_enable(&svga->mapping);
if (!(val & 0x80)) if (!(val & 0x80))
svga->vrammask = 0x3ffff; svga->vram_display_mask = 0x3ffff;
break; break;
case 0x11: case 0x11:
svga->read_bank = (val & 0xf) * 65536; svga->read_bank = (val & 0xf) * 65536;

View file

@ -818,7 +818,7 @@ void s3_out(uint16_t addr, uint8_t val, void *p)
s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4); s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4);
break; break;
case 0x32: case 0x32:
svga->vrammask = (val & 0x40) ? 0x3ffff : s3->vram_mask; svga->vram_display_mask = (val & 0x40) ? 0x3ffff : s3->vram_mask;
break; break;
case 0x50: case 0x50:
@ -2222,6 +2222,29 @@ static void *s3_init(char *bios_fn, int chip)
s3_hwcursor_draw, s3_hwcursor_draw,
NULL); NULL);
svga->decode_mask = (4 << 20) - 1;
switch (vram)
{
case 0: /*512kb*/
svga->vram_mask = (1 << 19) - 1;
svga->vram_max = 2 << 20;
break;
case 1: /*1MB*/
/*VRAM in first MB, mirrored in 2nd MB, 3rd and 4th MBs are open bus*/
svga->vram_mask = (1 << 20) - 1;
svga->vram_max = 2 << 20;
break;
case 2: default: /*2MB*/
/*VRAM in first 2 MB, 3rd and 4th MBs are open bus*/
svga->vram_mask = (2 << 20) - 1;
svga->vram_max = 2 << 20;
break;
case 4: /*4MB*/
svga->vram_mask = (4 << 20) - 1;
svga->vram_max = 4 << 20;
break;
}
if (PCI) if (PCI)
svga->crtc[0x36] = 2 | (3 << 2) | (1 << 4) | (vram_sizes[vram] << 5); svga->crtc[0x36] = 2 | (3 << 2) | (1 << 4) | (vram_sizes[vram] << 5);
else else

View file

@ -370,7 +370,7 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p)
break; break;
case 0x32: case 0x32:
if ((svga->crtc[0x67] & 0xc) != 0xc) if ((svga->crtc[0x67] & 0xc) != 0xc)
svga->vrammask = (val & 0x40) ? 0x3ffff : ((virge->memory_size << 20) - 1); svga->vram_display_mask = (val & 0x40) ? 0x3ffff : ((virge->memory_size << 20) - 1);
s3_virge_update_irqs(virge); s3_virge_update_irqs(virge);
break; break;
@ -583,7 +583,7 @@ static void s3_virge_recalctimings(svga_t *svga)
{ {
svga->rowoffset = (svga->rowoffset * 3) / 4; /*Hack*/ svga->rowoffset = (svga->rowoffset * 3) / 4; /*Hack*/
} }
svga->vrammask = (svga->crtc[0x32] & 0x40) ? 0x3ffff : ((virge->memory_size << 20) - 1); svga->vram_display_mask = (svga->crtc[0x32] & 0x40) ? 0x3ffff : ((virge->memory_size << 20) - 1);
//pclog("VGA mode x_disp=%i dispend=%i vtotal=%i\n", svga->hdisp, svga->dispend, svga->vtotal); //pclog("VGA mode x_disp=%i dispend=%i vtotal=%i\n", svga->hdisp, svga->dispend, svga->vtotal);
} }
else /*Streams mode*/ else /*Streams mode*/
@ -631,7 +631,7 @@ static void s3_virge_recalctimings(svga_t *svga)
svga->render = svga_render_32bpp_highres; svga->render = svga_render_32bpp_highres;
break; break;
} }
svga->vrammask = (virge->memory_size << 20) - 1; svga->vram_display_mask = (virge->memory_size << 20) - 1;
} }
if (((svga->miscout >> 2) & 3) == 3) if (((svga->miscout >> 2) & 3) == 3)

View file

@ -483,7 +483,7 @@ void svga_poll(void *p)
{ {
svga->hdisp_on=1; svga->hdisp_on=1;
svga->ma &= svga->vrammask; svga->ma &= svga->vram_display_mask;
if (svga->firstline == 2000) if (svga->firstline == 2000)
{ {
svga->firstline = svga->displine; svga->firstline = svga->displine;
@ -561,7 +561,7 @@ void svga_poll(void *p)
svga->maback += (svga->rowoffset << 3); svga->maback += (svga->rowoffset << 3);
if (svga->interlace) if (svga->interlace)
svga->maback += (svga->rowoffset << 3); svga->maback += (svga->rowoffset << 3);
svga->maback &= svga->vrammask; svga->maback &= svga->vram_display_mask;
svga->ma = svga->maback; svga->ma = svga->maback;
} }
else else
@ -594,7 +594,7 @@ void svga_poll(void *p)
svga->fullchange = 2; svga->fullchange = 2;
svga->blink++; svga->blink++;
for (x = 0; x < (svga->vram_limit >> 12); x++) for (x = 0; x < ((svga->vram_mask+1) >> 12); x++)
{ {
if (svga->changedvram[x]) if (svga->changedvram[x])
svga->changedvram[x]--; svga->changedvram[x]--;
@ -728,8 +728,10 @@ int svga_init(svga_t *svga, void *p, int memsize,
svga->dispofftime = 1000 * (1 << TIMER_SHIFT); svga->dispofftime = 1000 * (1 << TIMER_SHIFT);
svga->bpp = 8; svga->bpp = 8;
svga->vram = malloc(memsize); svga->vram = malloc(memsize);
svga->vram_limit = memsize; svga->vram_max = memsize;
svga->vrammask = memsize - 1; svga->vram_display_mask = memsize - 1;
svga->vram_mask = memsize - 1;
svga->decode_mask = 0x7fffff;
svga->changedvram = malloc(/*(memsize >> 12) << 1*/0x800000 >> 12); svga->changedvram = malloc(/*(memsize >> 12) << 1*/0x800000 >> 12);
svga->recalctimings_ex = recalctimings_ex; svga->recalctimings_ex = recalctimings_ex;
svga->video_in = video_in; svga->video_in = video_in;
@ -790,10 +792,12 @@ void svga_write(uint32_t addr, uint8_t val, void *p)
{ {
addr<<=2; addr<<=2;
} }
addr &= 0x7fffff; addr &= svga->decode_mask;
if (addr >= svga->vram_limit) if (addr >= svga->vram_max)
return; return;
addr &= svga->vram_mask;
if (svga_output) pclog("%08X (%i, %i) %02X %i %i %i %02X\n", addr, addr & 1023, addr >> 10, val, writemask2, svga->writemode, svga->chain4, svga->gdcreg[8]); if (svga_output) pclog("%08X (%i, %i) %02X %i %i %i %02X\n", addr, addr & 1023, addr >> 10, val, writemask2, svga->writemode, svga->chain4, svga->gdcreg[8]);
svga->changedvram[addr >> 12] = changeframecount; svga->changedvram[addr >> 12] = changeframecount;
@ -954,19 +958,20 @@ uint8_t svga_read(uint32_t addr, void *p)
egareads++; egareads++;
// pclog("Readega %06X ",addr); // pclog("Readega %06X ",addr);
addr &= svga->banked_mask; addr &= svga->banked_mask;
addr += svga->read_bank; addr += svga->read_bank;
latch_addr = (addr << 2) & 0x7fffff; latch_addr = (addr << 2) & svga->decode_mask;
// pclog("%05X %i %04X:%04X %02X %02X %i\n",addr,svga->chain4,CS,pc, vram[addr & 0x7fffff], vram[(addr << 2) & 0x7fffff], svga->readmode); // pclog("%05X %i %04X:%04X %02X %02X %i\n",addr,svga->chain4,CS,pc, vram[addr & 0x7fffff], vram[(addr << 2) & 0x7fffff], svga->readmode);
// pclog("%i\n", svga->readmode); // pclog("%i\n", svga->readmode);
if (svga->chain4 || svga->fb_only) if (svga->chain4 || svga->fb_only)
{ {
addr &= 0x7fffff; addr &= svga->decode_mask;
if (addr >= svga->vram_limit) if (addr >= svga->vram_max)
return 0xff; return 0xff;
return svga->vram[addr]; return svga->vram[addr & svga->vram_mask];
} }
else if (svga->chain2_read) else if (svga->chain2_read)
{ {
@ -976,22 +981,27 @@ uint8_t svga_read(uint32_t addr, void *p)
} }
else else
addr<<=2; addr<<=2;
addr &= svga->decode_mask;
addr &= 0x7fffff; if (latch_addr >= svga->vram_max)
{
if (addr >= svga->vram_limit) svga->la = svga->lb = svga->lc = svga->ld = 0xff;
return 0xff; }
else
if (latch_addr < svga->vram_limit)
{ {
latch_addr &= svga->vram_mask;
svga->la = svga->vram[latch_addr]; svga->la = svga->vram[latch_addr];
svga->lb = svga->vram[latch_addr | 0x1]; svga->lb = svga->vram[latch_addr | 0x1];
svga->lc = svga->vram[latch_addr | 0x2]; svga->lc = svga->vram[latch_addr | 0x2];
svga->ld = svga->vram[latch_addr | 0x3]; svga->ld = svga->vram[latch_addr | 0x3];
} }
else
svga->la = svga->lb = svga->lc = svga->ld = 0xff;
if (addr >= svga->vram_max)
return 0xff;
addr &= svga->vram_mask;
if (svga->readmode) if (svga->readmode)
{ {
temp = svga->la; temp = svga->la;
@ -1009,6 +1019,7 @@ uint8_t svga_read(uint32_t addr, void *p)
return ~(temp | temp2 | temp3 | temp4); return ~(temp | temp2 | temp3 | temp4);
} }
//pclog("Read %02X %04X %04X\n",vram[addr|svga->readplane],addr,svga->readplane); //pclog("Read %02X %04X %04X\n",vram[addr|svga->readplane],addr,svga->readplane);
return svga->vram[addr | readplane]; return svga->vram[addr | readplane];
} }
@ -1043,9 +1054,10 @@ void svga_write_linear(uint32_t addr, uint8_t val, void *p)
{ {
addr<<=2; addr<<=2;
} }
addr &= 0x7fffff; addr &= svga->decode_mask;
if (addr >= svga->vram_limit) if (addr >= svga->vram_max)
return; return;
addr &= svga->vram_mask;
if (svga_output) pclog("%08X\n", addr); if (svga_output) pclog("%08X\n", addr);
svga->changedvram[addr >> 12]=changeframecount; svga->changedvram[addr >> 12]=changeframecount;
@ -1206,10 +1218,10 @@ uint8_t svga_read_linear(uint32_t addr, void *p)
if (svga->chain4 || svga->fb_only) if (svga->chain4 || svga->fb_only)
{ {
addr &= 0x7fffff; addr &= svga->decode_mask;
if (addr >= svga->vram_limit) if (addr >= svga->vram_max)
return 0xff; return 0xff;
return svga->vram[addr & 0x7fffff]; return svga->vram[addr & svga->vram_mask];
} }
else if (svga->chain2_read) else if (svga->chain2_read)
{ {
@ -1220,10 +1232,12 @@ uint8_t svga_read_linear(uint32_t addr, void *p)
else else
addr<<=2; addr<<=2;
addr &= 0x7fffff; addr &= svga->decode_mask;
if (addr >= svga->vram_limit) if (addr >= svga->vram_max)
return 0xff; return 0xff;
addr &= svga->vram_mask;
svga->la = svga->vram[addr]; svga->la = svga->vram[addr];
svga->lb = svga->vram[addr | 0x1]; svga->lb = svga->vram[addr | 0x1];
@ -1296,9 +1310,10 @@ void svga_writew(uint32_t addr, uint16_t val, void *p)
if (svga_output) pclog("svga_writew: %05X ", addr); if (svga_output) pclog("svga_writew: %05X ", addr);
addr = (addr & svga->banked_mask) + svga->write_bank; addr = (addr & svga->banked_mask) + svga->write_bank;
addr &= 0x7FFFFF; addr &= svga->decode_mask;
if (addr >= svga->vram_limit) if (addr >= svga->vram_max)
return; return;
addr &= svga->vram_mask;
if (svga_output) pclog("%08X (%i, %i) %04X\n", addr, addr & 1023, addr >> 10, val); if (svga_output) pclog("%08X (%i, %i) %04X\n", addr, addr & 1023, addr >> 10, val);
svga->changedvram[addr >> 12] = changeframecount; svga->changedvram[addr >> 12] = changeframecount;
*(uint16_t *)&svga->vram[addr] = val; *(uint16_t *)&svga->vram[addr] = val;
@ -1324,9 +1339,10 @@ void svga_writel(uint32_t addr, uint32_t val, void *p)
if (svga_output) pclog("svga_writel: %05X ", addr); if (svga_output) pclog("svga_writel: %05X ", addr);
addr = (addr & svga->banked_mask) + svga->write_bank; addr = (addr & svga->banked_mask) + svga->write_bank;
addr &= 0x7FFFFF; addr &= svga->decode_mask;
if (addr >= svga->vram_limit) if (addr >= svga->vram_max)
return; return;
addr &= svga->vram_mask;
if (svga_output) pclog("%08X (%i, %i) %08X\n", addr, addr & 1023, addr >> 10, val); if (svga_output) pclog("%08X (%i, %i) %08X\n", addr, addr & 1023, addr >> 10, val);
svga->changedvram[addr >> 12] = changeframecount; svga->changedvram[addr >> 12] = changeframecount;
@ -1347,11 +1363,12 @@ uint16_t svga_readw(uint32_t addr, void *p)
// pclog("Readw %05X ", addr); // pclog("Readw %05X ", addr);
addr = (addr & svga->banked_mask) + svga->read_bank; addr = (addr & svga->banked_mask) + svga->read_bank;
addr &= 0x7FFFFF; addr &= svga->decode_mask;
// pclog("%08X %04X\n", addr, *(uint16_t *)&vram[addr]); // pclog("%08X %04X\n", addr, *(uint16_t *)&vram[addr]);
if (addr >= svga->vram_limit) return 0xffff; if (addr >= svga->vram_max)
return 0xffff;
return *(uint16_t *)&svga->vram[addr]; return *(uint16_t *)&svga->vram[addr & svga->vram_mask];
} }
uint32_t svga_readl(uint32_t addr, void *p) uint32_t svga_readl(uint32_t addr, void *p)
@ -1368,11 +1385,12 @@ uint32_t svga_readl(uint32_t addr, void *p)
// pclog("Readl %05X ", addr); // pclog("Readl %05X ", addr);
addr = (addr & svga->banked_mask) + svga->read_bank; addr = (addr & svga->banked_mask) + svga->read_bank;
addr &= 0x7FFFFF; addr &= svga->decode_mask;
// pclog("%08X %08X\n", addr, *(uint32_t *)&vram[addr]); // pclog("%08X %08X\n", addr, *(uint32_t *)&vram[addr]);
if (addr >= svga->vram_limit) return 0xffffffff; if (addr >= svga->vram_max)
return 0xffffffff;
return *(uint32_t *)&svga->vram[addr]; return *(uint32_t *)&svga->vram[addr & svga->vram_mask];
} }
void svga_writew_linear(uint32_t addr, uint16_t val, void *p) void svga_writew_linear(uint32_t addr, uint16_t val, void *p)
@ -1392,9 +1410,10 @@ void svga_writew_linear(uint32_t addr, uint16_t val, void *p)
cycles_lost += video_timing_w; cycles_lost += video_timing_w;
if (svga_output) pclog("Write LFBw %08X %04X\n", addr, val); if (svga_output) pclog("Write LFBw %08X %04X\n", addr, val);
addr &= 0x7FFFFF; addr &= svga->decode_mask;
if (addr >= svga->vram_limit) if (addr >= svga->vram_max)
return; return;
addr &= svga->vram_mask;
svga->changedvram[addr >> 12] = changeframecount; svga->changedvram[addr >> 12] = changeframecount;
*(uint16_t *)&svga->vram[addr] = val; *(uint16_t *)&svga->vram[addr] = val;
} }
@ -1418,9 +1437,10 @@ void svga_writel_linear(uint32_t addr, uint32_t val, void *p)
cycles_lost += video_timing_l; cycles_lost += video_timing_l;
if (svga_output) pclog("Write LFBl %08X %08X\n", addr, val); if (svga_output) pclog("Write LFBl %08X %08X\n", addr, val);
addr &= 0x7fffff; addr &= svga->decode_mask;
if (addr >= svga->vram_limit) if (addr >= svga->vram_max)
return; return;
addr &= svga->vram_mask;
svga->changedvram[addr >> 12] = changeframecount; svga->changedvram[addr >> 12] = changeframecount;
*(uint32_t *)&svga->vram[addr] = val; *(uint32_t *)&svga->vram[addr] = val;
} }
@ -1437,10 +1457,11 @@ uint16_t svga_readw_linear(uint32_t addr, void *p)
cycles -= video_timing_w; cycles -= video_timing_w;
cycles_lost += video_timing_w; cycles_lost += video_timing_w;
addr &= 0x7FFFFF; addr &= svga->decode_mask;
if (addr >= svga->vram_limit) return 0xffff; if (addr >= svga->vram_max)
return 0xffff;
return *(uint16_t *)&svga->vram[addr]; return *(uint16_t *)&svga->vram[addr & svga->vram_mask];
} }
uint32_t svga_readl_linear(uint32_t addr, void *p) uint32_t svga_readl_linear(uint32_t addr, void *p)
@ -1455,10 +1476,11 @@ uint32_t svga_readl_linear(uint32_t addr, void *p)
cycles -= video_timing_l; cycles -= video_timing_l;
cycles_lost += video_timing_l; cycles_lost += video_timing_l;
addr &= 0x7FFFFF; addr &= svga->decode_mask;
if (addr >= svga->vram_limit) return 0xffffffff; if (addr >= svga->vram_max)
return 0xffffffff;
return *(uint32_t *)&svga->vram[addr]; return *(uint32_t *)&svga->vram[addr & svga->vram_mask];
} }

View file

@ -15,7 +15,18 @@ typedef struct svga_t
uint8_t miscout; uint8_t miscout;
int vidclock; int vidclock;
uint32_t vram_limit; /*The three variables below allow us to implement memory maps like that seen on a 1MB Trio64 :
0MB-1MB - VRAM
1MB-2MB - VRAM mirror
2MB-4MB - open bus
4MB-xMB - mirror of above
For the example memory map, decode_mask would be 4MB-1 (4MB address space), vram_max would be 2MB
(present video memory only responds to first 2MB), vram_mask would be 1MB-1 (video memory wraps at 1MB)
*/
uint32_t decode_mask;
uint32_t vram_max;
uint32_t vram_mask;
uint8_t la, lb, lc, ld; uint8_t la, lb, lc, ld;
@ -71,7 +82,7 @@ typedef struct svga_t
uint8_t *vram; uint8_t *vram;
uint8_t *changedvram; uint8_t *changedvram;
int vrammask; uint32_t vram_display_mask;
uint32_t banked_mask; uint32_t banked_mask;
uint32_t write_bank, read_bank; uint32_t write_bank, read_bank;

View file

@ -51,8 +51,8 @@ void svga_render_text_40(svga_t *svga)
for (x = 0; x < svga->hdisp; x += xinc) for (x = 0; x < svga->hdisp; x += xinc)
{ {
drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
chr = svga->vram[(svga->ma << 1) & svga->vrammask]; chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask];
attr = svga->vram[((svga->ma << 1) + 1) & svga->vrammask]; attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask];
if (attr & 8) charaddr = svga->charsetb + (chr * 128); if (attr & 8) charaddr = svga->charsetb + (chr * 128);
else charaddr = svga->charseta + (chr * 128); else charaddr = svga->charseta + (chr * 128);
@ -91,7 +91,7 @@ void svga_render_text_40(svga_t *svga)
svga->ma += 4; svga->ma += 4;
p += xinc; p += xinc;
} }
svga->ma &= svga->vrammask; svga->ma &= svga->vram_display_mask;
} }
} }
@ -114,8 +114,8 @@ void svga_render_text_80(svga_t *svga)
for (x = 0; x < svga->hdisp; x += xinc) for (x = 0; x < svga->hdisp; x += xinc)
{ {
drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
chr = svga->vram[(svga->ma << 1) & svga->vrammask]; chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask];
attr = svga->vram[((svga->ma << 1) + 1) & svga->vrammask]; attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask];
if (attr & 8) charaddr = svga->charsetb + (chr * 128); if (attr & 8) charaddr = svga->charsetb + (chr * 128);
else charaddr = svga->charseta + (chr * 128); else charaddr = svga->charseta + (chr * 128);
@ -154,7 +154,7 @@ void svga_render_text_80(svga_t *svga)
svga->ma += 4; svga->ma += 4;
p += xinc; p += xinc;
} }
svga->ma &= svga->vrammask; svga->ma &= svga->vram_display_mask;
} }
} }
@ -192,7 +192,7 @@ void svga_render_2bpp_lowres(svga_t *svga)
dat[1] = svga->vram[(svga->ma << 1) + 1]; dat[1] = svga->vram[(svga->ma << 1) + 1];
} }
svga->ma += 4; svga->ma += 4;
svga->ma &= svga->vrammask; svga->ma &= svga->vram_display_mask;
p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]];
p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]];
@ -242,7 +242,7 @@ void svga_render_2bpp_highres(svga_t *svga)
dat[1] = svga->vram[(svga->ma << 1) + 1]; dat[1] = svga->vram[(svga->ma << 1) + 1];
} }
svga->ma += 4; svga->ma += 4;
svga->ma &= svga->vrammask; svga->ma &= svga->vram_display_mask;
p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]];
p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]];
@ -277,7 +277,7 @@ void svga_render_4bpp_lowres(svga_t *svga)
*(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma]); *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma]);
svga->ma += 4; svga->ma += 4;
svga->ma &= svga->vrammask; svga->ma &= svga->vram_display_mask;
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
p[0] = p[1] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; p[0] = p[1] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
@ -326,7 +326,7 @@ void svga_render_4bpp_highres(svga_t *svga)
else else
*(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma]); *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma]);
svga->ma += 4; svga->ma += 4;
svga->ma &= svga->vrammask; svga->ma &= svga->vram_display_mask;
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
@ -360,7 +360,7 @@ void svga_render_8bpp_lowres(svga_t *svga)
for (x = 0; x <= svga->hdisp; x += 8) for (x = 0; x <= svga->hdisp; x += 8)
{ {
uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vrammask]); uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
p[0] = p[1] = svga->pallook[dat & 0xff]; p[0] = p[1] = svga->pallook[dat & 0xff];
p[2] = p[3] = svga->pallook[(dat >> 8) & 0xff]; p[2] = p[3] = svga->pallook[(dat >> 8) & 0xff];
@ -370,7 +370,7 @@ void svga_render_8bpp_lowres(svga_t *svga)
svga->ma += 4; svga->ma += 4;
p += 8; p += 8;
} }
svga->ma &= svga->vrammask; svga->ma &= svga->vram_display_mask;
} }
} }
@ -389,13 +389,13 @@ void svga_render_8bpp_highres(svga_t *svga)
for (x = 0; x <= svga->hdisp; x += 8) for (x = 0; x <= svga->hdisp; x += 8)
{ {
uint32_t dat; uint32_t dat;
dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vrammask]); dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
p[0] = svga->pallook[dat & 0xff]; p[0] = svga->pallook[dat & 0xff];
p[1] = svga->pallook[(dat >> 8) & 0xff]; p[1] = svga->pallook[(dat >> 8) & 0xff];
p[2] = svga->pallook[(dat >> 16) & 0xff]; p[2] = svga->pallook[(dat >> 16) & 0xff];
p[3] = svga->pallook[(dat >> 24) & 0xff]; p[3] = svga->pallook[(dat >> 24) & 0xff];
dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vrammask]); dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]);
p[4] = svga->pallook[dat & 0xff]; p[4] = svga->pallook[dat & 0xff];
p[5] = svga->pallook[(dat >> 8) & 0xff]; p[5] = svga->pallook[(dat >> 8) & 0xff];
p[6] = svga->pallook[(dat >> 16) & 0xff]; p[6] = svga->pallook[(dat >> 16) & 0xff];
@ -404,7 +404,7 @@ void svga_render_8bpp_highres(svga_t *svga)
svga->ma += 8; svga->ma += 8;
p += 8; p += 8;
} }
svga->ma &= svga->vrammask; svga->ma &= svga->vram_display_mask;
} }
} }
@ -422,18 +422,18 @@ void svga_render_15bpp_lowres(svga_t *svga)
for (x = 0; x <= svga->hdisp; x += 4) for (x = 0; x <= svga->hdisp; x += 4)
{ {
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vrammask]); uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
p[x] = video_15to32[dat & 0xffff]; p[x] = video_15to32[dat & 0xffff];
p[x + 1] = video_15to32[dat >> 16]; p[x + 1] = video_15to32[dat >> 16];
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vrammask]); dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
p[x] = video_15to32[dat & 0xffff]; p[x] = video_15to32[dat & 0xffff];
p[x + 1] = video_15to32[dat >> 16]; p[x + 1] = video_15to32[dat >> 16];
} }
svga->ma += x << 1; svga->ma += x << 1;
svga->ma &= svga->vrammask; svga->ma &= svga->vram_display_mask;
} }
} }
@ -451,24 +451,24 @@ void svga_render_15bpp_highres(svga_t *svga)
for (x = 0; x <= svga->hdisp; x += 8) for (x = 0; x <= svga->hdisp; x += 8)
{ {
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vrammask]); uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
p[x] = video_15to32[dat & 0xffff]; p[x] = video_15to32[dat & 0xffff];
p[x + 1] = video_15to32[dat >> 16]; p[x + 1] = video_15to32[dat >> 16];
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vrammask]); dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
p[x + 2] = video_15to32[dat & 0xffff]; p[x + 2] = video_15to32[dat & 0xffff];
p[x + 3] = video_15to32[dat >> 16]; p[x + 3] = video_15to32[dat >> 16];
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vrammask]); dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]);
p[x + 4] = video_15to32[dat & 0xffff]; p[x + 4] = video_15to32[dat & 0xffff];
p[x + 5] = video_15to32[dat >> 16]; p[x + 5] = video_15to32[dat >> 16];
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vrammask]); dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]);
p[x + 6] = video_15to32[dat & 0xffff]; p[x + 6] = video_15to32[dat & 0xffff];
p[x + 7] = video_15to32[dat >> 16]; p[x + 7] = video_15to32[dat >> 16];
} }
svga->ma += x << 1; svga->ma += x << 1;
svga->ma &= svga->vrammask; svga->ma &= svga->vram_display_mask;
} }
} }
@ -486,18 +486,18 @@ void svga_render_16bpp_lowres(svga_t *svga)
for (x = 0; x <= svga->hdisp; x += 4) for (x = 0; x <= svga->hdisp; x += 4)
{ {
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vrammask]); uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
p[x] = video_16to32[dat & 0xffff]; p[x] = video_16to32[dat & 0xffff];
p[x + 1] = video_16to32[dat >> 16]; p[x + 1] = video_16to32[dat >> 16];
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vrammask]); dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
p[x] = video_16to32[dat & 0xffff]; p[x] = video_16to32[dat & 0xffff];
p[x + 1] = video_16to32[dat >> 16]; p[x + 1] = video_16to32[dat >> 16];
} }
svga->ma += x << 1; svga->ma += x << 1;
svga->ma &= svga->vrammask; svga->ma &= svga->vram_display_mask;
} }
} }
@ -515,24 +515,24 @@ void svga_render_16bpp_highres(svga_t *svga)
for (x = 0; x <= svga->hdisp; x += 8) for (x = 0; x <= svga->hdisp; x += 8)
{ {
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vrammask]); uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
p[x] = video_16to32[dat & 0xffff]; p[x] = video_16to32[dat & 0xffff];
p[x + 1] = video_16to32[dat >> 16]; p[x + 1] = video_16to32[dat >> 16];
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vrammask]); dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
p[x + 2] = video_16to32[dat & 0xffff]; p[x + 2] = video_16to32[dat & 0xffff];
p[x + 3] = video_16to32[dat >> 16]; p[x + 3] = video_16to32[dat >> 16];
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vrammask]); dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]);
p[x + 4] = video_16to32[dat & 0xffff]; p[x + 4] = video_16to32[dat & 0xffff];
p[x + 5] = video_16to32[dat >> 16]; p[x + 5] = video_16to32[dat >> 16];
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vrammask]); dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]);
p[x + 6] = video_16to32[dat & 0xffff]; p[x + 6] = video_16to32[dat & 0xffff];
p[x + 7] = video_16to32[dat >> 16]; p[x + 7] = video_16to32[dat >> 16];
} }
svga->ma += x << 1; svga->ma += x << 1;
svga->ma &= svga->vrammask; svga->ma &= svga->vram_display_mask;
} }
} }
@ -553,7 +553,7 @@ void svga_render_24bpp_lowres(svga_t *svga)
{ {
fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16);
svga->ma += 3; svga->ma += 3;
svga->ma &= svga->vrammask; svga->ma &= svga->vram_display_mask;
((uint32_t *)buffer32->line[svga->displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + 1 + offset] = fg; ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + 1 + offset] = fg;
} }
} }
@ -573,21 +573,21 @@ void svga_render_24bpp_highres(svga_t *svga)
for (x = 0; x <= svga->hdisp; x += 4) for (x = 0; x <= svga->hdisp; x += 4)
{ {
uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vrammask]); uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
p[x] = dat & 0xffffff; p[x] = dat & 0xffffff;
dat = *(uint32_t *)(&svga->vram[(svga->ma + 3) & svga->vrammask]); dat = *(uint32_t *)(&svga->vram[(svga->ma + 3) & svga->vram_display_mask]);
p[x + 1] = dat & 0xffffff; p[x + 1] = dat & 0xffffff;
dat = *(uint32_t *)(&svga->vram[(svga->ma + 6) & svga->vrammask]); dat = *(uint32_t *)(&svga->vram[(svga->ma + 6) & svga->vram_display_mask]);
p[x + 2] = dat & 0xffffff; p[x + 2] = dat & 0xffffff;
dat = *(uint32_t *)(&svga->vram[(svga->ma + 9) & svga->vrammask]); dat = *(uint32_t *)(&svga->vram[(svga->ma + 9) & svga->vram_display_mask]);
p[x + 3] = dat & 0xffffff; p[x + 3] = dat & 0xffffff;
svga->ma += 12; svga->ma += 12;
} }
svga->ma &= svga->vrammask; svga->ma &= svga->vram_display_mask;
} }
} }
@ -608,7 +608,7 @@ void svga_render_32bpp_lowres(svga_t *svga)
{ {
fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16);
svga->ma += 4; svga->ma += 4;
svga->ma &= svga->vrammask; svga->ma &= svga->vram_display_mask;
((uint32_t *)buffer32->line[svga->displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + 1 + offset] = fg; ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + 1 + offset] = fg;
} }
} }
@ -630,11 +630,11 @@ void svga_render_32bpp_highres(svga_t *svga)
for (x = 0; x <= svga->hdisp; x++) for (x = 0; x <= svga->hdisp; x++)
{ {
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vrammask]); uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
p[x] = dat & 0xffffff; p[x] = dat & 0xffffff;
} }
svga->ma += 4; svga->ma += 4;
svga->ma &= svga->vrammask; svga->ma &= svga->vram_display_mask;
} }
} }
@ -652,11 +652,11 @@ void svga_render_ABGR8888_highres(svga_t *svga)
for (x = 0; x <= svga->hdisp; x++) for (x = 0; x <= svga->hdisp; x++)
{ {
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vrammask]); uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
p[x] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); p[x] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16);
} }
svga->ma += 4; svga->ma += 4;
svga->ma &= svga->vrammask; svga->ma &= svga->vram_display_mask;
} }
} }
@ -674,10 +674,10 @@ void svga_render_RGBA8888_highres(svga_t *svga)
for (x = 0; x <= svga->hdisp; x++) for (x = 0; x <= svga->hdisp; x++)
{ {
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vrammask]); uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
p[x] = dat >> 8; p[x] = dat >> 8;
} }
svga->ma += 4; svga->ma += 4;
svga->ma &= svga->vrammask; svga->ma &= svga->vram_display_mask;
} }
} }

View file

@ -128,7 +128,7 @@ void tvga_out(uint16_t addr, uint8_t val, void *p)
switch (svga->crtcreg) switch (svga->crtcreg)
{ {
case 0x1e: case 0x1e:
svga->vrammask = (val & 0x80) ? tvga->vram_mask : 0x3ffff; svga->vram_display_mask = (val & 0x80) ? tvga->vram_mask : 0x3ffff;
break; break;
} }
return; return;