summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author MooglyGuy <MooglyGuy@users.noreply.github.com>2021-06-03 19:29:25 +0200
committer GitHub <noreply@github.com>2021-06-04 03:29:25 +1000
commit990d8233bfd26ccf6f60cfe922d29a2570bff9c2 (patch)
tree543c099fba760eacaef3e940bd4c8dacd7914e31
parentf2ba6b059a8f6569545e2e341ac52ac15adf9a8a (diff)
Made SPG2xx I/O IRQ checking a bit more lean; improved ADC behavior. (#8138) [Ryan Holtz]
-rw-r--r--src/devices/machine/spg2xx_io.cpp339
-rw-r--r--src/devices/machine/spg2xx_io.h44
2 files changed, 135 insertions, 248 deletions
diff --git a/src/devices/machine/spg2xx_io.cpp b/src/devices/machine/spg2xx_io.cpp
index 861a720cfa0..b465fdcc546 100644
--- a/src/devices/machine/spg2xx_io.cpp
+++ b/src/devices/machine/spg2xx_io.cpp
@@ -91,48 +91,32 @@ void spg2xx_io_device::device_start()
m_chip_sel.resolve_safe();
m_pal_read_cb.resolve_safe(0);
- m_timer_irq_cb.resolve();
- m_uart_adc_irq_cb.resolve();
- m_external_irq_cb.resolve();
- m_ffreq_tmr1_irq_cb.resolve();
- m_ffreq_tmr2_irq_cb.resolve();
+ m_timer_irq_cb.resolve_safe();
+ m_uart_adc_irq_cb.resolve_safe();
+ m_external_irq_cb.resolve_safe();
+ m_ffreq_tmr1_irq_cb.resolve_safe();
+ m_ffreq_tmr2_irq_cb.resolve_safe();
- m_fiq_vector_w.resolve();
+ m_fiq_vector_w.resolve_safe();
- m_tmb1 = timer_alloc(TIMER_TMB1);
- m_tmb2 = timer_alloc(TIMER_TMB2);
- m_tmb1->adjust(attotime::never);
- m_tmb2->adjust(attotime::never);
-
- m_uart_tx_timer = timer_alloc(TIMER_UART_TX);
- m_uart_tx_timer->adjust(attotime::never);
-
- m_uart_rx_timer = timer_alloc(TIMER_UART_RX);
- m_uart_rx_timer->adjust(attotime::never);
-
- m_4khz_timer = timer_alloc(TIMER_4KHZ);
- m_4khz_timer->adjust(attotime::never);
-
- m_timer_src_ab = timer_alloc(TIMER_SRC_AB);
- m_timer_src_ab->adjust(attotime::never);
+ m_tmb1 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(spg2xx_io_device::tmb_timer_tick<0>), this));
+ m_tmb2 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(spg2xx_io_device::tmb_timer_tick<1>), this));
- m_timer_src_c = timer_alloc(TIMER_SRC_C);
- m_timer_src_c->adjust(attotime::never);
+ m_uart_tx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(spg2xx_io_device::uart_transmit_tick), this));
+ m_uart_rx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(spg2xx_io_device::uart_receive_tick), this));
- m_rng_timer = timer_alloc(TIMER_RNG);
- m_rng_timer->adjust(attotime::never);
+ m_4khz_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(spg2xx_io_device::system_timer_tick), this));
- m_watchdog_timer = timer_alloc(TIMER_WATCHDOG);
- m_watchdog_timer->adjust(attotime::never);
+ m_timer_src_ab = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(spg2xx_io_device::timer_ab_tick), this));
+ m_timer_src_c = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(spg2xx_io_device::timer_c_tick), this));
+ m_rng_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(spg2xx_io_device::rng_clock_tick), this));
+ m_watchdog_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(spg2xx_io_device::watchdog_tick), this));
+ m_spi_tx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(spg2xx_io_device::spi_tx_tick), this));
- m_spi_tx_timer = timer_alloc(TIMER_SPI_TX);
- m_spi_tx_timer->adjust(attotime::never);
-
- for (int i = 0; i < 4; i++)
- {
- m_adc_timer[i] = timer_alloc(TIMER_ADC0 + i);
- m_adc_timer[i]->adjust(attotime::never);
- }
+ m_adc_timer[0] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(spg2xx_io_device::adc_convert_tick<0>), this));
+ m_adc_timer[1] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(spg2xx_io_device::adc_convert_tick<1>), this));
+ m_adc_timer[2] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(spg2xx_io_device::adc_convert_tick<2>), this));
+ m_adc_timer[3] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(spg2xx_io_device::adc_convert_tick<3>), this));
save_item(NAME(m_io_regs));
@@ -275,7 +259,7 @@ void spg2xx_io_device::set_spi_irq(bool set)
const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE);
if (changed)
- check_irqs(changed);
+ check_data_irq();
}
void spg2xx_io_device::update_spi_irqs()
@@ -286,7 +270,7 @@ void spg2xx_io_device::update_spi_irqs()
set_spi_irq(ovf_set || rxi_set || txi_set);
}
-void spg2xx_io_device::do_spi_tx()
+TIMER_CALLBACK_MEMBER(spg2xx_io_device::spi_tx_tick)
{
if (!BIT(m_io_regs[REG_SPI_CTRL], 15) || m_spi_tx_fifo_count == 0)
{
@@ -387,6 +371,12 @@ void spg2xx_io_device::spi_rx(int state)
}
}
+TIMER_CALLBACK_MEMBER(spg2xx_io_device::rng_clock_tick)
+{
+ clock_rng(0);
+ clock_rng(1);
+}
+
uint16_t spg2xx_io_device::clock_rng(int which)
{
const uint16_t value = m_io_regs[REG_PRNG1 + which];
@@ -458,15 +448,7 @@ uint16_t spg2xx_io_device::io_r(offs_t offset)
break;
case REG_ADC_DATA:
- if (!machine().side_effects_disabled())
- {
- const uint16_t old = IO_IRQ_STATUS;
- IO_IRQ_STATUS &= ~0x2000;
- const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE);
- if (changed)
- check_irqs(changed);
- LOGMASKED(LOG_IO_READS | LOG_ADC, "%s: io_r: ADC Data = %04x\n", machine().describe_context(), val);
- }
+ LOGMASKED(LOG_IO_READS | LOG_ADC, "%s: io_r: ADC Data = %04x\n", machine().describe_context(), val);
break;
case REG_WAKEUP_SOURCE:
@@ -545,7 +527,6 @@ uint16_t spg2xx_io_device::io_extended_r(offs_t offset)
else
{
LOGMASKED(LOG_UART, "Remaining count %d, setting up timer\n", m_uart_rx_fifo_count);
- //uart_receive_tick();
if (m_uart_rx_timer->remaining() == attotime::never)
m_uart_rx_timer->adjust(attotime::from_ticks(BIT(m_io_regs[REG_UART_CTRL], 5) ? 11 : 10, m_uart_baud_rate));
}
@@ -718,7 +699,7 @@ void spg2xx_io_device::update_timer_b_rate()
}
}
-void spg2xx_io_device::update_timer_ab_src()
+TIMER_CALLBACK_MEMBER(spg2xx_io_device::timer_ab_tick)
{
if (m_timer_b_tick_rate == 0)
return;
@@ -741,14 +722,11 @@ void spg2xx_io_device::increment_timer_a()
IO_IRQ_STATUS |= 0x0800;
const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE);
if (changed)
- {
- //printf("Timer A overflow\n");
- check_irqs(0x0800);
- }
+ check_timers_irq();
}
}
-void spg2xx_io_device::update_timer_c_src()
+TIMER_CALLBACK_MEMBER(spg2xx_io_device::timer_c_tick)
{
m_io_regs[REG_TIMERB_DATA]++;
if (m_io_regs[REG_TIMERB_DATA] == 0)
@@ -758,10 +736,7 @@ void spg2xx_io_device::update_timer_c_src()
IO_IRQ_STATUS |= 0x0400;
const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE);
if (changed)
- {
- printf("Timer B overflow\n");
- check_irqs(0x0400);
- }
+ check_timers_irq();
}
}
@@ -954,7 +929,7 @@ void spg2xx_io_device::io_w(offs_t offset, uint16_t data)
IO_IRQ_STATUS &= ~0x0800;
const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE);
if (changed)
- check_irqs(0x0800);
+ check_timers_irq();
break;
}
@@ -998,7 +973,7 @@ void spg2xx_io_device::io_w(offs_t offset, uint16_t data)
IO_IRQ_STATUS &= ~0x0400;
const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE);
if (changed)
- check_irqs(0x0400);
+ check_timers_irq();
break;
}
@@ -1030,7 +1005,7 @@ void spg2xx_io_device::io_w(offs_t offset, uint16_t data)
m_io_regs[REG_INT_CTRL] = data;
const uint16_t changed = (IO_IRQ_STATUS & old) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE);
if (changed)
- check_irqs(changed);
+ check_all_irqs(changed);
break;
}
@@ -1046,7 +1021,7 @@ void spg2xx_io_device::io_w(offs_t offset, uint16_t data)
IO_IRQ_STATUS |= 0x0100;
}
if (changed)
- check_irqs(changed);
+ check_all_irqs(changed);
break;
}
@@ -1099,41 +1074,24 @@ void spg2xx_io_device::io_w(offs_t offset, uint16_t data)
const uint16_t old_ctrl = m_io_regs[REG_ADC_CTRL];
m_io_regs[REG_ADC_CTRL] = data & ~0x2000;
- const uint16_t channel = (m_io_regs[REG_ADC_CTRL] >> 4) & 3;
- if (BIT(m_io_regs[REG_ADC_CTRL], 0))
+ if (BIT(old_ctrl, 13) && BIT(data, 13))
{
- // Does anything require the 0->1 check below?
- // jak_sith (and all the other Star Wars units / GameKeys) break on the high score table if you leave the demo
- // running or finish a game with a high score, as they write '0x0001' and then don't read any further directional
- // inputs until 0x2000 is set, but that never happens because the value at the time is already 0x0001.
- //
- // If the state of the lowest bit is important to other software, maybe it's more of a status flag than a true
- // read/write register?
-
- //if (!BIT(old_ctrl, 0))
- {
- m_io_regs[REG_ADC_CTRL] |= 0x2000;
- if (BIT(m_io_regs[REG_ADC_CTRL], 9))
- {
- const uint16_t old = IO_IRQ_STATUS;
- IO_IRQ_STATUS |= 0x2000;
- const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE);
- if (changed)
- check_irqs(changed);
- }
- }
+ m_io_regs[REG_ADC_CTRL] &= ~0x2000;
+ IO_IRQ_STATUS &= ~0x2000;
+ check_data_irq();
+ }
- if (BIT(data, 13))
- {
- m_io_regs[REG_ADC_CTRL] &= ~0x2000;
- check_irqs(0x2000);
- }
+ if (BIT(m_io_regs[REG_ADC_CTRL], 0))
+ {
+ // Assume ready unless stated otherwise (i.e., conversion request is issued).
+ m_io_regs[REG_ADC_CTRL] |= 0x2000;
+ const uint16_t adc_channel = (m_io_regs[REG_ADC_CTRL] >> 4) & 3;
if (!BIT(old_ctrl, 12) && BIT(m_io_regs[REG_ADC_CTRL], 12))
{
m_io_regs[REG_ADC_CTRL] &= ~0x3000;
const uint32_t adc_clocks = 16 << ((m_io_regs[REG_ADC_CTRL] >> 2) & 3);
- m_adc_timer[channel]->adjust(attotime::from_ticks(adc_clocks, 27000000));
+ m_adc_timer[adc_channel]->adjust(attotime::from_ticks(adc_clocks, 27000000));
m_io_regs[REG_ADC_DATA] &= ~0x8000;
}
@@ -1141,7 +1099,7 @@ void spg2xx_io_device::io_w(offs_t offset, uint16_t data)
if (BIT(data, 10))
{
m_io_regs[REG_ADC_DATA] &= ~0x8000;
- m_adc_timer[channel]->adjust(attotime::from_hz(8000), 0, attotime::from_hz(8000));
+ m_adc_timer[adc_channel]->adjust(attotime::from_hz(8000), 0, attotime::from_hz(8000));
}
}
else
@@ -1288,7 +1246,7 @@ void spg2xx_io_device::io_extended_w(offs_t offset, uint16_t data)
IO_IRQ_STATUS &= ~0x0100;
const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE);
if (changed)
- check_irqs(0x0100);
+ check_data_irq();
}
break;
@@ -1503,111 +1461,57 @@ void spg2xx_io_device::io_extended_w(offs_t offset, uint16_t data)
}
}
-void spg2xx_io_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+template <int Which>
+TIMER_CALLBACK_MEMBER(spg2xx_io_device::tmb_timer_tick)
{
- switch (id)
- {
- case TIMER_TMB1:
- {
- LOGMASKED(LOG_TIMERS, "TMB1 elapsed, setting IRQ Status bit 0 (old:%04x, new:%04x, enable:%04x)\n", IO_IRQ_STATUS, IO_IRQ_STATUS | 1, IO_IRQ_ENABLE);
- const uint16_t old = IO_IRQ_STATUS;
- IO_IRQ_STATUS |= 1;
- const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE);
- if (changed)
- check_irqs(0x0001);
- break;
- }
-
- case TIMER_TMB2:
- {
- LOGMASKED(LOG_TIMERS, "TMB2 elapsed, setting IRQ Status bit 1 (old:%04x, new:%04x, enable:%04x)\n", IO_IRQ_STATUS, IO_IRQ_STATUS | 2, IO_IRQ_ENABLE);
- const uint16_t old = IO_IRQ_STATUS;
- IO_IRQ_STATUS |= 2;
- const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE);
- if (changed)
- check_irqs(0x0002);
- break;
- }
-
- case TIMER_UART_TX:
- uart_transmit_tick();
- break;
-
- case TIMER_UART_RX:
- uart_receive_tick();
- break;
-
- case TIMER_4KHZ:
- system_timer_tick();
- break;
-
- case TIMER_SRC_AB:
- update_timer_ab_src();
- break;
-
- case TIMER_SRC_C:
- update_timer_c_src();
- break;
-
- case TIMER_RNG:
- clock_rng(0);
- clock_rng(1);
- break;
-
- case TIMER_WATCHDOG:
- m_cpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
- m_cpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE);
- break;
-
- case TIMER_SPI_TX:
- do_spi_tx();
- break;
+ LOGMASKED(LOG_TIMERS, "TMB%d elapsed, setting IRQ Status bit 0 (old:%04x, new:%04x, enable:%04x)\n", Which + 1, IO_IRQ_STATUS, IO_IRQ_STATUS | (1 << Which), IO_IRQ_ENABLE);
+ const uint16_t old = IO_IRQ_STATUS;
+ IO_IRQ_STATUS |= (1 << Which);
+ const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE);
+ if (changed)
+ check_tmb_lofreq_key_irq();
+}
- case TIMER_ADC0:
- case TIMER_ADC1:
- case TIMER_ADC2:
- case TIMER_ADC3:
- do_adc_capture(id - TIMER_ADC0);
- break;
- }
+TIMER_CALLBACK_MEMBER(spg2xx_io_device::watchdog_tick)
+{
+ m_cpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
+ m_cpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE);
}
-void spg2xx_io_device::system_timer_tick()
+TIMER_CALLBACK_MEMBER(spg2xx_io_device::system_timer_tick)
{
- const uint16_t old = IO_IRQ_STATUS;
- uint16_t check_mask = 0x0040;
IO_IRQ_STATUS |= 0x0040;
+ bool check_lofreq = false;
+
m_2khz_divider++;
if (m_2khz_divider == 2)
{
m_2khz_divider = 0;
IO_IRQ_STATUS |= 0x0020;
- check_mask |= 0x0020;
m_1khz_divider++;
if (m_1khz_divider == 2)
{
m_1khz_divider = 0;
IO_IRQ_STATUS |= 0x0010;
- check_mask |= 0x0010;
m_4hz_divider++;
if (m_4hz_divider == 256)
{
m_4hz_divider = 0;
IO_IRQ_STATUS |= 0x0008;
- check_mask |= 0x0008;
+ check_lofreq = BIT(IO_IRQ_ENABLE, 3);
}
}
}
- const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE);
- if (changed)
- check_irqs(check_mask);
+ check_hifreq_periodic_irq();
+ if (check_lofreq)
+ check_tmb_lofreq_key_irq();
}
-void spg2xx_io_device::uart_transmit_tick()
+TIMER_CALLBACK_MEMBER(spg2xx_io_device::uart_transmit_tick)
{
LOGMASKED(LOG_UART, "uart_transmit_tick: Transmitting %02x, setting TxReady, clearing TxBusy\n", (uint8_t)m_io_regs[REG_UART_TXBUF]);
m_uart_tx((uint8_t)m_io_regs[REG_UART_TXBUF]);
@@ -1619,15 +1523,15 @@ void spg2xx_io_device::uart_transmit_tick()
IO_IRQ_STATUS |= 0x0100;
m_uart_tx_irq = true;
LOGMASKED(LOG_UART, "uart_transmit_tick: Setting UART IRQ bit\n");
- if (IO_IRQ_STATUS != old)
+ if (IO_IRQ_STATUS != old && BIT(IO_IRQ_ENABLE, 8))
{
LOGMASKED(LOG_UART, "uart_transmit_tick: Bit newly set, checking IRQs\n");
- check_irqs(0x0100);
+ check_data_irq();
}
}
}
-void spg2xx_io_device::uart_receive_tick()
+TIMER_CALLBACK_MEMBER(spg2xx_io_device::uart_receive_tick)
{
LOGMASKED(LOG_UART, "uart_receive_tick: Setting RBF and RxRDY\n");
m_io_regs[REG_UART_STATUS] |= 0x81;
@@ -1637,7 +1541,8 @@ void spg2xx_io_device::uart_receive_tick()
LOGMASKED(LOG_UART, "uart_receive_tick: RxIntEn is set, setting rx_irq to true and setting UART IRQ\n");
m_uart_rx_irq = true;
IO_IRQ_STATUS |= 0x0100;
- check_irqs(0x0100);
+ if (BIT(IO_IRQ_ENABLE, 8))
+ check_data_irq();
}
}
@@ -1661,59 +1566,56 @@ void spg2xx_io_device::check_extint_irq(int channel)
if (old_irq != IO_IRQ_STATUS)
{
LOGMASKED(LOG_EXTINT, "extint IRQ changed, so checking interrupts\n");
- check_irqs(mask);
+ check_external_irq();
}
}
-void spg2xx_io_device::check_irqs(const uint16_t changed)
+void spg2xx_io_device::check_timers_irq()
{
- if (changed & 0x0c00) // Timer A, Timer B IRQ
- {
- LOGMASKED(LOG_TIMERS, "%ssserting IRQ2 (%04x, %04x)\n", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0c00) ? "A" : "Dea", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0c00), changed);
+ LOGMASKED(LOG_TIMERS, "Checking IRQ2 (%04x)\n", IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0c00);
+ m_timer_irq_cb((IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0c00) ? ASSERT_LINE : CLEAR_LINE);
+}
- if (m_timer_irq_cb)
- m_timer_irq_cb((IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0c00) ? ASSERT_LINE : CLEAR_LINE);
- else
- logerror("spg2xx_io_device::check_irqs, attempted to use m_timer_irq_cb without setting it\n");
- }
+void spg2xx_io_device::check_data_irq()
+{
+ LOGMASKED(LOG_UART | LOG_SIO | LOG_SPI | LOG_I2C | LOG_ADC, "Checking IRQ3 (%04x)\n", IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x2100);
+ m_uart_adc_irq_cb((IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x6100) ? ASSERT_LINE : CLEAR_LINE);
+}
+
+void spg2xx_io_device::check_external_irq()
+{
+ LOGMASKED(LOG_EXTINT, "Checking IRQ5 (%04x)\n", IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x1200);
+ m_external_irq_cb((IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x1200) ? ASSERT_LINE : CLEAR_LINE);
+}
+
+void spg2xx_io_device::check_hifreq_periodic_irq()
+{
+ LOGMASKED(LOG_TIMERS, "Checking IRQ6 (%04x)\n", IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0070);
+ m_ffreq_tmr1_irq_cb((IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0070) ? ASSERT_LINE : CLEAR_LINE);
+}
+
+void spg2xx_io_device::check_tmb_lofreq_key_irq()
+{
+ LOGMASKED(LOG_IRQS, "Checking IRQ7 (%04x)\n", IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x008b);
+ m_ffreq_tmr2_irq_cb((IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x008b) ? ASSERT_LINE : CLEAR_LINE);
+}
+
+void spg2xx_io_device::check_all_irqs(const uint16_t changed)
+{
+ if (changed & 0x0c00) // Timer A, Timer B IRQ
+ check_timers_irq();
if (changed & 0x6100) // UART, SPI, SIO, I2C, ADC IRQ
- {
- LOGMASKED(LOG_UART | LOG_SIO | LOG_SPI | LOG_I2C | LOG_ADC, "%ssserting IRQ3 (%04x, %04x)\n", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x6100) ? "A" : "Dea", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x2100), changed);
- if (m_uart_adc_irq_cb)
- m_uart_adc_irq_cb((IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x6100) ? ASSERT_LINE : CLEAR_LINE);
- else
- logerror("spg2xx_io_device::check_irqs, attempted to use m_uart_adc_irq_cb without setting it\n");
- }
+ check_data_irq();
if (changed & 0x1200) // External IRQ
- {
- LOGMASKED(LOG_EXTINT, "%ssserting IRQ5 (%04x, %04x)\n", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x1200) ? "A" : "Dea", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x1200), changed);
- if (m_external_irq_cb)
- m_external_irq_cb((IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x1200) ? ASSERT_LINE : CLEAR_LINE);
- else
- logerror("spg2xx_io_device::check_irqs, attempted to use m_external_irq_cb without setting it\n");
-
- }
+ check_external_irq();
if (changed & 0x0070) // 1024Hz, 2048Hz, 4096Hz IRQ
- {
- LOGMASKED(LOG_TIMERS, "%ssserting IRQ6 (%04x, %04x)\n", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0070) ? "A" : "Dea", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0070), changed); //m_cpu->set_state_unsynced(UNSP_IRQ6_LINE, (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0070) ? ASSERT_LINE : CLEAR_LINE);
- if (m_ffreq_tmr1_irq_cb)
- m_ffreq_tmr1_irq_cb((IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0070) ? ASSERT_LINE : CLEAR_LINE);
- else
- logerror("spg2xx_io_device::check_irqs, attempted to use m_ffreq_tmr1_irq_cb without setting it\n");
- }
+ check_hifreq_periodic_irq();
if (changed & 0x008b) // TMB1, TMB2, 4Hz, key change IRQ
- {
- LOGMASKED(LOG_IRQS, "%ssserting IRQ7 (%04x, %04x)\n", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x008b) ? "A" : "Dea", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x008b), changed);
- if (m_ffreq_tmr2_irq_cb)
- m_ffreq_tmr2_irq_cb((IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x008b) ? ASSERT_LINE : CLEAR_LINE);
- else
- logerror("spg2xx_io_device::check_irqs, attempted to use m_ffreq_tmr2_irq_cb without setting it\n");
-
- }
+ check_tmb_lofreq_key_irq();
}
uint16_t spg2xx_io_device::do_special_gpio(uint32_t index, uint16_t mask)
@@ -1784,22 +1686,17 @@ void spg2xx_io_device::do_gpio(uint32_t offset, bool write)
m_io_regs[5 * index + 1] = what;
}
-void spg2xx_io_device::do_adc_capture(int channel)
+template <int Which>
+TIMER_CALLBACK_MEMBER(spg2xx_io_device::adc_convert_tick)
{
- m_io_regs[REG_ADC_DATA] = (m_adc_in[channel]() & 0x0fff) | 0x8000;
- if (BIT(m_io_regs[REG_ADC_DATA], 11))
- {
- //m_io_regs[REG_ADC_DATA] |= 0xf000;
- }
+ m_io_regs[REG_ADC_DATA] = (m_adc_in[Which]() & 0x0fff) | 0x8000;
m_io_regs[REG_ADC_CTRL] |= 0x2000;
- const uint16_t old = IO_IRQ_STATUS;
if (BIT(m_io_regs[REG_ADC_CTRL], 9))
{
IO_IRQ_STATUS |= 0x2000;
- const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE);
- if (changed)
+ if (BIT(m_io_regs[REG_ADC_CTRL], 9) && BIT(IO_IRQ_ENABLE, 13))
{
- check_irqs(changed);
+ check_data_irq();
}
}
}
diff --git a/src/devices/machine/spg2xx_io.h b/src/devices/machine/spg2xx_io.h
index 6cbe3f95098..c04752eea96 100644
--- a/src/devices/machine/spg2xx_io.h
+++ b/src/devices/machine/spg2xx_io.h
@@ -149,26 +149,26 @@ protected:
REG_IO_DRIVE_CTRL
};
void check_extint_irq(int channel);
- void check_irqs(const uint16_t changed);
-
- static const device_timer_id TIMER_TMB1 = 0;
- static const device_timer_id TIMER_TMB2 = 1;
- static const device_timer_id TIMER_UART_TX = 4;
- static const device_timer_id TIMER_UART_RX = 5;
- static const device_timer_id TIMER_4KHZ = 6;
- static const device_timer_id TIMER_SRC_AB = 7;
- static const device_timer_id TIMER_SRC_C = 8;
- static const device_timer_id TIMER_RNG = 9;
- static const device_timer_id TIMER_WATCHDOG = 10;
- static const device_timer_id TIMER_SPI_TX = 11;
- static const device_timer_id TIMER_ADC0 = 12;
- static const device_timer_id TIMER_ADC1 = 13;
- static const device_timer_id TIMER_ADC2 = 14;
- static const device_timer_id TIMER_ADC3 = 15;
+ void check_timers_irq();
+ void check_data_irq();
+ void check_external_irq();
+ void check_hifreq_periodic_irq();
+ void check_tmb_lofreq_key_irq();
+ void check_all_irqs(const uint16_t changed);
virtual void device_start() override;
virtual void device_reset() override;
- virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+
+ TIMER_CALLBACK_MEMBER(timer_ab_tick);
+ TIMER_CALLBACK_MEMBER(timer_c_tick);
+ template <int Which> TIMER_CALLBACK_MEMBER(tmb_timer_tick);
+ TIMER_CALLBACK_MEMBER(uart_transmit_tick);
+ TIMER_CALLBACK_MEMBER(uart_receive_tick);
+ TIMER_CALLBACK_MEMBER(system_timer_tick);
+ TIMER_CALLBACK_MEMBER(rng_clock_tick);
+ TIMER_CALLBACK_MEMBER(watchdog_tick);
+ TIMER_CALLBACK_MEMBER(spi_tx_tick);
+ template <int Which> TIMER_CALLBACK_MEMBER(adc_convert_tick);
uint16_t clock_rng(int which);
@@ -178,23 +178,13 @@ protected:
uint16_t do_special_gpio(uint32_t index, uint16_t mask);
void update_timer_b_rate();
- void update_timer_ab_src();
- void update_timer_c_src();
void increment_timer_a();
- void uart_transmit_tick();
- void uart_receive_tick();
-
- void system_timer_tick();
-
- void do_spi_tx();
void set_spi_irq(bool set);
void update_spi_irqs();
void do_i2c();
- void do_adc_capture(int channel);
-
uint16_t m_io_regs[0x100];
uint8_t m_uart_rx_fifo[8];