From 7198b78069a84b9bb8a04fd1420152a0c470d4a7 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 7 Feb 2024 01:53:16 +0100 Subject: [PATCH] Couple of changes in the video side. 1. Second attempt to fix the banking in the Cirrus (sigh, why doesn't banking get nulled automatically...) 2. Introduce a new timer to the 8514/A side so it won't slow the VGA clock down it was shared before. --- src/include/86box/vid_8514a.h | 3 + src/include/86box/vid_svga.h | 4 +- src/include/86box/vid_svga_render.h | 1 + src/video/vid_8514a.c | 259 +++++++++++++++------------- src/video/vid_ati_mach8.c | 55 ++---- src/video/vid_cl54xx.c | 4 - src/video/vid_svga.c | 75 +++++++- 7 files changed, 234 insertions(+), 167 deletions(-) diff --git a/src/include/86box/vid_8514a.h b/src/include/86box/vid_8514a.h index ce346e84d..fab504bbe 100644 --- a/src/include/86box/vid_8514a.h +++ b/src/include/86box/vid_8514a.h @@ -64,6 +64,9 @@ typedef struct ibm8514_t { int hwcursor_on; int modechange; + uint64_t dispontime; + uint64_t dispofftime; + struct { uint16_t subsys_cntl; uint16_t setup_md; diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 32bfbfd2f..624e85a1b 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -166,8 +166,10 @@ typedef struct svga_t { latch_t latch; pc_timer_t timer; + pc_timer_t timer8514; double clock; + double clock8514; hwcursor_t hwcursor; hwcursor_t hwcursor_latch; @@ -287,7 +289,7 @@ typedef struct svga_t { extern int vga_on; -extern void ibm8514_poll(void *priv, svga_t *svga); +extern void ibm8514_poll(void *priv); extern void ibm8514_recalctimings(svga_t *svga); extern uint8_t ibm8514_ramdac_in(uint16_t port, void *priv); extern void ibm8514_ramdac_out(uint16_t port, uint8_t val, void *priv); diff --git a/src/include/86box/vid_svga_render.h b/src/include/86box/vid_svga_render.h index 33bb13bbf..febb5f917 100644 --- a/src/include/86box/vid_svga_render.h +++ b/src/include/86box/vid_svga_render.h @@ -75,6 +75,7 @@ extern void svga_render_ABGR8888_highres(svga_t *svga); extern void svga_render_RGBA8888_lowres(svga_t *svga); extern void svga_render_RGBA8888_highres(svga_t *svga); +extern void ibm8514_render_blank(svga_t *svga); extern void ibm8514_render_8bpp(svga_t *svga); extern void ibm8514_render_15bpp(svga_t *svga); extern void ibm8514_render_16bpp(svga_t *svga); diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index fdbd39979..3505d1e0b 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -925,7 +925,7 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) if (!(port & 1)) { if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { dev->hsync_width = val; - dev->hblank_end_val = (dev->hblankstart + (dev->hsync_start & 0x1f) - 1) & 0x3f; + dev->hblank_end_val = (dev->hblankstart + (dev->hsync_width & 0x1f) - 1) & 0x3f; } } ibm8514_log("IBM 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); @@ -3831,6 +3831,25 @@ bitblt: } } +void +ibm8514_render_blank(svga_t *svga) +{ + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + + if ((dev->displine + svga->y_add) < 0) + return; + + if (dev->firstline_draw == 2000) + dev->firstline_draw = dev->displine; + dev->lastline_draw = dev->displine; + + uint32_t *line_ptr = &svga->monitor->target_buffer->line[dev->displine + svga->y_add][svga->x_add]; + uint32_t line_width = (uint32_t)(dev->h_disp) * sizeof(uint32_t); + + if (dev->h_disp > 0) + memset(line_ptr, 0, line_width); +} + void ibm8514_render_8bpp(svga_t *svga) { @@ -4106,148 +4125,153 @@ ibm8514_render_overscan_right(ibm8514_t *dev, svga_t *svga) } void -ibm8514_poll(void *priv, svga_t *svga) +ibm8514_poll(void *priv) { - ibm8514_t *dev = (ibm8514_t *) priv; + svga_t *svga = (svga_t *)priv; + ibm8514_t *dev = (ibm8514_t *)svga->dev8514; uint32_t x; int wx; int wy; - if (!dev->linepos) { - if ((dev->displine == dev->hwcursor_latch.y) && dev->hwcursor_latch.ena) { - dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - dev->hwcursor_latch.yoff; - dev->hwcursor_oddeven = 0; - } - - if ((dev->displine == (dev->hwcursor_latch.y + 1)) && dev->hwcursor_latch.ena && dev->interlace) { - dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - (dev->hwcursor_latch.yoff + 1); - dev->hwcursor_oddeven = 1; - } - - timer_advance_u64(&svga->timer, svga->dispofftime); - svga->cgastat |= 1; - dev->linepos = 1; - - if (dev->dispon) { - dev->hdisp_on = 1; - - dev->ma &= dev->vram_mask; - - if (dev->firstline == 2000) { - dev->firstline = dev->displine; - video_wait_for_buffer_monitor(svga->monitor_index); + ibm8514_log("IBM 8514/A poll.\n"); + if (dev->on[0] || dev->on[1]) { + ibm8514_log("ON!\n"); + if (!dev->linepos) { + if ((dev->displine == dev->hwcursor_latch.y) && dev->hwcursor_latch.ena) { + dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - dev->hwcursor_latch.yoff; + dev->hwcursor_oddeven = 0; } - if (dev->hwcursor_on) - dev->changedvram[dev->ma >> 12] = dev->changedvram[(dev->ma >> 12) + 1] = dev->interlace ? 3 : 2; + if ((dev->displine == (dev->hwcursor_latch.y + 1)) && dev->hwcursor_latch.ena && dev->interlace) { + dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - (dev->hwcursor_latch.yoff + 1); + dev->hwcursor_oddeven = 1; + } - svga->render8514(svga); + timer_advance_u64(&svga->timer8514, dev->dispofftime); + svga->cgastat |= 1; + dev->linepos = 1; - svga->x_add = (overscan_x >> 1); - ibm8514_render_overscan_left(dev, svga); - ibm8514_render_overscan_right(dev, svga); - svga->x_add = (overscan_x >> 1); + if (dev->dispon) { + dev->hdisp_on = 1; - if (dev->hwcursor_on) { - if (svga->hwcursor_draw) - svga->hwcursor_draw(svga, dev->displine + svga->y_add); - dev->hwcursor_on--; - if (dev->hwcursor_on && dev->interlace) + dev->ma &= dev->vram_mask; + + if (dev->firstline == 2000) { + dev->firstline = dev->displine; + video_wait_for_buffer_monitor(svga->monitor_index); + } + + if (dev->hwcursor_on) + dev->changedvram[dev->ma >> 12] = dev->changedvram[(dev->ma >> 12) + 1] = dev->interlace ? 3 : 2; + + svga->render8514(svga); + + svga->x_add = (overscan_x >> 1); + ibm8514_render_overscan_left(dev, svga); + ibm8514_render_overscan_right(dev, svga); + svga->x_add = (overscan_x >> 1); + + if (dev->hwcursor_on) { + if (svga->hwcursor_draw) + svga->hwcursor_draw(svga, dev->displine + svga->y_add); dev->hwcursor_on--; + if (dev->hwcursor_on && dev->interlace) + dev->hwcursor_on--; + } + + if (dev->lastline < dev->displine) + dev->lastline = dev->displine; } - if (dev->lastline < dev->displine) - dev->lastline = dev->displine; - } - - dev->displine++; - if (dev->interlace) dev->displine++; - if ((svga->cgastat & 8) && ((dev->displine & 0x0f) == (svga->crtc[0x11] & 0x0f)) && svga->vslines) - svga->cgastat &= ~8; - svga->vslines++; - if (dev->displine > 1500) - dev->displine = 0; - } else { - timer_advance_u64(&svga->timer, svga->dispontime); - if (dev->dispon) - svga->cgastat &= ~1; - dev->hdisp_on = 0; + if (dev->interlace) + dev->displine++; + if ((svga->cgastat & 8) && ((dev->displine & 0x0f) == (svga->crtc[0x11] & 0x0f)) && svga->vslines) + svga->cgastat &= ~8; + svga->vslines++; + if (dev->displine > 1500) + dev->displine = 0; + } else { + timer_advance_u64(&svga->timer8514, dev->dispontime); + if (dev->dispon) + svga->cgastat &= ~1; + dev->hdisp_on = 0; - dev->linepos = 0; - if (dev->dispon) { - if (dev->sc == dev->rowcount) { - dev->sc = 0; - dev->maback += (dev->rowoffset << 3); - if (dev->interlace) + dev->linepos = 0; + if (dev->dispon) { + if (dev->sc == dev->rowcount) { + dev->sc = 0; dev->maback += (dev->rowoffset << 3); + if (dev->interlace) + dev->maback += (dev->rowoffset << 3); - dev->maback &= dev->vram_mask; - dev->ma = dev->maback; - } else { - dev->sc++; - dev->sc &= 0x1f; - dev->ma = dev->maback; - } - } - - dev->vc++; - dev->vc &= 0x7ff; - - if (dev->vc == dev->dispend) { - dev->dispon = 0; - - for (x = 0; x < ((dev->vram_mask + 1) >> 12); x++) { - if (dev->changedvram[x]) - dev->changedvram[x]--; + dev->maback &= dev->vram_mask; + dev->ma = dev->maback; + } else { + dev->sc++; + dev->sc &= 0x1f; + dev->ma = dev->maback; + } } - if (svga->fullchange) - svga->fullchange--; - } - if (dev->vc == dev->v_syncstart) { - dev->dispon = 0; - svga->cgastat |= 8; - x = dev->h_disp; + dev->vc++; + dev->vc &= 0x7ff; - if (dev->interlace && !dev->oddeven) - dev->lastline++; - if (dev->interlace && dev->oddeven) - dev->firstline--; + if (dev->vc == dev->dispend) { + dev->dispon = 0; - wx = x; - wy = dev->lastline - dev->firstline; - svga_doblit(wx, wy, svga); + for (x = 0; x < ((dev->vram_mask + 1) >> 12); x++) { + if (dev->changedvram[x]) + dev->changedvram[x]--; + } - dev->firstline = 2000; - dev->lastline = 0; + if (svga->fullchange) + svga->fullchange--; + } + if (dev->vc == dev->v_syncstart) { + dev->dispon = 0; + svga->cgastat |= 8; + x = dev->h_disp; - dev->firstline_draw = 2000; - dev->lastline_draw = 0; + if (dev->interlace && !dev->oddeven) + dev->lastline++; + if (dev->interlace && dev->oddeven) + dev->firstline--; - dev->oddeven ^= 1; + wx = x; + wy = dev->lastline - dev->firstline; + svga_doblit(wx, wy, svga); - svga->monitor->mon_changeframecount = dev->interlace ? 3 : 2; - svga->vslines = 0; + dev->firstline = 2000; + dev->lastline = 0; - if (dev->interlace && dev->oddeven) - dev->ma = dev->maback = (dev->rowoffset << 1); - else - dev->ma = dev->maback = 0; + dev->firstline_draw = 2000; + dev->lastline_draw = 0; - dev->ma = (dev->ma << 2); - dev->maback = (dev->maback << 2); - } - if (dev->vc == dev->v_total) { - dev->vc = 0; - dev->sc = 0; - dev->dispon = 1; - dev->displine = (dev->interlace && dev->oddeven) ? 1 : 0; + dev->oddeven ^= 1; - svga->x_add = (overscan_x >> 1); + svga->monitor->mon_changeframecount = dev->interlace ? 3 : 2; + svga->vslines = 0; - dev->hwcursor_on = 0; - dev->hwcursor_latch = dev->hwcursor; + if (dev->interlace && dev->oddeven) + dev->ma = dev->maback = (dev->rowoffset << 1); + else + dev->ma = dev->maback = 0; + + dev->ma = (dev->ma << 2); + dev->maback = (dev->maback << 2); + } + if (dev->vc == dev->v_total) { + dev->vc = 0; + dev->sc = 0; + dev->dispon = 1; + dev->displine = (dev->interlace && dev->oddeven) ? 1 : 0; + + svga->x_add = (overscan_x >> 1); + + dev->hwcursor_on = 0; + dev->hwcursor_latch = dev->hwcursor; + } } } } @@ -4257,6 +4281,7 @@ ibm8514_recalctimings(svga_t *svga) { ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + svga->render8514 = ibm8514_render_blank; #ifdef ATI_8514_ULTRA if (dev->extensions) { if (svga->ext8514 != NULL) @@ -4283,14 +4308,14 @@ ibm8514_recalctimings(svga_t *svga) dev->h_disp = 1024; dev->dispend = 768; } - svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0; } else { dev->pitch = 640; if (!dev->h_disp) { dev->h_disp = 640; dev->dispend = 480; } - svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; } if (dev->interlace) { @@ -4429,6 +4454,8 @@ ibm8514_init(const device_t *info) } #endif + timer_add(&svga->timer8514, ibm8514_poll, svga, 0); + return svga; } diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index ff6024677..5628e149a 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -2485,9 +2485,6 @@ ati8514_recalctimings(svga_t *svga) { const mach_t *mach = (mach_t *) svga->ext8514; ibm8514_t *dev = (ibm8514_t *) svga->dev8514; - uint32_t dot; - uint32_t adj_dot; - uint32_t eff_mask; mach_log("ON0=%d, ON1=%d, vgahdisp=%d.\n", dev->on[0], dev->on[1], svga->hdisp); if (dev->on[0] || dev->on[1]) { @@ -2530,27 +2527,6 @@ ati8514_recalctimings(svga_t *svga) mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, advfunc_cntl=%x, shadow=%x.\n", dev->accel.advfunc_cntl & 4, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, dev->accel.advfunc_cntl & 4, mach->shadow_set & 3); svga->map8 = dev->pallook; svga->render8514 = ibm8514_render_8bpp; - - dot = svga->hblankstart; - adj_dot = svga->hblankstart; - eff_mask = 0x0000003f; - dev->hblank_sub = 0; - - while (1) { - if (dot == dev->h_total) - dot = 0; - - if (adj_dot >= dev->h_total) - dev->hblank_sub++; - - if ((dot & 0x0000003f) == (svga->hblank_end_val & 0x0000003f)) - break; - - dot++; - adj_dot++; - } - - dev->h_disp -= dev->hblank_sub); } else { if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ if (svga->seqregs[1] & 8) { /*40 column*/ @@ -2615,6 +2591,8 @@ mach_recalctimings(svga_t *svga) } else svga->ati_4color = 0; } + + svga->render8514 = ibm8514_render_blank; mach_log("ON[0]=%d, ON[1]=%d, exton[0]=%d, exton[1]=%d, vendormode0=%d, vendormode1=%d.\n", dev->on[0], dev->on[1], mach->ext_on[0], mach->ext_on[1], dev->vendor_mode[0], dev->vendor_mode[1]); if (dev->on[0] || dev->on[1]) { mach_log("8514/A ON.\n"); @@ -2639,14 +2617,14 @@ mach_recalctimings(svga_t *svga) if ((dev->local & 0xff) >= 0x02) { if ((dev->accel.advfunc_cntl ^ dev->modechange) & 0x04) { if ((mach->shadow_set ^ mach->compat_mode) & 0x03) - svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); else - svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0; } else { if ((mach->shadow_set ^ mach->compat_mode) & 0x03) - svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); else - svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; } if (dev->interlace) { @@ -2706,13 +2684,13 @@ mach_recalctimings(svga_t *svga) } switch (mach->regs[0xb8] & 0xc0) { case 0x40: - svga->clock *= 2; + svga->clock8514 *= 2; break; case 0x80: - svga->clock *= 3; + svga->clock8514 *= 3; break; case 0xc0: - svga->clock *= 4; + svga->clock8514 *= 4; break; default: @@ -2721,21 +2699,20 @@ mach_recalctimings(svga_t *svga) } else { if ((dev->accel.advfunc_cntl ^ dev->modechange) & 0x04) { if ((mach->shadow_set ^ mach->compat_mode) & 0x03) - svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); else - svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0; } else { if ((mach->shadow_set ^ mach->compat_mode) & 0x03) - svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); else - svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; if (((mach->shadow_set & 0x03) != 0x02) || !(dev->accel.advfunc_cntl & 0x04)) { /*Shadow set of 2 and bit 2 of port 0x4ae8 mean 1024x768+*/ if (!(mach->accel.clock_sel & 0x01)) { dev->h_disp = 640; dev->dispend = 480; } - dev->interlace = 0; } } @@ -2754,7 +2731,7 @@ mach_recalctimings(svga_t *svga) svga->map8 = dev->pallook; svga->render8514 = ibm8514_render_8bpp; if (mach->regs[0xb8] & 0x40) - svga->clock *= 2; + svga->clock8514 *= 2; } } @@ -3670,7 +3647,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 if (!(port & 1)) { if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { dev->hsync_width = val; - dev->hblank_end_val = (dev->hblankstart + (dev->hsync_start & 0x1f) - 1) & 0x3f; + dev->hblank_end_val = (dev->hblankstart + (dev->hsync_width & 0x1f) - 1) & 0x3f; } } mach_log("ATI 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); @@ -6080,6 +6057,8 @@ mach8_init(const device_t *info) } else ati_eeprom_load_mach8(&mach->eeprom, "mach8.nvr"); + timer_add(&svga->timer8514, ibm8514_poll, svga, 0); + return mach; } diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 7ae985e95..49899b7b4 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -1643,10 +1643,6 @@ gd54xx_recalc_banking(gd54xx_t *gd54xx) svga->extra_banks[1] = svga->extra_banks[0] + 0x8000; } - if (!(svga->gdcreg[5] & 0x40) || !(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) { - svga->extra_banks[0] = 0; - svga->extra_banks[1] = 0x8000; - } svga->write_bank = svga->read_bank = svga->extra_banks[0]; } diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index a1ab605ea..d982a1ada 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -222,6 +222,7 @@ svga_out(uint16_t addr, uint8_t val, void *priv) svga_log("3C3: VGA ON = %d.\n", val & 0x01); vga_on = val & 0x01; + svga_recalctimings(svga); break; case 0x3c4: svga->seqaddr = val; @@ -567,11 +568,15 @@ svga_set_ramdac_type(svga_t *svga, int type) void svga_recalctimings(svga_t *svga) { - const ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; double crtcconst; double _dispontime; double _dispofftime; double disptime; + double crtcconst8514; + double _dispontime8514; + double _dispofftime8514; + double disptime8514; #ifdef ENABLE_SVGA_LOG int vsyncend; int vblankend; @@ -805,6 +810,31 @@ svga_recalctimings(svga_t *svga) } svga->hdisp -= (svga->hblank_sub * svga->dots_per_clock); + + if (ibm8514_active && (svga->dev8514 != NULL)) { + if (dev->on[0] || dev->on[1]) { + uint32_t dot8514 = dev->h_blankstart; + uint32_t adj_dot8514 = dev->h_blankstart; + uint32_t eff_mask8514 = 0x0000003f; + dev->hblank_sub = 0; + + while (1) { + if (dot8514 == dev->h_total) + dot = 0; + + if (adj_dot8514 >= dev->h_total) + dev->hblank_sub++; + + if ((dot8514 & eff_mask8514) == (dev->h_blank_end_val & eff_mask8514)) + break; + + dot8514++; + adj_dot8514++; + } + + dev->h_disp -= dev->hblank_sub; + } + } } if (svga->hdisp >= 2048) @@ -817,6 +847,10 @@ svga_recalctimings(svga_t *svga) svga->dispend = svga->vblankstart; crtcconst = svga->clock * svga->char_width; + if (ibm8514_active && (svga->dev8514 != NULL)) { + if (dev->on[0] || dev->on[1]) + crtcconst8514 = svga->clock8514; + } #ifdef ENABLE_SVGA_LOG vsyncend = (svga->vsyncstart & 0xfffffff0) | (svga->crtc[0x11] & 0x0f); @@ -858,6 +892,13 @@ svga_recalctimings(svga_t *svga) disptime = svga->htotal; _dispontime = svga->hdisp_time; + if (ibm8514_active && (svga->dev8514 != NULL)) { + if (dev->on[0] || dev->on[1]) { + disptime8514 = dev->htotal; + _dispontime8514 = dev->hdisped; + } + } + if (svga->seqregs[1] & 8) { disptime *= 2; _dispontime *= 2; @@ -874,6 +915,27 @@ svga_recalctimings(svga_t *svga) if (svga->dispofftime < TIMER_USEC) svga->dispofftime = TIMER_USEC; + if (ibm8514_active && (svga->dev8514 != NULL)) { + if (dev->on[0] || dev->on[1]) { + _dispofftime8514 = disptime8514 - _dispontime8514; + _dispontime8514 *= crtcconst8514; + _dispofftime8514 *= crtcconst8514; + + dev->dispontime = (uint64_t) (_dispontime8514); + dev->dispofftime = (uint64_t) (_dispofftime8514); + if (dev->dispontime < TIMER_USEC) + dev->dispontime = TIMER_USEC; + if (dev->dispofftime < TIMER_USEC) + dev->dispofftime = TIMER_USEC; + + timer_disable(&svga->timer); + timer_enable(&svga->timer8514); + } else { + timer_disable(&svga->timer8514); + timer_enable(&svga->timer); + } + } + if (!svga->force_old_addr) svga_recalc_remap_func(svga); @@ -946,10 +1008,6 @@ svga_poll(void *priv) int old_ma; if (!svga->override) { - if (ibm8514_active && dev && (dev->on[0] || dev->on[1])) { - ibm8514_poll(dev, svga); - return; - } if (xga_active && xga && xga->on) { if ((xga->disp_cntl_2 & 7) >= 2) { xga_poll(xga, svga); @@ -1347,9 +1405,10 @@ svga_decode_addr(svga_t *svga, uint32_t addr, int write) } if (memory_map_mode <= 1) { - if (svga->adv_flags & FLAG_EXTRA_BANKS) - addr = (addr & 0x17fff) + svga->extra_banks[(addr >> 15) & 1]; - else { + if (svga->adv_flags & FLAG_EXTRA_BANKS) { + if ((svga->gdcreg[5] & 0x40) || svga->packed_chain4) + addr = (addr & 0x17fff) + svga->extra_banks[(addr >> 15) & 1]; + } else { if (write) addr += svga->write_bank; else