diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 153723d..852406e 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -1,4 +1,5 @@ /*Cirrus Logic CL-GD5429 emulation*/ +//SR7.0 = "true packed-pixel memory addressing" #include #include "ibm.h" #include "cpu.h" @@ -178,6 +179,8 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) case 0x07: svga->set_reset_disabled = svga->seqregs[7] & 1; + svga->packed_chain4 = svga->seqregs[7] & 1; + svga_recalctimings(svga); case 0x17: if (gd5429->type >= CL_TYPE_GD5429) gd5429_recalc_mapping(gd5429); @@ -844,11 +847,16 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) svga->fullchange = 2; if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING) addr <<= 3; - else if ((svga->chain4 || svga->fb_only) && (svga->writemode < 4)) + else if (((svga->chain4 && svga->packed_chain4) || svga->fb_only) && (svga->writemode < 4)) { writemask2 = 1 << (addr & 3); addr &= ~3; } + else if (svga->chain4) + { + writemask2 = 1 << (addr & 3); + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_write) { writemask2 &= ~0xa; @@ -1193,13 +1201,18 @@ uint8_t gd5429_read_linear(uint32_t addr, void *p) if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING) addr <<= 3; - else if (svga->chain4 || svga->fb_only) + else if ((svga->chain4 && svga->packed_chain4) || svga->fb_only) { addr &= svga->decode_mask; if (addr >= svga->vram_max) return 0xff; return svga->vram[addr & svga->vram_mask]; } + else if (svga->chain4) + { + readplane = addr & 3; + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_read) { readplane = (readplane & 2) | (addr & 1); diff --git a/src/vid_et4000.c b/src/vid_et4000.c index ee30098..7f366b3 100644 --- a/src/vid_et4000.c +++ b/src/vid_et4000.c @@ -495,6 +495,8 @@ void *et4000_init() et4000_in, et4000_out, NULL, NULL); + + et4000->svga.packed_chain4 = 1; return et4000; } @@ -527,6 +529,8 @@ void *et4000k_init() et4000->svga.ksc5601_swap_mode = 0; et4000->svga.ksc5601_english_font_type = 0; + et4000->svga.packed_chain4 = 1; + return et4000; } @@ -571,6 +575,8 @@ void *et4000_kasan_init() et4000->svga.ksc5601_swap_mode = 0; et4000->svga.ksc5601_english_font_type = 0x1FF; + et4000->svga.packed_chain4 = 1; + return et4000; } diff --git a/src/vid_et4000w32.c b/src/vid_et4000w32.c index ae748ef..b84cdbd 100644 --- a/src/vid_et4000w32.c +++ b/src/vid_et4000w32.c @@ -1207,6 +1207,8 @@ void *et4000w32p_init() et4000->fifo_not_full_event = thread_create_event(); et4000->fifo_thread = thread_create(fifo_thread, et4000); + et4000->svga.packed_chain4 = 1; + return et4000; } diff --git a/src/vid_ht216.c b/src/vid_ht216.c index ab2e021..aa717e4 100644 --- a/src/vid_ht216.c +++ b/src/vid_ht216.c @@ -154,6 +154,9 @@ void ht216_out(uint16_t addr, uint8_t val, void *p) ht216->read_bank_reg[0] = (ht216->read_bank_reg[0] & ~0x10) | ((val & 1) ? 0x10 : 0); ht216->write_bank_reg[0] = (ht216->write_bank_reg[0] & ~0x10) | ((val & 1) ? 0x10 : 0); break; + case 0xfc: + svga->packed_chain4 = val & 0x20; + break; case 0xff: svga->hwcursor.addr = ((ht216->ht_regs[0x94] << 6) | (3 << 14) | ((val & 0x60) << 11)) << 2; //pclog("cursor_addr = %05x\n", svga->hwcursor.addr); @@ -421,6 +424,14 @@ static inline uint8_t extalu(int op, uint8_t input_a, uint8_t input_b) return val; } +/*Remap address for chain-4/doubleword style layout*/ +static inline uint32_t dword_remap(svga_t *svga, uint32_t in_addr) +{ + if (svga->packed_chain4) + return in_addr; + return ((in_addr & 0xfffc) << 2) | ((in_addr & 0x30000) >> 14) | (in_addr & ~0x3ffff); +} + static void ht216_dm_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t cpu_dat_unexpanded) { svga_t *svga = &ht216->svga; @@ -430,10 +441,10 @@ static void ht216_dm_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8 if (!(svga->gdcreg[6] & 1)) svga->fullchange = 2; - if (svga->chain4 || svga->fb_only) + if (svga->chain4) { - writemask2=1<<(addr&3); - addr&=~3; + writemask2 = 1 << (addr & 3); + addr = dword_remap(svga, addr) & ~3; } else if (svga->chain2_write) { @@ -666,9 +677,10 @@ static void ht216_dm_extalu_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat uint8_t input_a = 0, input_b = 0; uint8_t fg, bg; uint8_t output; + uint32_t remapped_addr = dword_remap(svga, addr); if (ht216->ht_regs[0xcd] & HT_REG_CD_RMWMDE) /*RMW*/ - input_b = svga->vram[addr]; + input_b = svga->vram[remapped_addr]; else input_b = ht216->bg_latch[addr & 7]; @@ -695,9 +707,9 @@ static void ht216_dm_extalu_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat bg = extalu(ht216->ht_regs[0xce] & 0xf, input_a, input_b); // svga->vram[addr] output = (fg & rop_select) | (bg & ~rop_select); - svga->vram[addr] = (svga->vram[addr] & ~bit_mask) | (output & bit_mask); + svga->vram[addr] = (svga->vram[remapped_addr] & ~bit_mask) | (output & bit_mask); // pclog(" A=%02x B=%02x R=%02x FG=%02x BG=%02x ops=%02x val=%02x addr=%05x\n", input_a, input_b, rop_select, fg, bg, ht216->ht_regs[0xce], svga->vram[addr], addr); - svga->changedvram[addr >> 12] = changeframecount; + svga->changedvram[remapped_addr >> 12] = changeframecount; } static void ht216_write_common(ht216_t *ht216, uint32_t addr, uint8_t val) @@ -909,7 +921,7 @@ static uint8_t ht216_read_common(ht216_t *ht216, uint32_t addr) egareads++; - if (svga->chain4 || svga->fb_only) + if (svga->chain4) { // if (ht216->ht_regs[0xcd]) // pclog(" addr=%08x decode_mask=%08x vram_max=%08x\n", addr, svga->decode_mask, svga->vram_max); @@ -920,20 +932,20 @@ static uint8_t ht216_read_common(ht216_t *ht216, uint32_t addr) latch_addr = (addr & svga->vram_mask) & ~7; if (ht216->ht_regs[0xcd] & HT_REG_CD_ASTODE) latch_addr += (svga->gdcreg[3] & 7); - ht216->bg_latch[0] = svga->vram[latch_addr]; - ht216->bg_latch[1] = svga->vram[latch_addr + 1]; - ht216->bg_latch[2] = svga->vram[latch_addr + 2]; - ht216->bg_latch[3] = svga->vram[latch_addr + 3]; - ht216->bg_latch[4] = svga->vram[latch_addr + 4]; - ht216->bg_latch[5] = svga->vram[latch_addr + 5]; - ht216->bg_latch[6] = svga->vram[latch_addr + 6]; - ht216->bg_latch[7] = svga->vram[latch_addr + 7]; + ht216->bg_latch[0] = svga->vram[dword_remap(svga, latch_addr)]; + ht216->bg_latch[1] = svga->vram[dword_remap(svga, latch_addr + 1)]; + ht216->bg_latch[2] = svga->vram[dword_remap(svga, latch_addr + 2)]; + ht216->bg_latch[3] = svga->vram[dword_remap(svga, latch_addr + 3)]; + ht216->bg_latch[4] = svga->vram[dword_remap(svga, latch_addr + 4)]; + ht216->bg_latch[5] = svga->vram[dword_remap(svga, latch_addr + 5)]; + ht216->bg_latch[6] = svga->vram[dword_remap(svga, latch_addr + 6)]; + ht216->bg_latch[7] = svga->vram[dword_remap(svga, latch_addr + 7)]; /*pclog(" Read %08x %02x %02x %02x %02x %02x %02x %02x %02x\n", addr, ht216->bg_latch[0],ht216->bg_latch[1],ht216->bg_latch[2],ht216->bg_latch[3], ht216->bg_latch[4],ht216->bg_latch[5],ht216->bg_latch[6],ht216->bg_latch[7]);*/ - return svga->vram[addr & svga->vram_mask]; + return svga->vram[dword_remap(svga, addr) & svga->vram_mask]; } else if (svga->chain2_read) { diff --git a/src/vid_s3.c b/src/vid_s3.c index f56ae34..65adde4 100644 --- a/src/vid_s3.c +++ b/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) diff --git a/src/vid_s3_virge.c b/src/vid_s3_virge.c index 562842d..428669b 100644 --- a/src/vid_s3_virge.c +++ b/src/vid_s3_virge.c @@ -3945,6 +3945,9 @@ static void *s3_virge_init() ddc_init(); + //TODO ViRGE does not use packed chain4 + virge->svga.packed_chain4 = 1; + return virge; } @@ -4044,6 +4047,9 @@ static void *s3_virge_375_init() ddc_init(); + //TODO ViRGE does not use packed chain4 + virge->svga.packed_chain4 = 1; + return virge; } diff --git a/src/vid_svga.c b/src/vid_svga.c index 369173d..c41528c 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -116,7 +116,8 @@ void svga_out(uint16_t addr, uint8_t val, void *p) case 4: svga->chain2_write = !(val & 4); svga->chain4 = val & 8; - svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && svga->chain4; + svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && + ((svga->chain4 && svga->packed_chain4) || svga->fb_only); break; } break; @@ -201,7 +202,8 @@ void svga_out(uint16_t addr, uint8_t val, void *p) case 7: svga->colournocare=val; break; } svga->gdcreg[svga->gdcaddr & 15] = val; - svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && svga->chain4; + svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && + ((svga->chain4 && svga->packed_chain4) || svga->fb_only); if (((svga->gdcaddr & 15) == 5 && (val ^ o) & 0x70) || ((svga->gdcaddr & 15) == 6 && (val ^ o) & 1)) svga_recalctimings(svga); break; @@ -444,6 +446,8 @@ void svga_recalctimings(svga_t *svga) svga->dispontime = TIMER_USEC; if (svga->dispofftime < TIMER_USEC) svga->dispofftime = TIMER_USEC; + + svga_recalc_remap_func(svga); /* printf("SVGA horiz total %i display end %i vidclock %f\n",svga->crtc[0],svga->crtc[1],svga->clock); printf("SVGA vert total %i display end %i max row %i vsync %i\n",svga->vtotal,svga->dispend,(svga->crtc[9]&31)+1,svga->vsyncstart); printf("total %f on %i cycles off %i cycles frame %i sec %i %02X\n",disptime*crtcconst,svga->dispontime,svga->dispofftime,(svga->dispontime+svga->dispofftime)*svga->vtotal,(svga->dispontime+svga->dispofftime)*svga->vtotal*70,svga->seqregs[1]); @@ -816,11 +820,17 @@ void svga_write(uint32_t addr, uint8_t val, void *p) addr += svga->write_bank; if (!(svga->gdcreg[6] & 1)) svga->fullchange=2; - if (svga->chain4 || svga->fb_only) + if ((svga->chain4 && svga->packed_chain4) || svga->fb_only) { writemask2=1<<(addr&3); addr&=~3; } + else if (svga->chain4) + { + writemask2 = 1 << (addr & 3); + addr &= ~3; + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_write) { writemask2 &= ~0xa; @@ -1007,7 +1017,7 @@ uint8_t svga_read(uint32_t addr, void *p) // 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); - if (svga->chain4 || svga->fb_only) + if ((svga->chain4 && svga->packed_chain4) || svga->fb_only) { addr &= svga->decode_mask; if (addr >= svga->vram_max) @@ -1019,6 +1029,11 @@ uint8_t svga_read(uint32_t addr, void *p) svga->ld = svga->vram[latch_addr | 0x3]; return svga->vram[addr & svga->vram_mask]; } + else if (svga->chain4) + { + readplane = addr & 3; + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_read) { readplane = (readplane & 2) | (addr & 1); @@ -1082,11 +1097,16 @@ void svga_write_linear(uint32_t addr, uint8_t val, void *p) if (svga_output) pclog("Write LFB %08X %02X ", addr, val); if (!(svga->gdcreg[6] & 1)) svga->fullchange = 2; - if (svga->chain4 || svga->fb_only) + if ((svga->chain4 && svga->packed_chain4) || svga->fb_only) { writemask2=1<<(addr&3); addr&=~3; } + else if (svga->chain4) + { + writemask2 = 1 << (addr & 3); + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_write) { writemask2 &= ~0xa; @@ -1262,13 +1282,18 @@ uint8_t svga_read_linear(uint32_t addr, void *p) egareads++; - if (svga->chain4 || svga->fb_only) + if ((svga->chain4 && svga->packed_chain4) || svga->fb_only) { addr &= svga->decode_mask; if (addr >= svga->vram_max) return 0xff; return svga->vram[addr & svga->vram_mask]; } + else if (svga->chain4) + { + readplane = addr & 3; + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_read) { readplane = (readplane & 2) | (addr & 1); @@ -1276,7 +1301,9 @@ uint8_t svga_read_linear(uint32_t addr, void *p) addr <<= 2; } else + { addr<<=2; + } addr &= svga->decode_mask; diff --git a/src/vid_svga.h b/src/vid_svga.h index 9e49bfd..f8fb48b 100644 --- a/src/vid_svga.h +++ b/src/vid_svga.h @@ -148,6 +148,16 @@ typedef struct svga_t /*Used to implement CRTC[0x17] bit 2 hsync divisor*/ int hsync_divisor; + + /*Tseng-style chain4 mode - CRTC dword mode is the same as byte mode, chain4 + addresses are shifted to match*/ + int packed_chain4; + + /*Force CRTC to dword mode, regardless of CR14/CR17. Required for S3 enhanced mode*/ + int force_dword_mode; + + int remap_required; + uint32_t (*remap_func)(struct svga_t *svga, uint32_t in_addr); } svga_t; extern int svga_init(svga_t *svga, void *p, int memsize, diff --git a/src/vid_svga_render.c b/src/vid_svga_render.c index eac363f..f07892b 100644 --- a/src/vid_svga_render.c +++ b/src/vid_svga_render.c @@ -3,6 +3,7 @@ #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" +#include "vid_svga_render_remap.h" void svga_render_null(svga_t *svga) { @@ -58,9 +59,12 @@ void svga_render_text_40(svga_t *svga) for (x = 0; x < svga->hdisp; x += xinc) { + uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; + drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); - chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + chr = svga->vram[addr]; + attr = svga->vram[addr+1]; + if (attr & 8) charaddr = svga->charsetb + (chr * 128); else charaddr = svga->charseta + (chr * 128); @@ -122,9 +126,12 @@ void svga_render_text_80(svga_t *svga) for (x = 0; x < svga->hdisp; x += xinc) { + uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; + drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); - chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + chr = svga->vram[addr]; + attr = svga->vram[addr+1]; + if (attr & 8) charaddr = svga->charsetb + (chr * 128); else charaddr = svga->charseta + (chr * 128); @@ -186,10 +193,12 @@ void svga_render_text_80_ksc5601(svga_t *svga) for (x = 0; x < svga->hdisp; x += xinc) { + uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; + drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); - chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; - nextchr = svga->vram[((svga->ma + 4) << 1) & svga->vram_display_mask]; - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + chr = svga->vram[addr]; + nextchr = svga->vram[addr + 8]; + attr = svga->vram[addr + 1]; if (drawcursor) { @@ -304,11 +313,9 @@ void svga_render_text_80_ksc5601(svga_t *svga) void svga_render_2bpp_lowres(svga_t *svga) { - int changed_offset; - - changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; + uint32_t changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = ((8 - svga->scrollcache) << 1) + 16; @@ -320,10 +327,11 @@ void svga_render_2bpp_lowres(svga_t *svga) for (x = 0; x <= svga->hdisp; x += 16) { + uint32_t addr = svga->remap_func(svga, svga->ma); uint8_t dat[2]; - dat[0] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000]; - dat[1] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000 + 1]; + dat[0] = svga->vram[addr]; + dat[1] = svga->vram[addr + 1]; svga->ma += 4; svga->ma &= svga->vram_display_mask; @@ -343,11 +351,9 @@ void svga_render_2bpp_lowres(svga_t *svga) void svga_render_2bpp_highres(svga_t *svga) { - int changed_offset; - - changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; - - if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = (8 - svga->scrollcache) + 24; @@ -359,30 +365,31 @@ void svga_render_2bpp_highres(svga_t *svga) for (x = 0; x <= svga->hdisp; x += 8) { + uint32_t addr = svga->remap_func(svga, svga->ma); uint8_t dat[2]; - dat[0] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000]; - dat[1] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000 + 1]; + dat[0] = svga->vram[addr]; + dat[1] = svga->vram[addr + 1]; svga->ma += 4; svga->ma &= svga->vram_display_mask; - p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; - p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; - p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; - p[3] = svga->pallook[svga->egapal[dat[0] & 3]]; - p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; - p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; - p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; - p[7] = svga->pallook[svga->egapal[dat[1] & 3]]; - - p += 8; + *p++ = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; + *p++ = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; + *p++ = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; + *p++ = svga->pallook[svga->egapal[dat[0] & 3]]; + *p++ = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; + *p++ = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; + *p++ = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; + *p++ = svga->pallook[svga->egapal[dat[1] & 3]]; } } } void svga_render_4bpp_lowres(svga_t *svga) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = ((8 - svga->scrollcache) << 1) + 16; @@ -396,8 +403,9 @@ void svga_render_4bpp_lowres(svga_t *svga) { uint8_t edat[4]; uint8_t dat; + uint32_t addr = svga->remap_func(svga, svga->ma); - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma]); + *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]); svga->ma += 4; svga->ma &= svga->vram_display_mask; @@ -421,11 +429,9 @@ void svga_render_4bpp_lowres(svga_t *svga) void svga_render_4bpp_highres(svga_t *svga) { - int changed_offset; - - changed_offset = (svga->ma + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; - - if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = (8 - svga->scrollcache) + 24; @@ -439,32 +445,33 @@ void svga_render_4bpp_highres(svga_t *svga) { uint8_t edat[4]; uint8_t dat; + uint32_t addr = svga->remap_func(svga, svga->ma); - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma | ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000]); + *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]); svga->ma += 4; svga->ma &= svga->vram_display_mask; 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[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + *p++ = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + *p++ = svga->pallook[svga->egapal[dat & svga->plane_mask]]; dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + *p++ = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + *p++ = svga->pallook[svga->egapal[dat & svga->plane_mask]]; dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + *p++ = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + *p++ = svga->pallook[svga->egapal[dat & svga->plane_mask]]; dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - - p += 8; + *p++ = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + *p++ = svga->pallook[svga->egapal[dat & svga->plane_mask]]; } } } void svga_render_8bpp_lowres(svga_t *svga) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = (8 - (svga->scrollcache & 6)) + 24; @@ -474,17 +481,36 @@ void svga_render_8bpp_lowres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 8) + if (!svga->remap_required) { - uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - - p[0] = p[1] = svga->pallook[dat & 0xff]; - p[2] = p[3] = svga->pallook[(dat >> 8) & 0xff]; - p[4] = p[5] = svga->pallook[(dat >> 16) & 0xff]; - p[6] = p[7] = svga->pallook[(dat >> 24) & 0xff]; - - svga->ma += 4; - p += 8; + for (x = 0; x <= svga->hdisp; x += 8) + { + uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + + p[0] = p[1] = svga->pallook[dat & 0xff]; + p[2] = p[3] = svga->pallook[(dat >> 8) & 0xff]; + p[4] = p[5] = svga->pallook[(dat >> 16) & 0xff]; + p[6] = p[7] = svga->pallook[(dat >> 24) & 0xff]; + + svga->ma += 4; + p += 8; + } + } + else + { + for (x = 0; x <= svga->hdisp; x += 8) + { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + + p[0] = p[1] = svga->pallook[dat & 0xff]; + p[2] = p[3] = svga->pallook[(dat >> 8) & 0xff]; + p[4] = p[5] = svga->pallook[(dat >> 16) & 0xff]; + p[6] = p[7] = svga->pallook[(dat >> 24) & 0xff]; + + svga->ma += 4; + p += 8; + } } svga->ma &= svga->vram_display_mask; } @@ -492,41 +518,62 @@ void svga_render_8bpp_lowres(svga_t *svga) void svga_render_8bpp_highres(svga_t *svga) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - if (svga->firstline_draw == 2000) + if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 8) + if (!svga->remap_required) { - uint32_t dat; - dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - 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]; + for (x = 0; x <= svga->hdisp; x += 8) + { + uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + *p++ = svga->pallook[dat & 0xff]; + *p++ = svga->pallook[(dat >> 8) & 0xff]; + *p++ = svga->pallook[(dat >> 16) & 0xff]; + *p++ = svga->pallook[(dat >> 24) & 0xff]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); - 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; - p += 8; + dat = *(uint32_t *)(&svga->vram[(svga->ma+4) & svga->vram_display_mask]); + *p++ = svga->pallook[dat & 0xff]; + *p++ = svga->pallook[(dat >> 8) & 0xff]; + *p++ = svga->pallook[(dat >> 16) & 0xff]; + *p++ = svga->pallook[(dat >> 24) & 0xff]; + + svga->ma += 8; + } } + else + { + for (x = 0; x <= svga->hdisp; x += 4) + { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + + svga->ma += 4; + + *p++ = svga->pallook[dat & 0xff]; + *p++ = svga->pallook[(dat >> 8) & 0xff]; + *p++ = svga->pallook[(dat >> 16) & 0xff]; + *p++ = svga->pallook[(dat >> 24) & 0xff]; + } + } + svga->ma &= svga->vram_display_mask; } } void svga_render_15bpp_lowres(svga_t *svga) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = (8 - (svga->scrollcache & 6)) + 24; @@ -536,26 +583,44 @@ void svga_render_15bpp_lowres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 4) + if (!svga->remap_required) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + for (x = 0; x <= svga->hdisp; x += 4) + { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = video_15to32[dat & 0xffff]; - p[x + 1] = video_15to32[dat >> 16]; + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x] = video_15to32[dat & 0xffff]; - p[x + 1] = video_15to32[dat >> 16]; + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + } + svga->ma += x << 1; + } + else + { + for (x = 0; x <= svga->hdisp; x += 2) + { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + + svga->ma += 4; + } } - svga->ma += x << 1; svga->ma &= svga->vram_display_mask; } } void svga_render_15bpp_highres(svga_t *svga) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; @@ -565,32 +630,51 @@ void svga_render_15bpp_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 8) + if (!svga->remap_required) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = video_15to32[dat & 0xffff]; - p[x + 1] = video_15to32[dat >> 16]; + for (x = 0; x <= svga->hdisp; x += 8) + { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = video_15to32[dat & 0xffff]; - p[x + 3] = video_15to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = video_15to32[dat & 0xffff]; - p[x + 5] = video_15to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - p[x + 6] = video_15to32[dat & 0xffff]; - p[x + 7] = video_15to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + } + + svga->ma += x << 1; + } + else + { + for (x = 0; x <= svga->hdisp; x += 2) + { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + + svga->ma += 4; + } } - svga->ma += x << 1; svga->ma &= svga->vram_display_mask; } } void svga_render_16bpp_lowres(svga_t *svga) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = (8 - (svga->scrollcache & 6)) + 24; @@ -600,26 +684,45 @@ void svga_render_16bpp_lowres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 4) + if (!svga->remap_required) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + for (x = 0; x <= svga->hdisp; x += 4) + { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = video_16to32[dat & 0xffff]; - p[x + 1] = video_16to32[dat >> 16]; + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x] = video_16to32[dat & 0xffff]; - p[x + 1] = video_16to32[dat >> 16]; + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + } + svga->ma += x << 1; } - svga->ma += x << 1; + else + { + for (x = 0; x <= svga->hdisp; x += 2) + { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + + svga->ma += 4; + } + } + svga->ma += x << 1; svga->ma &= svga->vram_display_mask; } } void svga_render_16bpp_highres(svga_t *svga) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; @@ -629,55 +732,106 @@ void svga_render_16bpp_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 8) + if (!svga->remap_required) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = video_16to32[dat & 0xffff]; - p[x + 1] = video_16to32[dat >> 16]; - - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = video_16to32[dat & 0xffff]; - p[x + 3] = video_16to32[dat >> 16]; + for (x = 0; x <= svga->hdisp; x += 8) + { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = video_16to32[dat & 0xffff]; - p[x + 5] = video_16to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - p[x + 6] = video_16to32[dat & 0xffff]; - p[x + 7] = video_16to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + } + + svga->ma += x << 1; + } + else + { + for (x = 0; x <= svga->hdisp; x += 2) + { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + + svga->ma += 4; + } } - svga->ma += x << 1; svga->ma &= svga->vram_display_mask; } } void svga_render_24bpp_lowres(svga_t *svga) { - int x, offset; - uint32_t fg; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + int x; + int offset = (8 - (svga->scrollcache & 6)) + 24; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; + if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - offset = (8 - (svga->scrollcache & 6)) + 24; - - for (x = 0; x <= svga->hdisp; x++) + if (!svga->remap_required) { - fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); - svga->ma += 3; - 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; + for (x = 0; x <= svga->hdisp; x++) + { + uint32_t dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + uint32_t dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + uint32_t dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); + + p[0] = p[1] = dat0 & 0xffffff; + p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8); + p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16); + p[6] = p[7] = dat2 >> 8; + + svga->ma += 12; + } + } + else + { + for (x = 0; x <= svga->hdisp; x += 4) + { + uint32_t dat0, dat1, dat2; + uint32_t addr; + + addr = svga->remap_func(svga, svga->ma); + dat0 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + addr = svga->remap_func(svga, svga->ma + 4); + dat1 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + addr = svga->remap_func(svga, svga->ma + 8); + dat2 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + + p[0] = p[1] = dat0 & 0xffffff; + p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8); + p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16); + p[6] = p[7] = dat2 >> 8; + + svga->ma += 12; + } } } } void svga_render_24bpp_highres(svga_t *svga) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; @@ -687,21 +841,43 @@ void svga_render_24bpp_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 4) + if (!svga->remap_required) { - uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - p[x] = dat & 0xffffff; - - dat = *(uint32_t *)(&svga->vram[(svga->ma + 3) & svga->vram_display_mask]); - p[x + 1] = dat & 0xffffff; - - dat = *(uint32_t *)(&svga->vram[(svga->ma + 6) & svga->vram_display_mask]); - p[x + 2] = dat & 0xffffff; - - dat = *(uint32_t *)(&svga->vram[(svga->ma + 9) & svga->vram_display_mask]); - p[x + 3] = dat & 0xffffff; - - svga->ma += 12; + for (x = 0; x <= svga->hdisp; x += 4) + { + uint32_t dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + uint32_t dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + uint32_t dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); + + *p++ = dat0 & 0xffffff; + *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8); + *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16); + *p++ = dat2 >> 8; + + svga->ma += 12; + } + } + else + { + for (x = 0; x <= svga->hdisp; x += 4) + { + uint32_t dat0, dat1, dat2; + uint32_t addr; + + addr = svga->remap_func(svga, svga->ma); + dat0 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + addr = svga->remap_func(svga, svga->ma + 4); + dat1 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + addr = svga->remap_func(svga, svga->ma + 8); + dat2 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + + *p++ = dat0 & 0xffffff; + *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8); + *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16); + *p++ = dat2 >> 8; + + svga->ma += 12; + } } svga->ma &= svga->vram_display_mask; } @@ -709,24 +885,40 @@ void svga_render_24bpp_highres(svga_t *svga) void svga_render_32bpp_lowres(svga_t *svga) { - int x, offset; - uint32_t fg; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + int x; + int offset = (8 - (svga->scrollcache & 6)) + 24; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; + if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - offset = (8 - (svga->scrollcache & 6)) + 24; - - for (x = 0; x <= svga->hdisp; x++) + if (!svga->remap_required) { - fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); - svga->ma += 4; - 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; + for (x = 0; x <= svga->hdisp; x++) + { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + *p++ = dat & 0xffffff; + *p++ = dat & 0xffffff; + } + svga->ma += x*4; } + else + { + for (x = 0; x <= svga->hdisp; x++) + { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr]); + *p++ = dat & 0xffffff; + *p++ = dat & 0xffffff; + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; } } @@ -734,7 +926,9 @@ void svga_render_32bpp_lowres(svga_t *svga) 91%*/ void svga_render_32bpp_highres(svga_t *svga) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; @@ -744,56 +938,102 @@ void svga_render_32bpp_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x++) + if (!svga->remap_required) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - p[x] = dat & 0xffffff; + for (x = 0; x <= svga->hdisp; x++) + { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + *p++ = dat & 0xffffff; + } + svga->ma += x*4; } - svga->ma += 4; + else + { + for (x = 0; x <= svga->hdisp; x++) + { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + *p++ = dat & 0xffffff; + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; } } void svga_render_ABGR8888_highres(svga_t *svga) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - - if (svga->firstline_draw == 2000) + + if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x++) + if (!svga->remap_required) { - 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); + for (x = 0; x <= svga->hdisp; x++) + { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + *p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + } + svga->ma += x*4; } - svga->ma += 4; + else + { + for (x = 0; x <= svga->hdisp; x++) + { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + *p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; } } void svga_render_RGBA8888_highres(svga_t *svga) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - - if (svga->firstline_draw == 2000) + + if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x++) + if (!svga->remap_required) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - p[x] = dat >> 8; + for (x = 0; x <= svga->hdisp; x++) + { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + *p++ = dat >> 8; + } + svga->ma += x*4; } - svga->ma += 4; + else + { + for (x = 0; x <= svga->hdisp; x++) + { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + *p++ = dat >> 8; + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; } } diff --git a/src/vid_svga_render.h b/src/vid_svga_render.h index 625ba6b..bb3b3c1 100644 --- a/src/vid_svga_render.h +++ b/src/vid_svga_render.h @@ -9,6 +9,8 @@ extern int scrollcache; extern uint8_t edatlookup[4][4]; +void svga_recalc_remap_func(svga_t *svga); + void svga_render_null(svga_t *svga); void svga_render_blank(svga_t *svga); void svga_render_text_40(svga_t *svga); diff --git a/src/vid_svga_render_remap.h b/src/vid_svga_render_remap.h new file mode 100644 index 0000000..189f846 --- /dev/null +++ b/src/vid_svga_render_remap.h @@ -0,0 +1,129 @@ +/*Variables : + byte/word/doubleword mode + word has MA13/MA15->MA0 + ET4000 treats doubleword as byte + row 0 -> MA13 + row 1 -> MA14 +*/ + +//S3 - enhanced mode mappings CR31.3 can force doubleword mode +//Cirrus Logic handles SVGA writes seperately +//S3, CL, TGUI blitters need checking + +//CL, S3, Mach64, ET4000, Banshee, TGUI all okay +//Still to check - ViRGE, HT216 +#define VAR_BYTE_MODE (0 << 0) +#define VAR_WORD_MODE_MA13 (1 << 0) +#define VAR_WORD_MODE_MA15 (2 << 0) +#define VAR_DWORD_MODE (3 << 0) +#define VAR_MODE_MASK (3 << 0) +#define VAR_ROW0_MA13 (1 << 2) +#define VAR_ROW1_MA14 (1 << 3) + +#define ADDRESS_REMAP_FUNC(nr) \ + static uint32_t address_remap_func_ ## nr(svga_t *svga, uint32_t in_addr) \ + { \ + uint32_t out_addr; \ + \ + switch (nr & VAR_MODE_MASK) \ + { \ + case VAR_BYTE_MODE: \ + out_addr = in_addr; \ + break; \ + \ + case VAR_WORD_MODE_MA13: \ + out_addr = ((in_addr << 1) & 0x1fff8) | \ + ((in_addr >> 13) & 0x4) | \ + (in_addr & ~0x1ffff); \ + break; \ + \ + case VAR_WORD_MODE_MA15: \ + out_addr = ((in_addr << 1) & 0x1fff8) | \ + ((in_addr >> 15) & 0x4) | \ + (in_addr & ~0x1ffff); \ + break; \ + \ + case VAR_DWORD_MODE: \ + out_addr = ((in_addr << 2) & 0x3fff0) | \ + ((in_addr >> 14) & 0xc) | \ + (in_addr & ~0x3ffff); \ + break; \ + } \ + \ + if (nr & VAR_ROW0_MA13) \ + out_addr = (out_addr & ~(1 << (13+2))) | \ + ((svga->sc & 1) ? (1 << (13+2)) : 0); \ + if (nr & VAR_ROW1_MA14) \ + out_addr = (out_addr & ~(1 << (14+2))) | \ + ((svga->sc & 2) ? (1 << (14+2)) : 0); \ + \ + return out_addr; \ + } + +ADDRESS_REMAP_FUNC(0) +ADDRESS_REMAP_FUNC(1) +ADDRESS_REMAP_FUNC(2) +ADDRESS_REMAP_FUNC(3) +ADDRESS_REMAP_FUNC(4) +ADDRESS_REMAP_FUNC(5) +ADDRESS_REMAP_FUNC(6) +ADDRESS_REMAP_FUNC(7) +ADDRESS_REMAP_FUNC(8) +ADDRESS_REMAP_FUNC(9) +ADDRESS_REMAP_FUNC(10) +ADDRESS_REMAP_FUNC(11) +ADDRESS_REMAP_FUNC(12) +ADDRESS_REMAP_FUNC(13) +ADDRESS_REMAP_FUNC(14) +ADDRESS_REMAP_FUNC(15) + +static uint32_t (*address_remap_funcs[16])(svga_t *svga, uint32_t in_addr) = +{ + address_remap_func_0, + address_remap_func_1, + address_remap_func_2, + address_remap_func_3, + address_remap_func_4, + address_remap_func_5, + address_remap_func_6, + address_remap_func_7, + address_remap_func_8, + address_remap_func_9, + address_remap_func_10, + address_remap_func_11, + address_remap_func_12, + address_remap_func_13, + address_remap_func_14, + address_remap_func_15 +}; + +void svga_recalc_remap_func(svga_t *svga) +{ + int func_nr; + + if (svga->fb_only) + func_nr = 0; + else + { + if (svga->force_dword_mode) + func_nr = VAR_DWORD_MODE; + else if (svga->crtc[0x14] & (1 << 6)) + func_nr = svga->packed_chain4 ? VAR_BYTE_MODE : VAR_DWORD_MODE; + else if (svga->crtc[0x17] & (1 << 6)) + func_nr = VAR_BYTE_MODE; + else if (svga->crtc[0x17] & (1 << 5)) + func_nr = VAR_WORD_MODE_MA15; + else + func_nr = VAR_WORD_MODE_MA13; + + if (!(svga->crtc[0x17] & (1 << 0))) + func_nr |= VAR_ROW0_MA13; + if (!(svga->crtc[0x17] & (1 << 1))) + func_nr |= VAR_ROW1_MA14; + } + +// pclog("svga_recalc_remap_func: fb_only=%i chain4=%i packed_chain4=%i crtc[14]=%02x crtc[17]=%02x func_nr=%i\n", +// svga->fb_only, svga->chain4, svga->packed_chain4, svga->crtc[0x14], svga->crtc[0x17], func_nr); + svga->remap_required = (func_nr != 0); + svga->remap_func = address_remap_funcs[func_nr]; +} diff --git a/src/vid_tgui9440.c b/src/vid_tgui9440.c index 2edf8c7..a42f7e9 100644 --- a/src/vid_tgui9440.c +++ b/src/vid_tgui9440.c @@ -631,17 +631,34 @@ void tgui_recalcmapping(tgui_t *tgui) } } +/*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); +} + void tgui_hwcursor_draw(svga_t *svga, int displine) { uint32_t dat[2]; int xx; int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + uint32_t remapped_addr; if (svga->interlace && svga->hwcursor_oddeven) svga->hwcursor_latch.addr += 8; - dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 24) | (svga->vram[svga->hwcursor_latch.addr + 1] << 16) | (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3]; - dat[1] = (svga->vram[svga->hwcursor_latch.addr + 4] << 24) | (svga->vram[svga->hwcursor_latch.addr + 5] << 16) | (svga->vram[svga->hwcursor_latch.addr + 6] << 8) | svga->vram[svga->hwcursor_latch.addr + 7]; + remapped_addr = dword_remap(svga->hwcursor_latch.addr); + dat[0] = (svga->vram[remapped_addr] << 24) | (svga->vram[remapped_addr + 1] << 16) | (svga->vram[remapped_addr + 2] << 8) | svga->vram[remapped_addr + 3]; + remapped_addr = dword_remap(svga->hwcursor_latch.addr+4); + dat[1] = (svga->vram[remapped_addr] << 24) | (svga->vram[remapped_addr + 1] << 16) | (svga->vram[remapped_addr + 2] << 8) | svga->vram[remapped_addr + 3]; for (xx = 0; xx < 32; xx++) { if (offset >= svga->hwcursor_latch.x) @@ -840,8 +857,13 @@ static uint8_t tgui_ext_linear_read(uint32_t addr, void *p) return 0xff; addr &= ~0xf; + addr = dword_remap(addr); + for (c = 0; c < 16; c++) - tgui->copy_latch[c] = svga->vram[addr+c]; + { + tgui->copy_latch[c] = svga->vram[addr]; + addr += ((c & 3) == 3) ? 13 : 1; + } return svga->vram[addr & svga->vram_mask]; } @@ -871,7 +893,9 @@ static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p) if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - addr &= ~0x7; + addr &= (tgui->ext_gdc_regs[0] & 8) ? ~0xf : ~0x7; + + addr = dword_remap(addr); svga->changedvram[addr >> 12] = changeframecount; switch (tgui->ext_gdc_regs[0] & 0xf) @@ -882,7 +906,7 @@ static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p) { if (mask & (1 << c)) *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0]; - addr++; + addr += (c == 4) ? 13 : 1; } break; @@ -892,7 +916,7 @@ static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p) { if (mask & (1 << c)) *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1]; - addr++; + addr += (c == 4) ? 13 : 1; } break; @@ -902,7 +926,7 @@ static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p) { if ((val & mask) & (1 << c)) *(uint8_t *)&svga->vram[addr] = fg[0]; - addr++; + addr += (c == 4) ? 13 : 1; } break; @@ -912,15 +936,17 @@ static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p) { if ((val & mask) & (1 << c)) *(uint8_t *)&svga->vram[addr] = fg[(c & 1) ^ 1]; - addr++; + addr += (c == 4) ? 13 : 1; } break; case 0x8: case 0x9: case 0xa: case 0xb: case 0xc: case 0xd: case 0xe: case 0xf: - addr &= ~0xf; for (c = 0; c < 16; c++) - *(uint8_t *)&svga->vram[addr+c] = tgui->copy_latch[c]; + { + *(uint8_t *)&svga->vram[addr] = tgui->copy_latch[c]; + addr += ((c & 3) == 3) ? 13 : 1; + } break; } } @@ -942,6 +968,8 @@ static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p) return; addr &= svga->vram_mask; addr &= ~0xf; + + addr = dword_remap(addr); svga->changedvram[addr >> 12] = changeframecount; val = (val >> 8) | (val << 8); @@ -954,7 +982,7 @@ static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p) { if (mask & (1 << c)) *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0]; - addr++; + addr += (c & 3) ? 1 : 13; } break; @@ -964,7 +992,7 @@ static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p) { if (mask & (1 << c)) *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1]; - addr++; + addr += (c & 3) ? 1 : 13; } break; @@ -974,7 +1002,7 @@ static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p) { if ((val & mask) & (1 << c)) *(uint8_t *)&svga->vram[addr] = fg[0]; - addr++; + addr += (c & 3) ? 1 : 13; } break; @@ -984,14 +1012,17 @@ static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p) { if ((val & mask) & (1 << c)) *(uint8_t *)&svga->vram[addr] = fg[(c & 1) ^ 1]; - addr++; + addr += (c & 3) ? 1 : 13; } break; case 0x8: case 0x9: case 0xa: case 0xb: case 0xc: case 0xd: case 0xe: case 0xf: for (c = 0; c < 16; c++) - *(uint8_t *)&svga->vram[addr+c] = tgui->copy_latch[c]; + { + *(uint8_t *)&svga->vram[addr] = tgui->copy_latch[c]; + addr += ((c & 3) == 3) ? 13 : 1; + } break; } } @@ -1044,8 +1075,8 @@ enum TGUI_SOLIDFILL = 0x4000 /*Pattern all zero?*/ }; -#define READ(addr, dat) if (tgui->accel.bpp == 0) dat = svga->vram[addr & 0x1fffff]; \ - else dat = vram_w[addr & 0xfffff]; +#define READ(addr, dat) if (tgui->accel.bpp == 0) dat = svga->vram[dword_remap(addr) & 0x1fffff]; \ + else dat = vram_w[dword_remap_w(addr) & 0xfffff]; #define MIX() do \ { \ @@ -1061,13 +1092,13 @@ enum #define WRITE(addr, dat) if (tgui->accel.bpp == 0) \ { \ - svga->vram[addr & 0x1fffff] = dat; \ - svga->changedvram[((addr) & 0x1fffff) >> 12] = changeframecount; \ + svga->vram[dword_remap(addr) & 0x1fffff] = dat; \ + svga->changedvram[(dword_remap(addr) & 0x1fffff) >> 12] = changeframecount; \ } \ else \ { \ - vram_w[addr & 0xfffff] = dat; \ - svga->changedvram[((addr) & 0xfffff) >> 11] = changeframecount; \ + vram_w[dword_remap_w(addr) & 0xfffff] = dat; \ + svga->changedvram[(dword_remap_w(addr) & 0xfffff) >> 11] = changeframecount; \ } void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)