From 990d8233bfd26ccf6f60cfe922d29a2570bff9c2 Mon Sep 17 00:00:00 2001 From: MooglyGuy Date: Thu, 3 Jun 2021 19:29:25 +0200 Subject: Made SPG2xx I/O IRQ checking a bit more lean; improved ADC behavior. (#8138) [Ryan Holtz] --- src/devices/machine/spg2xx_io.cpp | 339 +++++++++++++------------------------- src/devices/machine/spg2xx_io.h | 44 ++--- 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 +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 +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 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 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]; -- cgit v1.2.3