diff options
Diffstat (limited to 'src/devices/machine/spg2xx.cpp')
-rw-r--r-- | src/devices/machine/spg2xx.cpp | 82 |
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) { |