mirror of
https://github.com/holub/mame
synced 2025-07-01 00:09:18 +03:00
sun4: Rewrote timers to actually tick at 1MHz. NetBSD 6.0 now runs until failing to reset the keyboard. [Ryan Holtz]
This commit is contained in:
parent
fc37ac35b0
commit
e3b77361d0
@ -755,7 +755,10 @@ private:
|
||||
uint8_t m_diag;
|
||||
int m_arch;
|
||||
|
||||
emu_timer *m_c0_timer, *m_c1_timer;
|
||||
attotime m_c0_last_read_time;
|
||||
attotime m_c1_last_read_time;
|
||||
emu_timer *m_c0_timer;
|
||||
emu_timer *m_c1_timer;
|
||||
emu_timer *m_reset_timer;
|
||||
|
||||
void dma_check_interrupts();
|
||||
@ -763,8 +766,6 @@ private:
|
||||
void dma_transfer_write();
|
||||
void dma_transfer_read();
|
||||
|
||||
void start_timer(int num);
|
||||
|
||||
void l2p_command(int ref, const std::vector<std::string> ¶ms);
|
||||
void fcodes_command(int ref, const std::vector<std::string> ¶ms);
|
||||
};
|
||||
@ -789,7 +790,7 @@ READ32_MEMBER( sun4_state::sun4_system_r )
|
||||
return m_cachetags[offset&0xfff];
|
||||
|
||||
case 9: // (d-)cache data
|
||||
logerror("sun4: read dcache data @ %x, PC = %x\n", offset, m_maincpu->pc());
|
||||
//logerror("sun4: read dcache data @ %x, PC = %x\n", offset, m_maincpu->pc());
|
||||
return 0xffffffff;
|
||||
|
||||
case 0xf: // UART bypass
|
||||
@ -803,7 +804,7 @@ READ32_MEMBER( sun4_state::sun4_system_r )
|
||||
|
||||
case 0:
|
||||
default:
|
||||
logerror("sun4: ASI 2 space unhandled read @ %x (PC=%x)\n", offset<<2, m_maincpu->pc());
|
||||
//logerror("sun4: ASI 2 space unhandled read @ %x (PC=%x)\n", offset<<2, m_maincpu->pc());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -822,9 +823,9 @@ WRITE32_MEMBER( sun4_state::sun4_system_w )
|
||||
|
||||
if (m_system_enable & ENA_RESET)
|
||||
{
|
||||
m_reset_timer->adjust(attotime::from_usec(1));
|
||||
m_reset_timer->adjust(attotime::from_usec(1), 0);
|
||||
m_maincpu->set_input_line(SPARC_RESET, ASSERT_LINE);
|
||||
logerror("%s: Asserting reset line\n", machine().describe_context());
|
||||
//logerror("%s: Asserting reset line\n", machine().describe_context());
|
||||
}
|
||||
//printf("%08x to system enable, mask %08x\n", data, mem_mask);
|
||||
if (m_system_enable & ENA_RESET)
|
||||
@ -860,7 +861,7 @@ WRITE32_MEMBER( sun4_state::sun4_system_w )
|
||||
return;
|
||||
|
||||
case 9: // cache data
|
||||
logerror("sun4: %08x to cache data @ %x, PC = %x\n", data, offset, m_maincpu->pc());
|
||||
//logerror("sun4: %08x to cache data @ %x, PC = %x\n", data, offset, m_maincpu->pc());
|
||||
return;
|
||||
|
||||
case 0xf: // UART bypass
|
||||
@ -874,7 +875,7 @@ WRITE32_MEMBER( sun4_state::sun4_system_w )
|
||||
|
||||
case 0: // IDPROM
|
||||
default:
|
||||
logerror("sun4: ASI 2 space unhandled write %x @ %x (mask %08x, PC=%x)\n", data, offset<<2, mem_mask, m_maincpu->pc());
|
||||
//logerror("sun4: ASI 2 space unhandled write %x @ %x (mask %08x, PC=%x)\n", data, offset<<2, mem_mask, m_maincpu->pc());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -966,7 +967,7 @@ READ32_MEMBER( sun4_state::sun4_insn_data_r )
|
||||
return m_type1space->read32(space, tmp, mem_mask);
|
||||
|
||||
default:
|
||||
logerror("sun4: access to unhandled memory type\n");
|
||||
//logerror("sun4: access to unhandled memory type\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -974,7 +975,7 @@ READ32_MEMBER( sun4_state::sun4_insn_data_r )
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
logerror("sun4: INVALID PTE entry %d %08x accessed! vaddr=%x PC=%x\n", entry_index, m_pagemap[entry_index].to_uint(), offset <<2, m_maincpu->pc());
|
||||
//logerror("sun4: INVALID PTE entry %d %08x accessed! vaddr=%x PC=%x\n", entry_index, m_pagemap[entry_index].to_uint(), offset <<2, m_maincpu->pc());
|
||||
m_maincpu->set_mae();
|
||||
m_buserr[0] |= 0x80; // invalid PTE
|
||||
m_buserr[0] &= ~0x8000; // read
|
||||
@ -1026,13 +1027,13 @@ WRITE32_MEMBER( sun4_state::sun4_insn_data_w )
|
||||
return;
|
||||
|
||||
default:
|
||||
logerror("sun4: access to memory type not defined in sun4c\n");
|
||||
//logerror("sun4: access to memory type not defined in sun4\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logerror("sun4: INVALID PTE entry %d %08x accessed! data=%08x vaddr=%x PC=%x\n", entry_index, m_pagemap[entry_index].to_uint(), data, offset <<2, m_maincpu->pc());
|
||||
//logerror("sun4: INVALID PTE entry %d %08x accessed! data=%08x vaddr=%x PC=%x\n", entry_index, m_pagemap[entry_index].to_uint(), data, offset <<2, m_maincpu->pc());
|
||||
//m_maincpu->trap(SPARC_DATA_ACCESS_EXCEPTION);
|
||||
//m_buserr[0] = 0x8; // invalid PTE
|
||||
//m_buserr[1] = offset<<2;
|
||||
@ -1184,6 +1185,11 @@ void sun4_state::machine_reset()
|
||||
m_dma_tc_read = false;
|
||||
m_dma_pack_register = 0;
|
||||
|
||||
m_c0_last_read_time = attotime::zero;
|
||||
m_c1_last_read_time = attotime::zero;
|
||||
m_counter[0] = 1 << 10;
|
||||
m_counter[2] = 1 << 10;
|
||||
|
||||
memset(m_counter, 0, sizeof(m_counter));
|
||||
memset(m_dma, 0, sizeof(m_dma));
|
||||
}
|
||||
@ -1207,8 +1213,8 @@ void sun4_state::machine_start()
|
||||
// allocate timers for the built-in two channel timer
|
||||
m_c0_timer = timer_alloc(TIMER_0);
|
||||
m_c1_timer = timer_alloc(TIMER_1);
|
||||
m_c0_timer->adjust(attotime::never);
|
||||
m_c1_timer->adjust(attotime::never);
|
||||
m_c0_timer->adjust(attotime::from_usec(1), 0, attotime::from_usec(1));
|
||||
m_c1_timer->adjust(attotime::from_usec(1), 0, attotime::from_usec(1));
|
||||
|
||||
// allocate timer for system reset
|
||||
m_reset_timer = timer_alloc(TIMER_RESET);
|
||||
@ -1417,6 +1423,7 @@ WRITE8_MEMBER( sun4_state::auxio_w )
|
||||
|
||||
READ8_MEMBER( sun4_state::irq_r )
|
||||
{
|
||||
//logerror("%02x from IRQ\n", m_irq_reg);
|
||||
return m_irq_reg;
|
||||
}
|
||||
|
||||
@ -1433,10 +1440,16 @@ WRITE8_MEMBER( sun4_state::irq_w )
|
||||
|
||||
if (BIT(changed, 0))
|
||||
{
|
||||
if (BIT(m_irq_reg, 7) && BIT(m_counter[2] | m_counter[3], 31))
|
||||
m_maincpu->set_input_line(SPARC_IRQ14, BIT(data, 0) ? ASSERT_LINE : CLEAR_LINE);
|
||||
if (BIT(m_irq_reg, 5) && BIT(m_counter[0] | m_counter[1], 31))
|
||||
m_maincpu->set_input_line(SPARC_IRQ10, BIT(data, 0) ? ASSERT_LINE : CLEAR_LINE);
|
||||
if (BIT(m_irq_reg, 7))
|
||||
{
|
||||
//logerror("Changing interrupt enable, %s IRQ14\n", BIT(data, 0) && BIT(m_counter[2] | m_counter[3], 31) ? "asserting" : "deasserting");
|
||||
m_maincpu->set_input_line(SPARC_IRQ14, BIT(data, 0) && BIT(m_counter[2] | m_counter[3], 31) ? ASSERT_LINE : CLEAR_LINE);
|
||||
}
|
||||
if (BIT(m_irq_reg, 5))
|
||||
{
|
||||
//logerror("Changing interrupt enable, %s IRQ10\n", BIT(data, 0) && BIT(m_counter[0] | m_counter[1], 31) ? "asserting" : "deasserting");
|
||||
m_maincpu->set_input_line(SPARC_IRQ10, BIT(data, 0) && BIT(m_counter[0] | m_counter[1], 31) ? ASSERT_LINE : CLEAR_LINE);
|
||||
}
|
||||
if (BIT(m_irq_reg, 3))
|
||||
m_maincpu->set_input_line(SPARC_IRQ6, BIT(data, 0) ? ASSERT_LINE : CLEAR_LINE);
|
||||
if (BIT(m_irq_reg, 2))
|
||||
@ -1446,10 +1459,16 @@ WRITE8_MEMBER( sun4_state::irq_w )
|
||||
}
|
||||
else if (BIT(m_irq_reg, 0))
|
||||
{
|
||||
if (BIT(changed, 7) && BIT(m_counter[2] | m_counter[3], 31))
|
||||
m_maincpu->set_input_line(SPARC_IRQ14, BIT(m_irq_reg, 7) ? ASSERT_LINE : CLEAR_LINE);
|
||||
if (BIT(changed, 5) && BIT(m_counter[0] | m_counter[1], 31))
|
||||
m_maincpu->set_input_line(SPARC_IRQ10, BIT(m_irq_reg, 5) ? ASSERT_LINE : CLEAR_LINE);
|
||||
if (BIT(changed, 7))
|
||||
{
|
||||
//logerror("Changing IRQ14 enable, %s IRQ14\n", BIT(data, 7) && BIT(m_counter[2] | m_counter[3], 31) ? "asserting" : "deasserting");
|
||||
m_maincpu->set_input_line(SPARC_IRQ14, BIT(m_irq_reg, 7) && BIT(m_counter[2] | m_counter[3], 31) ? ASSERT_LINE : CLEAR_LINE);
|
||||
}
|
||||
if (BIT(changed, 5))
|
||||
{
|
||||
//logerror("Changing IRQ10 enable, %s IRQ10\n", BIT(data, 7) && BIT(m_counter[0] | m_counter[1], 31) ? "asserting" : "deasserting");
|
||||
m_maincpu->set_input_line(SPARC_IRQ10, BIT(m_irq_reg, 5) && BIT(m_counter[0] | m_counter[1], 31) ? ASSERT_LINE : CLEAR_LINE);
|
||||
}
|
||||
if (BIT(changed, 3))
|
||||
m_maincpu->set_input_line(SPARC_IRQ6, BIT(m_irq_reg, 3) ? ASSERT_LINE : CLEAR_LINE);
|
||||
if (BIT(changed, 2))
|
||||
@ -1478,28 +1497,40 @@ void sun4_state::device_timer(emu_timer &timer, device_timer_id id, int param, v
|
||||
switch (id)
|
||||
{
|
||||
case TIMER_0:
|
||||
//printf("Timer 0 expired\n");
|
||||
m_counter[0] = 0x80000000 | (1 << 10);
|
||||
m_counter[1] |= 0x80000000;
|
||||
//m_c0_timer->adjust(attotime::never);
|
||||
start_timer(0);
|
||||
if ((m_irq_reg & 0x21) == 0x21)
|
||||
//logerror("Timer 0 expired\n");
|
||||
m_counter[0] += 1 << 10;
|
||||
if ((m_counter[0] & 0x7fffffff) == (m_counter[1] & 0x7fffffff))
|
||||
{
|
||||
m_maincpu->set_input_line(SPARC_IRQ10, ASSERT_LINE);
|
||||
//printf("Taking INT10\n");
|
||||
m_counter[0] = 0x80000000 | (1 << 10);
|
||||
m_counter[1] |= 0x80000000;
|
||||
if ((m_irq_reg & 0x21) == 0x21)
|
||||
{
|
||||
m_maincpu->set_input_line(SPARC_IRQ10, ASSERT_LINE);
|
||||
//logerror("Taking INT10\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
//logerror("Not taking INT10\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TIMER_1:
|
||||
//printf("Timer 1 expired\n");
|
||||
m_counter[2] = 0x80000000 | (1 << 10);
|
||||
m_counter[3] |= 0x80000000;
|
||||
start_timer(1);
|
||||
//m_c1_timer->adjust(attotime::never);
|
||||
if ((m_irq_reg & 0x81) == 0x81)
|
||||
//logerror("Timer 1 expired\n");
|
||||
m_counter[2] += 1 << 10;
|
||||
if ((m_counter[2] & 0x7fffffff) == (m_counter[3] & 0x7fffffff))
|
||||
{
|
||||
m_maincpu->set_input_line(SPARC_IRQ14, ASSERT_LINE);
|
||||
//printf("Taking INT14\n");
|
||||
m_counter[2] = 0x80000000 | (1 << 10);
|
||||
m_counter[3] |= 0x80000000;
|
||||
if ((m_irq_reg & 0x81) == 0x81)
|
||||
{
|
||||
m_maincpu->set_input_line(SPARC_IRQ14, ASSERT_LINE);
|
||||
//logerror("Taking INT14\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
//logerror("Not taking INT14\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1513,79 +1544,61 @@ void sun4_state::device_timer(emu_timer &timer, device_timer_id id, int param, v
|
||||
|
||||
READ32_MEMBER( sun4_state::timer_r )
|
||||
{
|
||||
uint32_t ret = m_counter[offset];
|
||||
const uint32_t ret = m_counter[offset];
|
||||
|
||||
// reading limt 0
|
||||
if (offset == 0)
|
||||
{
|
||||
//printf("Read timer counter 0 (%08x) @ %x, mask %08x\n", ret, m_maincpu->pc(), mem_mask);
|
||||
//logerror("Read timer counter 0 (%x) @ %x, mask %08x\n", ret, m_maincpu->pc(), mem_mask);
|
||||
}
|
||||
if (offset == 1)
|
||||
else if (offset == 1)
|
||||
{
|
||||
//printf("Read timer limit 0 (%08x) @ %x, mask %08x\n", ret, m_maincpu->pc(), mem_mask);
|
||||
//logerror("Read timer limit 0 (%08x) @ %x, mask %08x, clearing IRQ10\n", ret, m_maincpu->pc(), mem_mask);
|
||||
m_counter[0] &= ~0x80000000;
|
||||
m_counter[1] &= ~0x80000000;
|
||||
m_maincpu->set_input_line(SPARC_IRQ10, CLEAR_LINE);
|
||||
}
|
||||
|
||||
if (offset == 2)
|
||||
else if (offset == 2)
|
||||
{
|
||||
//printf("Read timer counter 1 (%08x) @ %x, mask %08x\n", ret, m_maincpu->pc(), mem_mask);
|
||||
//logerror("Read timer counter 1 (%x) @ %x, mask %08x\n", ret, m_maincpu->pc(), mem_mask);
|
||||
}
|
||||
if (offset == 3)
|
||||
else if (offset == 3)
|
||||
{
|
||||
//printf("Read timer limit 1 (%08x) @ %x, mask %08x\n", ret, m_maincpu->pc(), mem_mask);
|
||||
//logerror("Read timer limit 1 (%08x) @ %x, mask %08x, clearing IRQ14\n", ret, m_maincpu->pc(), mem_mask);
|
||||
m_counter[2] &= ~0x80000000;
|
||||
m_counter[3] &= ~0x80000000;
|
||||
m_maincpu->set_input_line(SPARC_IRQ14, CLEAR_LINE);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void sun4_state::start_timer(int num)
|
||||
{
|
||||
int period = (m_counter[num * 2 + 1] >> 10) & 0x1fffff;
|
||||
if (period == 0)
|
||||
period = 0x200000;
|
||||
|
||||
//printf("Setting limit %d period to %d us\n", num, period);
|
||||
|
||||
if (num == 0)
|
||||
{
|
||||
m_c0_timer->adjust(attotime::from_usec(period));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_c1_timer->adjust(attotime::from_usec(period));
|
||||
}
|
||||
}
|
||||
|
||||
WRITE32_MEMBER( sun4_state::timer_w )
|
||||
{
|
||||
COMBINE_DATA(&m_counter[offset]);
|
||||
|
||||
if (offset == 0)
|
||||
{
|
||||
printf("%08x to timer counter 0 @ %x, mask %08x\n", data, m_maincpu->pc(), mem_mask);
|
||||
//logerror("%08x to timer counter 0 @ %x, mask %08x\n", data, m_maincpu->pc(), mem_mask);
|
||||
}
|
||||
|
||||
// writing limit 0
|
||||
if (offset == 1)
|
||||
{
|
||||
//logerror("%08x to timer limit 0 @ %x, mask %08x\n", data, m_maincpu->pc(), mem_mask);
|
||||
m_counter[0] = 1 << 10;
|
||||
start_timer(0);
|
||||
}
|
||||
|
||||
if (offset == 2)
|
||||
{
|
||||
printf("%08x to timer counter 1 @ %x, mask %08x\n", data, m_maincpu->pc(), mem_mask);
|
||||
//printf("%08x to timer counter 1 @ %x, mask %08x\n", data, m_maincpu->pc(), mem_mask);
|
||||
}
|
||||
|
||||
// writing limit 1
|
||||
if (offset == 3)
|
||||
{
|
||||
//logerror("%08x to timer limit 1 @ %x, mask %08x\n", data, m_maincpu->pc(), mem_mask);
|
||||
m_counter[2] = 1 << 10;
|
||||
start_timer(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user