diff options
Diffstat (limited to 'src/devices/video/voodoo.cpp')
-rw-r--r-- | src/devices/video/voodoo.cpp | 50 |
1 files changed, 32 insertions, 18 deletions
diff --git a/src/devices/video/voodoo.cpp b/src/devices/video/voodoo.cpp index b9f77931c90..639a0af1e2f 100644 --- a/src/devices/video/voodoo.cpp +++ b/src/devices/video/voodoo.cpp @@ -482,7 +482,8 @@ void voodoo_device::init_fbi(voodoo_device* vd,fbi_state *f, void *memory, int f } /* allocate a VBLANK timer */ - f->vblank_timer = vd->machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(voodoo_device::vblank_callback),vd), vd); + f->vsync_stop_timer = vd->machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(voodoo_device::vblank_off_callback), vd), vd); + f->vsync_start_timer = vd->machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(voodoo_device::vblank_callback),vd), vd); f->vblank = false; /* initialize the memory FIFO */ @@ -643,7 +644,8 @@ void voodoo_device::init_save_state(voodoo_device *vd) vd->save_item(NAME(vd->fbi.height)); vd->save_item(NAME(vd->fbi.xoffs)); vd->save_item(NAME(vd->fbi.yoffs)); - vd->save_item(NAME(vd->fbi.vsyncscan)); + vd->save_item(NAME(vd->fbi.vsyncstart)); + vd->save_item(NAME(vd->fbi.vsyncstop)); vd->save_item(NAME(vd->fbi.rowpixels)); vd->save_item(NAME(vd->fbi.vblank)); vd->save_item(NAME(vd->fbi.vblank_count)); @@ -930,14 +932,14 @@ void voodoo_device::swap_buffers(voodoo_device *vd) } -static void adjust_vblank_timer(voodoo_device *vd) +void voodoo_device::adjust_vblank_timer() { - attotime vblank_period = vd->screen->time_until_pos(vd->fbi.vsyncscan); - if (LOG_VBLANK_SWAP) vd->logerror("adjust_vblank_timer: period: %s\n", vblank_period.as_string()); + attotime vblank_period = screen->time_until_pos(fbi.vsyncstart); + if (LOG_VBLANK_SWAP) logerror("adjust_vblank_timer: period: %s\n", vblank_period.as_string()); /* if zero, adjust to next frame, otherwise we may get stuck in an infinite loop */ if (vblank_period == attotime::zero) - vblank_period = vd->screen->frame_period(); - vd->fbi.vblank_timer->adjust(vblank_period); + vblank_period = screen->frame_period(); + fbi.vsync_start_timer->adjust(vblank_period); } @@ -965,7 +967,7 @@ TIMER_CALLBACK_MEMBER( voodoo_device::vblank_off_callback ) m_vblank(false); /* go to the end of the next frame */ - adjust_vblank_timer(this); + adjust_vblank_timer(); } @@ -995,7 +997,7 @@ TIMER_CALLBACK_MEMBER( voodoo_device::vblank_callback ) swap_buffers(this); /* set a timer for the next off state */ - machine().scheduler().timer_set(screen->time_until_pos(0), timer_expired_delegate(FUNC(voodoo_device::vblank_off_callback),this), 0, this); + fbi.vsync_stop_timer->adjust(screen->time_until_pos(fbi.vsyncstop)); @@ -2632,10 +2634,11 @@ int32_t voodoo_device::register_w(voodoo_device *vd, offs_t offset, uint32_t dat vd->fbi.height = vvis; vd->fbi.xoffs = hbp; vd->fbi.yoffs = vbp; - vd->fbi.vsyncscan = (vd->reg[vSync].u >> 16) & 0xfff; - + vd->fbi.vsyncstart = (vd->reg[vSync].u >> 16) & 0xfff; + vd->fbi.vsyncstop = (vd->reg[vSync].u >> 0) & 0xfff; + osd_printf_debug("yoffs: %d vsyncstart: %d vsyncstop: %d\n", vbp, vd->fbi.vsyncstart, vd->fbi.vsyncstop); /* recompute the time of VBLANK */ - adjust_vblank_timer(vd); + vd->adjust_vblank_timer(); /* if changing dimensions, update video memory layout */ if (regnum == videoDimensions) @@ -3947,7 +3950,6 @@ uint32_t voodoo_device::register_r(voodoo_device *vd, offs_t offset) /* return the current visible scanline */ case vRetrace: - /* eat some cycles since people like polling here */ if (EAT_CYCLES) vd->cpu->execute().eat_cycles(10); // Return 0 if vblank is active @@ -4950,10 +4952,19 @@ WRITE32_MEMBER( voodoo_banshee_device::banshee_io_w ) int vtotal = banshee.crtc[6]; vtotal |= ((banshee.crtc[7] >> 0) & 0x1) << 8; vtotal |= ((banshee.crtc[7] >> 5) & 0x1) << 9; + vtotal += 2; + int vstart = banshee.crtc[0x10]; vstart |= ((banshee.crtc[7] >> 2) & 0x1) << 8; vstart |= ((banshee.crtc[7] >> 7) & 0x1) << 9; + int vstop = banshee.crtc[0x11] & 0xf; + // Compare to see if vstop is before or after low 4 bits of vstart + if (vstop < (vstart & 0xf)) + vstop |= (vstart + 0x10) & ~0xf; + else + vstop |= vstart & ~0xf; + // Get pll k, m and n from pllCtrl0 const uint32_t k = (banshee.io[io_pllCtrl0] >> 0) & 0x3; const uint32_t m = (banshee.io[io_pllCtrl0] >> 2) & 0x3f; @@ -4964,21 +4975,24 @@ WRITE32_MEMBER( voodoo_banshee_device::banshee_io_w ) int width = fbi.width; int height = fbi.height; + //vd->fbi.xoffs = hbp; + //vd->fbi.yoffs = vbp; if (banshee.io[io_vidOverlayDudx] != 0) width = (fbi.width * banshee.io[io_vidOverlayDudx]) / 1048576; if (banshee.io[io_vidOverlayDvdy] != 0) height = (fbi.height * banshee.io[io_vidOverlayDvdy]) / 1048576; if (LOG_REGISTERS) - logerror("configure screen: htotal: %d vtotal: %d vstart: %d width: %d height: %d refresh: %f\n", - htotal, vtotal, vstart, width, height, 1.0 / frame_period); + logerror("configure screen: htotal: %d vtotal: %d vstart: %d vstop: %d width: %d height: %d refresh: %f\n", + htotal, vtotal, vstart, vstop, width, height, 1.0 / frame_period); if (htotal > 0 && vtotal > 0) { rectangle visarea(0, width - 1, 0, height - 1); screen->configure(htotal, vtotal, visarea, DOUBLE_TO_ATTOSECONDS(frame_period)); - // Set the vsync start - fbi.vsyncscan = vstart; - adjust_vblank_timer(this); + // Set the vsync start and stop + fbi.vsyncstart = vstart; + fbi.vsyncstop = vstop; + adjust_vblank_timer(); } if (LOG_REGISTERS) logerror("%s:banshee_io_w(%s) = %08X & %08X\n", machine().describe_context(), banshee_io_reg_name[offset], data, mem_mask); |