diff --git a/src/vid_svga.c b/src/vid_svga.c index 4c69bd9e0..62e03c512 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -592,6 +592,10 @@ uint32_t svga_mask_addr(uint32_t addr, svga_t *svga) { limit_shift = 1; } + if ((svga->gdcreg[5] & 0x60) == 0x20) + { + limit_shift = 1; + } if (svga->vrammask == (svga->vram_limit - 1)) { return addr % (svga->vram_limit >> limit_shift); @@ -602,6 +606,18 @@ uint32_t svga_mask_addr(uint32_t addr, svga_t *svga) } } +uint32_t svga_mask_changedaddr(uint32_t addr, svga_t *svga) +{ + if (svga->vrammask == (svga->vram_limit - 1)) + { + return addr % (svga->vram_limit >> 12); + } + else + { + return addr & (svga->vrammask >> 12); + } +} + void svga_poll(void *p) { svga_t *svga = (svga_t *)p; @@ -978,6 +994,8 @@ void svga_write(uint32_t addr, uint8_t val, void *p) if (addr >= svga->vram_limit) return; + addr = svga_mask_addr(addr, svga); + 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; @@ -1147,7 +1165,8 @@ uint8_t svga_read(uint32_t addr, void *p) addr &= svga->banked_mask; addr += svga->read_bank; - latch_addr = (addr << 2) % svga->vram_limit; + // latch_addr = (addr << 2) % svga->vram_limit; + latch_addr = svga_mask_addr(addr << 2); // latch_addr = (addr << 2); // pclog("%05X %i %04X:%04X %02X %02X %i\n",addr,svga->chain4,CS,pc, vram[addr & 0x7fffff], vram[(addr << 2) & 0x7fffff], svga->readmode); @@ -1157,7 +1176,7 @@ uint8_t svga_read(uint32_t addr, void *p) // addr %= svga->vram_limit; if (addr >= svga->vram_limit) return 0xff; - return svga->vram[addr]; + return svga->vram[svga_mask_addr(addr)]; } else if (svga->chain2_read) { @@ -1172,6 +1191,8 @@ uint8_t svga_read(uint32_t addr, void *p) if (addr >= svga->vram_limit) return 0xff; + + addr = svga_mask_addr(addr, svga); if (latch_addr < svga->vram_limit) { @@ -1396,6 +1417,7 @@ uint8_t svga_read_linear(uint32_t addr, void *p) { svga_t *svga = (svga_t *)p; uint8_t temp, temp2, temp3, temp4; + uint32_t latch_addr; int readplane = svga->readplane; cycles -= video_timing_b; @@ -1404,13 +1426,15 @@ uint8_t svga_read_linear(uint32_t addr, void *p) egareads++; addr -= svga->linear_base; + + latch_addr = svga_mask_addr(addr << 2); if (svga->chain4 || svga->fb_only) { // addr %= svga->vram_limit; if (addr >= svga->vram_limit) return 0xff; - return svga->vram[addr]; + return svga->vram[svga_mask_addr(addr)]; } else if (svga->chain2_read) { @@ -1426,10 +1450,12 @@ uint8_t svga_read_linear(uint32_t addr, void *p) if (addr >= svga->vram_limit) return 0xff; - svga->la = svga->vram[addr]; - svga->lb = svga->vram[addr | 0x1]; - svga->lc = svga->vram[addr | 0x2]; - svga->ld = svga->vram[addr | 0x3]; + addr = svga_mask_addr(addr, svga); + + svga->la = svga->vram[latch_addr]; + svga->lb = svga->vram[latch_addr | 0x1]; + svga->lc = svga->vram[latch_addr | 0x2]; + svga->ld = svga->vram[latch_addr | 0x3]; if (svga->readmode) { temp = (svga->colournocare & 1) ? 0xff : 0; diff --git a/src/vid_svga_render.c b/src/vid_svga_render.c index 6d4f47e12..93104b944 100644 --- a/src/vid_svga_render.c +++ b/src/vid_svga_render.c @@ -432,15 +432,21 @@ void svga_render_4bpp_lowres(svga_t *svga) void svga_render_4bpp_highres(svga_t *svga) { int changed_offset; + int changed_offset2; int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; if (svga->sc & 1 && !(svga->crtc[0x17] & 1)) - changed_offset = (svga->ma | 0x8000) >> 12; + changed_offset = svga_mask_addr(svga->ma | 0x8000) >> 12; else changed_offset = svga->ma >> 12; - if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) + if (svga->sc & 1 && !(svga->crtc[0x17] & 1)) + changed_offset2 = svga_mask_addr((svga->ma | 0x8000) + 4096) >> 12; + else + changed_offset2 = svga_mask_addr(svga->ma + 4096) >> 12; + + if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset2] || svga->fullchange) { int x; int offset = (8 - svga->scrollcache) + 24; @@ -456,7 +462,7 @@ void svga_render_4bpp_highres(svga_t *svga) uint8_t dat; if (svga->sc & 1 && !(svga->crtc[0x17] & 1)) - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma | 0x8000]); + *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma | 0x8000)]); else *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma]); svga->ma += 4; @@ -485,7 +491,7 @@ void svga_render_8bpp_lowres(svga_t *svga) int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 1)] || svga->fullchange) { int x; int offset = (8 - (svga->scrollcache & 6)) + 24; @@ -497,7 +503,7 @@ void svga_render_8bpp_lowres(svga_t *svga) 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]); p[0] = p[1] = svga->pallook[dat & 0xff]; p[2] = p[3] = svga->pallook[(dat >> 8) & 0xff]; @@ -505,9 +511,9 @@ void svga_render_8bpp_lowres(svga_t *svga) p[6] = p[7] = svga->pallook[(dat >> 24) & 0xff]; svga->ma += 4; + svga->ma = svga_mask_addr(svga->ma, svga); p += 8; } - svga->ma = svga_mask_addr(svga->ma, svga); } // return NULL; @@ -518,7 +524,7 @@ void svga_render_8bpp_highres(svga_t *svga) int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 1)] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; @@ -531,22 +537,22 @@ void svga_render_8bpp_highres(svga_t *svga) for (x = 0; x <= svga->hdisp; x += 8) { uint32_t dat; - dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vrammask]); + dat = *(uint32_t *)(&svga->vram[svga->ma]); p[0] = svga->pallook[dat & 0xff]; p[1] = svga->pallook[(dat >> 8) & 0xff]; p[2] = svga->pallook[(dat >> 16) & 0xff]; p[3] = svga->pallook[(dat >> 24) & 0xff]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vrammask]); + dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + 4)]); p[4] = svga->pallook[dat & 0xff]; p[5] = svga->pallook[(dat >> 8) & 0xff]; p[6] = svga->pallook[(dat >> 16) & 0xff]; p[7] = svga->pallook[(dat >> 24) & 0xff]; svga->ma += 8; + svga->ma = svga_mask_addr(svga->ma, svga); p += 8; } - svga->ma = svga_mask_addr(svga->ma, svga); } // return NULL; @@ -557,7 +563,7 @@ void svga_render_15bpp_lowres(svga_t *svga) int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 1)] || svga->fullchange) { int x; int offset = (8 - (svga->scrollcache & 6)) + 24; @@ -569,12 +575,12 @@ void svga_render_15bpp_lowres(svga_t *svga) 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_mask_addr(svga->ma + (x << 1))]); p[x] = video_15to32[dat & 0xffff]; 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_mask_addr(svga->ma + (x << 1) + 4)]); p[x] = video_15to32[dat & 0xffff]; p[x + 1] = video_15to32[dat >> 16]; @@ -589,7 +595,7 @@ void svga_render_15bpp_highres(svga_t *svga) int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 1)] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; @@ -601,19 +607,19 @@ void svga_render_15bpp_highres(svga_t *svga) 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_mask_addr(svga->ma + (x << 1))]); p[x] = video_15to32[dat & 0xffff]; 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_mask_addr(svga->ma + (x << 1) + 4)]); p[x + 2] = video_15to32[dat & 0xffff]; 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_mask_addr(svga->ma + (x << 1) + 8)]); p[x + 4] = video_15to32[dat & 0xffff]; 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_mask_addr(svga->ma + (x << 1) + 12)]); p[x + 6] = video_15to32[dat & 0xffff]; p[x + 7] = video_15to32[dat >> 16]; } @@ -627,7 +633,7 @@ void svga_render_16bpp_lowres(svga_t *svga) int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 1)] || svga->fullchange) { int x; int offset = (8 - (svga->scrollcache & 6)) + 24; @@ -639,12 +645,12 @@ void svga_render_16bpp_lowres(svga_t *svga) 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_mask_addr(svga->ma + (x << 1))]); p[x] = video_16to32[dat & 0xffff]; 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_mask_addr(svga->ma + (x << 1) + 4)]); p[x] = video_16to32[dat & 0xffff]; p[x + 1] = video_16to32[dat >> 16]; @@ -659,7 +665,7 @@ void svga_render_16bpp_highres(svga_t *svga) int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 1)] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; @@ -671,19 +677,19 @@ void svga_render_16bpp_highres(svga_t *svga) 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_mask_addr(svga->ma + (x << 1))]); p[x] = video_16to32[dat & 0xffff]; 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_mask_addr(svga->ma + (x << 1) + 4)]); p[x + 2] = video_16to32[dat & 0xffff]; 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_mask_addr(svga->ma + (x << 1) + 8)]); p[x + 4] = video_16to32[dat & 0xffff]; 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_mask_addr(svga->ma + (x << 1) + 12)]); p[x + 6] = video_16to32[dat & 0xffff]; p[x + 7] = video_16to32[dat >> 16]; } @@ -699,7 +705,7 @@ void svga_render_24bpp_lowres(svga_t *svga) int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 1)] || svga->fullchange) { if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; @@ -709,7 +715,7 @@ void svga_render_24bpp_lowres(svga_t *svga) for (x = 0; x <= svga->hdisp; x++) { - 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_mask_addr(svga->ma + 1)] << 8) | (svga->vram[svga_mask_addr(svga->ma + 2)] << 16); svga->ma += 3; svga->ma = svga_mask_addr(svga->ma, svga); ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + offset + x_add] = ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + 1 + offset + x_add] = fg; @@ -722,7 +728,7 @@ void svga_render_24bpp_highres(svga_t *svga) int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 1)] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; @@ -734,16 +740,16 @@ void svga_render_24bpp_highres(svga_t *svga) 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_mask_addr(svga->ma)]); p[x] = dat & 0xffffff; - dat = *(uint32_t *)(&svga->vram[(svga->ma + 3) & svga->vrammask]); + dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + 3)]); p[x + 1] = dat & 0xffffff; - dat = *(uint32_t *)(&svga->vram[(svga->ma + 6) & svga->vrammask]); + dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + 6)]); p[x + 2] = dat & 0xffffff; - dat = *(uint32_t *)(&svga->vram[(svga->ma + 9) & svga->vrammask]); + dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + 9)]); p[x + 3] = dat & 0xffffff; svga->ma += 12; @@ -759,7 +765,7 @@ void svga_render_32bpp_lowres(svga_t *svga) int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 1)] || svga->fullchange) { if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; @@ -769,7 +775,7 @@ void svga_render_32bpp_lowres(svga_t *svga) for (x = 0; x <= svga->hdisp; x++) { - 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_mask_addr(svga->ma + 1)] << 8) | (svga->vram[svga_mask_addr(svga->ma + 2)] << 16); svga->ma += 4; svga->ma = svga_mask_addr(svga->ma, svga); ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + offset + x_add] = ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + 1 + offset + x_add] = fg; @@ -784,7 +790,7 @@ void svga_render_32bpp_highres(svga_t *svga) int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 1)] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 2)] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; @@ -796,7 +802,7 @@ void svga_render_32bpp_highres(svga_t *svga) 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_mask_addr(svga->ma + (x << 2))]); p[x] = dat & 0xffffff; } svga->ma += 4; @@ -809,7 +815,7 @@ void svga_render_ABGR8888_highres(svga_t *svga) int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 1)] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 2)] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; @@ -821,7 +827,7 @@ void svga_render_ABGR8888_highres(svga_t *svga) 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_mask_addr(svga->ma + (x << 2))]); p[x] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); } svga->ma += 4; @@ -834,7 +840,7 @@ void svga_render_RGBA8888_highres(svga_t *svga) int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 1)] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 2)] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; @@ -846,7 +852,7 @@ void svga_render_RGBA8888_highres(svga_t *svga) 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_mask_addr(svga->ma + (x << 2))]); p[x] = dat >> 8; } svga->ma += 4;