diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 1e8cc2b91..1502fba2d 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -158,7 +158,8 @@ typedef struct svga_t /*Force CRTC to dword mode, regardless of CR14/CR17. Required for S3 enhanced mode*/ int force_dword_mode; - int force_byte_mode; + + int force_old_addr; int remap_required; uint32_t (*remap_func)(struct svga_t *svga, uint32_t in_addr); diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index e77817782..e8826f4e4 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -404,9 +404,9 @@ static void s3_pci_write(int func, int addr, uint8_t val, void *p); static __inline uint32_t dword_remap(svga_t *svga, uint32_t in_addr) { - if (svga->packed_chain4) + if (svga->packed_chain4 || svga->force_old_addr) return in_addr; - + return ((in_addr << 2) & 0x3fff0) | ((in_addr >> 14) & 0xc) | (in_addr & ~0x3fffc); @@ -414,9 +414,9 @@ dword_remap(svga_t *svga, uint32_t in_addr) static __inline uint32_t dword_remap_w(svga_t *svga, uint32_t in_addr) { - if (svga->packed_chain4) - return in_addr; - + if (svga->packed_chain4 || svga->force_old_addr) + return in_addr; + return ((in_addr << 2) & 0x1fff8) | ((in_addr >> 14) & 0x6) | (in_addr & ~0x1fffe); @@ -424,9 +424,9 @@ dword_remap_w(svga_t *svga, uint32_t in_addr) static __inline uint32_t dword_remap_l(svga_t *svga, uint32_t in_addr) { - if (svga->packed_chain4) - return in_addr; - + if (svga->packed_chain4 || svga->force_old_addr) + return in_addr; + return ((in_addr << 2) & 0xfffc) | ((in_addr >> 14) & 0x3) | (in_addr & ~0xffff); @@ -2552,6 +2552,7 @@ 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: if ((svga->crtc[0x31] & 0x30) && (svga->crtc[0x51] & 0x01) && (val & 0x40)) @@ -2971,7 +2972,6 @@ static void s3_recalctimings(svga_t *svga) } if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { - svga->fb_only = 1; switch (svga->bpp) { case 8: svga->render = svga_render_8bpp_highres; @@ -3154,7 +3154,6 @@ static void s3_recalctimings(svga_t *svga) break; } } else { - svga->fb_only = 0; if (!svga->scrblank && svga->attr_palette_enable) { if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { if ((svga->crtc[0x31] & 0x08) && ((svga->gdcreg[5] & 0x60) == 0x00)) { @@ -3208,7 +3207,6 @@ static void s3_trio64v_recalctimings(svga_t *svga) svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)); if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { - svga->fb_only = 1; switch (svga->bpp) { case 8: svga->render = svga_render_8bpp_highres; @@ -3229,13 +3227,10 @@ static void s3_trio64v_recalctimings(svga_t *svga) svga->render = svga_render_32bpp_highres; break; } - } else - svga->fb_only = 0; + } } else /*Streams mode*/ { - svga->fb_only = 1; - if (s3->streams.buffer_ctrl & 1) svga->ma_latch = s3->streams.pri_fb1 >> 2; else @@ -3379,7 +3374,12 @@ s3_updatemapping(s3_t *s3) mem_mapping_set_addr(&s3->linear_mapping, s3->linear_base, s3->linear_size); } + if (s3->chip >= S3_TRIO64V) + svga->fb_only = 1; } else { + if (s3->chip >= S3_TRIO64V) + svga->fb_only = 0; + mem_mapping_disable(&s3->linear_mapping); } @@ -7140,6 +7140,8 @@ static void *s3_init(const device_t *info) s3->card_type = info->local; + svga->force_old_addr = 1; + switch(s3->card_type) { case S3_ORCHID_86C911: case S3_DIAMOND_STEALTH_VRAM: @@ -7401,8 +7403,6 @@ static void *s3_init(const device_t *info) return NULL; } - svga->packed_chain4 = 1; - if (s3->pci) s3->card = pci_add_card(PCI_ADD_VIDEO, s3_pci_read, s3_pci_write, s3); @@ -7609,73 +7609,124 @@ static void s3_force_redraw(void *p) s3->svga.fullchange = changeframecount; } -// clang-format off -static const device_config_t s3_orchid_86c911_config[] = { - { - "memory", "Memory size", CONFIG_SELECTION, "", 1, "", { 0 }, - { - { "512 KB", 0 }, - { "1 MB", 1 }, - { "" } - } - }, - { "", "", -1 } +static const device_config_t s3_orchid_86c911_config[] = +{ + { + "memory", "Memory size", CONFIG_SELECTION, "", 1, "", { 0 }, + { + { + "512 KB", 0 + }, + { + "1 MB", 1 + }, + { + "" + } + } + }, + { + "", "", -1 + } }; -static const device_config_t s3_9fx_config[] = { - { - "memory", "Memory size", CONFIG_SELECTION, "", 2, "", { 0 }, - { - { "1 MB", 1 }, - { "2 MB", 2 }, - /*Trio64 also supports 4 MB, however the Number Nine BIOS does not*/ - { "" } - } - }, - { "", "", -1 } +static const device_config_t s3_9fx_config[] = +{ + { + "memory", "Memory size", CONFIG_SELECTION, "", 2, "", { 0 }, + { + { + "1 MB", 1 + }, + { + "2 MB", 2 + }, + /*Trio64 also supports 4 MB, however the Number Nine BIOS does not*/ + { + "" + } + } + }, + { + "", "", -1 + } }; -static const device_config_t s3_phoenix_trio32_config[] = { - { - "memory", "Memory size", CONFIG_SELECTION, "", 2, "", { 0 }, - { - { "512 KB", 0 }, - { "1 MB", 1 }, - { "2 MB", 2 }, - { "" } - } - }, - { "", "", -1 } +static const device_config_t s3_phoenix_trio32_config[] = +{ + { + "memory", "Memory size", CONFIG_SELECTION, "", 2, "", { 0 }, + { + { + "512 KB", 0 + }, + { + "1 MB", 1 + }, + { + "2 MB", 2 + }, + { + "" + } + } + }, + { + "", "", -1 + } }; -static const device_config_t s3_standard_config[] = { - { - "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, - { - { "1 MB", 1 }, - { "2 MB", 2 }, - { "4 MB", 4 }, - { "" } - } - }, - { "", "", -1 } +static const device_config_t s3_standard_config[] = +{ + { + "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, + { + { + "1 MB", 1 + }, + { + "2 MB", 2 + }, + { + "4 MB", 4 + }, + { + "" + } + } + }, + { + "", "", -1 + } }; -static const device_config_t s3_968_config[] = { - { - "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, - { - { "1 MB", 1 }, - { "2 MB", 2 }, - { "4 MB", 4 }, - { "8 MB", 8 }, - { "" } - } - }, - { "", "", -1 } +static const device_config_t s3_968_config[] = +{ + { + "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, + { + { + "1 MB", 1 + }, + { + "2 MB", 2 + }, + { + "4 MB", 4 + }, + { + "8 MB", 8 + }, + { + "" + } + } + }, + { + "", "", -1 + } }; -// clang-format on const device_t s3_orchid_86c911_isa_device = { @@ -8333,7 +8384,7 @@ const device_t s3_elsa_winner2000_pro_x_964_pci_device = S3_ELSAWIN2KPROX_964, s3_init, s3_close, - s3_reset, + s3_reset, { s3_elsa_winner2000_pro_x_964_available }, s3_speed_changed, s3_force_redraw, @@ -8348,7 +8399,7 @@ const device_t s3_elsa_winner2000_pro_x_pci_device = S3_ELSAWIN2KPROX, s3_init, s3_close, - s3_reset, + s3_reset, { s3_elsa_winner2000_pro_x_available }, s3_speed_changed, s3_force_redraw, @@ -8363,7 +8414,7 @@ const device_t s3_trio64v2_dx_pci_device = S3_TRIO64V2_DX, s3_init, s3_close, - s3_reset, + s3_reset, { s3_trio64v2_dx_available }, s3_speed_changed, s3_force_redraw, @@ -8379,7 +8430,7 @@ const device_t s3_trio64v2_dx_onboard_pci_device = S3_TRIO64V2_DX_ONBOARD, s3_init, s3_close, - NULL, + NULL, { NULL }, s3_speed_changed, s3_force_redraw, diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 4acaa0aa0..6f46278da 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -117,10 +117,10 @@ typedef struct s3d_t { uint32_t cmd_set; int clip_l, clip_r, clip_t, clip_b; - + uint32_t dest_base; uint32_t dest_str; - + uint32_t z_base; uint32_t z_str; @@ -136,14 +136,14 @@ typedef struct s3d_t int32_t TdWdX, TdWdY; uint32_t tws; - + int32_t TdDdX, TdDdY; uint32_t tds; - + int16_t TdGdX, TdBdX, TdRdX, TdAdX; int16_t TdGdY, TdBdY, TdRdY, TdAdY; uint32_t tgs, tbs, trs, tas; - + uint32_t TdXdY12; uint32_t txend12; uint32_t TdXdY01; @@ -161,9 +161,9 @@ typedef struct virge_t mem_mapping_t linear_mapping; mem_mapping_t mmio_mapping; mem_mapping_t new_mmio_mapping; - + rom_t bios_rom; - + svga_t svga; uint8_t bank; @@ -195,7 +195,7 @@ typedef struct virge_t uint32_t hwc_fg_col, hwc_bg_col; int hwc_col_stack_pos; - + struct { uint32_t src_base; @@ -212,21 +212,21 @@ typedef struct virge_t int r_width, r_height; int rsrc_x, rsrc_y; int rdest_x, rdest_y; - + int lxend0, lxend1; int32_t ldx; uint32_t lxstart, lystart; int lycnt; int line_dir; - + int src_x, src_y; int dest_x, dest_y; int w, h; uint8_t rop; - + int data_left_count; uint32_t data_left; - + uint32_t pattern_8[8*8]; uint32_t pattern_16[8*8]; uint32_t pattern_24[8*8]; @@ -240,14 +240,14 @@ typedef struct virge_t uint32_t pycnt; uint32_t dest_l, dest_r; } s3d; - + s3d_t s3d_tri; s3d_t s3d_buffer[RB_SIZE]; int s3d_read_idx, s3d_write_idx; int s3d_busy; int render_idx; - + struct { uint32_t pri_ctrl; @@ -273,9 +273,9 @@ typedef struct virge_t uint32_t pri_size; uint32_t sec_start; uint32_t sec_size; - + int sdif; - + int pri_x, pri_y, pri_w, pri_h; int sec_x, sec_y, sec_w, sec_h; } streams; @@ -285,7 +285,7 @@ typedef struct virge_t uint32_t dma_ptr; uint64_t blitter_time; volatile int fifo_slot; - + pc_timer_t tri_timer; int virge_busy, local; @@ -297,7 +297,7 @@ typedef struct virge_t uint8_t serialport; void *i2c, *ddc; - + int waiting; } virge_t; @@ -324,29 +324,29 @@ enum { CMD_SET_AE = 1, CMD_SET_HC = (1 << 1), - + CMD_SET_FORMAT_MASK = (7 << 2), CMD_SET_FORMAT_8 = (0 << 2), CMD_SET_FORMAT_16 = (1 << 2), CMD_SET_FORMAT_24 = (2 << 2), - + CMD_SET_MS = (1 << 6), CMD_SET_IDS = (1 << 7), CMD_SET_MP = (1 << 8), CMD_SET_TP = (1 << 9), - + CMD_SET_ITA_MASK = (3 << 10), CMD_SET_ITA_BYTE = (0 << 10), CMD_SET_ITA_WORD = (1 << 10), CMD_SET_ITA_DWORD = (2 << 10), - + CMD_SET_ZUP = (1 << 23), - + CMD_SET_ZB_MODE = (3 << 24), CMD_SET_XP = (1 << 25), CMD_SET_YP = (1 << 26), - + CMD_SET_COMMAND_MASK = (15 << 27) }; @@ -440,7 +440,7 @@ static void render_thread(void *param) { virge_t *virge = (virge_t *)param; - + while (virge->render_thread_run) { thread_wait_event(virge->wake_render_thread, -1); thread_reset_event(virge->wake_render_thread); @@ -467,9 +467,9 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) uint8_t old; uint32_t cursoraddr; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; - + switch (addr) { case 0x3c5: @@ -495,7 +495,7 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) return; } break; - + case 0x3d4: svga->crtcreg = val; return; @@ -503,7 +503,7 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) return; if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); + val = (svga->crtc[7] & ~0x10) | (val & 0x10); if ((svga->crtcreg >= 0x20) && (svga->crtcreg < 0x40) && (svga->crtcreg != 0x36) && (svga->crtcreg != 0x38) && (svga->crtcreg != 0x39) && ((svga->crtc[0x38] & 0xcc) != 0x48)) @@ -516,10 +516,10 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) return; old = svga->crtc[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; - + if (svga->crtcreg > 0x18) s3_virge_log("OUTB VGA reg = %02x, val = %02x\n", svga->crtcreg, val); - + switch (svga->crtcreg) { case 0x31: @@ -528,11 +528,11 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) case 0x32: s3_virge_update_irqs(virge); break; - + case 0x69: virge->ma_ext = val & 0x1f; break; - + case 0x35: virge->bank = (virge->bank & 0x70) | (val & 0xf); if (svga->chain4) @@ -555,12 +555,12 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) else svga->write_bank = svga->read_bank = virge->bank << 14; break; - + case 0x3a: if (val & 0x10) svga->gdcreg[5] |= 0x40; /*Horrible cheat*/ break; - + case 0x45: svga->hwcursor.ena = val & 1; break; @@ -573,7 +573,7 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) cursoraddr = (virge->memory_size == 8) ? 0x1fff : 0x0fff; svga->hwcursor.addr = ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & cursoraddr) * 1024) + (svga->hwcursor.yoff * 16); break; - + case 0x4a: switch (virge->hwc_col_stack_pos) { @@ -614,12 +614,12 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) svga->dpms = (svga->seqregs[0x0d] & 0x50) || (svga->crtc[0x56] & 0x06); old = ~val; /* force recalc */ break; - + case 0x5c: if ((val & 0xa0) == 0x80) i2c_gpio_set(virge->i2c, !!(val & 0x40), !!(val & 0x10)); break; - + case 0x67: switch (val >> 4) { @@ -630,7 +630,7 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) default: svga->bpp = 8; break; } break; - + case 0xaa: i2c_gpio_set(virge->i2c, !!(val & SERIAL_PORT_SCW), !!(val & SERIAL_PORT_SDW)); break; @@ -660,8 +660,8 @@ static uint8_t s3_virge_in(uint16_t addr, void *p) virge_t *virge = (virge_t *)p; svga_t *svga = &virge->svga; uint8_t ret; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; switch (addr) @@ -671,7 +671,7 @@ static uint8_t s3_virge_in(uint16_t addr, void *p) ret = 0xff; else ret = svga_in(addr, svga); - break; + break; case 0x3c5: if (svga->seqaddr >= 8) @@ -690,7 +690,7 @@ static uint8_t s3_virge_in(uint16_t addr, void *p) { case 0x2d: ret = virge->virge_id_high; break; /*Extended chip ID*/ case 0x2e: ret = virge->virge_id_low; break; /*New chip ID*/ - case 0x2f: ret = virge->virge_rev; break; + case 0x2f: ret = virge->virge_rev; break; case 0x30: ret = virge->virge_id; break; /*Chip ID*/ case 0x31: ret = (svga->crtc[0x31] & 0xcf) | ((virge->ma_ext & 3) << 4); break; case 0x33: ret = (svga->crtc[0x33] | 0x04); break; @@ -724,16 +724,16 @@ static uint8_t s3_virge_in(uint16_t addr, void *p) } else ret = svga->crtc[0xaa]; break; - + default: ret = svga->crtc[svga->crtcreg]; break; } break; - + default: ret = svga_in(addr, svga); - break; + break; } return ret; } @@ -741,7 +741,7 @@ static uint8_t s3_virge_in(uint16_t addr, void *p) static void s3_virge_recalctimings(svga_t *svga) { virge_t *virge = (virge_t *)svga->p; - + svga->hdisp = svga->hdisp_old; if (svga->crtc[0x5d] & 0x01) svga->htotal += 0x100; @@ -759,36 +759,36 @@ static void s3_virge_recalctimings(svga_t *svga) if (((svga->miscout >> 2) & 3) == 3) { int n = svga->seqregs[0x12] & 0x1f; int r = (svga->seqregs[0x12] >> 5); - - if (virge->chip == S3_VIRGEVX || virge->chip == S3_VIRGEDX) + + if (virge->chip == S3_VIRGEVX || virge->chip == S3_VIRGEDX) r &= 7; else if (virge->chip >= S3_VIRGEGX2) r &= 10; else r &= 3; - + int m = svga->seqregs[0x13] & 0x7f; double freq = (((double)m + 2) / (((double)n + 2) * (double)(1 << r))) * 14318184.0; svga->clock = (cpuclock * (float)(1ull << 32)) / freq; } - + if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/ - { + { + svga->fb_only = 0; svga->ma_latch |= (virge->ma_ext << 16); if (svga->crtc[0x51] & 0x30) svga->rowoffset += (svga->crtc[0x51] & 0x30) << 4; else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100; if (!svga->rowoffset) svga->rowoffset = 256; - + svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)); if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { - svga->fb_only = 1; switch (svga->bpp) { - case 8: - svga->render = svga_render_8bpp_highres; + case 8: + svga->render = svga_render_8bpp_highres; break; - case 15: + case 15: svga->render = svga_render_15bpp_highres; if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) { @@ -796,12 +796,12 @@ static void s3_virge_recalctimings(svga_t *svga) svga->hdisp >>= 1; } break; - case 16: + case 16: svga->render = svga_render_16bpp_highres; if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) { svga->htotal >>= 1; - svga->hdisp >>= 1; + svga->hdisp >>= 1; } break; case 24: @@ -809,28 +809,27 @@ static void s3_virge_recalctimings(svga_t *svga) if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) svga->rowoffset = (svga->rowoffset * 3) / 4; /*Hack*/ break; - case 32: + case 32: svga->render = svga_render_32bpp_highres; break; } - } else - svga->fb_only = 0; + } svga->vram_display_mask = (!(svga->crtc[0x31] & 0x08) && (svga->crtc[0x32] & 0x40)) ? 0x3ffff : virge->vram_mask; s3_virge_log("VGA mode\n"); } else /*Streams mode*/ { svga->fb_only = 1; - + if (virge->streams.buffer_ctrl & 1) svga->ma_latch = virge->streams.pri_fb1 >> 2; else svga->ma_latch = virge->streams.pri_fb0 >> 2; - + svga->hdisp = virge->streams.pri_w + 1; if (virge->streams.pri_h < svga->dispend) svga->dispend = virge->streams.pri_h; - + svga->overlay.x = virge->streams.sec_x - virge->streams.pri_x; svga->overlay.y = virge->streams.sec_y - virge->streams.pri_y; svga->overlay.ysize = virge->streams.sec_h; @@ -847,21 +846,21 @@ static void s3_virge_recalctimings(svga_t *svga) switch ((virge->streams.pri_ctrl >> 24) & 0x7) { case 0: /*RGB-8 (CLUT)*/ - svga->render = svga_render_8bpp_highres; + svga->render = svga_render_8bpp_highres; break; - case 3: /*KRGB-16 (1.5.5.5)*/ + case 3: /*KRGB-16 (1.5.5.5)*/ svga->htotal >>= 1; - svga->render = svga_render_15bpp_highres; + svga->render = svga_render_15bpp_highres; break; - case 5: /*RGB-16 (5.6.5)*/ + case 5: /*RGB-16 (5.6.5)*/ svga->htotal >>= 1; - svga->render = svga_render_16bpp_highres; + svga->render = svga_render_16bpp_highres; break; - case 6: /*RGB-24 (8.8.8)*/ - svga->render = svga_render_24bpp_highres; + case 6: /*RGB-24 (8.8.8)*/ + svga->render = svga_render_24bpp_highres; break; case 7: /*XRGB-32 (X.8.8.8)*/ - svga->render = svga_render_32bpp_highres; + svga->render = svga_render_32bpp_highres; break; } svga->vram_display_mask = virge->vram_mask; @@ -881,7 +880,7 @@ static void s3_virge_updatemapping(virge_t *virge) return; } - s3_virge_log("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); + s3_virge_log("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); /*Banked framebuffer*/ switch (svga->gdcreg[6] & 0xc) { /*VGA mapping*/ case 0x0: /*128k at A0000*/ @@ -901,7 +900,7 @@ static void s3_virge_updatemapping(virge_t *virge) svga->banked_mask = 0x7fff; break; } - + virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); s3_virge_log("Linear framebuffer %02X, linear base = %08x, display mask = %08x\n", svga->crtc[0x58] & 0x17, virge->linear_base, svga->vram_display_mask); @@ -937,13 +936,15 @@ static void s3_virge_updatemapping(virge_t *virge) } else { virge->linear_base &= 0xfc000000; } - + mem_mapping_set_addr(&virge->linear_mapping, virge->linear_base, virge->linear_size); } + svga->fb_only = 1; } else { mem_mapping_disable(&virge->linear_mapping); + svga->fb_only = 0; } - + s3_virge_log("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x38); /* Memory mapped I/O. */ @@ -983,8 +984,8 @@ s3_virge_mmio_fifo_write(uint32_t addr, uint8_t val, virge_t *virge) case 0x859c: virge->cmd_dma = val; break; - } - } + } + } } static void @@ -1003,7 +1004,7 @@ s3_virge_mmio_fifo_write_w(uint32_t addr, uint16_t val, virge_t *virge) static void s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge) -{ +{ if ((addr & 0xfffc) < 0x8000) { if (virge->s3d.cmd_set & CMD_SET_MS) s3_virge_bitblt(virge, 32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); @@ -1015,7 +1016,7 @@ s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge) case 0x8590: virge->cmd_dma_base = val; break; - + case 0x8594: virge->dma_ptr = val; break; @@ -1026,7 +1027,7 @@ s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge) case 0x859c: virge->cmd_dma = val; break; - + case 0xa000: case 0xa004: case 0xa008: case 0xa00c: case 0xa010: case 0xa014: case 0xa018: case 0xa01c: case 0xa020: case 0xa024: case 0xa028: case 0xa02c: @@ -1068,7 +1069,7 @@ s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge) virge->s3d.pattern_8[y*8 + x + 1] = val >> 8; virge->s3d.pattern_8[y*8 + x + 2] = val >> 16; virge->s3d.pattern_8[y*8 + x + 3] = val >> 24; - + x = (addr >> 1) & 6; y = (addr >> 4) & 7; virge->s3d.pattern_16[y*8 + x] = val & 0xffff; @@ -1194,7 +1195,7 @@ s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge) if (virge->s3d.cmd_set & CMD_SET_AE) s3_virge_bitblt(virge, -1, 0); break; - + case 0xb0f4: case 0xb4f4: virge->s3d_tri.fog_b = val & 0xff; virge->s3d_tri.fog_g = (val >> 8) & 0xff; @@ -1298,7 +1299,7 @@ s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge) virge->s3d_tri.tas = (val >> 16) & 0xffff; virge->s3d_tri.trs = val & 0xffff; break; - + case 0xb554: virge->s3d_tri.TdZdX = val; break; @@ -1361,7 +1362,7 @@ s3_virge_mmio_read(uint32_t addr, void *p) if (virge->fifo_slot) virge->fifo_slot--; return ret; - + case 0x83b0: case 0x83b1: case 0x83b2: case 0x83b3: case 0x83b4: case 0x83b5: case 0x83b6: case 0x83b7: case 0x83b8: case 0x83b9: case 0x83ba: case 0x83bb: @@ -1375,10 +1376,10 @@ s3_virge_mmio_read(uint32_t addr, void *p) case 0x83d8: case 0x83d9: case 0x83da: case 0x83db: case 0x83dc: case 0x83dd: case 0x83de: case 0x83df: return s3_virge_in(addr & 0x3ff, virge); - + case 0x859c: return virge->cmd_dma; - + case 0xff20: case 0xff21: ret = virge->serialport & ~(SERIAL_PORT_SCR | SERIAL_PORT_SDR); if ((virge->serialport & SERIAL_PORT_SCW) && i2c_gpio_get_scl(virge->i2c)) @@ -1394,9 +1395,9 @@ s3_virge_mmio_read_w(uint32_t addr, void *p) { virge_t *virge = (virge_t *)p; uint16_t ret = 0xffff; - + s3_virge_log("[%04X:%08X]: MMIO ReadW addr = %04x\n", CS, cpu_state.pc, addr & 0xfffe); - + switch (addr & 0xfffe) { case 0x8504: if (!virge->fifo_slot) @@ -1407,10 +1408,10 @@ s3_virge_mmio_read_w(uint32_t addr, void *p) ret |= 0x30; /*A bit of a workaround at the moment.*/ s3_virge_update_irqs(virge); return ret; - + case 0x859c: return virge->cmd_dma; - + default: return s3_virge_mmio_read(addr, virge) | (s3_virge_mmio_read(addr + 1, virge) << 8); @@ -1493,7 +1494,7 @@ s3_virge_mmio_read_l(uint32_t addr, void *p) break; case 0x81fc: ret = virge->streams.sec_size; - break; + break; case 0x8504: if (virge->s3d_busy || virge->fifo_slot) { @@ -1510,7 +1511,7 @@ s3_virge_mmio_read_l(uint32_t addr, void *p) virge->fifo_slot--; s3_virge_update_irqs(virge); break; - + case 0x8590: ret = virge->cmd_dma_base; break; @@ -1522,7 +1523,7 @@ s3_virge_mmio_read_l(uint32_t addr, void *p) case 0x859c: ret = virge->cmd_dma; break; - + case 0xa4d4: ret = virge->s3d.src_base; break; @@ -1568,11 +1569,11 @@ s3_virge_mmio_read_l(uint32_t addr, void *p) case 0xa50c: ret = (virge->s3d.rdest_x << 16) | virge->s3d.rdest_y; break; - + default: ret = s3_virge_mmio_read(addr, virge) | (s3_virge_mmio_read(addr + 1, virge) << 8) | - (s3_virge_mmio_read(addr + 2, virge) << 16) | + (s3_virge_mmio_read(addr + 2, virge) << 16) | (s3_virge_mmio_read(addr + 3, virge) << 24); break; } @@ -1626,7 +1627,7 @@ s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p) if ((addr & 0xfffe) == 0x83d4) { s3_virge_mmio_write(addr, val, virge); s3_virge_mmio_write(addr + 1, val >> 8, virge); - } + } } } @@ -1634,12 +1635,12 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) { virge_t *virge = (virge_t *)p; - svga_t *svga = &virge->svga; - + svga_t *svga = &virge->svga; + s3_virge_log("[%04X:%08X]: MMIO WriteL addr = %04x, val = %04x\n", CS, cpu_state.pc, addr & 0xfffc, val); if (((addr & 0xfffc) >= 0x8590) || ((addr & 0xfffc) < 0x8000)) if ((addr & 0xfffc) == 0xff20) - s3_virge_mmio_write(addr, val, virge); + s3_virge_mmio_write(addr, val, virge); else { s3_virge_mmio_fifo_write_l(addr, val, virge); } @@ -1734,38 +1735,38 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) case 0x81f0: virge->streams.pri_start = val; virge->streams.pri_x = (val >> 16) & 0x7ff; - virge->streams.pri_y = val & 0x7ff; + virge->streams.pri_y = val & 0x7ff; svga_recalctimings(svga); svga->fullchange = changeframecount; break; case 0x81f4: virge->streams.pri_size = val; virge->streams.pri_w = (val >> 16) & 0x7ff; - virge->streams.pri_h = val & 0x7ff; + virge->streams.pri_h = val & 0x7ff; svga_recalctimings(svga); svga->fullchange = changeframecount; break; case 0x81f8: virge->streams.sec_start = val; virge->streams.sec_x = (val >> 16) & 0x7ff; - virge->streams.sec_y = val & 0x7ff; + virge->streams.sec_y = val & 0x7ff; svga_recalctimings(svga); svga->fullchange = changeframecount; break; case 0x81fc: virge->streams.sec_size = val; virge->streams.sec_w = (val >> 16) & 0x7ff; - virge->streams.sec_h = val & 0x7ff; + virge->streams.sec_h = val & 0x7ff; svga_recalctimings(svga); svga->fullchange = changeframecount; break; - + case 0x8504: virge->subsys_stat &= ~(val & 0xff); virge->subsys_cntl = (val >> 8); s3_virge_update_irqs(virge); break; - + case 0x850c: virge->advfunc_cntl = val & 0xff; s3_virge_updatemapping(virge); @@ -1809,7 +1810,7 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) y > s3d_tri->clip_b)) \ update = 0; \ } - + #define MIX() \ { \ @@ -1861,7 +1862,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) uint32_t source = 0, dest = 0, pattern; uint32_t out = 0; int update; - + switch (virge->s3d.cmd_set & CMD_SET_FORMAT_MASK) { case CMD_SET_FORMAT_8: @@ -1892,7 +1893,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) } if (virge->s3d.cmd_set & CMD_SET_MP) pattern_data = mono_pattern; - + switch (virge->s3d.cmd_set & CMD_SET_ITA_MASK) { case CMD_SET_ITA_BYTE: @@ -1937,7 +1938,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) virge->s3d.h = virge->s3d.r_height; virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; virge->s3d.data_left_count = 0; - + s3_virge_log("BitBlt start src_x=%i,src_y=%i,dest_x=%i,dest_y=%i,w=%i,h=%i,rop=%02X,src_base=%x,dest_base=%x\n", virge->s3d.src_x, virge->s3d.src_y, @@ -1948,7 +1949,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) virge->s3d.rop, virge->s3d.src_base, virge->s3d.dest_base); - + if (virge->s3d.cmd_set & CMD_SET_IDS) return; } @@ -2019,7 +2020,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) WRITE(dest_addr, out); } - + virge->s3d.src_x += x_inc; virge->s3d.src_x &= 0x7ff; virge->s3d.dest_x += x_inc; @@ -2033,7 +2034,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) virge->s3d.src_y += y_inc; virge->s3d.dest_y += y_inc; virge->s3d.h--; - + switch (virge->s3d.cmd_set & (CMD_SET_MS | CMD_SET_IDS)) { case CMD_SET_IDS: @@ -2053,10 +2054,10 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) } } else - virge->s3d.w--; + virge->s3d.w--; } break; - + case CMD_SET_COMMAND_RECTFILL: /*No source, pattern = pat_fg_clr*/ if (count == -1) @@ -2068,7 +2069,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) virge->s3d.w = virge->s3d.r_width; virge->s3d.h = virge->s3d.r_height; virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; - + s3_virge_log("RctFll start %i,%i %i,%i %02X %08x\n", virge->s3d.dest_x, virge->s3d.dest_y, virge->s3d.w, @@ -2114,11 +2115,11 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) } } else - virge->s3d.w--; + virge->s3d.w--; count--; } break; - + case CMD_SET_COMMAND_LINE: if (count == -1) { @@ -2132,7 +2133,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) int x; int new_x; int first_pixel = 1; - + x = virge->s3d.dest_x >> 20; if (virge->s3d.h == virge->s3d.lycnt && @@ -2145,11 +2146,11 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) else new_x = (virge->s3d.dest_x + virge->s3d.ldx) >> 20; - + if ((virge->s3d.line_dir && x > new_x) || (!virge->s3d.line_dir && x < new_x)) goto skip_line; - + do { uint32_t dest_addr = virge->s3d.dest_base + (x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); @@ -2178,7 +2179,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) WRITE(dest_addr, out); } - + if (x < new_x) x++; else if (x > new_x) @@ -2224,7 +2225,7 @@ skip_line: WRITE(dest_addr, out); } - + x = (x + xdir) & 0x7ff; } while (x != (xend + xdir)); @@ -2273,21 +2274,21 @@ typedef struct s3d_state_t int32_t r, g, b, a, u, v, d, w; int32_t base_r, base_g, base_b, base_a, base_u, base_v, base_d, base_w; - + uint32_t base_z; uint32_t tbu, tbv; uint32_t cmd_set; int max_d; - + uint16_t *texture[10]; - + uint32_t tex_bdr_clr; - + int32_t x1, x2; int y; - + rgba_t dest_rgba; } s3d_state_t; @@ -2295,7 +2296,7 @@ typedef struct s3d_texture_state_t { int level; int texture_shift; - + int32_t u, v; } s3d_texture_state_t; @@ -2391,7 +2392,7 @@ static void tex_ARGB8888_nowrap(s3d_state_t *state, s3d_texture_state_t *texture static void tex_sample_normal(s3d_state_t *state) { s3d_texture_state_t texture_state; - + texture_state.level = state->max_d; texture_state.texture_shift = 18 + (9 - texture_state.level); texture_state.u = state->u + state->tbu; @@ -2429,12 +2430,12 @@ static void tex_sample_normal_filter(s3d_state_t *state) texture_state.u = state->u + state->tbu + tex_offset; texture_state.v = state->v + state->tbv + tex_offset; tex_read(state, &texture_state, &tex_samples[3]); - + d[0] = (256 - du) * (256 - dv); d[1] = du * (256 - dv); d[2] = (256 - du) * dv; d[3] = du * dv; - + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; @@ -2468,7 +2469,7 @@ static void tex_sample_mipmap_filter(s3d_state_t *state) texture_state.level = 0; texture_state.texture_shift = 18 + (9 - texture_state.level); tex_offset = 1 << texture_state.texture_shift; - + texture_state.u = state->u + state->tbu; texture_state.v = state->v + state->tbv; tex_read(state, &texture_state, &tex_samples[0]); @@ -2491,7 +2492,7 @@ static void tex_sample_mipmap_filter(s3d_state_t *state) d[1] = du * (256 - dv); d[2] = (256 - du) * dv; d[3] = du * dv; - + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; @@ -2505,9 +2506,9 @@ static void tex_sample_persp_normal(s3d_state_t *state) if (state->w) w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - + texture_state.level = state->max_d; - texture_state.texture_shift = 18 + (9 - texture_state.level); + texture_state.texture_shift = 18 + (9 - texture_state.level); texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu; texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv; @@ -2532,7 +2533,7 @@ static void tex_sample_persp_normal_filter(s3d_state_t *state) texture_state.level = state->max_d; texture_state.texture_shift = 18 + (9 - texture_state.level); tex_offset = 1 << texture_state.texture_shift; - + texture_state.u = u; texture_state.v = v; tex_read(state, &texture_state, &tex_samples[0]); @@ -2555,7 +2556,7 @@ static void tex_sample_persp_normal_filter(s3d_state_t *state) d[1] = du * (256 - dv); d[2] = (256 - du) * dv; d[3] = du * dv; - + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; @@ -2569,9 +2570,9 @@ static void tex_sample_persp_normal_375(s3d_state_t *state) if (state->w) w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - + texture_state.level = state->max_d; - texture_state.texture_shift = 18 + (9 - texture_state.level); + texture_state.texture_shift = 18 + (9 - texture_state.level); texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; @@ -2592,7 +2593,7 @@ static void tex_sample_persp_normal_filter_375(s3d_state_t *state) u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; - + texture_state.level = state->max_d; texture_state.texture_shift = 18 + (9 - texture_state.level); tex_offset = 1 << texture_state.texture_shift; @@ -2619,7 +2620,7 @@ static void tex_sample_persp_normal_filter_375(s3d_state_t *state) d[1] = du * (256 - dv); d[2] = (256 - du) * dv; d[3] = du * dv; - + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; @@ -2634,7 +2635,7 @@ static void tex_sample_persp_mipmap(s3d_state_t *state) if (state->w) w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - + texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); if (texture_state.level < 0) texture_state.level = 0; @@ -2659,7 +2660,7 @@ static void tex_sample_persp_mipmap_filter(s3d_state_t *state) u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu; v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv; - + texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); if (texture_state.level < 0) texture_state.level = 0; @@ -2688,7 +2689,7 @@ static void tex_sample_persp_mipmap_filter(s3d_state_t *state) d[1] = du * (256 - dv); d[2] = (256 - du) * dv; d[3] = du * dv; - + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; @@ -2702,7 +2703,7 @@ static void tex_sample_persp_mipmap_375(s3d_state_t *state) if (state->w) w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - + texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); if (texture_state.level < 0) texture_state.level = 0; @@ -2727,13 +2728,13 @@ static void tex_sample_persp_mipmap_filter_375(s3d_state_t *state) u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; - + texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); if (texture_state.level < 0) texture_state.level = 0; texture_state.texture_shift = 18 + (9 - texture_state.level); tex_offset = 1 << texture_state.texture_shift; - + texture_state.u = u; texture_state.v = v; tex_read(state, &texture_state, &tex_samples[0]); @@ -2756,7 +2757,7 @@ static void tex_sample_persp_mipmap_filter_375(s3d_state_t *state) d[1] = du * (256 - dv); d[2] = (256 - du) * dv; d[3] = du * dv; - + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; @@ -2780,7 +2781,7 @@ static void tex_sample_persp_mipmap_filter_375(s3d_state_t *state) b = ((b) < 0) ? 0 : 0xff; \ if ((a) & ~0xff) \ a = ((a) < 0) ? 0 : 0xff; - + #define CLAMP_RGB(r, g, b) do \ { \ if ((r) < 0) \ @@ -2845,11 +2846,11 @@ static void dest_pixel_lit_texture_reflection(s3d_state_t *state) static void dest_pixel_lit_texture_modulate(s3d_state_t *state) { int r = state->r >> 7, g = state->g >> 7, b = state->b >> 7, a = state->a >> 7; - + tex_sample(state); - + CLAMP_RGBA(r, g, b, a); - + state->dest_rgba.r = ((state->dest_rgba.r) * r) >> 8; state->dest_rgba.g = ((state->dest_rgba.g) * g) >> 8; state->dest_rgba.b = ((state->dest_rgba.b) * b) >> 8; @@ -2864,13 +2865,13 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 uint8_t *vram = (uint8_t *)svga->vram; int x_dir = s3d_tri->tlr ? 1 : -1; - + int use_z = !(s3d_tri->cmd_set & CMD_SET_ZB_MODE); int y_count = yc; - + int bpp = (s3d_tri->cmd_set >> 2) & 7; - + uint32_t dest_offset = 0, z_offset = 0; uint32_t src_col; @@ -2888,7 +2889,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 int update; uint16_t src_z = 0; - + if (s3d_tri->cmd_set & CMD_SET_HC) { if (state->y < s3d_tri->clip_t) @@ -2896,10 +2897,10 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 if (state->y > s3d_tri->clip_b) { int diff_y = state->y - s3d_tri->clip_b; - + if (diff_y > y_count) diff_y = y_count; - + state->base_u += (s3d_tri->TdUdY * diff_y); state->base_v += (s3d_tri->TdVdY * diff_y); state->base_z += (s3d_tri->TdZdY * diff_y); @@ -2922,7 +2923,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 dest_offset = s3d_tri->dest_base + (state->y * s3d_tri->dest_str); z_offset = s3d_tri->z_base + (state->y * s3d_tri->z_str); - + while (y_count > 0) { x = (state->x1 + ((1 << 20) - 1)) >> 20; @@ -2964,7 +2965,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 if (x < s3d_tri->clip_l) { int diff_x = s3d_tri->clip_l - x; - + z += (s3d_tri->TdZdX * diff_x); state->u += (s3d_tri->TdUdX * diff_x); state->v += (s3d_tri->TdVdX * diff_x); @@ -2974,7 +2975,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 state->a += (s3d_tri->TdAdX * diff_x); state->d += (s3d_tri->TdDdX * diff_x); state->w += (s3d_tri->TdWdX * diff_x); - + x = s3d_tri->clip_l; } } @@ -2989,7 +2990,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 if (x > s3d_tri->clip_r) { int diff_x = x - s3d_tri->clip_r; - + z += (s3d_tri->TdZdX * diff_x); state->u += (s3d_tri->TdUdX * diff_x); state->v += (s3d_tri->TdVdX * diff_x); @@ -2999,7 +3000,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 state->a += (s3d_tri->TdAdX * diff_x); state->d += (s3d_tri->TdDdX * diff_x); state->w += (s3d_tri->TdWdX * diff_x); - + x = s3d_tri->clip_r; } } @@ -3012,7 +3013,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 x &= 0xfff; xe &= 0xfff; - + while (x != xe) { update = 1; _x = x; _y = state->y; @@ -3104,7 +3105,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 switch (bpp) { - case 0: /*8 bpp*/ + case 0: /*8 bpp*/ /*Not implemented yet*/ break; case 1: /*16 bpp*/ @@ -3138,13 +3139,13 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 state->w += s3d_tri->TdWdX; dest_addr += x_offset; z_addr += xz_offset; - + x = (x + x_dir) & 0xfff; } } y_count--; - + tri_skip_line: state->x1 += dx1; state->x2 += dx2; @@ -3187,11 +3188,11 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) state.tbu = s3d_tri->tbu << 11; state.tbv = s3d_tri->tbv << 11; - + state.max_d = (s3d_tri->cmd_set >> 8) & 15; - + state.tex_bdr_clr = s3d_tri->tex_bdr_clr; - + state.cmd_set = s3d_tri->cmd_set; state.base_u = s3d_tri->tus; @@ -3203,7 +3204,7 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) state.base_a = (int32_t)s3d_tri->tas; state.base_d = s3d_tri->tds; state.base_w = s3d_tri->tws; - + tex_base = s3d_tri->tex_base; for (c = 9; c >= 0; c--) { @@ -3242,8 +3243,8 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) default: s3_virge_log("bad triangle type %x\n", (s3d_tri->cmd_set >> 27) & 0xf); return; - } - + } + switch (((s3d_tri->cmd_set >> 12) & 7) | ((s3d_tri->cmd_set & (1 << 29)) ? 8 : 0)) { case 0: case 1: @@ -3283,7 +3284,7 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter : tex_sample_persp_normal; break; } - + switch ((s3d_tri->cmd_set >> 5) & 7) { case 0: @@ -3307,9 +3308,9 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) tri(virge, s3d_tri, &state, s3d_tri->ty01, s3d_tri->TdXdY02, s3d_tri->TdXdY01); state.x2 = s3d_tri->txend12; tri(virge, s3d_tri, &state, s3d_tri->ty12, s3d_tri->TdXdY02, s3d_tri->TdXdY12); - + end_time = plat_timer_read(); - + virge->blitter_time += end_time - start_time; } @@ -3327,17 +3328,17 @@ static void s3_virge_hwcursor_draw(svga_t *svga, int displine) svga->hwcursor_latch.addr += 16; switch (svga->bpp) - { + { case 15: fg = video_15to32[virge->hwc_fg_col & 0xffff]; bg = video_15to32[virge->hwc_bg_col & 0xffff]; break; - + case 16: fg = video_16to32[virge->hwc_fg_col & 0xffff]; bg = video_16to32[virge->hwc_bg_col & 0xffff]; break; - + case 24: case 32: fg = virge->hwc_fg_col; bg = virge->hwc_bg_col; @@ -3363,7 +3364,7 @@ static void s3_virge_hwcursor_draw(svga_t *svga, int displine) if (dat[0] & 0x8000) buffer32->line[displine][offset + svga->x_add] = (dat[1] & 0x8000) ? fg : bg; } - + offset++; dat[0] <<= 1; dat[1] <<= 1; @@ -3381,7 +3382,7 @@ static void s3_virge_hwcursor_draw(svga_t *svga, int displine) else if (dat[1] & 0x8000) buffer32->line[displine][offset + svga->x_add] ^= 0xffffff; } - + offset++; dat[0] <<= 1; dat[1] <<= 1; @@ -3630,7 +3631,7 @@ static void s3_virge_overlay_draw(svga_t *svga, int displine) int x; uint32_t *p; uint8_t *src = &svga->vram[svga->overlay_latch.addr]; - + p = &(buffer32->line[displine][offset + svga->x_add]); if ((offset + virge->streams.sec_w) > virge->streams.pri_w) @@ -3639,7 +3640,7 @@ static void s3_virge_overlay_draw(svga_t *svga, int displine) x_size = virge->streams.sec_w + 1; OVERLAY_SAMPLE(); - + for (x = 0; x < x_size; x++) { *p++ = r[x_read] | (g[x_read] << 8) | (b[x_read] << 16); @@ -3672,22 +3673,22 @@ static uint8_t s3_virge_pci_read(int func, int addr, void *p) switch (addr) { case 0x00: ret = 0x33; break; /*'S3'*/ case 0x01: ret = 0x53; break; - + case 0x02: ret = virge->virge_id_low; break; case 0x03: ret = virge->virge_id_high; break; case PCI_REG_COMMAND: ret = virge->pci_regs[PCI_REG_COMMAND] & 0x27; break; - + case 0x07: ret = virge->pci_regs[0x07] & 0x36; break; - + case 0x08: ret = virge->virge_rev; break; /*Revision ID*/ case 0x09: ret = 0; break; /*Programming interface*/ - + case 0x0a: ret = 0x00; break; /*Supports VGA interface*/ case 0x0b: ret = 0x03; break; case 0x0d: ret = virge->pci_regs[0x0d] & 0xf8; break; - + case 0x10: ret = 0x00; break;/*Linear frame buffer address*/ case 0x11: ret = 0x00; break; case 0x12: ret = 0x00; break; @@ -3706,12 +3707,12 @@ static uint8_t s3_virge_pci_read(int func, int addr, void *p) case 0x34: ret = (virge->chip >= S3_VIRGEGX2) ? 0xdc : 0x00; break; case 0x3c: ret = virge->pci_regs[0x3c]; break; - + case 0x3d: ret = PCI_INTA; break; /*INTA*/ - + case 0x3e: ret = 0x04; break; case 0x3f: ret = 0xff; break; - + case 0x80: ret = 0x02; break; /* AGP capability */ case 0x81: ret = 0x00; break; case 0x82: ret = 0x10; break; /* assumed AGP 1.0 */ @@ -3745,8 +3746,8 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) case 0x00: case 0x01: case 0x02: case 0x03: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x3d: case 0x3e: case 0x3f: - return; - + return; + case PCI_REG_COMMAND: if (val & PCI_COMMAND_IO) { @@ -3756,12 +3757,12 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) else io_removehandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); virge->pci_regs[PCI_REG_COMMAND] = val & 0x27; - s3_virge_updatemapping(virge); + s3_virge_updatemapping(virge); return; case 0x07: virge->pci_regs[0x07] = val & 0x3e; return; - case 0x0d: + case 0x0d: virge->pci_regs[0x0d] = val & 0xf8; return; @@ -3785,7 +3786,7 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) mem_mapping_disable(&virge->bios_rom.mapping); } return; - case 0x3c: + case 0x3c: virge->pci_regs[0x3c] = val; return; @@ -3833,7 +3834,7 @@ static void s3_virge_reset(void *priv) virge->pci_regs[0x06] = 0; virge->pci_regs[0x07] = 2; virge->pci_regs[0x32] = 0x0c; - virge->pci_regs[0x3d] = 1; + virge->pci_regs[0x3d] = 1; virge->pci_regs[0x3e] = 4; virge->pci_regs[0x3f] = 0xff; @@ -3887,7 +3888,7 @@ static void s3_virge_reset(void *priv) else virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); break; - } + } if (virge->local == S3_VIRGE_GX) virge->svga.crtc[0x36] |= (1 << 2); } @@ -3916,8 +3917,8 @@ static void *s3_virge_init(const device_t *info) virge->memory_size = 4; else virge->memory_size = device_get_config_int("memory"); - - + + switch(info->local) { case S3_VIRGE_325: bios_fn = ROM_VIRGE_325; @@ -3965,7 +3966,7 @@ static void *s3_virge_init(const device_t *info) rom_init(&virge->bios_rom, (char *) bios_fn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); else rom_init(&virge->bios_rom, (char *) bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - + mem_mapping_disable(&virge->bios_rom.mapping); mem_mapping_add(&virge->linear_mapping, 0, 0, svga_read_linear, @@ -4003,10 +4004,10 @@ static void *s3_virge_init(const device_t *info) virge->pci_regs[0x06] = 0; virge->pci_regs[0x07] = 2; virge->pci_regs[0x32] = 0x0c; - virge->pci_regs[0x3d] = 1; + virge->pci_regs[0x3d] = 1; virge->pci_regs[0x3e] = 4; virge->pci_regs[0x3f] = 0xff; - + virge->virge_rev = 0; virge->virge_id = 0xe1; virge->is_agp = !!(info->flags & DEVICE_AGP); @@ -4105,11 +4106,11 @@ static void *s3_virge_init(const device_t *info) else virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); break; - } + } if (info->local == S3_VIRGE_GX) virge->svga.crtc[0x36] |= (1 << 2); } - + virge->svga.crtc[0x37] = 1 | (7 << 5); virge->svga.crtc[0x53] = 8; @@ -4117,8 +4118,8 @@ static void *s3_virge_init(const device_t *info) virge->i2c = i2c_gpio_init("ddc_s3_virge"); virge->ddc = ddc_init(i2c_gpio_get_bus(virge->i2c)); - - virge->svga.packed_chain4 = 1; + + virge->svga.force_old_addr = 1; virge->wake_render_thread = thread_create_event(); virge->wake_main_thread = thread_create_event(); @@ -4127,9 +4128,9 @@ static void *s3_virge_init(const device_t *info) virge->render_thread = thread_create(render_thread, virge); timer_add(&virge->tri_timer, s3_virge_tri_timer, virge, 0); - + virge->local = info->local; - + return virge; } @@ -4148,7 +4149,7 @@ static void s3_virge_close(void *p) ddc_close(virge->ddc); i2c_gpio_close(virge->i2c); - + free(virge); } @@ -4205,7 +4206,7 @@ static int s3_trio3d2x_available(void) static void s3_virge_speed_changed(void *p) { virge_t *virge = (virge_t *)p; - + svga_recalctimings(&virge->svga); } @@ -4216,60 +4217,102 @@ static void s3_virge_force_redraw(void *p) virge->svga.fullchange = changeframecount; } -// clang-format off static const device_config_t s3_virge_config[] = { - { - "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, { - { "2 MB", 2 }, - { "4 MB", 4 }, - { "" } + "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, + { + { + "2 MB", 2 + }, + { + "4 MB", 4 + }, + { + "" + } + } + }, + { + "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 + }, + { + "dithering", "Dithering", CONFIG_BINARY, "", 1 + }, + { + "", "", -1 } - }, - { "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 }, - { "dithering", "Dithering", CONFIG_BINARY, "", 1 }, - { "", "", -1 } }; static const device_config_t s3_virge_stb_config[] = { - { - "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, { - { "2 MB", 2 }, - { "4 MB", 4 }, - { "8 MB", 8 }, - { "" } + "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, + { + { + "2 MB", 2 + }, + { + "4 MB", 4 + }, + { + "8 MB", 8 + }, + { + "" + } + } + }, + { + "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 + }, + { + "dithering", "Dithering", CONFIG_BINARY, "", 1 + }, + { + "", "", -1 } - }, - { "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 }, - { "dithering", "Dithering", CONFIG_BINARY, "", 1 }, - { "", "", -1 } }; static const device_config_t s3_virge_357_config[] = { - { "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 }, - { "dithering", "Dithering", CONFIG_BINARY, "", 1 }, - { "", "", -1 } + { + "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 + }, + { + "dithering", "Dithering", CONFIG_BINARY, "", 1 + }, + { + "", "", -1 + } }; static const device_config_t s3_trio3d2x_config[] = { - { - "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, { - { "4 MB", 4 }, - { "8 MB", 8 }, - { "" } + "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, + { + { + "4 MB", 4 + }, + { + "8 MB", 8 + }, + { + "" + } + } + }, + { + "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 + }, + { + "dithering", "Dithering", CONFIG_BINARY, "", 1 + }, + { + "", "", -1 } - }, - { "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 }, - { "dithering", "Dithering", CONFIG_BINARY, "", 1 }, - { "", "", -1 } }; -// clang-format on const device_t s3_virge_325_pci_device = { @@ -4279,7 +4322,7 @@ const device_t s3_virge_325_pci_device = S3_VIRGE_325, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_325_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4294,7 +4337,7 @@ const device_t s3_diamond_stealth_2000_pci_device = S3_DIAMOND_STEALTH3D_2000, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_325_diamond_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4309,7 +4352,7 @@ const device_t s3_diamond_stealth_3000_pci_device = S3_DIAMOND_STEALTH3D_3000, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_988_diamond_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4324,7 +4367,7 @@ const device_t s3_stb_velocity_3d_pci_device = S3_STB_VELOCITY_3D, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_988_stb_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4339,7 +4382,7 @@ const device_t s3_virge_375_pci_device = S3_VIRGE_DX, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_375_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4354,7 +4397,7 @@ const device_t s3_diamond_stealth_2000pro_pci_device = S3_DIAMOND_STEALTH3D_2000PRO, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_375_diamond_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4369,7 +4412,7 @@ const device_t s3_virge_385_pci_device = S3_VIRGE_GX, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_385_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4384,7 +4427,7 @@ const device_t s3_virge_357_pci_device = S3_VIRGE_GX2, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_357_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4399,7 +4442,7 @@ const device_t s3_virge_357_agp_device = S3_VIRGE_GX2, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_357_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4414,7 +4457,7 @@ const device_t s3_diamond_stealth_4000_pci_device = S3_DIAMOND_STEALTH3D_4000, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_357_diamond_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4429,7 +4472,7 @@ const device_t s3_diamond_stealth_4000_agp_device = S3_DIAMOND_STEALTH3D_4000, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_virge_357_diamond_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4444,7 +4487,7 @@ const device_t s3_trio3d2x_pci_device = S3_TRIO_3D2X, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_trio3d2x_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4459,7 +4502,7 @@ const device_t s3_trio3d2x_agp_device = S3_TRIO_3D2X, s3_virge_init, s3_virge_close, - s3_virge_reset, + s3_virge_reset, { s3_trio3d2x_available }, s3_virge_speed_changed, s3_virge_force_redraw, diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 9640b5540..20c4d6dd6 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -179,7 +179,7 @@ svga_out(uint16_t addr, uint8_t val, void *p) 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->packed_chain4) || svga->fb_only) && !(svga->adv_flags & FLAG_ADDR_BY8); + !svga->gdcreg[1]) && ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && !(svga->adv_flags & FLAG_ADDR_BY8); break; } break; @@ -264,7 +264,7 @@ svga_out(uint16_t addr, uint8_t val, void *p) } svga->gdcreg[svga->gdcaddr & 15] = val; svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && - !svga->gdcreg[1]) && ((svga->chain4 && svga->packed_chain4) || svga->fb_only); + !svga->gdcreg[1]) && ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only); if (((svga->gdcaddr & 15) == 5 && (val ^ o) & 0x70) || ((svga->gdcaddr & 15) == 6 && (val ^ o) & 1)) svga_recalctimings(svga); @@ -582,7 +582,8 @@ svga_recalctimings(svga_t *svga) if (svga->dispofftime < TIMER_USEC) svga->dispofftime = TIMER_USEC; - svga_recalc_remap_func(svga); + if (!svga->force_old_addr) + svga_recalc_remap_func(svga); /* Inform the user interface of any DPMS mode changes. */ if (svga->dpms) { @@ -1068,7 +1069,7 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) addr <<= 4; else if ((svga->adv_flags & FLAG_ADDR_BY8) && (svga->writemode < 4)) addr <<= 3; - else if (((svga->chain4 && svga->packed_chain4) || svga->fb_only) && (svga->writemode < 4)) { + else if (((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && (svga->writemode < 4)) { writemask2 = 1 << (addr & 3); addr &= ~3; } else if (svga->chain4 && (svga->writemode < 4)) { @@ -1256,7 +1257,7 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p) addr <<= 4; else if (svga->adv_flags & FLAG_ADDR_BY8) addr <<= 3; - else if ((svga->chain4 && svga->packed_chain4) || svga->fb_only) { + else if ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) { addr &= svga->decode_mask; if (svga->translate_address) addr = svga->translate_address(addr, p); @@ -1266,7 +1267,7 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p) for (i = 0; i < count; i++) svga->latch.b[i] = svga->vram[latch_addr | i]; return svga->vram[addr & svga->vram_mask]; - } else if (svga->chain4) { + } else if (svga->chain4 && !svga->force_old_addr) { readplane = addr & 3; addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); } else if (svga->chain2_read) { diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index ddd3ad0eb..2d23231be 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -117,6 +117,7 @@ svga_render_text_40(svga_t *svga) uint8_t chr, attr, dat; uint32_t charaddr; int fg, bg; + uint32_t addr = 0; if ((svga->displine + svga->y_add) < 0) return; @@ -130,13 +131,19 @@ svga_render_text_40(svga_t *svga) xinc = (svga->seqregs[1] & 1) ? 16 : 18; for (x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { - uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; + if (!svga->force_old_addr) + addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); if (svga->crtc[0x17] & 0x80) { - chr = svga->vram[addr]; - attr = svga->vram[addr+1]; + if (svga->force_old_addr) { + chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; + attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + } else { + chr = svga->vram[addr]; + attr = svga->vram[addr+1]; + } } else chr = attr = 0; @@ -186,6 +193,7 @@ svga_render_text_80(svga_t *svga) uint8_t chr, attr, dat; uint32_t charaddr; int fg, bg; + uint32_t addr = 0; if ((svga->displine + svga->y_add) < 0) return; @@ -199,13 +207,19 @@ svga_render_text_80(svga_t *svga) xinc = (svga->seqregs[1] & 1) ? 8 : 9; for (x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { - uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; + if (!svga->force_old_addr) + addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); if (svga->crtc[0x17] & 0x80) { - chr = svga->vram[addr]; - attr = svga->vram[addr+1]; + if (svga->force_old_addr) { + chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; + attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + } else { + chr = svga->vram[addr]; + attr = svga->vram[addr+1]; + } } else chr = attr = 0; @@ -244,7 +258,7 @@ svga_render_text_80(svga_t *svga) } } - +/*Not available on most generic cards.*/ void svga_render_text_80_ksc5601(svga_t *svga) { @@ -373,6 +387,7 @@ svga_render_text_80_ksc5601(svga_t *svga) void svga_render_2bpp_lowres(svga_t *svga) { + int changed_offset; int x; uint8_t dat[2]; uint32_t addr, *p; @@ -381,41 +396,94 @@ svga_render_2bpp_lowres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - changed_addr = svga->remap_func(svga, svga->ma); + if (svga->force_old_addr) { + 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) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { + addr = svga->ma; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { - addr = svga->remap_func(svga, svga->ma); + if (!(svga->crtc[0x17] & 0x40)) { + addr = (addr << 1) & svga->vram_mask; + addr &= ~7; - dat[0] = svga->vram[addr]; - dat[1] = svga->vram[addr | 0x1]; - if (svga->seqregs[1] & 4) - svga->ma += 2; - else - svga->ma += 4; + if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000)) + addr |= 4; - svga->ma &= svga->vram_mask; + if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000)) + addr |= 4; + } - if (svga->crtc[0x17] & 0x80) { - 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[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; - p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]]; - p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; - p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; - p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; - p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]]; - } else - memset(p, 0x00, 16 * sizeof(uint32_t)); + if (!(svga->crtc[0x17] & 0x01)) + addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0); - p += 16; - } + if (!(svga->crtc[0x17] & 0x02)) + addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0); + + dat[0] = svga->vram[addr]; + dat[1] = svga->vram[addr | 0x1]; + if (svga->seqregs[1] & 4) + svga->ma += 2; + else + svga->ma += 4; + svga->ma &= svga->vram_mask; + if (svga->crtc[0x17] & 0x80) { + 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[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; + p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]]; + p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; + p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; + p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; + p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]]; + } else + memset(p, 0x00, 16 * sizeof(uint32_t)); + p += 16; + } + } + } else { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { + addr = svga->remap_func(svga, svga->ma); + + dat[0] = svga->vram[addr]; + dat[1] = svga->vram[addr | 0x1]; + if (svga->seqregs[1] & 4) + svga->ma += 2; + else + svga->ma += 4; + + svga->ma &= svga->vram_mask; + + if (svga->crtc[0x17] & 0x80) { + 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[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; + p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]]; + p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; + p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; + p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; + p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]]; + } else + memset(p, 0x00, 16 * sizeof(uint32_t)); + + p += 16; + } + } } } @@ -423,6 +491,7 @@ svga_render_2bpp_lowres(svga_t *svga) void svga_render_2bpp_highres(svga_t *svga) { + int changed_offset; int x; uint8_t dat[2]; uint32_t addr, *p; @@ -431,42 +500,95 @@ svga_render_2bpp_highres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - changed_addr = svga->remap_func(svga, svga->ma); + if (svga->force_old_addr) { + changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - addr = svga->remap_func(svga, svga->ma); + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + addr = svga->ma; - dat[0] = svga->vram[addr]; - dat[1] = svga->vram[addr | 0x1]; - if (svga->seqregs[1] & 4) - svga->ma += 2; - else - svga->ma += 4; + if (!(svga->crtc[0x17] & 0x40)) { + addr = (addr << 1) & svga->vram_mask; + addr &= ~7; - svga->ma &= svga->vram_mask; + if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000)) + addr |= 4; - if (svga->crtc[0x17] & 0x80) { - 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]]; - } else - memset(p, 0x00, 8 * sizeof(uint32_t)); + if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000)) + addr |= 4; + } - p += 8; + if (!(svga->crtc[0x17] & 0x01)) + addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0); + + if (!(svga->crtc[0x17] & 0x02)) + addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0); + + dat[0] = svga->vram[addr]; + dat[1] = svga->vram[addr | 0x1]; + if (svga->seqregs[1] & 4) + svga->ma += 2; + else + svga->ma += 4; + svga->ma &= svga->vram_mask; + if (svga->crtc[0x17] & 0x80) { + 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]]; + } else + memset(p, 0x00, 8 * sizeof(uint32_t)); + p += 8; + } + } + } else { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + addr = svga->remap_func(svga, svga->ma); + + dat[0] = svga->vram[addr]; + dat[1] = svga->vram[addr | 0x1]; + if (svga->seqregs[1] & 4) + svga->ma += 2; + else + svga->ma += 4; + + svga->ma &= svga->vram_mask; + + if (svga->crtc[0x17] & 0x80) { + 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]]; + } else + memset(p, 0x00, 8 * sizeof(uint32_t)); + + p += 8; + } + } } - } } @@ -540,56 +662,120 @@ svga_render_4bpp_lowres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - changed_addr = svga->remap_func(svga, svga->ma); + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { + addr = svga->ma; + oddeven = 0; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { - addr = svga->remap_func(svga, svga->ma); - oddeven = 0; + if (!(svga->crtc[0x17] & 0x40)) { + addr = (addr << 1) & svga->vram_mask; - if (svga->seqregs[1] & 4) { - oddeven = (addr & 4) ? 1 : 0; - edat[0] = svga->vram[addr | oddeven]; - edat[2] = svga->vram[addr | oddeven | 0x2]; - edat[1] = edat[3] = 0; - svga->ma += 2; - } else { - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]); - svga->ma += 4; + if (svga->seqregs[1] & 4) + oddeven = (addr & 4) ? 1 : 0; + + addr &= ~7; + + if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000)) + addr |= 4; + if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000)) + addr |= 4; + } + + if (!(svga->crtc[0x17] & 0x01)) + addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0); + if (!(svga->crtc[0x17] & 0x02)) + addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0); + + if (svga->seqregs[1] & 4) { + edat[0] = svga->vram[addr | oddeven]; + edat[2] = svga->vram[addr | oddeven | 0x2]; + edat[1] = edat[3] = 0; + svga->ma += 2; + } else { + *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]); + svga->ma += 4; + } + svga->ma &= svga->vram_mask; + + if (svga->crtc[0x17] & 0x80) { + 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[2] = p[3] = 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[4] = p[5] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[6] = p[7] = 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[8] = p[9] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[10] = p[11] = 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[12] = p[13] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[14] = p[15] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + } else + memset(p, 0x00, 16 * sizeof(uint32_t)); + + p += 16; } - svga->ma &= svga->vram_mask; + } + } else { + changed_addr = svga->remap_func(svga, svga->ma); - if (svga->crtc[0x17] & 0x80) { - 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[2] = p[3] = 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[4] = p[5] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[6] = p[7] = 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[8] = p[9] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[10] = p[11] = 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[12] = p[13] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[14] = p[15] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - } else - memset(p, 0x00, 16 * sizeof(uint32_t)); + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - p += 16; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { + addr = svga->remap_func(svga, svga->ma); + oddeven = 0; + + if (svga->seqregs[1] & 4) { + oddeven = (addr & 4) ? 1 : 0; + edat[0] = svga->vram[addr | oddeven]; + edat[2] = svga->vram[addr | oddeven | 0x2]; + edat[1] = edat[3] = 0; + svga->ma += 2; + } else { + *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]); + svga->ma += 4; + } + svga->ma &= svga->vram_mask; + + if (svga->crtc[0x17] & 0x80) { + 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[2] = p[3] = 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[4] = p[5] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[6] = p[7] = 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[8] = p[9] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[10] = p[11] = 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[12] = p[13] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[14] = p[15] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + } else + memset(p, 0x00, 16 * sizeof(uint32_t)); + + p += 16; + } + } } - } } void svga_render_4bpp_highres(svga_t *svga) { + int changed_offset; int x, oddeven; uint32_t addr, *p; uint8_t edat[4]; @@ -598,51 +784,116 @@ svga_render_4bpp_highres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; + + if (svga->force_old_addr) { + changed_offset = (svga->ma + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; - changed_addr = svga->remap_func(svga, svga->ma); + if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + addr = svga->ma; + oddeven = 0; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - addr = svga->remap_func(svga, svga->ma); - oddeven = 0; + if (!(svga->crtc[0x17] & 0x40)) { + addr = (addr << 1) & svga->vram_mask; - if (svga->seqregs[1] & 4) { - oddeven = (addr & 4) ? 1 : 0; - edat[0] = svga->vram[addr | oddeven]; - edat[2] = svga->vram[addr | oddeven | 0x2]; - edat[1] = edat[3] = 0; - svga->ma += 2; - } else { - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]); - svga->ma += 4; + if (svga->seqregs[1] & 4) + oddeven = (addr & 4) ? 1 : 0; + + addr &= ~7; + + if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000)) + addr |= 4; + if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000)) + addr |= 4; + } + + if (!(svga->crtc[0x17] & 0x01)) + addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0); + if (!(svga->crtc[0x17] & 0x02)) + addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0); + + if (svga->seqregs[1] & 4) { + edat[0] = svga->vram[addr | oddeven]; + edat[2] = svga->vram[addr | oddeven | 0x2]; + edat[1] = edat[3] = 0; + svga->ma += 2; + } else { + *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]); + svga->ma += 4; + } + svga->ma &= svga->vram_mask; + + if (svga->crtc[0x17] & 0x80) { + 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]]; + 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]]; + 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]]; + 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]]; + } else + memset(p, 0x00, 8 * sizeof(uint32_t)); + + p += 8; } - svga->ma &= svga->vram_mask; + } + } else { + changed_addr = svga->remap_func(svga, svga->ma); - if (svga->crtc[0x17] & 0x80) { - 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]]; - 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]]; - 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]]; - 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]]; - } else - memset(p, 0x00, 8 * sizeof(uint32_t)); + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - p += 8; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + addr = svga->remap_func(svga, svga->ma); + oddeven = 0; + + if (svga->seqregs[1] & 4) { + oddeven = (addr & 4) ? 1 : 0; + edat[0] = svga->vram[addr | oddeven]; + edat[2] = svga->vram[addr | oddeven | 0x2]; + edat[1] = edat[3] = 0; + svga->ma += 2; + } else { + *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]); + svga->ma += 4; + } + svga->ma &= svga->vram_mask; + + if (svga->crtc[0x17] & 0x80) { + 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]]; + 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]]; + 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]]; + 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]]; + } else + memset(p, 0x00, 8 * sizeof(uint32_t)); + + p += 8; + } + } } - } } @@ -657,19 +908,18 @@ svga_render_8bpp_lowres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; + + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - changed_addr = svga->remap_func(svga, svga->ma); + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + p[0] = p[1] = svga->map8[dat & 0xff]; p[2] = p[3] = svga->map8[(dat >> 8) & 0xff]; p[4] = p[5] = svga->map8[(dat >> 16) & 0xff]; @@ -678,21 +928,45 @@ svga_render_8bpp_lowres(svga_t *svga) svga->ma += 4; p += 8; } + svga->ma &= svga->vram_display_mask; + } } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - addr = svga->remap_func(svga, svga->ma); - dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - p[0] = p[1] = svga->map8[dat & 0xff]; - p[2] = p[3] = svga->map8[(dat >> 8) & 0xff]; - p[4] = p[5] = svga->map8[(dat >> 16) & 0xff]; - p[6] = p[7] = svga->map8[(dat >> 24) & 0xff]; + changed_addr = svga->remap_func(svga, svga->ma); - svga->ma += 4; - p += 8; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + p[0] = p[1] = svga->map8[dat & 0xff]; + p[2] = p[3] = svga->map8[(dat >> 8) & 0xff]; + p[4] = p[5] = svga->map8[(dat >> 16) & 0xff]; + p[6] = p[7] = svga->map8[(dat >> 24) & 0xff]; + + svga->ma += 4; + p += 8; + } + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + p[0] = p[1] = svga->map8[dat & 0xff]; + p[2] = p[3] = svga->map8[(dat >> 8) & 0xff]; + p[4] = p[5] = svga->map8[(dat >> 16) & 0xff]; + p[6] = p[7] = svga->map8[(dat >> 24) & 0xff]; + + svga->ma += 4; + p += 8; + } + } + svga->ma &= svga->vram_display_mask; } } - svga->ma &= svga->vram_display_mask; - } } @@ -707,17 +981,15 @@ svga_render_8bpp_highres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; + + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - changed_addr = svga->remap_func(svga, svga->ma); + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp/* + svga->scrollcache*/); x += 8) { dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); p[0] = svga->map8[dat & 0xff]; @@ -734,21 +1006,51 @@ svga_render_8bpp_highres(svga_t *svga) svga->ma += 8; p += 8; } + svga->ma &= svga->vram_display_mask; + } } else { - for (x = 0; x <= (svga->hdisp/* + svga->scrollcache*/); x += 4) { - addr = svga->remap_func(svga, svga->ma); - dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - p[0] = svga->map8[dat & 0xff]; - p[1] = svga->map8[(dat >> 8) & 0xff]; - p[2] = svga->map8[(dat >> 16) & 0xff]; - p[3] = svga->map8[(dat >> 24) & 0xff]; + changed_addr = svga->remap_func(svga, svga->ma); - svga->ma += 4; - p += 4; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp/* + svga->scrollcache*/); x += 8) { + dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + p[0] = svga->map8[dat & 0xff]; + p[1] = svga->map8[(dat >> 8) & 0xff]; + p[2] = svga->map8[(dat >> 16) & 0xff]; + p[3] = svga->map8[(dat >> 24) & 0xff]; + + dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + p[4] = svga->map8[dat & 0xff]; + p[5] = svga->map8[(dat >> 8) & 0xff]; + p[6] = svga->map8[(dat >> 16) & 0xff]; + p[7] = svga->map8[(dat >> 24) & 0xff]; + + svga->ma += 8; + p += 8; + } + } else { + for (x = 0; x <= (svga->hdisp/* + svga->scrollcache*/); x += 4) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + p[0] = svga->map8[dat & 0xff]; + p[1] = svga->map8[(dat >> 8) & 0xff]; + p[2] = svga->map8[(dat >> 16) & 0xff]; + p[3] = svga->map8[(dat >> 24) & 0xff]; + + svga->ma += 4; + p += 4; + } + } + svga->ma &= svga->vram_display_mask; } } - svga->ma &= svga->vram_display_mask; - } } void @@ -870,47 +1172,74 @@ svga_render_15bpp_lowres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; + + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - changed_addr = svga->remap_func(svga, svga->ma); + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { if (svga->crtc[0x17] & 0x80) { dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + p[(x << 1)] = p[(x << 1) + 1] = video_15to32[dat & 0xffff]; + p[(x << 1) + 2] = p[(x << 1) + 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]; + p[(x << 1) + 4] = p[(x << 1) + 5] = video_15to32[dat & 0xffff]; + p[(x << 1) + 6] = p[(x << 1) + 7] = video_15to32[dat >> 16]; } else memset(&(p[(x << 1)]), 0x00, 8 * sizeof(uint32_t)); } svga->ma += x << 1; + svga->ma &= svga->vram_display_mask; + } } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { - if (svga->crtc[0x17] & 0x80) { - addr = svga->remap_func(svga, svga->ma); - dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + changed_addr = svga->remap_func(svga, svga->ma); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; - } else - memset(&(p[x]), 0x00, 2 * sizeof(uint32_t)); - svga->ma += 4; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { + if (svga->crtc[0x17] & 0x80) { + 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++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + } else + memset(&(p[(x << 1)]), 0x00, 8 * sizeof(uint32_t)); + } + svga->ma += x << 1; + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { + if (svga->crtc[0x17] & 0x80) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + } else + memset(&(p[x]), 0x00, 2 * sizeof(uint32_t)); + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; } } - svga->ma &= svga->vram_display_mask; - } } @@ -924,53 +1253,86 @@ svga_render_15bpp_highres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; + + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - changed_addr = svga->remap_func(svga, svga->ma); + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { if (svga->crtc[0x17] & 0x80) { dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + p[x] = video_15to32[dat & 0xffff]; + p[x + 1] = 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]; + 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->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + 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->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + p[x + 6] = video_15to32[dat & 0xffff]; + p[x + 7] = video_15to32[dat >> 16]; } else memset(&(p[x]), 0x00, 8 * sizeof(uint32_t)); } - svga->ma += x << 1; + svga->ma += x << 1; + svga->ma &= svga->vram_display_mask; + } } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { - if (svga->crtc[0x17] & 0x80) { - addr = svga->remap_func(svga, svga->ma); - dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + changed_addr = svga->remap_func(svga, svga->ma); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; - } else - memset(&(p[x]), 0x00, 2 * sizeof(uint32_t)); - svga->ma += 4; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + if (svga->crtc[0x17] & 0x80) { + 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++ = video_15to32[dat & 0xffff]; + *p++ = 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++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + } else + memset(&(p[x]), 0x00, 8 * sizeof(uint32_t)); + } + svga->ma += x << 1; + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { + if (svga->crtc[0x17] & 0x80) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + } else + memset(&(p[x]), 0x00, 2 * sizeof(uint32_t)); + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; } } - svga->ma &= svga->vram_display_mask; - } } @@ -1071,46 +1433,71 @@ svga_render_16bpp_lowres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - changed_addr = svga->remap_func(svga, svga->ma); + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { if (svga->crtc[0x17] & 0x80) { dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + p[(x << 1)] = p[(x << 1) + 1] = video_16to32[dat & 0xffff]; + p[(x << 1) + 2] = p[(x << 1) + 3] = 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]; + p[(x << 1) + 4] = p[(x << 1) + 5] = video_16to32[dat & 0xffff]; + p[(x << 1) + 6] = p[(x << 1) + 7] = video_16to32[dat >> 16]; } else memset(&(p[(x << 1)]), 0x00, 8 * sizeof(uint32_t)); } - svga->ma += x << 1; - } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { - if (svga->crtc[0x17] & 0x80) { - addr = svga->remap_func(svga, svga->ma); - dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; - } else - memset(&(p[x]), 0x00, 2 * sizeof(uint32_t)); + svga->ma += x << 1; + svga->ma &= svga->vram_display_mask; } - svga->ma += 4; + } else { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { + if (svga->crtc[0x17] & 0x80) { + 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) + 4) & svga->vram_display_mask]); + + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + } else + memset(&(p[(x << 1)]), 0x00, 8 * sizeof(uint32_t)); + } + svga->ma += x << 1; + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { + if (svga->crtc[0x17] & 0x80) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + } else + memset(&(p[x]), 0x00, 2 * sizeof(uint32_t)); + } + svga->ma += 4; + } + svga->ma &= svga->vram_display_mask; + } } - svga->ma &= svga->vram_display_mask; - } } @@ -1124,54 +1511,87 @@ svga_render_16bpp_highres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - - changed_addr = svga->remap_func(svga, svga->ma); - - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) + if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - if (!svga->remap_required) { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - if (svga->crtc[0x17] & 0x80) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + if (svga->crtc[0x17] & 0x80) { + 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++ = video_16to32[dat & 0xffff]; - *p++ = 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]; - 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) + 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) + 12) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; - } else - memset(&(p[x]), 0x00, 8 * sizeof(uint32_t)); - } - svga->ma += x << 1; - } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { - if (svga->crtc[0x17] & 0x80) { - addr = svga->remap_func(svga, svga->ma); - dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; - } else - memset(&(p[x]), 0x00, 2 * sizeof(uint32_t)); - - svga->ma += 4; - } + 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]; + } else + memset(&(p[x]), 0x00, 8 * sizeof(uint32_t)); } + svga->ma += x << 1; svga->ma &= svga->vram_display_mask; - } + } + } else { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + if (svga->crtc[0x17] & 0x80) { + 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) + 4) & 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++ = 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]; + } else + memset(&(p[x]), 0x00, 8 * sizeof(uint32_t)); + } + svga->ma += x << 1; + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { + if (svga->crtc[0x17] & 0x80) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + } else + memset(&(p[x]), 0x00, 2 * sizeof(uint32_t)); + + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; + } + } } @@ -1182,56 +1602,79 @@ svga_render_24bpp_lowres(svga_t *svga) uint32_t *p; uint32_t changed_addr, addr; uint32_t dat0, dat1, dat2; + uint32_t fg; if ((svga->displine + svga->y_add) < 0) return; + + if (svga->force_old_addr) { + if ((svga->displine + svga->y_add) < 0) + return; - changed_addr = svga->remap_func(svga, svga->ma); + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - if (svga->crtc[0x17] & 0x80) { - dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); - dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); - } else - dat0 = dat1 = dat2 = 0x00000000; - - 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; + if (svga->crtc[0x17] & 0x80) + fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); + else + fg = 0x00000000; + svga->ma += 3; + svga->ma &= svga->vram_display_mask; + buffer32->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = + buffer32->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = fg; } - } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - if (svga->crtc[0x17] & 0x80) { - 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]); - } else - dat0 = dat1 = dat2 = 0x00000000; - - 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; } - } - svga->ma &= svga->vram_display_mask; + } else { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + if (svga->crtc[0x17] & 0x80) { + dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); + } else + dat0 = dat1 = dat2 = 0x00000000; + + 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 + svga->scrollcache); x += 4) { + if (svga->crtc[0x17] & 0x80) { + 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]); + } else + dat0 = dat1 = dat2 = 0x00000000; + + 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; + } + } + svga->ma &= svga->vram_display_mask; + } } } @@ -1243,57 +1686,88 @@ svga_render_24bpp_highres(svga_t *svga) uint32_t *p; uint32_t changed_addr, addr; uint32_t dat0, dat1, dat2; + uint32_t dat; if ((svga->displine + svga->y_add) < 0) return; + + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - changed_addr = svga->remap_func(svga, svga->ma); + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { if (svga->crtc[0x17] & 0x80) { - dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); - dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); + dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + p[x] = dat & 0xffffff; - *p++ = dat0 & 0xffffff; - *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8); - *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16); - *p++ = dat2 >> 8; + 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; } else memset(&(p[x]), 0x0, 4 * sizeof(uint32_t)); svga->ma += 12; } + svga->ma &= svga->vram_display_mask; + } } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - if (svga->crtc[0x17] & 0x80) { - 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]); + changed_addr = svga->remap_func(svga, svga->ma); - *p++ = dat0 & 0xffffff; - *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8); - *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16); - *p++ = dat2 >> 8; - } else - memset(&(p[x]), 0x0, 4 * sizeof(uint32_t)); + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - svga->ma += 12; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { + if (svga->crtc[0x17] & 0x80) { + dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + 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; + } else + memset(&(p[x]), 0x0, 4 * sizeof(uint32_t)); + + svga->ma += 12; + } + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { + if (svga->crtc[0x17] & 0x80) { + 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; + } else + memset(&(p[x]), 0x0, 4 * sizeof(uint32_t)); + + svga->ma += 12; + } } + svga->ma &= svga->vram_display_mask; + } } - svga->ma &= svga->vram_display_mask; - } } @@ -1307,40 +1781,59 @@ svga_render_32bpp_lowres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; + + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - changed_addr = svga->remap_func(svga, svga->ma); - - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { if (svga->crtc[0x17] & 0x80) - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + dat = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); else dat = 0x00000000; - *p++ = dat & 0xffffff; - *p++ = dat & 0xffffff; - } - svga->ma += (x * 4); - } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - if (svga->crtc[0x17] & 0x80) { - addr = svga->remap_func(svga, svga->ma); - dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - } else - dat = 0x00000000; - *p++ = dat & 0xffffff; - *p++ = dat & 0xffffff; svga->ma += 4; + svga->ma &= svga->vram_display_mask; + buffer32->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = + buffer32->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = dat; + } + } + } else { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + if (svga->crtc[0x17] & 0x80) + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + else + dat = 0x00000000; + *p++ = dat & 0xffffff; + *p++ = dat & 0xffffff; + } + svga->ma += (x * 4); + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + if (svga->crtc[0x17] & 0x80) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + } else + dat = 0x00000000; + *p++ = dat & 0xffffff; + *p++ = dat & 0xffffff; + svga->ma += 4; + } + svga->ma &= svga->vram_display_mask; + } } - svga->ma &= svga->vram_display_mask; } - } } @@ -1354,39 +1847,59 @@ svga_render_32bpp_highres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; + + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - changed_addr = svga->remap_func(svga, svga->ma); - - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - if (svga->crtc[0x17] & 0x80) { + if (svga->crtc[0x17] & 0x80) dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - *p++ = dat & 0xffffff; - } else - memset(&(p[x]), 0x0, 1 * sizeof(uint32_t)); + else + dat = 0x00000000; + p[x] = dat & 0xffffff; + } + svga->ma += 4; + svga->ma &= svga->vram_display_mask; } - svga->ma += (x * 4); } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - if (svga->crtc[0x17] & 0x80) { - addr = svga->remap_func(svga, svga->ma); - dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - *p++ = dat & 0xffffff; - } else - memset(&(p[x]), 0x0, 1 * sizeof(uint32_t)); + changed_addr = svga->remap_func(svga, svga->ma); - svga->ma += 4; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + if (svga->crtc[0x17] & 0x80) { + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + *p++ = dat & 0xffffff; + } else + memset(&(p[x]), 0x0, 1 * sizeof(uint32_t)); + } + svga->ma += (x * 4); + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + if (svga->crtc[0x17] & 0x80) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + *p++ = dat & 0xffffff; + } else + memset(&(p[x]), 0x0, 1 * sizeof(uint32_t)); + + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; } } - svga->ma &= svga->vram_display_mask; - } }