summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/sa1110.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/sa1110.cpp')
-rw-r--r--src/devices/machine/sa1110.cpp761
1 files changed, 680 insertions, 81 deletions
diff --git a/src/devices/machine/sa1110.cpp b/src/devices/machine/sa1110.cpp
index eded21499d2..218819f44ad 100644
--- a/src/devices/machine/sa1110.cpp
+++ b/src/devices/machine/sa1110.cpp
@@ -10,21 +10,26 @@
#include "sa1110.h"
#define LOG_UNKNOWN (1 << 1)
-#define LOG_UART (1 << 2)
-#define LOG_UART_HF (1 << 3)
-#define LOG_MCP (1 << 4)
-#define LOG_SSP (1 << 5)
-#define LOG_OSTIMER (1 << 6)
-#define LOG_OSTIMER_HF (1 << 7)
-#define LOG_RTC (1 << 8)
-#define LOG_POWER (1 << 9)
-#define LOG_RESET (1 << 10)
-#define LOG_GPIO (1 << 11)
-#define LOG_GPIO_HF (1 << 12)
-#define LOG_INTC (1 << 13)
-#define LOG_ALL (LOG_UNKNOWN | LOG_UART | LOG_MCP | LOG_SSP | LOG_OSTIMER | LOG_RTC | LOG_POWER | LOG_RESET | LOG_GPIO | LOG_INTC)
-
-#define VERBOSE (0) // (LOG_ALL)
+#define LOG_ICP (1 << 2)
+#define LOG_UART3 (1 << 3)
+#define LOG_UART3_HF (1 << 4)
+#define LOG_MCP (1 << 5)
+#define LOG_SSP (1 << 6)
+#define LOG_OSTIMER (1 << 7)
+#define LOG_OSTIMER_HF (1 << 8)
+#define LOG_RTC (1 << 9)
+#define LOG_RTC_HF (1 << 10)
+#define LOG_POWER (1 << 11)
+#define LOG_POWER_HF (1 << 12)
+#define LOG_RESET (1 << 13)
+#define LOG_GPIO (1 << 14)
+#define LOG_GPIO_HF (1 << 15)
+#define LOG_INTC (1 << 16)
+#define LOG_PPC (1 << 17)
+#define LOG_DMA (1 << 18)
+#define LOG_ALL (LOG_UNKNOWN | LOG_ICP | LOG_UART3 | LOG_MCP | LOG_OSTIMER | LOG_RTC | LOG_POWER | LOG_RESET | LOG_GPIO | LOG_INTC | LOG_PPC | LOG_DMA)
+
+#define VERBOSE (0)
#include "logmacro.h"
DEFINE_DEVICE_TYPE(SA1110_PERIPHERALS, sa1110_periphs_device, "sa1110_periphs", "Intel XScale SA1110 Peripherals")
@@ -44,6 +49,252 @@ sa1110_periphs_device::sa1110_periphs_device(const machine_config &mconfig, cons
/*
+ Intel SA-1110 ICP - Serial Port 2
+
+ pg. 264 to 288 Intel StrongARM SA-1110 Microprocessor Developer's Manual
+
+*/
+
+TIMER_CALLBACK_MEMBER(sa1110_periphs_device::icp_rx_callback)
+{
+}
+
+TIMER_CALLBACK_MEMBER(sa1110_periphs_device::icp_tx_callback)
+{
+}
+
+TIMER_CALLBACK_MEMBER(sa1110_periphs_device::hssp_rx_callback)
+{
+}
+
+TIMER_CALLBACK_MEMBER(sa1110_periphs_device::hssp_tx_callback)
+{
+}
+
+void sa1110_periphs_device::icp_uart_set_receiver_enabled(bool enabled)
+{
+}
+
+void sa1110_periphs_device::icp_uart_set_transmitter_enabled(bool enabled)
+{
+}
+
+void sa1110_periphs_device::icp_uart_set_receive_irq_enabled(bool enabled)
+{
+}
+
+void sa1110_periphs_device::icp_uart_set_transmit_irq_enabled(bool enabled)
+{
+}
+
+uint8_t sa1110_periphs_device::icp_uart_read_receive_fifo()
+{
+ return 0;
+}
+
+void sa1110_periphs_device::icp_uart_write_transmit_fifo(uint8_t data)
+{
+}
+
+uint16_t sa1110_periphs_device::icp_hssp_read_receive_fifo()
+{
+ return 0;
+}
+
+void sa1110_periphs_device::icp_hssp_write_transmit_fifo(uint8_t data)
+{
+}
+
+void sa1110_periphs_device::icp_uart_set_receiver_idle()
+{
+}
+
+void sa1110_periphs_device::icp_uart_begin_of_break()
+{
+}
+
+void sa1110_periphs_device::icp_uart_end_of_break()
+{
+}
+
+
+uint32_t sa1110_periphs_device::icp_r(offs_t offset, uint32_t mem_mask)
+{
+ switch (offset)
+ {
+ case REG_UTCR0:
+ LOGMASKED(LOG_ICP, "%s: icp_r: UART Control Register 0: %08x & %08x\n", machine().describe_context(), m_icp_regs.uart.utcr[0], mem_mask);
+ return m_icp_regs.uart.utcr[0];
+ case REG_UTCR1:
+ LOGMASKED(LOG_ICP, "%s: icp_r: UART Control Register 1: %08x & %08x\n", machine().describe_context(), m_icp_regs.uart.utcr[1], mem_mask);
+ return m_icp_regs.uart.utcr[1];
+ case REG_UTCR2:
+ LOGMASKED(LOG_ICP, "%s: icp_r: UART Control Register 2: %08x & %08x\n", machine().describe_context(), m_icp_regs.uart.utcr[2], mem_mask);
+ return m_icp_regs.uart.utcr[2];
+ case REG_UTCR3:
+ LOGMASKED(LOG_ICP, "%s: icp_r: UART Control Register 3: %08x & %08x\n", machine().describe_context(), m_icp_regs.uart.utcr[3], mem_mask);
+ return m_icp_regs.uart.utcr[3];
+ case REG_UTCR4:
+ LOGMASKED(LOG_ICP, "%s: icp_r: UART Control Register 4: %08x & %08x\n", machine().describe_context(), m_icp_regs.utcr4, mem_mask);
+ return m_icp_regs.utcr4;
+ case REG_UTDR:
+ {
+ const uint8_t data = icp_uart_read_receive_fifo();
+ LOGMASKED(LOG_ICP, "%s: icp_r: UART Data Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ return data;
+ }
+ case REG_UTSR0:
+ LOGMASKED(LOG_ICP, "%s: icp_r: UART Status Register 0: %08x & %08x\n", machine().describe_context(), m_icp_regs.uart.utsr0, mem_mask);
+ return m_icp_regs.uart.utsr0;
+ case REG_UTSR1:
+ LOGMASKED(LOG_ICP, "%s: icp_r: UART Status Register 1: %08x & %08x\n", machine().describe_context(), m_icp_regs.uart.utsr1, mem_mask);
+ return m_icp_regs.uart.utsr1;
+ case REG_HSCR0:
+ LOGMASKED(LOG_ICP, "%s: icp_r: HSSP Control Register 0: %08x & %08x\n", machine().describe_context(), m_icp_regs.hssp.hscr0, mem_mask);
+ return m_icp_regs.hssp.hscr0;
+ case REG_HSCR1:
+ LOGMASKED(LOG_ICP, "%s: icp_r: HSSP Control Register 1: %08x & %08x\n", machine().describe_context(), m_icp_regs.hssp.hscr1, mem_mask);
+ return m_icp_regs.hssp.hscr1;
+ case REG_HSDR:
+ {
+ const uint16_t data = icp_hssp_read_receive_fifo();
+ LOGMASKED(LOG_ICP, "%s: icp_r: HSSP Data Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ return data;
+ }
+ case REG_HSSR0:
+ LOGMASKED(LOG_ICP, "%s: icp_r: HSSP Status Register 0: %08x & %08x\n", machine().describe_context(), m_icp_regs.hssp.hssr0, mem_mask);
+ return m_icp_regs.hssp.hssr0;
+ case REG_HSSR1:
+ LOGMASKED(LOG_ICP, "%s: icp_r: HSSP Status Register 1: %08x & %08x\n", machine().describe_context(), m_icp_regs.hssp.hssr1, mem_mask);
+ return m_icp_regs.hssp.hssr1;
+ default:
+ LOGMASKED(LOG_ICP | LOG_UNKNOWN, "%s: icp_r: Unknown address: %08x & %08x\n", machine().describe_context(), ICP_BASE_ADDR | (offset << 2), mem_mask);
+ return 0;
+ }
+}
+
+void sa1110_periphs_device::icp_w(offs_t offset, uint32_t data, uint32_t mem_mask)
+{
+ switch (offset)
+ {
+ case REG_UTCR0:
+ {
+ LOGMASKED(LOG_ICP, "%s: icp_w: UART Control Register 0 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_ICP, "%s: Parity Enable: %d\n", machine().describe_context(), BIT(data, 0));
+ LOGMASKED(LOG_ICP, "%s: Parity Mode: %s\n", machine().describe_context(), BIT(data, 1) ? "Even" : "Odd");
+ LOGMASKED(LOG_ICP, "%s: Stop Bits: %d\n", machine().describe_context(), BIT(data, 2) + 1);
+ LOGMASKED(LOG_ICP, "%s: Data Size: %d\n", machine().describe_context(), BIT(data, 3) ? 8 : 7);
+ LOGMASKED(LOG_ICP, "%s: Sample Clock: %s\n", machine().describe_context(), BIT(data, 4) ? "External" : "Internal");
+ LOGMASKED(LOG_ICP, "%s: Receive Edge: %s\n", machine().describe_context(), BIT(data, 5) ? "Falling" : "Rising");
+ LOGMASKED(LOG_ICP, "%s: Transmit Edge: %s\n", machine().describe_context(), BIT(data, 6) ? "Falling" : "Rising");
+
+ //stop_bits_t stop_bits = (BIT(data, 2) ? STOP_BITS_2 : STOP_BITS_1);
+
+ //parity_t parity = PARITY_NONE;
+ //if (BIT(data, 0))
+ //{
+ // parity = (BIT(data, 1) ? PARITY_EVEN : PARITY_ODD);
+ //}
+
+ //set_data_frame(1, BIT(data, 3) ? 8 : 7, parity, stop_bits);
+ //receive_register_reset();
+ //transmit_register_reset();
+
+ COMBINE_DATA(&m_icp_regs.uart.utcr[0]);
+ break;
+ }
+ case REG_UTCR1:
+ {
+ LOGMASKED(LOG_ICP, "%s: icp_w: UART Control Register 1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_ICP, "%s: Baud Rate Divisor MSB: %02x\n", machine().describe_context(), data & 0x0f);
+ //const uint8_t old = m_uart_regs.utcr[1] & 0x0f;
+ COMBINE_DATA(&m_icp_regs.uart.utcr[1]);
+ //if ((m_uart_regs.utcr[1] & 0x0f) != old)
+ // icp_uart_recalculate_divisor();
+ break;
+ }
+ case REG_UTCR2:
+ {
+ LOGMASKED(LOG_ICP, "%s: icp_w: UART Control Register 2 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_ICP, "%s: Baud Rate Divisor LSB: %02x\n", machine().describe_context(), (uint8_t)data);
+ //const uint8_t old = m_uart_regs.utcr[2] & 0xff;
+ COMBINE_DATA(&m_icp_regs.uart.utcr[2]);
+ //if ((m_uart_regs.utcr[2] & 0xff) != old)
+ // icp_uart_recalculate_divisor();
+ break;
+ }
+ case REG_UTCR3:
+ {
+ LOGMASKED(LOG_ICP, "%s: icp_w: UART Control Register 3 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_ICP, "%s: Receive Enable: %d\n", machine().describe_context(), BIT(data, 0));
+ LOGMASKED(LOG_ICP, "%s: Transmit Enable: %d\n", machine().describe_context(), BIT(data, 1));
+ LOGMASKED(LOG_ICP, "%s: Send Break: %d\n", machine().describe_context(), BIT(data, 2));
+ LOGMASKED(LOG_ICP, "%s: Receive FIFO IRQ Enable: %d\n", machine().describe_context(), BIT(data, 3));
+ LOGMASKED(LOG_ICP, "%s: Transmit FIFO IRQ Enable: %d\n", machine().describe_context(), BIT(data, 4));
+ LOGMASKED(LOG_ICP, "%s: Loopback Enable: %d\n", machine().describe_context(), BIT(data, 5));
+ const uint32_t old = m_icp_regs.uart.utcr[3];
+ COMBINE_DATA(&m_icp_regs.uart.utcr[3]);
+ const uint32_t changed = old ^ m_icp_regs.uart.utcr[3];
+ if (BIT(changed, 0))
+ icp_uart_set_receiver_enabled(BIT(data, 0));
+ if (BIT(changed, 1))
+ icp_uart_set_transmitter_enabled(BIT(data, 1));
+ if (BIT(changed, 3))
+ icp_uart_set_receive_irq_enabled(BIT(data, 3));
+ if (BIT(changed, 4))
+ icp_uart_set_transmit_irq_enabled(BIT(data, 4));
+ break;
+ }
+ case REG_UTCR4:
+ LOGMASKED(LOG_ICP, "%s: icp_w: UART Control Register 4 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_ICP, "%s: HP-SIR enable: %d\n", machine().describe_context(), BIT(data, UTCR4_HSE_BIT), mem_mask);
+ LOGMASKED(LOG_ICP, "%s: Low-Power enable: %d\n", machine().describe_context(), BIT(data, UTCR4_LPM_BIT), mem_mask);
+ COMBINE_DATA(&m_icp_regs.utcr4);
+ break;
+ case REG_UTDR:
+ LOGMASKED(LOG_ICP, "%s: icp_w: UART Data Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ if (data == 0x0d || data == 0x0a || (data >= 0x20 && data < 0x7f))
+ {
+ printf("%c", (char)data);
+ }
+ icp_uart_write_transmit_fifo((uint8_t)data);
+ break;
+ case REG_UTSR0:
+ LOGMASKED(LOG_ICP, "%s: icp_w: UART Status Register 0 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_ICP, "%s: Receiver Idle Status: %d\n", machine().describe_context(), BIT(data, 2));
+ LOGMASKED(LOG_ICP, "%s: Receiver Begin of Break Status: %d\n", machine().describe_context(), BIT(data, 3));
+ LOGMASKED(LOG_ICP, "%s: Receiver End of Break Status: %d\n", machine().describe_context(), BIT(data, 4));
+ if (BIT(data, 2))
+ icp_uart_set_receiver_idle();
+ if (BIT(data, 3))
+ icp_uart_begin_of_break();
+ if (BIT(data, 4))
+ icp_uart_end_of_break();
+ break;
+ case REG_HSCR0:
+ LOGMASKED(LOG_ICP, "%s: icp_w: HSSP Control Register 0 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ break;
+ case REG_HSCR1:
+ LOGMASKED(LOG_ICP, "%s: icp_w: HSSP Control Register 1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ break;
+ case REG_HSDR:
+ LOGMASKED(LOG_ICP, "%s: icp_w: HSSP Data Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ icp_hssp_write_transmit_fifo((uint8_t)data);
+ break;
+ case REG_HSSR0:
+ LOGMASKED(LOG_ICP, "%s: icp_w: HSSP Status Register 0 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ break;
+ case REG_HSSR1:
+ LOGMASKED(LOG_ICP, "%s: icp_w: HSSP Status Register 1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ break;
+ default:
+ LOGMASKED(LOG_ICP | LOG_UNKNOWN, "%s: icp_w: Unknown address: %08x = %08x & %08x\n", machine().describe_context(), ICP_BASE_ADDR | (offset << 2), data, mem_mask);
+ break;
+ }
+}
+
+/*
+
Intel SA-1110 Serial Port 3 - UART
pg. 289 to 306 Intel StrongARM SA-1110 Microprocessor Developer's Manual
@@ -140,9 +391,6 @@ void sa1110_periphs_device::uart_write_receive_fifo(uint16_t data_and_flags)
m_uart_regs.rx_fifo_count++;
m_uart_regs.rx_fifo_write_idx = (m_uart_regs.rx_fifo_write_idx + 1) % ARRAY_LENGTH(m_uart_regs.rx_fifo);
- // update receiver-not-full flag
- m_uart_regs.utsr1 |= (1 << UTSR1_RNE_BIT);
-
// update error flags
uart_update_eif_status();
@@ -163,18 +411,20 @@ uint8_t sa1110_periphs_device::uart_read_receive_fifo()
m_uart_regs.utsr1 &= ~((1 << UTSR1_PRE_BIT) | (1 << UTSR1_FRE_BIT) | (1 << UTSR1_ROR_BIT));
m_uart_regs.utsr1 |= fifo_bottom_flags << UTSR1_PRE_BIT;
}
- else
- {
- m_uart_regs.utsr1 &= ~(1 << UTSR1_RNE_BIT);
- }
uart_update_eif_status();
}
+ uart_check_rx_fifo_service();
return data;
}
void sa1110_periphs_device::uart_check_rx_fifo_service()
{
- if (m_uart_regs.rx_fifo_count > 4 && BIT(m_uart_regs.utcr[3], UTCR3_RXE_BIT))
+ if (m_uart_regs.rx_fifo_count != 0)
+ m_uart_regs.utsr1 |= (1 << UTSR1_RNE_BIT);
+ else
+ m_uart_regs.utsr1 &= ~(1 << UTSR1_RNE_BIT);
+
+ if (m_uart_regs.rx_fifo_count > 4)
{
m_uart_regs.utsr0 |= (1 << UTSR0_RFS_BIT);
if (BIT(m_uart_regs.utcr[3], UTCR3_RIE_BIT))
@@ -208,19 +458,18 @@ void sa1110_periphs_device::uart_write_transmit_fifo(uint8_t data)
m_uart_regs.tx_fifo_count++;
m_uart_regs.tx_fifo_write_idx = (m_uart_regs.tx_fifo_write_idx + 1) % ARRAY_LENGTH(m_uart_regs.tx_fifo);
- // update transmitter-not-full flag
- if (m_uart_regs.tx_fifo_count == ARRAY_LENGTH(m_uart_regs.tx_fifo))
- m_uart_regs.utsr1 &= ~(1 << UTSR1_TNF_BIT);
- else
- m_uart_regs.utsr1 |= (1 << UTSR1_TNF_BIT);
-
// update FIFO-service interrupt
uart_check_tx_fifo_service();
}
void sa1110_periphs_device::uart_check_tx_fifo_service()
{
- if (m_uart_regs.tx_fifo_count <= 4 && BIT(m_uart_regs.utcr[3], UTCR3_TXE_BIT))
+ if (m_uart_regs.tx_fifo_count < ARRAY_LENGTH(m_uart_regs.tx_fifo))
+ m_uart_regs.utsr1 |= (1 << UTSR1_TNF_BIT);
+ else
+ m_uart_regs.utsr1 &= ~(1 << UTSR1_TNF_BIT);
+
+ if (m_uart_regs.tx_fifo_count <= 4)
{
m_uart_regs.utsr0 |= (1 << UTSR0_TFS_BIT);
if (BIT(m_uart_regs.utcr[3], UTCR3_TIE_BIT))
@@ -268,18 +517,18 @@ void sa1110_periphs_device::uart_set_transmitter_enabled(bool enabled)
{
if (enabled)
{
- m_uart_regs.utsr0 |= (1 << UTSR0_TFS_BIT);
- m_uart3_irqs->in_w<UART3_TFS>(1);
+ //m_uart_regs.utsr0 |= (1 << UTSR0_TFS_BIT);
+ //m_uart3_irqs->in_w<UART3_TFS>(1);
- m_uart_regs.utsr1 |= (1 << UTSR1_TNF_BIT);
+ //m_uart_regs.utsr1 |= (1 << UTSR1_TNF_BIT);
}
else
{
- m_uart_regs.utsr0 &= ~(1 << UTSR0_TFS_BIT);
- m_uart3_irqs->in_w<UART3_TFS>(0);
+ //m_uart_regs.utsr0 &= ~(1 << UTSR0_TFS_BIT);
+ //m_uart3_irqs->in_w<UART3_TFS>(0);
- m_uart_regs.utsr1 &= ~(1 << UTSR1_TBY_BIT);
- m_uart_regs.utsr1 &= ~(1 << UTSR1_TNF_BIT);
+ //m_uart_regs.utsr1 &= ~(1 << UTSR1_TBY_BIT);
+ //m_uart_regs.utsr1 &= ~(1 << UTSR1_TNF_BIT);
m_uart_regs.tx_fifo_count = 0;
m_uart_regs.tx_fifo_read_idx = 0;
@@ -287,6 +536,8 @@ void sa1110_periphs_device::uart_set_transmitter_enabled(bool enabled)
transmit_register_reset();
}
+
+ uart_check_tx_fifo_service();
}
void sa1110_periphs_device::uart_set_receive_irq_enabled(bool enabled)
@@ -302,31 +553,31 @@ uint32_t sa1110_periphs_device::uart3_r(offs_t offset, uint32_t mem_mask)
switch (offset)
{
case REG_UTCR0:
- LOGMASKED(LOG_UART, "%s: uart3_r: UART Control Register 0: %08x & %08x\n", machine().describe_context(), m_uart_regs.utcr[0], mem_mask);
+ LOGMASKED(LOG_UART3, "%s: uart3_r: UART Control Register 0: %08x & %08x\n", machine().describe_context(), m_uart_regs.utcr[0], mem_mask);
return m_uart_regs.utcr[0];
case REG_UTCR1:
- LOGMASKED(LOG_UART, "%s: uart3_r: UART Control Register 1: %08x & %08x\n", machine().describe_context(), m_uart_regs.utcr[1], mem_mask);
+ LOGMASKED(LOG_UART3, "%s: uart3_r: UART Control Register 1: %08x & %08x\n", machine().describe_context(), m_uart_regs.utcr[1], mem_mask);
return m_uart_regs.utcr[1];
case REG_UTCR2:
- LOGMASKED(LOG_UART, "%s: uart3_r: UART Control Register 2: %08x & %08x\n", machine().describe_context(), m_uart_regs.utcr[2], mem_mask);
+ LOGMASKED(LOG_UART3, "%s: uart3_r: UART Control Register 2: %08x & %08x\n", machine().describe_context(), m_uart_regs.utcr[2], mem_mask);
return m_uart_regs.utcr[2];
case REG_UTCR3:
- LOGMASKED(LOG_UART, "%s: uart3_r: UART Control Register 3: %08x & %08x\n", machine().describe_context(), m_uart_regs.utcr[3], mem_mask);
+ LOGMASKED(LOG_UART3, "%s: uart3_r: UART Control Register 3: %08x & %08x\n", machine().describe_context(), m_uart_regs.utcr[3], mem_mask);
return m_uart_regs.utcr[3];
case REG_UTDR:
{
const uint8_t data = uart_read_receive_fifo();
- LOGMASKED(LOG_UART, "%s: uart3_r: UART Data Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_UART3, "%s: uart3_r: UART Data Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
return data;
}
case REG_UTSR0:
- LOGMASKED(LOG_UART_HF, "%s: uart3_r: UART Status Register 0: %08x & %08x\n", machine().describe_context(), m_uart_regs.utsr0, mem_mask);
+ LOGMASKED(LOG_UART3, "%s: uart3_r: UART Status Register 0: %08x & %08x\n", machine().describe_context(), m_uart_regs.utsr0, mem_mask);
return m_uart_regs.utsr0;
case REG_UTSR1:
- LOGMASKED(LOG_UART_HF, "%s: uart3_r: UART Status Register 1: %08x & %08x\n", machine().describe_context(), m_uart_regs.utsr1, mem_mask);
+ LOGMASKED(LOG_UART3, "%s: uart3_r: UART Status Register 1: %08x & %08x\n", machine().describe_context(), m_uart_regs.utsr1, mem_mask);
return m_uart_regs.utsr1;
default:
- LOGMASKED(LOG_UART | LOG_UNKNOWN, "%s: uart3_r: Unknown address: %08x & %08x\n", machine().describe_context(), UART_BASE_ADDR | (offset << 2), mem_mask);
+ LOGMASKED(LOG_UART3 | LOG_UNKNOWN, "%s: uart3_r: Unknown address: %08x & %08x\n", machine().describe_context(), UART_BASE_ADDR | (offset << 2), mem_mask);
return 0;
}
}
@@ -337,14 +588,14 @@ void sa1110_periphs_device::uart3_w(offs_t offset, uint32_t data, uint32_t mem_m
{
case REG_UTCR0:
{
- LOGMASKED(LOG_UART, "%s: uart3_w: UART Control Register 0: %08x & %08x\n", machine().describe_context(), data, mem_mask);
- LOGMASKED(LOG_UART, "%s: Parity Enable: %d\n", machine().describe_context(), BIT(data, 0));
- LOGMASKED(LOG_UART, "%s: Parity Mode: %s\n", machine().describe_context(), BIT(data, 1) ? "Even" : "Odd");
- LOGMASKED(LOG_UART, "%s: Stop Bits: %d\n", machine().describe_context(), BIT(data, 2) + 1);
- LOGMASKED(LOG_UART, "%s: Data Size: %d\n", machine().describe_context(), BIT(data, 3) ? 8 : 7);
- LOGMASKED(LOG_UART, "%s: Sample Clock: %s\n", machine().describe_context(), BIT(data, 4) ? "External" : "Internal");
- LOGMASKED(LOG_UART, "%s: Receive Edge: %s\n", machine().describe_context(), BIT(data, 5) ? "Falling" : "Rising");
- LOGMASKED(LOG_UART, "%s: Transmit Edge: %s\n", machine().describe_context(), BIT(data, 6) ? "Falling" : "Rising");
+ LOGMASKED(LOG_UART3, "%s: uart3_w: UART Control Register 0 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_UART3, "%s: Parity Enable: %d\n", machine().describe_context(), BIT(data, 0));
+ LOGMASKED(LOG_UART3, "%s: Parity Mode: %s\n", machine().describe_context(), BIT(data, 1) ? "Even" : "Odd");
+ LOGMASKED(LOG_UART3, "%s: Stop Bits: %d\n", machine().describe_context(), BIT(data, 2) + 1);
+ LOGMASKED(LOG_UART3, "%s: Data Size: %d\n", machine().describe_context(), BIT(data, 3) ? 8 : 7);
+ LOGMASKED(LOG_UART3, "%s: Sample Clock: %s\n", machine().describe_context(), BIT(data, 4) ? "External" : "Internal");
+ LOGMASKED(LOG_UART3, "%s: Receive Edge: %s\n", machine().describe_context(), BIT(data, 5) ? "Falling" : "Rising");
+ LOGMASKED(LOG_UART3, "%s: Transmit Edge: %s\n", machine().describe_context(), BIT(data, 6) ? "Falling" : "Rising");
stop_bits_t stop_bits = (BIT(data, 2) ? STOP_BITS_2 : STOP_BITS_1);
@@ -363,8 +614,8 @@ void sa1110_periphs_device::uart3_w(offs_t offset, uint32_t data, uint32_t mem_m
}
case REG_UTCR1:
{
- LOGMASKED(LOG_UART, "%s: uart3_w: UART Control Register 1: %08x & %08x\n", machine().describe_context(), data, mem_mask);
- LOGMASKED(LOG_UART, "%s: Baud Rate Divisor MSB: %02x\n", machine().describe_context(), data & 0x0f);
+ LOGMASKED(LOG_UART3, "%s: uart3_w: UART Control Register 1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_UART3, "%s: Baud Rate Divisor MSB: %02x\n", machine().describe_context(), data & 0x0f);
const uint8_t old = m_uart_regs.utcr[1] & 0x0f;
COMBINE_DATA(&m_uart_regs.utcr[1]);
if ((m_uart_regs.utcr[1] & 0x0f) != old)
@@ -373,8 +624,8 @@ void sa1110_periphs_device::uart3_w(offs_t offset, uint32_t data, uint32_t mem_m
}
case REG_UTCR2:
{
- LOGMASKED(LOG_UART, "%s: uart3_w: UART Control Register 2: %08x & %08x\n", machine().describe_context(), data, mem_mask);
- LOGMASKED(LOG_UART, "%s: Baud Rate Divisor LSB: %02x\n", machine().describe_context(), (uint8_t)data);
+ LOGMASKED(LOG_UART3, "%s: uart3_w: UART Control Register 2 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_UART3, "%s: Baud Rate Divisor LSB: %02x\n", machine().describe_context(), (uint8_t)data);
const uint8_t old = m_uart_regs.utcr[2] & 0xff;
COMBINE_DATA(&m_uart_regs.utcr[2]);
if ((m_uart_regs.utcr[2] & 0xff) != old)
@@ -383,13 +634,13 @@ void sa1110_periphs_device::uart3_w(offs_t offset, uint32_t data, uint32_t mem_m
}
case REG_UTCR3:
{
- LOGMASKED(LOG_UART, "%s: uart3_w: UART Control Register 3: %08x & %08x\n", machine().describe_context(), data, mem_mask);
- LOGMASKED(LOG_UART, "%s: Receive Enable: %d\n", machine().describe_context(), BIT(data, 0));
- LOGMASKED(LOG_UART, "%s: Transmit Enable: %d\n", machine().describe_context(), BIT(data, 1));
- LOGMASKED(LOG_UART, "%s: Send Break: %d\n", machine().describe_context(), BIT(data, 2));
- LOGMASKED(LOG_UART, "%s: Receive FIFO IRQ Enable: %d\n", machine().describe_context(), BIT(data, 3));
- LOGMASKED(LOG_UART, "%s: Transmit FIFO IRQ Enable: %d\n", machine().describe_context(), BIT(data, 4));
- LOGMASKED(LOG_UART, "%s: Loopback Enable: %d\n", machine().describe_context(), BIT(data, 5));
+ LOGMASKED(LOG_UART3, "%s: uart3_w: UART Control Register 3 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_UART3, "%s: Receive Enable: %d\n", machine().describe_context(), BIT(data, 0));
+ LOGMASKED(LOG_UART3, "%s: Transmit Enable: %d\n", machine().describe_context(), BIT(data, 1));
+ LOGMASKED(LOG_UART3, "%s: Send Break: %d\n", machine().describe_context(), BIT(data, 2));
+ LOGMASKED(LOG_UART3, "%s: Receive FIFO IRQ Enable: %d\n", machine().describe_context(), BIT(data, 3));
+ LOGMASKED(LOG_UART3, "%s: Transmit FIFO IRQ Enable: %d\n", machine().describe_context(), BIT(data, 4));
+ LOGMASKED(LOG_UART3, "%s: Loopback Enable: %d\n", machine().describe_context(), BIT(data, 5));
const uint32_t old = m_uart_regs.utcr[3];
COMBINE_DATA(&m_uart_regs.utcr[3]);
const uint32_t changed = old ^ m_uart_regs.utcr[3];
@@ -404,7 +655,7 @@ void sa1110_periphs_device::uart3_w(offs_t offset, uint32_t data, uint32_t mem_m
break;
}
case REG_UTDR:
- LOGMASKED(LOG_UART, "%s: uart3_w: UART Data Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_UART3, "%s: uart3_w: UART Data Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
if (data == 0x0d || data == 0x0a || (data >= 0x20 && data < 0x7f))
{
printf("%c", (char)data);
@@ -412,10 +663,10 @@ void sa1110_periphs_device::uart3_w(offs_t offset, uint32_t data, uint32_t mem_m
uart_write_transmit_fifo((uint8_t)data);
break;
case REG_UTSR0:
- LOGMASKED(LOG_UART, "%s: uart3_w: UART Status Register 0: %08x & %08x\n", machine().describe_context(), data, mem_mask);
- LOGMASKED(LOG_UART, "%s: Receiver Idle Status: %d\n", machine().describe_context(), BIT(data, 2));
- LOGMASKED(LOG_UART, "%s: Receiver Begin of Break Status: %d\n", machine().describe_context(), BIT(data, 3));
- LOGMASKED(LOG_UART, "%s: Receiver End of Break Status: %d\n", machine().describe_context(), BIT(data, 4));
+ LOGMASKED(LOG_UART3, "%s: uart3_w: UART Status Register 0 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_UART3, "%s: Receiver Idle Status: %d\n", machine().describe_context(), BIT(data, 2));
+ LOGMASKED(LOG_UART3, "%s: Receiver Begin of Break Status: %d\n", machine().describe_context(), BIT(data, 3));
+ LOGMASKED(LOG_UART3, "%s: Receiver End of Break Status: %d\n", machine().describe_context(), BIT(data, 4));
if (BIT(data, 2))
uart_set_receiver_idle();
if (BIT(data, 3))
@@ -424,7 +675,7 @@ void sa1110_periphs_device::uart3_w(offs_t offset, uint32_t data, uint32_t mem_m
uart_end_of_break();
break;
default:
- LOGMASKED(LOG_UART | LOG_UNKNOWN, "%s: uart3_w: Unknown address: %08x = %08x & %08x\n", machine().describe_context(), UART_BASE_ADDR | (offset << 2), data, mem_mask);
+ LOGMASKED(LOG_UART3 | LOG_UNKNOWN, "%s: uart3_w: Unknown address: %08x = %08x & %08x\n", machine().describe_context(), UART_BASE_ADDR | (offset << 2), data, mem_mask);
break;
}
}
@@ -1198,7 +1449,7 @@ uint32_t sa1110_periphs_device::rtc_r(offs_t offset, uint32_t mem_mask)
LOGMASKED(LOG_RTC, "%s: rtc_r: RTC Alarm Register: %08x & %08x\n", machine().describe_context(), m_rtc_regs.rtar, mem_mask);
return m_rtc_regs.rtar;
case REG_RCNR:
- LOGMASKED(LOG_RTC, "%s: rtc_r: RTC Count Register: %08x & %08x\n", machine().describe_context(), m_rtc_regs.rcnr, mem_mask);
+ LOGMASKED(LOG_RTC_HF, "%s: rtc_r: RTC Count Register: %08x & %08x\n", machine().describe_context(), m_rtc_regs.rcnr, mem_mask);
return m_rtc_regs.rcnr;
case REG_RTTR:
LOGMASKED(LOG_RTC, "%s: rtc_r: RTC Timer Trim Register: %08x & %08x\n", machine().describe_context(), m_rtc_regs.rttr, mem_mask);
@@ -1276,7 +1527,7 @@ uint32_t sa1110_periphs_device::power_r(offs_t offset, uint32_t mem_mask)
LOGMASKED(LOG_POWER, "%s: power_r: Power Manager Sleep Status Register: %08x & %08x\n", machine().describe_context(), m_power_regs.pssr, mem_mask);
return m_power_regs.pssr;
case REG_PSPR:
- LOGMASKED(LOG_POWER, "%s: power_r: Power Manager Scratch Pad Register: %08x & %08x\n", machine().describe_context(), m_power_regs.pspr, mem_mask);
+ LOGMASKED(LOG_POWER_HF, "%s: power_r: Power Manager Scratch Pad Register: %08x & %08x\n", machine().describe_context(), m_power_regs.pspr, mem_mask);
return m_power_regs.pspr;
case REG_PWER:
LOGMASKED(LOG_POWER, "%s: power_r: Power Manager Wake-up Enable Register: %08x & %08x\n", machine().describe_context(), m_power_regs.pwer, mem_mask);
@@ -1312,7 +1563,7 @@ void sa1110_periphs_device::power_w(offs_t offset, uint32_t data, uint32_t mem_m
m_power_regs.pssr &= ~(data & 0x0000001f);
break;
case REG_PSPR:
- LOGMASKED(LOG_POWER, "%s: power_w: Power Manager Scratch Pad Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_POWER_HF, "%s: power_w: Power Manager Scratch Pad Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
COMBINE_DATA(&m_power_regs.pspr);
break;
case REG_PWER:
@@ -1398,6 +1649,7 @@ void sa1110_periphs_device::gpio_in(const uint32_t line, const int state)
m_gpio_regs.input_latch &= ~mask;
m_gpio_regs.input_latch |= (state << line);
+ LOGMASKED(LOG_GPIO, "gpio_in: Line %d, state %d\n", line, state);
if (old_latch != m_gpio_regs.input_latch && !BIT(m_gpio_regs.gafr, line))
{
// TODO: The manual is unclear if edge detection functions on both inputs and outputs.
@@ -1414,6 +1666,7 @@ void sa1110_periphs_device::gpio_in(const uint32_t line, const int state)
}
m_gpio_regs.gplr = (m_gpio_regs.input_latch & ~m_gpio_regs.gafr) | (m_gpio_regs.alt_input_latch & m_gpio_regs.gafr);
+ LOGMASKED(LOG_GPIO, "gpio_in: New GPLR: %08x\n", m_gpio_regs.gplr);
}
}
@@ -1557,7 +1810,7 @@ void sa1110_periphs_device::gpio_w(offs_t offset, uint32_t data, uint32_t mem_ma
const uint32_t old = m_gpio_regs.gedr;
m_gpio_regs.gedr &= ~(data & mem_mask);
if (old != m_gpio_regs.gedr)
- gpio_update_interrupts(old);
+ gpio_update_interrupts(old ^ m_gpio_regs.gedr);
break;
}
case REG_GAFR:
@@ -1566,7 +1819,7 @@ void sa1110_periphs_device::gpio_w(offs_t offset, uint32_t data, uint32_t mem_ma
const uint32_t old = m_gpio_regs.gafr;
COMBINE_DATA(&m_gpio_regs.gafr);
if (old != m_gpio_regs.gafr)
- gpio_update_alternate_pins(old);
+ gpio_update_alternate_pins(old ^ m_gpio_regs.gafr);
break;
}
default:
@@ -1649,11 +1902,11 @@ void sa1110_periphs_device::intc_w(offs_t offset, uint32_t data, uint32_t mem_ma
switch (offset)
{
case REG_ICIP:
- LOGMASKED(LOG_INTC, "%s: intc_w: (Invalid Write) Interrupt Controller IRQ Pending Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_INTC, "%s: intc_w: (Invalid Write) Interrupt Controller IRQ Pending Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_ICMR:
{
- LOGMASKED(LOG_INTC, "%s: intc_w: Interrupt Controller Mask Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_INTC, "%s: intc_w: Interrupt Controller Mask Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
const uint32_t old = m_intc_regs.icmr;
COMBINE_DATA(&m_intc_regs.icmr);
if (old != m_intc_regs.icmr)
@@ -1662,7 +1915,7 @@ void sa1110_periphs_device::intc_w(offs_t offset, uint32_t data, uint32_t mem_ma
}
case REG_ICLR:
{
- LOGMASKED(LOG_INTC, "%s: intc_w: Interrupt Controller Level Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_INTC, "%s: intc_w: Interrupt Controller Level Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
const uint32_t old = m_intc_regs.iclr;
COMBINE_DATA(&m_intc_regs.iclr);
if (old != m_intc_regs.iclr)
@@ -1670,13 +1923,13 @@ void sa1110_periphs_device::intc_w(offs_t offset, uint32_t data, uint32_t mem_ma
break;
}
case REG_ICFP:
- LOGMASKED(LOG_INTC, "%s: intc_w: (Invalid Write) Interrupt Controller FIQ Pending Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_INTC, "%s: intc_w: (Invalid Write) Interrupt Controller FIQ Pending Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_ICPR:
- LOGMASKED(LOG_INTC, "%s: intc_w: (Invalid Write) Interrupt Controller Pending Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_INTC, "%s: intc_w: (Invalid Write) Interrupt Controller Pending Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_ICCR:
- LOGMASKED(LOG_INTC, "%s: intc_w: Interrupt Controller Control Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_INTC, "%s: intc_w: Interrupt Controller Control Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_intc_regs.iccr = BIT(data, 0);
break;
default:
@@ -1685,8 +1938,292 @@ void sa1110_periphs_device::intc_w(offs_t offset, uint32_t data, uint32_t mem_ma
}
}
+/*
+
+ Intel SA-1110 Peripheral Pin Controller
+
+ pg. 347 to 357 Intel StrongARM SA-1110 Microprocessor Developer's Manual
+
+*/
+
+uint32_t sa1110_periphs_device::ppc_r(offs_t offset, uint32_t mem_mask)
+{
+ switch (offset)
+ {
+ case REG_PPDR:
+ LOGMASKED(LOG_PPC, "%s: ppc_r: PPC Pin Direction Register: %08x & %08x\n", machine().describe_context(), m_ppc_regs.ppdr, mem_mask);
+ return m_ppc_regs.ppdr;
+ case REG_PPSR:
+ LOGMASKED(LOG_PPC, "%s: ppc_r: PPC Pin State Register: %08x & %08x\n", machine().describe_context(), m_ppc_regs.ppsr, mem_mask);
+ return m_ppc_regs.ppsr;
+ case REG_PPAR:
+ LOGMASKED(LOG_PPC, "%s: ppc_r: PPC Pin Assignment Register: %08x & %08x\n", machine().describe_context(), m_ppc_regs.ppar, mem_mask);
+ return m_ppc_regs.ppar;
+ case REG_PSDR:
+ LOGMASKED(LOG_PPC, "%s: ppc_r: PPC Sleep Mode Direction Register: %08x & %08x\n", machine().describe_context(), m_ppc_regs.psdr, mem_mask);
+ return m_ppc_regs.psdr;
+ case REG_PPFR:
+ LOGMASKED(LOG_PPC, "%s: ppc_r: PPC Pin Flag Register: %08x & %08x\n", machine().describe_context(), m_ppc_regs.ppfr, mem_mask);
+ return m_ppc_regs.ppfr;
+ default:
+ LOGMASKED(LOG_PPC | LOG_UNKNOWN, "%s: ppc_r: Unknown address: %08x & %08x\n", machine().describe_context(), PPC_BASE_ADDR | (offset << 2), mem_mask);
+ return 0;
+ }
+}
+
+void sa1110_periphs_device::ppc_w(offs_t offset, uint32_t data, uint32_t mem_mask)
+{
+ switch (offset)
+ {
+ case REG_PPDR:
+ {
+ LOGMASKED(LOG_PPC, "%s: ppc_w: PPC Pin Direction Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ COMBINE_DATA(&m_ppc_regs.ppdr);
+ //const uint32_t old_ppsr = m_ppc_regs.ppsr;
+ m_ppc_regs.ppsr = (m_ppc_regs.ppsr_out & m_ppc_regs.ppdr) | (m_ppc_regs.ppsr_in & ~m_ppc_regs.ppdr);
+ //const uint32_t changed_states = old_ppsr ^ m_ppc_regs.ppsr;
+ //if (changed_states)
+ //{
+ //}
+ break;
+ }
+ case REG_PPSR:
+ {
+ LOGMASKED(LOG_PPC, "%s: ppc_w: PPC Pin State Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ //const uint32_t old_latch = m_ppc_regs.ppsr_out;
+ COMBINE_DATA(&m_ppc_regs.ppsr_out);
+ m_ppc_regs.ppsr = (m_ppc_regs.ppsr_out & m_ppc_regs.ppdr) | (m_ppc_regs.ppsr_in & ~m_ppc_regs.ppdr);
+ //const uint32_t changed_outputs = (old ^ m_ppc_regs.ppsr_out) & m_ppc_regs.ppdr;
+ //if (changed_outputs)
+ //{
+ // Do stuff
+ //}
+ break;
+ }
+ case REG_PPAR:
+ LOGMASKED(LOG_PPC, "%s: ppc_w: PPC Pin Assignment Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ COMBINE_DATA(&m_ppc_regs.ppar);
+ break;
+ case REG_PSDR:
+ LOGMASKED(LOG_PPC, "%s: ppc_w: PPC Sleep Mode Direction Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ COMBINE_DATA(&m_ppc_regs.psdr);
+ break;
+ case REG_PPFR:
+ LOGMASKED(LOG_PPC, "%s: ppc_w: PPC Pin Flag Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ COMBINE_DATA(&m_ppc_regs.ppfr);
+ break;
+ default:
+ LOGMASKED(LOG_PPC | LOG_UNKNOWN, "%s: ppc_w: Unknown address: %08x = %08x & %08x\n", machine().describe_context(), PPC_BASE_ADDR | (offset << 2), data, mem_mask);
+ break;
+ }
+}
+
+/*
+
+ Intel SA-1110 Peripheral Pin Controller
+
+ pg. 186 to 194 Intel StrongARM SA-1110 Microprocessor Developer's Manual
+
+*/
+
+void sa1110_periphs_device::dma_set_control_bits(int channel, uint32_t bits)
+{
+ dma_regs &regs = m_dma_regs[channel];
+ const uint32_t old = regs.dsr;
+ regs.dsr |= bits;
+ const uint32_t newly_set = ~old & bits;
+ if (newly_set == 0)
+ return;
+
+ const uint32_t irq_mask = (1 << DSR_ERROR_BIT) | (1 << DSR_DONEA_BIT) | (1 << DSR_DONEB_BIT);
+
+ if (BIT(newly_set, DSR_RUN_BIT))
+ regs.dsr &= ~(1 << DSR_ERROR_BIT);
+ if (BIT(newly_set, DSR_DONEA_BIT) || BIT(newly_set, DSR_STRTA_BIT))
+ regs.dsr &= ~(1 << DSR_DONEA_BIT);
+ if (BIT(newly_set, DSR_DONEB_BIT) || BIT(newly_set, DSR_STRTB_BIT))
+ regs.dsr &= ~(1 << DSR_DONEB_BIT);
+
+ if (regs.ddar == 0x81400580 && BIT(regs.dsr, DSR_RUN_BIT))
+ {
+ const uint32_t buf = BIT(regs.dsr, DSR_BIU_BIT);
+ const uint32_t count = regs.dbt[buf];
+ if (count)
+ {
+ const uint32_t start_mask = (buf ? (1 << DSR_STRTB_BIT) : (1 << DSR_STRTA_BIT));
+ const uint32_t done_mask = (buf ? (1 << DSR_DONEB_BIT) : (1 << DSR_DONEA_BIT));
+ const uint32_t addr = regs.dbs[buf];
+ address_space &space = m_maincpu->space(AS_PROGRAM);
+ if (regs.dsr & start_mask)
+ {
+ for (uint32_t i = 0; i < count; i++)
+ {
+ const uint8_t value = space.read_byte(addr + i);
+ if (value == 0x0d || value == 0x0a || (value >= 0x20 && value < 0x7f))
+ {
+ printf("%c", (char)value);
+ }
+ }
+ printf("\n");
+ regs.dsr &= ~start_mask;
+ regs.dsr |= done_mask;
+ regs.dsr ^= (1 << DSR_BIU_BIT);
+ }
+ }
+ }
+
+ set_irq_line(INT_DMA0 + channel, (BIT(regs.dsr, DSR_IE_BIT) && (regs.dsr & irq_mask)) ? 1 : 0);
+}
+
+void sa1110_periphs_device::dma_clear_control_bits(int channel, uint32_t bits)
+{
+ dma_regs &regs = m_dma_regs[channel];
+
+ const uint32_t irq_mask = (1 << DSR_ERROR_BIT) | (1 << DSR_DONEA_BIT) | (1 << DSR_DONEB_BIT);
+
+ regs.dsr &= ~bits;
+ set_irq_line(INT_DMA0 + channel, (BIT(regs.dsr, DSR_IE_BIT) && (regs.dsr & irq_mask)) ? 1 : 0);
+}
+
+uint32_t sa1110_periphs_device::dma_r(offs_t offset, uint32_t mem_mask)
+{
+ uint32_t channel = (offset >> 3) & 7;
+ if (channel < 6)
+ {
+ switch (offset & 7)
+ {
+ case REG_DDAR:
+ LOGMASKED(LOG_DMA, "%s: dma_r: DMA%d Device Address Register: %08x & %08x\n", machine().describe_context(), channel, m_dma_regs[channel].ddar, mem_mask);
+ return m_dma_regs[channel].ddar;
+ case REG_DSSR:
+ case REG_DCSR:
+ case REG_DSR:
+ LOGMASKED(LOG_DMA, "%s: dma_r: DMA%d Control/Status Register: %08x & %08x\n", machine().describe_context(), channel, m_dma_regs[channel].dsr, mem_mask);
+ return m_dma_regs[channel].dsr;
+ case REG_DBSA:
+ LOGMASKED(LOG_DMA, "%s: dma_r: DMA%d Buffer A Start Address: %08x & %08x\n", machine().describe_context(), channel, m_dma_regs[channel].dbs[0], mem_mask);
+ return m_dma_regs[channel].dbs[0];
+ case REG_DBTA:
+ LOGMASKED(LOG_DMA, "%s: dma_r: DMA%d Buffer A Transfer Count: %08x & %08x\n", machine().describe_context(), channel, m_dma_regs[channel].dbt[0], mem_mask);
+ return m_dma_regs[channel].dbt[0];
+ case REG_DBSB:
+ LOGMASKED(LOG_DMA, "%s: dma_r: DMA%d Buffer B Start Address: %08x & %08x\n", machine().describe_context(), channel, m_dma_regs[channel].dbs[1], mem_mask);
+ return m_dma_regs[channel].dbs[1];
+ case REG_DBTB:
+ LOGMASKED(LOG_DMA, "%s: dma_r: DMA%d Buffer B Transfer Count: %08x & %08x\n", machine().describe_context(), channel, m_dma_regs[channel].dbt[1], mem_mask);
+ return m_dma_regs[channel].dbt[1];
+ default:
+ LOGMASKED(LOG_DMA | LOG_UNKNOWN, "%s: dma_r: Unknown address: %08x & %08x\n", machine().describe_context(), DMA_BASE_ADDR | (offset << 2), mem_mask);
+ return 0;
+ }
+ }
+ return 0;
+}
+
+void sa1110_periphs_device::dma_w(offs_t offset, uint32_t data, uint32_t mem_mask)
+{
+ uint32_t channel = (offset >> 3) & 7;
+ if (channel < 6)
+ {
+ switch (offset & 7)
+ {
+ case REG_DDAR:
+ LOGMASKED(LOG_DMA, "%s: dma_w: DMA%d Device Address Register = %08x & %08x\n", machine().describe_context(), channel, data, mem_mask);
+ COMBINE_DATA(&m_dma_regs[channel].ddar);
+ break;
+ case REG_DSSR:
+ LOGMASKED(LOG_DMA, "%s: dma_w: DMA%d Control/Status Register (1S) = %08x & %08x\n", machine().describe_context(), channel, data, mem_mask);
+ LOGMASKED(LOG_DMA, "%s: Run Set: %d\n", machine().describe_context(), BIT(data, DSR_RUN_BIT));
+ LOGMASKED(LOG_DMA, "%s: Interrupt Enable Set: %d\n", machine().describe_context(), BIT(data, DSR_IE_BIT));
+ LOGMASKED(LOG_DMA, "%s: Error Set: %d\n", machine().describe_context(), BIT(data, DSR_ERROR_BIT));
+ LOGMASKED(LOG_DMA, "%s: Done A Set: %d\n", machine().describe_context(), BIT(data, DSR_DONEA_BIT));
+ LOGMASKED(LOG_DMA, "%s: Start A Set: %d\n", machine().describe_context(), BIT(data, DSR_STRTA_BIT));
+ LOGMASKED(LOG_DMA, "%s: Done B Set: %d\n", machine().describe_context(), BIT(data, DSR_DONEB_BIT));
+ LOGMASKED(LOG_DMA, "%s: Start B Set: %d\n", machine().describe_context(), BIT(data, DSR_STRTB_BIT));
+ LOGMASKED(LOG_DMA, "%s: Buffer In Use Set: %d\n", machine().describe_context(), BIT(data, DSR_BIU_BIT));
+ dma_set_control_bits(channel, data & mem_mask);
+ break;
+ case REG_DCSR:
+ LOGMASKED(LOG_DMA, "%s: dma_w: DMA%d Control/Status Register (1C) = %08x & %08x\n", machine().describe_context(), channel, data, mem_mask);
+ LOGMASKED(LOG_DMA, "%s: Run Clear: %d\n", machine().describe_context(), BIT(data, DSR_RUN_BIT));
+ LOGMASKED(LOG_DMA, "%s: Interrupt Enable Clear: %d\n", machine().describe_context(), BIT(data, DSR_IE_BIT));
+ LOGMASKED(LOG_DMA, "%s: Error Clear: %d\n", machine().describe_context(), BIT(data, DSR_ERROR_BIT));
+ LOGMASKED(LOG_DMA, "%s: Done A Clear: %d\n", machine().describe_context(), BIT(data, DSR_DONEA_BIT));
+ LOGMASKED(LOG_DMA, "%s: Start A Clear: %d\n", machine().describe_context(), BIT(data, DSR_STRTA_BIT));
+ LOGMASKED(LOG_DMA, "%s: Done B Clear: %d\n", machine().describe_context(), BIT(data, DSR_DONEB_BIT));
+ LOGMASKED(LOG_DMA, "%s: Start B Clear: %d\n", machine().describe_context(), BIT(data, DSR_STRTB_BIT));
+ LOGMASKED(LOG_DMA, "%s: Buffer In Use Clear: %d\n", machine().describe_context(), BIT(data, DSR_BIU_BIT));
+ dma_clear_control_bits(channel, data & mem_mask);
+ break;
+ case REG_DSR:
+ LOGMASKED(LOG_DMA, "%s: dma_w: DMA%d Control/Status Register (RO) = %08x & %08x\n", machine().describe_context(), channel, data, mem_mask);
+ break;
+ case REG_DBSA:
+ LOGMASKED(LOG_DMA, "%s: dma_w: DMA%d Buffer A Start Address = %08x & %08x\n", machine().describe_context(), channel, data, mem_mask);
+ if (!BIT(m_dma_regs[channel].dsr, DSR_STRTA_BIT))
+ COMBINE_DATA(&m_dma_regs[channel].dbs[0]);
+ break;
+ case REG_DBTA:
+ LOGMASKED(LOG_DMA, "%s: dma_w: DMA%d Buffer A Transfer Count = %08x & %08x\n", machine().describe_context(), channel, data, mem_mask);
+ if (!BIT(m_dma_regs[channel].dsr, DSR_STRTA_BIT))
+ {
+ COMBINE_DATA(&m_dma_regs[channel].dbt[0]);
+ m_dma_regs[channel].dbt[0] &= DBT_MASK;
+ }
+ break;
+ case REG_DBSB:
+ LOGMASKED(LOG_DMA, "%s: dma_w: DMA%d Buffer B Start Address = %08x & %08x\n", machine().describe_context(), channel, data, mem_mask);
+ if (!BIT(m_dma_regs[channel].dsr, DSR_STRTB_BIT))
+ COMBINE_DATA(&m_dma_regs[channel].dbs[1]);
+ break;
+ case REG_DBTB:
+ LOGMASKED(LOG_DMA, "%s: dma_w: DMA%d Buffer B Transfer Count = %08x & %08x\n", machine().describe_context(), channel, data, mem_mask);
+ if (!BIT(m_dma_regs[channel].dsr, DSR_STRTB_BIT))
+ {
+ COMBINE_DATA(&m_dma_regs[channel].dbt[1]);
+ m_dma_regs[channel].dbt[1] &= DBT_MASK;
+ }
+ break;
+ default:
+ LOGMASKED(LOG_DMA | LOG_UNKNOWN, "%s: dma_w: Unknown address %08x = %08x & %08x\n", machine().describe_context(), DMA_BASE_ADDR | (offset << 2), data, mem_mask);
+ break;
+ }
+ }
+}
+
void sa1110_periphs_device::device_start()
{
+ save_item(NAME(m_icp_regs.uart.utcr));
+ save_item(NAME(m_icp_regs.uart.utsr0));
+ save_item(NAME(m_icp_regs.uart.utsr1));
+ save_item(NAME(m_icp_regs.uart.rx_fifo));
+ save_item(NAME(m_icp_regs.uart.rx_fifo_read_idx));
+ save_item(NAME(m_icp_regs.uart.rx_fifo_write_idx));
+ save_item(NAME(m_icp_regs.uart.rx_fifo_count));
+ m_icp_regs.uart_rx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sa1110_periphs_device::icp_rx_callback), this));
+ save_item(NAME(m_icp_regs.uart.tx_fifo));
+ save_item(NAME(m_icp_regs.uart.tx_fifo_read_idx));
+ save_item(NAME(m_icp_regs.uart.tx_fifo_write_idx));
+ save_item(NAME(m_icp_regs.uart.tx_fifo_count));
+ m_icp_regs.uart_tx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sa1110_periphs_device::icp_tx_callback), this));
+ save_item(NAME(m_icp_regs.uart.rx_break_interlock));
+
+ save_item(NAME(m_icp_regs.utcr4));
+ save_item(NAME(m_icp_regs.hssp.hscr0));
+ save_item(NAME(m_icp_regs.hssp.hscr1));
+ save_item(NAME(m_icp_regs.hssp.hssr0));
+ save_item(NAME(m_icp_regs.hssp.hssr1));
+ save_item(NAME(m_icp_regs.hssp.rx_fifo));
+ save_item(NAME(m_icp_regs.hssp.rx_fifo_read_idx));
+ save_item(NAME(m_icp_regs.hssp.rx_fifo_write_idx));
+ save_item(NAME(m_icp_regs.hssp.rx_fifo_count));
+ m_icp_regs.hssp.rx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sa1110_periphs_device::hssp_rx_callback), this));
+ save_item(NAME(m_icp_regs.hssp.tx_fifo));
+ save_item(NAME(m_icp_regs.hssp.tx_fifo_read_idx));
+ save_item(NAME(m_icp_regs.hssp.tx_fifo_write_idx));
+ save_item(NAME(m_icp_regs.hssp.tx_fifo_count));
+ m_icp_regs.hssp.tx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sa1110_periphs_device::hssp_tx_callback), this));
+
save_item(NAME(m_uart_regs.utcr));
save_item(NAME(m_uart_regs.utsr0));
save_item(NAME(m_uart_regs.utsr1));
@@ -1783,6 +2320,18 @@ void sa1110_periphs_device::device_start()
save_item(NAME(m_intc_regs.icfp));
save_item(NAME(m_intc_regs.icpr));
+ save_item(NAME(m_ppc_regs.ppdr));
+ save_item(NAME(m_ppc_regs.ppsr));
+ save_item(NAME(m_ppc_regs.ppar));
+ save_item(NAME(m_ppc_regs.psdr));
+ save_item(NAME(m_ppc_regs.ppfr));
+
+ save_item(STRUCT_MEMBER(m_dma_regs, ddar));
+ save_item(STRUCT_MEMBER(m_dma_regs, dsr));
+ save_item(STRUCT_MEMBER(m_dma_regs, dbs));
+ save_item(STRUCT_MEMBER(m_dma_regs, dbt));
+ save_item(NAME(m_dma_active_mask));
+
m_gpio_out.resolve_all_safe();
m_ssp_out.resolve_safe();
m_uart3_tx_out.resolve_safe();
@@ -1790,6 +2339,38 @@ void sa1110_periphs_device::device_start()
void sa1110_periphs_device::device_reset()
{
+ // init ICP
+ memset(m_icp_regs.uart.utcr, 0, sizeof(uint32_t) * 4);
+ m_icp_regs.uart.utsr0 = 0;
+ m_icp_regs.uart.utsr1 = 0;
+ memset(m_icp_regs.uart.rx_fifo, 0, sizeof(uint16_t) * 12);
+ m_icp_regs.uart.rx_fifo_read_idx = 0;
+ m_icp_regs.uart.rx_fifo_write_idx = 0;
+ m_icp_regs.uart.rx_fifo_count = 0;
+ m_icp_regs.uart_rx_timer->adjust(attotime::never);
+ memset(m_icp_regs.uart.tx_fifo, 0, 8);
+ m_icp_regs.uart.tx_fifo_read_idx = 0;
+ m_icp_regs.uart.tx_fifo_write_idx = 0;
+ m_icp_regs.uart.tx_fifo_count = 0;
+ m_icp_regs.uart_tx_timer->adjust(attotime::never);
+ m_icp_regs.uart.rx_break_interlock = false;
+
+ m_icp_regs.utcr4 = 0;
+ m_icp_regs.hssp.hscr0 = 0;
+ m_icp_regs.hssp.hscr1 = 0;
+ m_icp_regs.hssp.hssr0 = 0;
+ m_icp_regs.hssp.hssr1 = 0;
+ memset(m_icp_regs.hssp.rx_fifo, 0, sizeof(uint16_t) * 8);
+ m_icp_regs.hssp.rx_fifo_read_idx = 0;
+ m_icp_regs.hssp.rx_fifo_write_idx = 0;
+ m_icp_regs.hssp.rx_fifo_count = 0;
+ m_icp_regs.hssp.rx_timer->adjust(attotime::never);
+ memset(m_icp_regs.hssp.tx_fifo, 0, sizeof(uint16_t) * 8);
+ m_icp_regs.hssp.tx_fifo_read_idx = 0;
+ m_icp_regs.hssp.tx_fifo_write_idx = 0;
+ m_icp_regs.hssp.tx_fifo_count = 0;
+ m_icp_regs.hssp.tx_timer->adjust(attotime::never);
+
// init UART3
memset(m_uart_regs.utcr, 0, sizeof(uint32_t) * 4);
m_uart_regs.utsr0 = 0;
@@ -1868,10 +2449,28 @@ void sa1110_periphs_device::device_reset()
memset(&m_power_regs, 0, sizeof(m_power_regs));
m_power_regs.posr = 1; // flag oscillator OK
+ // init PPC regs
+ m_ppc_regs.ppdr = 0;
+ m_ppc_regs.ppsr = 0;
+ m_ppc_regs.ppar = 0;
+ m_ppc_regs.psdr = 0x003fffff;
+ m_ppc_regs.ppfr = 0x0007f001;
+
+ // init DMA regs
+ for (int channel = 0; channel < 6; channel++)
+ {
+ m_dma_regs[channel].ddar = 0;
+ m_dma_regs[channel].dsr = 0;
+ memset(m_dma_regs[channel].dbs, 0, sizeof(uint32_t) * 2);
+ memset(m_dma_regs[channel].dbt, 0, sizeof(uint32_t) * 2);
+ }
// bulk-init other registers
m_rcsr = 0x00000001; // indicate hardware reset
memset(&m_gpio_regs, 0, sizeof(m_gpio_regs));
memset(&m_intc_regs, 0, sizeof(m_intc_regs));
+
+ uart_check_rx_fifo_service();
+ uart_check_tx_fifo_service();
}
void sa1110_periphs_device::device_add_mconfig(machine_config &config)