mirror of
https://github.com/holub/mame
synced 2025-04-24 17:30:55 +03:00
Calculate screen size and timing using voodoo CRTC and PLL registers. (nw)
This commit is contained in:
parent
71ffd5f082
commit
0e6222c005
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user