From a031030f2169a7b24fd4709ff2009abb561ecb50 Mon Sep 17 00:00:00 2001 From: Ted Green Date: Mon, 7 Aug 2017 14:10:32 -0600 Subject: [PATCH] vrc5074: Add 16550 uart subdevice. (nw) --- src/devices/machine/vrc5074.cpp | 105 +++++++++++++------------------- src/devices/machine/vrc5074.h | 8 ++- 2 files changed, 51 insertions(+), 62 deletions(-) diff --git a/src/devices/machine/vrc5074.cpp b/src/devices/machine/vrc5074.cpp index fd65170cb2e..8988676c269 100644 --- a/src/devices/machine/vrc5074.cpp +++ b/src/devices/machine/vrc5074.cpp @@ -7,7 +7,7 @@ #define LOG_NILE_IRQS (0) #define LOG_PCI (0) #define LOG_TIMERS (0) -#define LOG_DYNAMIC (0) +#define LOG_MAP (0) #define LOG_NILE_MASTER (0) #define LOG_NILE_TARGET (0) #define PRINTF_SERIAL (0) @@ -136,16 +136,30 @@ ADDRESS_MAP_END // Target Window 1 map DEVICE_ADDRESS_MAP_START(target1_map, 32, vrc5074_device) - AM_RANGE(0x00000000, 0xFFFFFFFF) AM_READWRITE( target1_r, target1_w) + AM_RANGE(0x00000000, 0xFFFFFFFF) AM_READWRITE(target1_r, target1_w) ADDRESS_MAP_END +MACHINE_CONFIG_MEMBER(vrc5074_device::device_add_mconfig) + MCFG_DEVICE_ADD("uart", NS16550, SYSTEM_CLOCK / 12) + MCFG_INS8250_OUT_INT_CB(WRITELINE(vrc5074_device, uart_irq_callback)) + MCFG_INS8250_OUT_TX_CB(DEVWRITELINE("ttys00", rs232_port_device, write_txd)) + MCFG_INS8250_OUT_DTR_CB(DEVWRITELINE("ttys00", rs232_port_device, write_dtr)) + MCFG_INS8250_OUT_RTS_CB(DEVWRITELINE("ttys00", rs232_port_device, write_rts)) + + MCFG_RS232_PORT_ADD("ttys00", default_rs232_devices, nullptr) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("uart", ns16550_device, rx_w)) + MCFG_RS232_DCD_HANDLER(DEVWRITELINE("uart", ns16550_device, dcd_w)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("uart", ns16550_device, cts_w)) +MACHINE_CONFIG_END + vrc5074_device::vrc5074_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : pci_host_device(mconfig, VRC5074, tag, owner, clock), - m_cpu_space(nullptr), m_cpu(nullptr), cpu_tag(nullptr), - m_mem_config("memory_space", ENDIANNESS_LITTLE, 32, 32), - m_io_config("io_space", ENDIANNESS_LITTLE, 32, 32), - m_romRegion(*this, "rom"), - m_updateRegion(*this, "update") + m_uart(*this, "uart"), + m_cpu_space(nullptr), m_cpu(nullptr), cpu_tag(nullptr), + m_mem_config("memory_space", ENDIANNESS_LITTLE, 32, 32), + m_io_config("io_space", ENDIANNESS_LITTLE, 32, 32), + m_romRegion(*this, "rom"), + m_updateRegion(*this, "update") { for (int i = 0; i < 2; i++) m_sdram_size[i] = 0x0; @@ -224,7 +238,6 @@ void vrc5074_device::device_start() save_item(NAME(m_sdram[0])); save_item(NAME(m_sdram[1])); save_item(NAME(m_cpu_regs)); - save_item(NAME(m_serial_regs)); save_item(NAME(m_nile_irq_state)); save_item(NAME(m_sdram_addr)); machine().save().register_postload(save_prepost_delegate(FUNC(vrc5074_device::postload), this)); @@ -241,7 +254,6 @@ void vrc5074_device::device_reset() { pci_device::device_reset(); memset(m_cpu_regs, 0, sizeof(m_cpu_regs)); - memset(m_serial_regs, 0, sizeof(m_serial_regs)); m_nile_irq_state = 0; regenerate_config_mapping(); m_dma_timer->adjust(attotime::never); @@ -279,7 +291,7 @@ void vrc5074_device::map_cpu_space() m_cpu_space->install_ram(winStart, winStart + winSize - 1, m_sdram[index].data()); m_cpu->add_fastram(winStart, winStart + winSize - 1, false, m_sdram[index].data()); } - if (LOG_NILE) + if (LOG_NILE | LOG_MAP) logerror("map_cpu_space ram_size=%08X ram_base=%08X\n", winSize, winStart); } } @@ -296,7 +308,7 @@ void vrc5074_device::map_cpu_space() if (winSize > 0 && m_cs_devices[index - 2] != nullptr) { m_cpu_space->install_device_delegate(winStart, winStart + winSize - 1, *m_cs_devices[index - 2], m_cs_maps[index - 2]); } - if (LOG_NILE) + if (LOG_NILE | LOG_MAP) logerror("map_cpu_space cs%d_size=%08X cs%d_base=%08X\n", index, winSize, index, winStart); } } @@ -320,7 +332,7 @@ void vrc5074_device::map_cpu_space() m_cpu_space->install_write_handler(winStart, winStart + winSize - 1, write32_delegate(FUNC(vrc5074_device::pci1_w), this)); } } - if (LOG_NILE) + if (LOG_NILE | LOG_MAP) logerror("map_cpu_space pci%d_size=%08X pci%d_base=%08X\n", index, winSize, index, winStart); } } @@ -343,7 +355,7 @@ void vrc5074_device::map_extra(uint64_t memory_window_start, uint64_t memory_win winEnd = winStart + winSize -1; memory_space->install_read_handler(winStart, winEnd, read32_delegate(FUNC(vrc5074_device::target1_r), this)); memory_space->install_write_handler(winStart, winEnd, write32_delegate(FUNC(vrc5074_device::target1_w), this)); - if (LOG_NILE) + if (LOG_NILE | LOG_MAP) logerror("%s: map_extra Target Window 1 start=%08X end=%08X size=%08X\n", tag(), winStart, winEnd, winSize); } //// PCI Target Window 2 @@ -667,12 +679,6 @@ void vrc5074_device::update_nile_irqs() uint8_t irq[6]; int i; - /* check for UART transmit IRQ enable and synthsize one */ - if (m_serial_regs[NREG_UARTIER] & 2) - m_nile_irq_state |= 0x0010; - else - m_nile_irq_state &= ~0x0010; - irq[0] = irq[1] = irq[2] = irq[3] = irq[4] = irq[5] = 0; m_cpu_regs[NREG_INTSTAT0 + 0] = 0; m_cpu_regs[NREG_INTSTAT0 + 1] = 0; @@ -1010,54 +1016,31 @@ WRITE32_MEMBER(vrc5074_device::cpu_reg_w) logerror("%06X:cpu_reg_w offset %03X = %08X & %08X\n", m_cpu_space->device().safe_pc(), offset * 4, data, mem_mask); } +WRITE_LINE_MEMBER(vrc5074_device::uart_irq_callback) +{ + if (state ^ ((m_nile_irq_state >> 4) & 0x1)) { + if (state) + m_nile_irq_state |= 1 << 4; + else + m_nile_irq_state &= ~(1 << 4); + update_nile_irqs(); + if (LOG_NILE) + logerror("uart_irq_callback: state = %d\n", state); + } +} + READ32_MEMBER(vrc5074_device::serial_r) { - uint32_t result = m_serial_regs[offset]; - bool logit = true; + uint32_t result = m_uart->ins8250_r(space, offset>>1); - switch (offset) - { - - case NREG_UARTIIR: /* serial port interrupt ID */ - if (m_cpu_regs[NREG_UARTIER] & 2) - result = 0x02; /* transmitter buffer IRQ pending */ - else - result = 0x01; /* no IRQ pending */ - break; - - case NREG_UARTLSR: /* serial port line status */ - result = 0x60; - logit = 0; - break; - - } - - if (LOG_NILE && logit) - logerror("%06X:serial_r offset %03X = %08X\n", m_cpu_space->device().safe_pc(), offset * 4, result); + if (LOG_NILE) + logerror("%06X:serial_r offset %03X = %08X\n", m_cpu_space->device().safe_pc(), offset>>1, result); return result; } - WRITE32_MEMBER(vrc5074_device::serial_w) { - bool logit = true; - COMBINE_DATA(&m_serial_regs[offset]); - - switch (offset) - { - - case NREG_UARTTHR: /* serial port output */ - if (PRINTF_SERIAL) { - logerror("%c", data & 0xff); - printf("%c", data & 0xff); - } - logit = 0; - break; - case NREG_UARTIER: /* serial interrupt enable */ - update_nile_irqs(); - break; - } - - if (LOG_NILE && logit) - logerror("%06X:serial_w offset %03X = %08X & %08X\n", m_cpu_space->device().safe_pc(), offset * 4, data, mem_mask); + m_uart->ins8250_w(space, offset>>1, data); + if (LOG_NILE) + logerror("%06X:serial_w offset %03X = %08X & %08X\n", m_cpu_space->device().safe_pc(), offset>>1, data, mem_mask); } diff --git a/src/devices/machine/vrc5074.h b/src/devices/machine/vrc5074.h index ac5bf548e49..9c7bcbe0961 100644 --- a/src/devices/machine/vrc5074.h +++ b/src/devices/machine/vrc5074.h @@ -9,6 +9,8 @@ #include "pci.h" #include "cpu/mips/mips3.h" +#include "machine/ins8250.h" +#include "bus/rs232/rs232.h" #define MCFG_VRC5074_ADD(_tag, _cpu_tag) \ MCFG_PCI_HOST_ADD(_tag, VRC5074, 0x1033005a, 0x04, 0x00000000) \ @@ -25,7 +27,9 @@ public: static constexpr unsigned SYSTEM_CLOCK = 100000000; vrc5074_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + required_device m_uart; + virtual void device_add_mconfig(machine_config &config) override; virtual void reset_all_mappings() override; virtual void map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space, uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space) override; @@ -65,6 +69,9 @@ public: DECLARE_READ32_MEMBER (target1_r); DECLARE_WRITE32_MEMBER(target1_w); + // Serial port + DECLARE_WRITE_LINE_MEMBER(uart_irq_callback); + protected: address_space *m_cpu_space; virtual space_config_vector memory_space_config() const override; @@ -103,7 +110,6 @@ private: address_map_delegate m_cs_maps[7]; uint32_t m_cpu_regs[0x1ff / 4]; - uint32_t m_serial_regs[0x40 / 4]; uint16_t m_nile_irq_state; void setup_pci_space();