mirror of
https://github.com/holub/mame
synced 2025-04-25 17:56:43 +03:00
spg2xx: Added rudimentary SPI support. [Ryan Holtz]
This commit is contained in:
parent
b6b4957fe8
commit
f6ceb77644
@ -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));
|
||||
|
@ -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); }
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user