spg2xx: Added rudimentary SPI support. [Ryan Holtz]

This commit is contained in:
mooglyguy 2020-02-19 18:45:09 +01:00
parent b6b4957fe8
commit f6ceb77644
6 changed files with 326 additions and 32 deletions

View File

@ -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));

View File

@ -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); }
};

View File

@ -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

View File

@ -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;

View File

@ -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:

View File

@ -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));