summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/spg2xx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/spg2xx.cpp')
-rw-r--r--src/devices/machine/spg2xx.cpp82
1 files changed, 67 insertions, 15 deletions
diff --git a/src/devices/machine/spg2xx.cpp b/src/devices/machine/spg2xx.cpp
index 3ca6e8b5ada..95814ab145b 100644
--- a/src/devices/machine/spg2xx.cpp
+++ b/src/devices/machine/spg2xx.cpp
@@ -41,12 +41,14 @@ DEFINE_DEVICE_TYPE(SPG28X, spg28x_device, "spg28x", "SPG280-series System-on-a-C
#define LOG_PPU_READS (1U << 22)
#define LOG_PPU_WRITES (1U << 23)
#define LOG_UNKNOWN_PPU (1U << 24)
+#define LOG_FIQ (1U << 25)
+#define LOG_SIO (1U << 26)
#define LOG_IO (LOG_IO_READS | LOG_IO_WRITES | LOG_IRQS | LOG_GPIO | LOG_UART | LOG_I2C | LOG_DMA | LOG_TIMERS | LOG_UNKNOWN_IO)
#define LOG_CHANNELS (LOG_CHANNEL_READS | LOG_CHANNEL_WRITES)
#define LOG_SPU (LOG_SPU_READS | LOG_SPU_WRITES | LOG_UNKNOWN_SPU | LOG_CHANNEL_READS | LOG_CHANNEL_WRITES \
| LOG_ENVELOPES | LOG_SAMPLES | LOG_RAMPDOWN | LOG_BEAT)
#define LOG_PPU (LOG_PPU_READS | LOG_PPU_WRITES | LOG_UNKNOWN_PPU)
-#define LOG_ALL (LOG_IO | LOG_SPU | LOG_PPU | LOG_VLINES | LOG_SEGMENT)
+#define LOG_ALL (LOG_IO | LOG_SPU | LOG_PPU | LOG_VLINES | LOG_SEGMENT | LOG_FIQ)
#define VERBOSE (0)
#include "logmacro.h"
@@ -891,7 +893,8 @@ void spg2xx_device::uart_rx(uint8_t data)
m_uart_rx_fifo[m_uart_rx_fifo_end] = data;
m_uart_rx_fifo_end = (m_uart_rx_fifo_end + 1) % ARRAY_LENGTH(m_uart_rx_fifo);
m_uart_rx_fifo_count++;
- m_uart_rx_timer->adjust(attotime::from_ticks(BIT(m_io_regs[0x30], 5) ? 11 : 10, m_uart_baud_rate));
+ if (m_uart_rx_timer->remaining() == attotime::never)
+ m_uart_rx_timer->adjust(attotime::from_ticks(BIT(m_io_regs[0x30], 5) ? 11 : 10, m_uart_baud_rate));
}
}
@@ -947,6 +950,8 @@ READ16_MEMBER(spg2xx_device::io_r)
case 0x27: // ADC Data
m_io_regs[0x27] = 0;
+ IO_IRQ_STATUS &= ~0x4000;
+ check_irqs(0x4000);
LOGMASKED(LOG_IO_READS, "%s: io_r: ADC Data = %04x\n", machine().describe_context(), val);
break;
@@ -964,7 +969,7 @@ READ16_MEMBER(spg2xx_device::io_r)
break;
case 0x2e: // FIQ Source Select
- LOGMASKED(LOG_IRQS, "io_r: FIQ Source Select = %04x\n", val);
+ LOGMASKED(LOG_FIQ, "io_r: FIQ Source Select = %04x\n", val);
break;
case 0x2f: // Data Segment
@@ -979,20 +984,30 @@ READ16_MEMBER(spg2xx_device::io_r)
case 0x36: // UART RX Data
if (m_uart_rx_available)
{
+ m_io_regs[0x31] &= ~0x0081;
+ logerror("UART Rx data is available, clearing bits\n");
if (m_uart_rx_fifo_count)
{
+ logerror("Remaining count %d, value %02x\n", m_uart_rx_fifo_count, m_uart_rx_fifo[m_uart_rx_fifo_start]);
m_io_regs[0x36] = m_uart_rx_fifo[m_uart_rx_fifo_start];
+ val = m_io_regs[0x36];
m_uart_rx_fifo_start = (m_uart_rx_fifo_start + 1) % ARRAY_LENGTH(m_uart_rx_fifo);
m_uart_rx_fifo_count--;
+
if (m_uart_rx_fifo_count == 0)
{
- m_io_regs[0x31] &= ~0x0081;
m_uart_rx_available = false;
}
+ else
+ {
+ logerror("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[0x30], 5) ? 11 : 10, m_uart_baud_rate));
+ }
}
else
{
- m_io_regs[0x31] &= ~0x0081;
m_uart_rx_available = false;
}
}
@@ -1091,6 +1106,20 @@ void spg2xx_device::update_portb_special_modes()
}
}
+WRITE16_MEMBER(spg28x_device::io_w)
+{
+ if (offset == 0x33)
+ {
+ m_io_regs[offset] = data;
+ m_uart_baud_rate = 27000000 / (0x10000 - m_io_regs[0x33]);
+ LOGMASKED(LOG_UART, "io_w: UART Baud Rate scaler = %04x (%d baud)\n", data, m_uart_baud_rate);
+ }
+ else
+ {
+ spg2xx_device::io_w(space, offset, data, mem_mask);
+ }
+}
+
WRITE16_MEMBER(spg2xx_device::io_w)
{
static const char *const gpioregs[] = { "GPIO Data Port", "GPIO Buffer Port", "GPIO Direction Port", "GPIO Attribute Port", "GPIO IRQ/Latch Port" };
@@ -1274,16 +1303,17 @@ WRITE16_MEMBER(spg2xx_device::io_w)
case 0x25: // ADC Control
{
LOGMASKED(LOG_IO_WRITES, "%s: io_w: ADC Control = %04x\n", machine().describe_context(), data);
- const uint16_t changed = m_io_regs[offset] ^ data;
- m_io_regs[offset] = data;
- if (BIT(changed, 12) && BIT(data, 12) && !BIT(m_io_regs[offset], 1))
+ m_io_regs[offset] = data & ~0x1000;
+ if (BIT(data, 12) && !BIT(m_io_regs[offset], 1))
{
m_io_regs[0x27] = 0x8000 | (m_adc_in() & 0x7fff);
const uint16_t old = IO_IRQ_STATUS;
- IO_IRQ_STATUS |= 0x2000;
+ IO_IRQ_STATUS |= 0x4000;
const uint16_t changed = IO_IRQ_STATUS ^ old;
if (changed)
+ {
check_irqs(changed);
+ }
}
break;
}
@@ -1324,7 +1354,7 @@ WRITE16_MEMBER(spg2xx_device::io_w)
{
"PPU", "SPU Channel", "Timer A", "Timer B", "UART/SPI", "External", "Reserved", "None"
};
- LOGMASKED(LOG_IRQS, "io_w: FIQ Source Select (not yet implemented) = %04x, %s\n", data, s_fiq_select[data & 7]);
+ LOGMASKED(LOG_FIQ, "io_w: FIQ Source Select (not yet implemented) = %04x, %s\n", data, s_fiq_select[data & 7]);
m_io_regs[offset] = data;
break;
}
@@ -1424,6 +1454,33 @@ WRITE16_MEMBER(spg2xx_device::io_w)
m_io_regs[offset] |= data & 0x0007;
break;
+ case 0x50: // SIO Setup
+ {
+ static const char* const s_addr_mode[4] = { "16-bit", "None", "8-bit", "24-bit" };
+ static const char* const s_baud_rate[4] = { "/16", "/4", "/8", "/32" };
+ LOGMASKED(LOG_SIO, "io_w: SIO Setup (not implemented) = %04x (DS301Ready:%d, Start:%d, Auto:%d, IRQEn:%d, Width:%d, Related:%d\n", data
+ , BIT(data, 11), BIT(data, 10), BIT(data, 9), BIT(data, 8), BIT(data, 7) ? 16 : 8, BIT(data, 6));
+ LOGMASKED(LOG_SIO, " (Mode:%s, RWProtocol:%d, Rate:sysclk%s, AddrMode:%s)\n"
+ , BIT(data, 5), BIT(data, 4), s_baud_rate[(data >> 2) & 3], s_addr_mode[data & 3]);
+ break;
+ }
+
+ case 0x52: // SIO Start Address (low)
+ LOGMASKED(LOG_SIO, "io_w: SIO Stat Address (low) (not implemented) = %04x\n", data);
+ break;
+
+ case 0x53: // SIO Start Address (hi)
+ LOGMASKED(LOG_SIO, "io_w: SIO Stat Address (hi) (not implemented) = %04x\n", data);
+ break;
+
+ case 0x54: // SIO Data
+ LOGMASKED(LOG_SIO, "io_w: SIO Data (not implemented) = %04x\n", data);
+ break;
+
+ case 0x55: // SIO Automatic Transmit Count
+ LOGMASKED(LOG_SIO, "io_w: SIO Auto Transmit Count (not implemented) = %04x\n", data);
+ break;
+
case 0x58: // I2C Command
LOGMASKED(LOG_I2C, "io_w: I2C Command = %04x\n", data);
m_io_regs[offset] = data;
@@ -1607,9 +1664,6 @@ void spg2xx_device::uart_receive_tick()
{
LOGMASKED(LOG_UART, "uart_receive_tick: Setting RBF and RxRDY\n");
m_io_regs[0x31] |= 0x81;
- m_io_regs[0x36] = m_uart_rx_fifo[m_uart_rx_fifo_start];
- m_uart_rx_fifo_start = (m_uart_rx_fifo_start + 1) % ARRAY_LENGTH(m_uart_rx_fifo);
- m_uart_rx_fifo_count--;
m_uart_rx_available = true;
if (BIT(m_io_regs[0x30], 0))
{
@@ -1732,8 +1786,6 @@ void spg2xx_device::do_gpio(uint32_t offset)
uint16_t what = (buffer & (push | pull));
what ^= (dir & ~attr);
what &= ~special;
- //if (index == 0)
- //printf("buf:%04x, dir:%04x, pull:%04x, push:%04x\n", buffer, dir, pull, push);
switch (index)
{