From f6ceb7764434236a5d7260dd1b88ee42af86e0c9 Mon Sep 17 00:00:00 2001 From: mooglyguy Date: Wed, 19 Feb 2020 18:45:09 +0100 Subject: [PATCH] spg2xx: Added rudimentary SPI support. [Ryan Holtz] --- src/devices/machine/spg2xx.cpp | 5 +- src/devices/machine/spg2xx.h | 6 +- src/devices/machine/spg2xx_io.cpp | 267 ++++++++++++++++++++-- src/devices/machine/spg2xx_io.h | 26 ++- src/mame/drivers/spg2xx_jakks_gkr.cpp | 2 - src/mame/drivers/spg2xx_jakks_tvtouch.cpp | 52 ++++- 6 files changed, 326 insertions(+), 32 deletions(-) diff --git a/src/devices/machine/spg2xx.cpp b/src/devices/machine/spg2xx.cpp index 42b05c7e9a2..2a6aafdfaea 100644 --- a/src/devices/machine/spg2xx.cpp +++ b/src/devices/machine/spg2xx.cpp @@ -39,6 +39,7 @@ spg2xx_device::spg2xx_device(const machine_config &mconfig, device_type type, co m_i2c_w(*this), m_i2c_r(*this), m_uart_tx(*this), + m_spi_tx(*this), m_chip_sel(*this), m_screen(*this, finder_base::DUMMY_TAG) { @@ -85,6 +86,7 @@ void spg2xx_device::device_start() m_i2c_w.resolve_safe(); m_i2c_r.resolve_safe(0); m_uart_tx.resolve_safe(); + m_spi_tx.resolve_safe(); m_chip_sel.resolve_safe(); save_item(NAME(m_sprite_limit)); @@ -170,7 +172,8 @@ void spg2xx_device::configure_spg_io(spg2xx_io_device* io) io->adc_in<1>().set(FUNC(spg2xx_device::adc_r<1>)); io->i2c_w().set(FUNC(spg2xx_device::eepromx_w)); io->i2c_r().set(FUNC(spg2xx_device::eepromx_r)); - io->uart_tx().set(FUNC(spg2xx_device::tx_w)); + io->uart_tx().set(FUNC(spg2xx_device::uart_tx_w)); + io->spi_tx().set(FUNC(spg2xx_device::spi_tx_w)); io->chip_select().set(FUNC(spg2xx_device::cs_w)); io->pal_read_callback().set(FUNC(spg2xx_device::get_pal_ntsc)); io->write_timer_irq_callback().set(FUNC(spg2xx_device::timerirq_w)); diff --git a/src/devices/machine/spg2xx.h b/src/devices/machine/spg2xx.h index e7f69a79b0c..e67636eaa8d 100644 --- a/src/devices/machine/spg2xx.h +++ b/src/devices/machine/spg2xx.h @@ -62,6 +62,7 @@ public: auto i2c_r() { return m_i2c_r.bind(); } auto uart_tx() { return m_uart_tx.bind(); } + auto spi_tx() { return m_spi_tx.bind(); } auto chip_select() { return m_chip_sel.bind(); } @@ -72,6 +73,7 @@ public: void extint_w(int channel, bool state) { m_spg_io->extint_w(channel, state); } void uart_rx(uint8_t data) { m_spg_io->uart_rx(data); } + void spi_rx(int state) { m_spg_io->spi_rx(state); } DECLARE_WRITE_LINE_MEMBER(vblank) { m_spg_video->vblank(state); } uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { return m_spg_video->screen_update(screen, bitmap, cliprect); } @@ -120,6 +122,7 @@ protected: devcb_read8 m_i2c_r; devcb_write8 m_uart_tx; + devcb_write_line m_spi_tx; devcb_write8 m_chip_sel; @@ -144,7 +147,8 @@ protected: DECLARE_WRITE8_MEMBER(eepromx_w) { m_i2c_w(offset, data, mem_mask); } DECLARE_READ8_MEMBER(eepromx_r) { return m_i2c_r(); }; - DECLARE_WRITE8_MEMBER(tx_w) { m_uart_tx(offset, data, mem_mask); } + DECLARE_WRITE8_MEMBER(uart_tx_w) { m_uart_tx(offset, data, mem_mask); } + DECLARE_WRITE_LINE_MEMBER(spi_tx_w) { m_spi_tx(state); } DECLARE_WRITE8_MEMBER(cs_w) { m_chip_sel(offset, data, mem_mask); } }; diff --git a/src/devices/machine/spg2xx_io.cpp b/src/devices/machine/spg2xx_io.cpp index 0f89a0d3d4f..be1abc1137f 100644 --- a/src/devices/machine/spg2xx_io.cpp +++ b/src/devices/machine/spg2xx_io.cpp @@ -49,6 +49,7 @@ spg2xx_io_device::spg2xx_io_device(const machine_config &mconfig, device_type ty m_i2c_w(*this), m_i2c_r(*this), m_uart_tx(*this), + m_spi_tx(*this), m_chip_sel(*this), m_cpu(*this, finder_base::DUMMY_TAG), m_screen(*this, finder_base::DUMMY_TAG), @@ -85,6 +86,7 @@ void spg2xx_io_device::device_start() m_i2c_w.resolve_safe(); m_i2c_r.resolve_safe(0); m_uart_tx.resolve_safe(); + m_spi_tx.resolve_safe(); m_chip_sel.resolve_safe(); m_pal_read_cb.resolve_safe(0); @@ -122,21 +124,48 @@ void spg2xx_io_device::device_start() m_watchdog_timer = timer_alloc(TIMER_WATCHDOG); m_watchdog_timer->adjust(attotime::never); + m_spi_tx_timer = timer_alloc(TIMER_SPI_TX); + m_spi_tx_timer->adjust(attotime::never); + + save_item(NAME(m_io_regs)); + + save_item(NAME(m_uart_rx_fifo)); + save_item(NAME(m_uart_rx_fifo_start)); + save_item(NAME(m_uart_rx_fifo_end)); + save_item(NAME(m_uart_rx_fifo_count)); + save_item(NAME(m_uart_rx_available)); + save_item(NAME(m_uart_rx_irq)); + save_item(NAME(m_uart_tx_irq)); + + save_item(NAME(m_spi_tx_fifo)); + save_item(NAME(m_spi_tx_fifo_start)); + save_item(NAME(m_spi_tx_fifo_end)); + save_item(NAME(m_spi_tx_fifo_count)); + save_item(NAME(m_spi_tx_buf)); + save_item(NAME(m_spi_tx_bit)); + + save_item(NAME(m_spi_rx_fifo)); + save_item(NAME(m_spi_rx_fifo_start)); + save_item(NAME(m_spi_rx_fifo_end)); + save_item(NAME(m_spi_rx_fifo_count)); + save_item(NAME(m_spi_rx_buf)); + save_item(NAME(m_spi_rx_bit)); + + save_item(NAME(m_extint)); + save_item(NAME(m_timer_a_preload)); save_item(NAME(m_timer_b_preload)); save_item(NAME(m_timer_b_divisor)); save_item(NAME(m_timer_b_tick_rate)); - save_item(NAME(m_io_regs)); - - save_item(NAME(m_extint)); - save_item(NAME(m_2khz_divider)); save_item(NAME(m_1khz_divider)); save_item(NAME(m_4hz_divider)); save_item(NAME(m_uart_baud_rate)); + save_item(NAME(m_spi_rate)); + save_item(NAME(m_sio_bits_remaining)); save_item(NAME(m_sio_writing)); } @@ -154,14 +183,30 @@ void spg2xx_io_device::device_reset() m_io_regs[REG_PRNG1] = 0x1418; m_io_regs[REG_PRNG2] = 0x1658; - m_uart_rx_available = false; memset(m_uart_rx_fifo, 0, ARRAY_LENGTH(m_uart_rx_fifo)); m_uart_rx_fifo_start = 0; m_uart_rx_fifo_end = 0; m_uart_rx_fifo_count = 0; + m_uart_rx_available = false; m_uart_tx_irq = false; m_uart_rx_irq = false; + memset(m_spi_tx_fifo, 0, ARRAY_LENGTH(m_spi_tx_fifo)); + m_spi_tx_fifo_start = 0; + m_spi_tx_fifo_end = 0; + m_spi_tx_fifo_count = 0; + m_spi_tx_buf = 0x00; + m_spi_tx_bit = 8; + + memset(m_spi_rx_fifo, 0, ARRAY_LENGTH(m_spi_rx_fifo)); + m_spi_rx_fifo_start = 0; + m_spi_rx_fifo_end = 0; + m_spi_rx_fifo_count = 0; + m_spi_rx_buf = 0x00; + m_spi_rx_bit = 7; + + m_spi_rate = 0; + memset(m_extint, 0, sizeof(bool) * 2); m_4khz_timer->adjust(attotime::from_hz(4096), 0, attotime::from_hz(4096)); @@ -193,6 +238,134 @@ void spg2xx_io_device::uart_rx(uint8_t data) } } +void spg2xx_io_device::set_spi_irq(bool set) +{ + const uint16_t old = IO_IRQ_STATUS; + if (set) + { + LOGMASKED(LOG_SPI, "Raising SPI IRQ\n"); + IO_IRQ_STATUS |= 0x4000; + } + else + { + LOGMASKED(LOG_SPI, "Lowering SPI IRQ\n"); + IO_IRQ_STATUS &= ~0x4000; + } + + const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE); + if (changed) + check_irqs(changed); +} + +void spg2xx_io_device::update_spi_irqs() +{ + bool ovf_set = BIT(m_io_regs[REG_SPI_RXSTATUS], 8); + bool rxi_set = BIT(m_io_regs[REG_SPI_RXSTATUS], 15) && BIT(m_io_regs[REG_SPI_RXSTATUS], 14); + bool txi_set = BIT(m_io_regs[REG_SPI_TXSTATUS], 15) && BIT(m_io_regs[REG_SPI_TXSTATUS], 14); + set_spi_irq(ovf_set || rxi_set || txi_set); +} + +void spg2xx_io_device::do_spi_tx() +{ + if (!BIT(m_io_regs[REG_SPI_CTRL], 15) || m_spi_tx_fifo_count == 0) + { + LOGMASKED(LOG_SPI, "Nothing to transmit or SPI disabled, bailing.\n"); + return; + } + + if (m_spi_tx_bit == 8) + { + m_spi_tx_bit--; + m_spi_tx_buf = m_spi_tx_fifo[m_spi_tx_fifo_end]; + m_spi_tx_fifo_end = (m_spi_tx_fifo_end + 1) & 0x0f; + LOGMASKED(LOG_SPI, "Peeling off byte %02x and putting it in the Tx buffer.\n", m_spi_tx_buf); + } + + m_spi_tx(BIT(m_spi_tx_buf, m_spi_tx_bit)); + + if (m_spi_tx_bit == 0) + { + m_spi_tx_bit = 8; + m_spi_tx_fifo_count--; + LOGMASKED(LOG_SPI, "Done transmitting byte, new FIFO count is %d.\n", m_spi_tx_fifo_count); + if (m_spi_tx_fifo_count == 0) + { + LOGMASKED(LOG_SPI, "Stopping Tx timer.\n"); + m_spi_tx_timer->adjust(attotime::never); + } + + m_io_regs[REG_SPI_TXSTATUS] &= ~0x000f; + m_io_regs[REG_SPI_TXSTATUS] |= m_spi_tx_fifo_count; + + if ((m_io_regs[REG_SPI_TXSTATUS] & 0x000f) < ((m_io_regs[REG_SPI_TXSTATUS] >> 4) & 0x000f)) + { + LOGMASKED(LOG_SPI, "We're below the Tx IRQ threshold, flagging IRQ.\n"); + m_io_regs[REG_SPI_TXSTATUS] |= 0x8000; + update_spi_irqs(); + } + } + else + { + m_spi_tx_bit--; + } +} + +void spg2xx_io_device::spi_rx(int state) +{ + if (!BIT(m_io_regs[REG_SPI_CTRL], 15)) + { + LOGMASKED(LOG_SPI, "SPI Rx, but SPI is disabled, bailing.\n"); + return; + } + + m_spi_rx_buf |= state << (m_spi_rx_bit); + if (m_spi_rx_bit == 0) + { + LOGMASKED(LOG_SPI, "Done receiving byte: %02x\n", m_spi_rx_buf); + m_spi_rx_bit = 7; + if (m_spi_rx_fifo_count == 16) + { + LOGMASKED(LOG_SPI, "Rx FIFO overflow.\n"); + m_io_regs[REG_SPI_RXSTATUS] |= 0x0100; // Set RFOV flag + + update_spi_irqs(); + + if (BIT(m_io_regs[REG_SPI_MISC], 9)) + m_spi_rx_fifo[(m_spi_rx_fifo_start - 1) & 0x0f] = m_spi_rx_buf; + + m_spi_rx_buf = 0x00; + return; + } + + m_spi_rx_fifo[m_spi_rx_fifo_start] = m_spi_rx_buf; + m_spi_rx_fifo_start = (m_spi_rx_fifo_start + 1) & 0x0f; + LOGMASKED(LOG_SPI, "Putting byte into Rx buffer.\n"); + + m_io_regs[REG_SPI_MISC] |= 0x0004; // Set RNE flag + + if (m_spi_rx_fifo_count == 0) + m_io_regs[REG_SPI_RXDATA] = m_spi_rx_buf; + + m_spi_rx_buf = 0x00; + m_spi_rx_fifo_count++; + LOGMASKED(LOG_SPI, "New Rx FIFO count: %d\n", m_spi_rx_fifo_count); + + m_io_regs[REG_SPI_RXSTATUS] &= ~0x000f; + m_io_regs[REG_SPI_RXSTATUS] |= m_spi_rx_fifo_count; // Update RXFFLAG bits + + if (m_spi_rx_fifo_count >= ((m_io_regs[REG_SPI_RXSTATUS] >> 4) & 0x000f)) + { + LOGMASKED(LOG_SPI, "Rx buffer is at or above threshold, flagging IRQ\n"); + m_io_regs[REG_SPI_RXSTATUS] |= 0x8000; // Set SPIRXIF + update_spi_irqs(); + } + } + else + { + m_spi_rx_bit--; + } +} + uint16_t spg2xx_io_device::clock_rng(int which) { const uint16_t value = m_io_regs[REG_PRNG1 + which]; @@ -362,27 +535,43 @@ READ16_MEMBER(spg2xx_io_device::io_extended_r) break; case REG_SPI_CTRL: - LOGMASKED(LOG_SIO, "%s: io_r: SPI Control = %04x\n", machine().describe_context(), val); + LOGMASKED(LOG_SPI, "%s: io_r: SPI Control = %04x\n", machine().describe_context(), val); break; case REG_SPI_TXSTATUS: - LOGMASKED(LOG_SIO, "%s: io_r: SPI Tx Status = %04x\n", machine().describe_context(), val); + LOGMASKED(LOG_SPI, "%s: io_r: SPI Tx Status = %04x\n", machine().describe_context(), val); break; case REG_SPI_TXDATA: - LOGMASKED(LOG_SIO, "%s: io_r: SPI Tx Data = %04x\n", machine().describe_context(), val); + LOGMASKED(LOG_SPI, "%s: io_r: SPI Tx Data = %04x\n", machine().describe_context(), val); break; case REG_SPI_RXSTATUS: - LOGMASKED(LOG_SIO, "%s: io_r: SPI Rx Status = %04x\n", machine().describe_context(), val); + LOGMASKED(LOG_SPI, "%s: io_r: SPI Rx Status = %04x\n", machine().describe_context(), val); break; case REG_SPI_RXDATA: - LOGMASKED(LOG_SIO, "%s: io_r: SPI Rx Data = %04x\n", machine().describe_context(), val); + LOGMASKED(LOG_SPI, "%s: io_r: SPI Rx Data = %04x, FIFO count %d\n", machine().describe_context(), val, m_spi_rx_fifo_count); + if (m_spi_rx_fifo_count > 0) + { + m_spi_rx_fifo_count--; + if (m_spi_rx_fifo_count > 0) + { + m_spi_rx_fifo_end = (m_spi_rx_fifo_end + 1) & 0x0f; + m_io_regs[REG_SPI_RXDATA] = m_spi_rx_fifo[m_spi_rx_fifo_end]; + } + + m_io_regs[REG_SPI_RXSTATUS] &= ~(0x0200); // Clear RXFULL + m_io_regs[REG_SPI_MISC] &= ~(0x0008); // Clear RFF + if (m_spi_rx_fifo_count == 0) + { + m_io_regs[REG_SPI_MISC] &= ~(0x0004); // Clear RNE + } + } break; case REG_SPI_MISC: - LOGMASKED(LOG_SIO, "%s: io_r: SPI Misc. = %04x\n", machine().describe_context(), val); + LOGMASKED(LOG_SPI, "%s: io_r: SPI Misc. = %04x\n", machine().describe_context(), val); break; case REG_SIO_SETUP: @@ -1058,44 +1247,76 @@ WRITE16_MEMBER(spg2xx_io_device::io_extended_w) case REG_SPI_CTRL: { static const char* const s_spi_clock[8] = { "SYSCLK/2" , "SYSCLK/4", "SYSCLK/8", "SYSCLK/16", "SYSCLK/32", "SYSCLK/64", "SYSCLK/128", "Reserved" }; - LOGMASKED(LOG_SIO, "%s: io_r: SPI Control = %04x (Enable:%d, Loopback:%d, Reset:%d, Mode:%s, Phase:%d, Polarity:%d, Clock:%s)\n", machine().describe_context(), data, + LOGMASKED(LOG_SPI, "%s: io_w: SPI Control = %04x (Enable:%d, Loopback:%d, Reset:%d, Mode:%s, Phase:%d, Polarity:%d, Clock:%s)\n", machine().describe_context(), data, BIT(data, 15), BIT(data, 13), BIT(data, 11), BIT(data, 8) ? "Slave" : "Master", BIT(data, 5), BIT(data, 4), s_spi_clock[data & 7]); m_io_regs[offset] = data; + if ((data & 7) == 7 || !BIT(m_io_regs[offset], 15)) + { + m_spi_rate = 0; + m_spi_tx_timer->adjust(attotime::never); + } + else + { + m_spi_rate = 2 << (data & 7); + attotime rate = attotime::from_ticks(m_spi_rate, clock()); + if (m_spi_tx_timer->remaining() != attotime::never) + m_spi_tx_timer->adjust(rate); + } break; } case REG_SPI_TXSTATUS: - LOGMASKED(LOG_SIO, "%s: io_r: SPI Tx Status = %04x\n", machine().describe_context(), data); + LOGMASKED(LOG_SPI, "%s: io_w: SPI Tx Status = %04x\n", machine().describe_context(), data); m_io_regs[offset] &= ~0x40f0; m_io_regs[offset] |= data & 0x40f0; if (BIT(data, 15)) { m_io_regs[offset] &= ~0x8000; + update_spi_irqs(); } break; case REG_SPI_TXDATA: - LOGMASKED(LOG_SIO, "%s: io_r: SPI Tx Data = %04x\n", machine().describe_context(), data); + LOGMASKED(LOG_SPI, "%s: io_w: SPI Tx Data = %04x\n", machine().describe_context(), data); + m_io_regs[offset] = data; + if (BIT(m_io_regs[REG_SPI_CTRL], 15)) + { + if (m_spi_tx_fifo_count < 16) + { + LOGMASKED(LOG_SPI, "%s: SPI Tx FIFO is full, pushing onto FIFO and enabling timer.\n", machine().describe_context()); + m_spi_tx_fifo[m_spi_tx_fifo_start] = (uint8_t)m_io_regs[REG_SPI_TXDATA]; + m_spi_tx_fifo_start = (m_spi_tx_fifo_start + 1) & 0x0f; + m_spi_tx_fifo_count++; + + attotime rate = attotime::from_ticks(m_spi_rate, clock()); + m_spi_tx_timer->adjust(rate, 0, rate); + } + else + { + LOGMASKED(LOG_SPI, "%s: SPI Tx FIFO is full, not pushing.\n", machine().describe_context()); + } + } break; case REG_SPI_RXSTATUS: - LOGMASKED(LOG_SIO, "%s: io_r: SPI Rx Status = %04x\n", machine().describe_context(), data); + LOGMASKED(LOG_SPI, "%s: io_w: SPI Rx Status = %04x\n", machine().describe_context(), data); m_io_regs[offset] &= ~0x40f0; m_io_regs[offset] |= data & 0x40f0; + m_io_regs[offset] &= ~0x0100; // Clear RXFOV if (BIT(data, 15)) { m_io_regs[offset] &= ~0x8000; + update_spi_irqs(); } break; case REG_SPI_RXDATA: - LOGMASKED(LOG_SIO, "%s: io_r: SPI Rx Data = %04x\n", machine().describe_context(), data); + LOGMASKED(LOG_SPI, "%s: io_w: SPI Rx Data = %04x\n", machine().describe_context(), data); break; case REG_SPI_MISC: { - //static const char* const s_spi_clock[8] = { "SYSCLK/2" , "SYSCLK/4", "SYSCLK/8", "SYSCLK/16", "SYSCLK/32", "SYSCLK/64", "SYSCLK/128", "Reserved" }; - LOGMASKED(LOG_SIO, "%s: io_r: SPI Misc. = %04x (Over:%d, SmartInt:%d, Busy:%d, RxFull:%d, RxNotEmpty:%d, TxNotFull:%d, TxEmpty:%d)\n", machine().describe_context(), data, + LOGMASKED(LOG_SPI, "%s: io_w: SPI Misc. = %04x (Over:%d, SmartInt:%d, Busy:%d, RxFull:%d, RxNotEmpty:%d, TxNotFull:%d, TxEmpty:%d)\n", machine().describe_context(), data, BIT(data, 9), BIT(data, 8), BIT(data, 4), BIT(data, 3), BIT(data, 2), BIT(data, 1), BIT(data, 0)); m_io_regs[offset] &= ~0x0300; m_io_regs[offset] |= data & 0x0300; @@ -1250,6 +1471,10 @@ void spg2xx_io_device::device_timer(emu_timer &timer, device_timer_id id, int pa 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; } } @@ -1358,10 +1583,10 @@ void spg2xx_io_device::check_irqs(const uint16_t changed) m_timer_irq_cb((IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0c00) ? ASSERT_LINE : CLEAR_LINE); } - if (changed & 0x2100) // UART, ADC IRQ + if (changed & 0x6100) // UART, SPI, SIO, I2C, ADC IRQ { - LOGMASKED(LOG_UART, "%ssserting IRQ3 (%04x, %04x)\n", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x2100) ? "A" : "Dea", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x2100), changed); - m_uart_adc_irq_cb((IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x2100) ? ASSERT_LINE : CLEAR_LINE); + LOGMASKED(LOG_UART | LOG_SIO | LOG_SPI | LOG_I2C, "%ssserting IRQ3 (%04x, %04x)\n", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x6100) ? "A" : "Dea", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x2100), changed); + m_uart_adc_irq_cb((IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x6100) ? ASSERT_LINE : CLEAR_LINE); } if (changed & 0x1200) // External IRQ diff --git a/src/devices/machine/spg2xx_io.h b/src/devices/machine/spg2xx_io.h index 2a5db8e00f3..da0b5f8900c 100644 --- a/src/devices/machine/spg2xx_io.h +++ b/src/devices/machine/spg2xx_io.h @@ -27,10 +27,11 @@ public: auto i2c_r() { return m_i2c_r.bind(); } auto uart_tx() { return m_uart_tx.bind(); } - + auto spi_tx() { return m_spi_tx.bind(); } auto chip_select() { return m_chip_sel.bind(); } void uart_rx(uint8_t data); + void spi_rx(int state); void extint_w(int channel, bool state); @@ -156,6 +157,7 @@ protected: 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; virtual void device_start() override; virtual void device_reset() override; @@ -178,6 +180,10 @@ protected: void system_timer_tick(); + void do_spi_tx(); + void set_spi_irq(bool set); + void update_spi_irqs(); + void do_i2c(); uint16_t m_io_regs[0x100]; @@ -190,6 +196,20 @@ protected: bool m_uart_rx_irq; bool m_uart_tx_irq; + uint8_t m_spi_tx_fifo[16]; + uint8_t m_spi_tx_fifo_start; + uint8_t m_spi_tx_fifo_end; + uint8_t m_spi_tx_fifo_count; + uint8_t m_spi_tx_buf; + uint8_t m_spi_tx_bit; + + uint8_t m_spi_rx_fifo[16]; + uint8_t m_spi_rx_fifo_start; + uint8_t m_spi_rx_fifo_end; + uint8_t m_spi_rx_fifo_count; + uint8_t m_spi_rx_buf; + uint8_t m_spi_rx_bit; + bool m_extint[2]; devcb_write16 m_porta_out; @@ -205,6 +225,7 @@ protected: devcb_read8 m_i2c_r; devcb_write8 m_uart_tx; + devcb_write_line m_spi_tx; devcb_write8 m_chip_sel; @@ -230,6 +251,9 @@ protected: emu_timer *m_rng_timer; emu_timer *m_watchdog_timer; + uint32_t m_spi_rate; + emu_timer* m_spi_tx_timer; + uint8_t m_sio_bits_remaining; bool m_sio_writing; diff --git a/src/mame/drivers/spg2xx_jakks_gkr.cpp b/src/mame/drivers/spg2xx_jakks_gkr.cpp index ce31bf4e9f0..535728f0476 100644 --- a/src/mame/drivers/spg2xx_jakks_gkr.cpp +++ b/src/mame/drivers/spg2xx_jakks_gkr.cpp @@ -36,8 +36,6 @@ public: void jakks_gkr_wp(machine_config &config); void jakks_gkr_cb(machine_config &config); - void jakks_tvtouch(machine_config& config); - DECLARE_READ_LINE_MEMBER(i2c_gkr_r); protected: diff --git a/src/mame/drivers/spg2xx_jakks_tvtouch.cpp b/src/mame/drivers/spg2xx_jakks_tvtouch.cpp index 3baf688c5d5..d81ef07418c 100644 --- a/src/mame/drivers/spg2xx_jakks_tvtouch.cpp +++ b/src/mame/drivers/spg2xx_jakks_tvtouch.cpp @@ -14,12 +14,19 @@ public: void tvtouch(machine_config &config); private: + virtual void machine_start() override; + virtual void machine_reset() override; + DECLARE_READ16_MEMBER(porta_r); DECLARE_READ16_MEMBER(portb_r); DECLARE_READ16_MEMBER(portc_r); DECLARE_WRITE16_MEMBER(porta_w) override; DECLARE_WRITE16_MEMBER(portb_w) override; DECLARE_WRITE16_MEMBER(portc_w) override; + DECLARE_WRITE_LINE_MEMBER(spi_w); + + uint8_t m_spi_bit; + uint8_t m_spi_val; }; static INPUT_PORTS_START( tvtouch ) @@ -172,6 +179,22 @@ static INPUT_PORTS_START( tvtouch ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) INPUT_PORTS_END +void jakks_tvtouch_state::machine_start() +{ + spg2xx_game_state::machine_start(); + + save_item(NAME(m_spi_bit)); + save_item(NAME(m_spi_val)); +} + +void jakks_tvtouch_state::machine_reset() +{ + spg2xx_game_state::machine_reset(); + + m_spi_bit = 7; + m_spi_val = 0x00; +} + READ16_MEMBER(jakks_tvtouch_state::porta_r) { logerror("%s: porta_r: %04x & %04x\n", machine().describe_context(), 0, mem_mask); @@ -187,8 +210,6 @@ READ16_MEMBER(jakks_tvtouch_state::portb_r) READ16_MEMBER(jakks_tvtouch_state::portc_r) { uint16_t data = m_i2cmem->read_sda(); - //if (mem_mask & 0xfffc) - //logerror("%s: portc_r: %04x & %04x\n", machine().describe_context(), data, mem_mask); return data; } @@ -204,19 +225,38 @@ WRITE16_MEMBER(jakks_tvtouch_state::portb_w) WRITE16_MEMBER(jakks_tvtouch_state::portc_w) { - //if (mem_mask & 0xfffc) - //logerror("%s: portc_w: %04x & %04x\n", machine().describe_context(), data, mem_mask); if (BIT(mem_mask, 1)) m_i2cmem->write_scl(BIT(data, 1)); if (BIT(mem_mask, 0)) m_i2cmem->write_sda(BIT(data, 0)); } +WRITE_LINE_MEMBER(jakks_tvtouch_state::spi_w) +{ + m_spi_val |= state << m_spi_bit; + if (m_spi_bit == 0) + { + logerror("Received via SPI: %02x\n", m_spi_val); + m_spi_bit = 7; + m_spi_val = 0x00; + /*static uint8_t s_value = 0x40; + for (int bit = 7; bit >= 0; bit--) + { + m_maincpu->spi_rx(BIT(s_value, bit)); + } + s_value ^= 0x80;*/ + } + else + { + m_spi_bit--; + } +} + void jakks_tvtouch_state::tvtouch(machine_config &config) { SPG24X(config, m_maincpu, XTAL(27'000'000), m_screen); - m_maincpu->set_addrmap(AS_PROGRAM, &jakks_tvtouch_state::mem_map_4m); - + m_maincpu->set_addrmap(AS_PROGRAM, &jakks_tvtouch_state::mem_map_2m); + m_maincpu->spi_tx().set(FUNC(jakks_tvtouch_state::spi_w)); spg2xx_base(config); m_maincpu->porta_in().set(FUNC(jakks_tvtouch_state::porta_r));