Calculate screen size and timing using voodoo CRTC and PLL registers. (nw)

This commit is contained in:
Ted Green 2018-01-06 11:05:45 -07:00
parent 71ffd5f082
commit 0e6222c005
3 changed files with 49 additions and 36 deletions

View File

@ -673,6 +673,8 @@ void vrc5074_device::update_pci_irq(const int index, const int state)
{
m_nile_irq_state &= ~(1 << (index + 8));
m_nile_irq_state |= state << (index + 8);
if (LOG_NILE_IRQS)
logerror("update_pci_irq: m_nile_irq_state: %04x index=%d state=%d\n", m_nile_irq_state, index, state);
update_nile_irqs();
}
@ -725,15 +727,14 @@ void vrc5074_device::update_nile_irqs()
if (LOG_NILE_IRQS) logerror("NILE IRQs:");
for (i = 0; i < 6; i++)
{
if (LOG_NILE_IRQS) logerror(" %d", (irq & (1 << i)) ? 1 : 0);
if (change & (1 << i)) {
if (irq & (1 << i))
{
if (LOG_NILE_IRQS) logerror(" 1");
m_cpu->set_input_line(MIPS3_IRQ0 + i, ASSERT_LINE);
}
else
{
if (LOG_NILE_IRQS) logerror(" 0");
m_cpu->set_input_line(MIPS3_IRQ0 + i, CLEAR_LINE);
}
}
@ -747,7 +748,7 @@ TIMER_CALLBACK_MEMBER(vrc5074_device::nile_timer_callback)
{
int which = param;
if (LOG_TIMERS) logerror("timer %d fired\n", which);
if (LOG_TIMERS | LOG_NILE_IRQS) logerror("timer %d fired period: %e\n", which, m_timer_period[which]);
/* adjust the timer to fire again */
{
@ -787,7 +788,7 @@ READ32_MEMBER(vrc5074_device::cpu_reg_r)
case NREG_INTCTRL + 0: /* Interrupt control */
case NREG_INTCTRL + 1: /* Interrupt control */
if (LOG_NILE) logerror("%s NILE READ: interrupt control(%03X) = %08X\n", machine().describe_context(), offset * 4, result);
if (LOG_NILE | LOG_NILE_IRQS) logerror("%s NILE READ: interrupt control(%03X) = %08X\n", machine().describe_context(), offset * 4, result);
update_nile_irqs();
logit = 0;
break;
@ -891,28 +892,28 @@ WRITE32_MEMBER(vrc5074_device::cpu_reg_w)
case NREG_INTCTRL + 0: /* Interrupt control */
case NREG_INTCTRL + 1: /* Interrupt control */
if (LOG_NILE) logerror("%s NILE WRITE: interrupt control(%03X) = %08X & %08X\n", machine().describe_context(), offset * 4, data, mem_mask);
if (LOG_NILE | LOG_NILE_IRQS) logerror("%s NILE WRITE: interrupt control(%03X) = %08X & %08X\n", machine().describe_context(), offset * 4, data, mem_mask);
logit = 0;
update_nile_irqs();
break;
case NREG_INTSTAT0 + 0: /* Interrupt status 0 */
case NREG_INTSTAT0 + 1: /* Interrupt status 0 */
if (LOG_NILE) logerror("%s NILE WRITE: interrupt status 0(%03X) = %08X & %08X\n", machine().describe_context(), offset * 4, data, mem_mask);
if (LOG_NILE | LOG_NILE_IRQS) logerror("%s NILE WRITE: interrupt status 0(%03X) = %08X & %08X\n", machine().describe_context(), offset * 4, data, mem_mask);
logit = 0;
update_nile_irqs();
break;
case NREG_INTSTAT1 + 0: /* Interrupt status 1 */
case NREG_INTSTAT1 + 1: /* Interrupt status 1 */
if (LOG_NILE) logerror("%s NILE WRITE: interrupt status 1/enable(%03X) = %08X & %08X\n", machine().describe_context(), offset * 4, data, mem_mask);
if (LOG_NILE | LOG_NILE_IRQS) logerror("%s NILE WRITE: interrupt status 1/enable(%03X) = %08X & %08X\n", machine().describe_context(), offset * 4, data, mem_mask);
logit = 0;
update_nile_irqs();
break;
case NREG_INTCLR + 0: /* Interrupt clear */
//case NREG_INTCLR + 1: /* Interrupt clear */
if (LOG_NILE) logerror("%s NILE WRITE: interrupt clear(%03X) = %08X & %08X\n", machine().describe_context(), offset * 4, data, mem_mask);
if (LOG_NILE | LOG_NILE_IRQS) logerror("%s NILE WRITE: interrupt clear(%03X) = %08X & %08X\n", machine().describe_context(), offset * 4, data, mem_mask);
logit = 0;
//m_nile_irq_state &= ~(m_cpu_regs[offset] & ~0xf00);
m_nile_irq_state &= ~(data);
@ -1001,7 +1002,7 @@ WRITE_LINE_MEMBER(vrc5074_device::uart_irq_callback)
if (state ^ m_uart_irq) {
m_uart_irq = state;
update_nile_irqs();
if (LOG_NILE)
if (LOG_NILE | LOG_NILE_IRQS)
logerror("uart_irq_callback: state = %d\n", state);
}
}

View File

@ -860,8 +860,10 @@ void voodoo_device::swap_buffers(voodoo_device *vd)
/* reset the last_op_time to now and start processing the next command */
if (vd->pci.op_pending)
{
if (LOG_VBLANK_SWAP) vd->logerror("---- swap_buffers flush begin\n");
vd->pci.op_end_time = vd->machine().time();
flush_fifos(vd, vd->pci.op_end_time);
if (LOG_VBLANK_SWAP) vd->logerror("---- swap_buffers flush end\n");
}
/* we may be able to unstall now */
@ -931,7 +933,7 @@ void voodoo_device::swap_buffers(voodoo_device *vd)
static void adjust_vblank_timer(voodoo_device *vd)
{
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());
/* 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();
@ -4941,10 +4943,22 @@ WRITE32_MEMBER( voodoo_banshee_device::banshee_io_w )
case io_vidOverlayDudx:
case io_vidOverlayDvdy:
{
/* warning: this is a hack for now! We should really compute the screen size */
/* from the CRTC registers */
COMBINE_DATA(&banshee.io[offset]);
// Get horizontal total and vertical total from CRTC registers
int htotal = (banshee.crtc[0] + 5) * 8;
int vtotal = banshee.crtc[6];
vtotal |= ((banshee.crtc[7] >> 0) & 0x1) << 8;
vtotal |= ((banshee.crtc[7] >> 5) & 0x1) << 9;
// 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;
const uint32_t n = (banshee.io[io_pllCtrl0] >> 8) & 0xff;
const double video_clock = XTAL_14_31818MHz * (n + 2) / double((m + 2) << k);
const double frame_period = vtotal * htotal / video_clock;
//osd_printf_info("k: %d m: %d n: %d clock: %f period: %f rate: %.2f\n", k, m, n, video_clock, frame_period, 1.0 / frame_period);
int width = fbi.width;
int height = fbi.height;
@ -4953,9 +4967,17 @@ WRITE32_MEMBER( voodoo_banshee_device::banshee_io_w )
if (banshee.io[io_vidOverlayDvdy] != 0)
height = (fbi.height * banshee.io[io_vidOverlayDvdy]) / 1048576;
screen->set_visible_area(0, width - 1, 0, height - 1);
if (LOG_REGISTERS)
logerror("configure screen: htotal: %d vtotal: %d width: %d height: %d refresh: %f\n",
htotal, vtotal, 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));
adjust_vblank_timer(this);
// Set the vsync to start at top of screen
fbi.vsyncscan = height;
adjust_vblank_timer(this);
}
if (LOG_REGISTERS)
logerror("%s:banshee_io_w(%s) = %08X & %08X\n", machine().describe_context(), banshee_io_reg_name[offset], data, mem_mask);
break;
@ -5295,7 +5317,7 @@ int32_t voodoo_device::swapbuffer(voodoo_device* vd, uint32_t data)
/* determine how many cycles to wait; we deliberately overshoot here because */
/* the final count gets updated on the VBLANK */
return (vd->fbi.vblank_swap + 1) * vd->freq / 30;
return (vd->fbi.vblank_swap + 1) * vd->freq / 10;
}

View File

@ -350,7 +350,6 @@ public:
uint8_t m_vblank_state;
uint8_t m_cpuio_data[4];
uint8_t m_sio_reset_ctrl;
uint8_t m_sio_irq_clear;
uint8_t m_sio_irq_enable;
uint8_t m_sio_irq_state;
uint8_t m_sio_led_state;
@ -448,7 +447,6 @@ void vegas_state::machine_start()
save_item(NAME(m_vblank_state));
save_item(NAME(m_cpuio_data));
save_item(NAME(m_sio_reset_ctrl));
save_item(NAME(m_sio_irq_clear));
save_item(NAME(m_sio_irq_enable));
save_item(NAME(m_sio_irq_state));
save_item(NAME(m_sio_led_state));
@ -599,7 +597,7 @@ WRITE_LINE_MEMBER(vegas_state::duart_irq_cb)
WRITE_LINE_MEMBER(vegas_state::vblank_assert)
{
if (LOG_SIO)
logerror("vblank_assert: state: %d\n", state);
logerror("vblank_assert: m_sio_reset_ctrl: %04x state: %d\n", m_sio_reset_ctrl, state);
// latch on the correct polarity transition
if ((state && !(m_sio_reset_ctrl & 0x10)) || (!state && (m_sio_reset_ctrl & 0x10)))
{
@ -630,7 +628,6 @@ WRITE_LINE_MEMBER(vegas_state::ethernet_interrupt)
void vegas_state::reset_sio()
{
m_sio_reset_ctrl = 0;
m_sio_irq_clear = 0;
m_sio_irq_enable = 0;
m_sio_irq_state = 0;
m_sio_led_state = 0;
@ -644,7 +641,7 @@ READ8_MEMBER(vegas_state::sio_r)
switch (index) {
case 0:
// Reset Control: Bit 0=>Reset IOASIC, Bit 1=>Reset NSS Connection, Bit 2=>Reset SMC, Bit 3=>Reset VSYNC, Bit 4=>VSYNC Polarity
result = m_sio_irq_clear;
result = m_sio_reset_ctrl;
// Hack for fpga programming finished
m_cpuio_data[3] |= 0x1;
break;
@ -724,20 +721,22 @@ WRITE8_MEMBER(vegas_state::sio_w)
if (LOG_SIO)
logerror("sio_w: Reset Control offset: %08x index: %d data: %02X\n", offset, index, data);
// Reset Control: Bit 0=>Reset IOASIC, Bit 1=>Reset NSS Connection, Bit 2=>Reset SMC, Bit 3=>Reset VSYNC, Bit 4=>VSYNC Polarity
m_sio_reset_ctrl = data;
/* bit 0x01 is used to reset the IOASIC */
if (!(data & 0x01))
/* bit 0 is used to reset the IOASIC */
if (!(data & (1 << 0)))
{
m_ioasic->ioasic_reset();
m_dcs->reset_w(data & 0x01);
}
/* toggle bit 0x08 low to reset the VBLANK */
if (!(data & 0x08))
if ((data & (1 << 2)) && !(m_sio_reset_ctrl & (1 << 2))) {
m_ethernet->reset();
}
/* toggle bit 3 low to reset the VBLANK */
if (!(data & (1 << 3)))
{
m_sio_irq_state &= ~0x20;
update_sio_irqs();
}
m_sio_irq_clear = data;
m_sio_reset_ctrl = data;
break;
case 1:
// Interrupt Enable
@ -1714,6 +1713,7 @@ static MACHINE_CONFIG_START( vegascore )
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
// Screeen size and timing is re-calculated later in voodoo card
MCFG_SCREEN_REFRESH_RATE(57)
MCFG_SCREEN_SIZE(640, 480)
MCFG_SCREEN_VISIBLE_AREA(0, 639, 0, 479)
@ -1740,11 +1740,6 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( vegasban, vegas32m)
// Short term hack to get nbashowt, nbanfl, nbagold to boot.
// Probably due to CRTC registers not used for timing in voodoo
MCFG_SCREEN_MODIFY("screen")
MCFG_SCREEN_REFRESH_RATE(120)
MCFG_DEVICE_REMOVE(PCI_ID_VIDEO)
MCFG_VOODOO_PCI_ADD(PCI_ID_VIDEO, TYPE_VOODOO_BANSHEE, ":maincpu")
MCFG_VOODOO_PCI_FBMEM(16)
@ -1759,11 +1754,6 @@ static MACHINE_CONFIG_DERIVED( vegasv3, vegas32m)
MCFG_MIPS3_DCACHE_SIZE(16384)
MCFG_MIPS3_SYSTEM_CLOCK(vegas_state::SYSTEM_CLOCK)
// Short term hack to get cartfury to boot.
// Probably due to CRTC registers not used for timing in voodoo
MCFG_SCREEN_MODIFY("screen")
MCFG_SCREEN_REFRESH_RATE(120)
MCFG_DEVICE_REMOVE(PCI_ID_VIDEO)
MCFG_VOODOO_PCI_ADD(PCI_ID_VIDEO, TYPE_VOODOO_3, ":maincpu")
MCFG_VOODOO_PCI_FBMEM(16)