vrc5074: Add 16550 uart subdevice. (nw)

This commit is contained in:
Ted Green 2017-08-07 14:10:32 -06:00
parent 461dcb6a77
commit a031030f21
2 changed files with 51 additions and 62 deletions

View File

@ -7,7 +7,7 @@
#define LOG_NILE_IRQS (0) #define LOG_NILE_IRQS (0)
#define LOG_PCI (0) #define LOG_PCI (0)
#define LOG_TIMERS (0) #define LOG_TIMERS (0)
#define LOG_DYNAMIC (0) #define LOG_MAP (0)
#define LOG_NILE_MASTER (0) #define LOG_NILE_MASTER (0)
#define LOG_NILE_TARGET (0) #define LOG_NILE_TARGET (0)
#define PRINTF_SERIAL (0) #define PRINTF_SERIAL (0)
@ -139,8 +139,22 @@ 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 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) 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), : pci_host_device(mconfig, VRC5074, tag, owner, clock),
m_uart(*this, "uart"),
m_cpu_space(nullptr), m_cpu(nullptr), cpu_tag(nullptr), m_cpu_space(nullptr), m_cpu(nullptr), cpu_tag(nullptr),
m_mem_config("memory_space", ENDIANNESS_LITTLE, 32, 32), m_mem_config("memory_space", ENDIANNESS_LITTLE, 32, 32),
m_io_config("io_space", ENDIANNESS_LITTLE, 32, 32), m_io_config("io_space", ENDIANNESS_LITTLE, 32, 32),
@ -224,7 +238,6 @@ void vrc5074_device::device_start()
save_item(NAME(m_sdram[0])); save_item(NAME(m_sdram[0]));
save_item(NAME(m_sdram[1])); save_item(NAME(m_sdram[1]));
save_item(NAME(m_cpu_regs)); save_item(NAME(m_cpu_regs));
save_item(NAME(m_serial_regs));
save_item(NAME(m_nile_irq_state)); save_item(NAME(m_nile_irq_state));
save_item(NAME(m_sdram_addr)); save_item(NAME(m_sdram_addr));
machine().save().register_postload(save_prepost_delegate(FUNC(vrc5074_device::postload), this)); 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(); pci_device::device_reset();
memset(m_cpu_regs, 0, sizeof(m_cpu_regs)); memset(m_cpu_regs, 0, sizeof(m_cpu_regs));
memset(m_serial_regs, 0, sizeof(m_serial_regs));
m_nile_irq_state = 0; m_nile_irq_state = 0;
regenerate_config_mapping(); regenerate_config_mapping();
m_dma_timer->adjust(attotime::never); 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_space->install_ram(winStart, winStart + winSize - 1, m_sdram[index].data());
m_cpu->add_fastram(winStart, winStart + winSize - 1, false, 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); 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) { 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]); 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); 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)); 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); 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; winEnd = winStart + winSize -1;
memory_space->install_read_handler(winStart, winEnd, read32_delegate(FUNC(vrc5074_device::target1_r), this)); 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)); 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); logerror("%s: map_extra Target Window 1 start=%08X end=%08X size=%08X\n", tag(), winStart, winEnd, winSize);
} }
//// PCI Target Window 2 //// PCI Target Window 2
@ -667,12 +679,6 @@ void vrc5074_device::update_nile_irqs()
uint8_t irq[6]; uint8_t irq[6];
int i; 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; 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 + 0] = 0;
m_cpu_regs[NREG_INTSTAT0 + 1] = 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); logerror("%06X:cpu_reg_w offset %03X = %08X & %08X\n", m_cpu_space->device().safe_pc(), offset * 4, data, mem_mask);
} }
READ32_MEMBER(vrc5074_device::serial_r) WRITE_LINE_MEMBER(vrc5074_device::uart_irq_callback)
{ {
uint32_t result = m_serial_regs[offset]; if (state ^ ((m_nile_irq_state >> 4) & 0x1)) {
bool logit = true; if (state)
m_nile_irq_state |= 1 << 4;
switch (offset)
{
case NREG_UARTIIR: /* serial port interrupt ID */
if (m_cpu_regs[NREG_UARTIER] & 2)
result = 0x02; /* transmitter buffer IRQ pending */
else else
result = 0x01; /* no IRQ pending */ m_nile_irq_state &= ~(1 << 4);
break; update_nile_irqs();
if (LOG_NILE)
case NREG_UARTLSR: /* serial port line status */ logerror("uart_irq_callback: state = %d\n", state);
result = 0x60; }
logit = 0;
break;
} }
if (LOG_NILE && logit) READ32_MEMBER(vrc5074_device::serial_r)
logerror("%06X:serial_r offset %03X = %08X\n", m_cpu_space->device().safe_pc(), offset * 4, result); {
uint32_t result = m_uart->ins8250_r(space, offset>>1);
if (LOG_NILE)
logerror("%06X:serial_r offset %03X = %08X\n", m_cpu_space->device().safe_pc(), offset>>1, result);
return result; return result;
} }
WRITE32_MEMBER(vrc5074_device::serial_w) WRITE32_MEMBER(vrc5074_device::serial_w)
{ {
bool logit = true; m_uart->ins8250_w(space, offset>>1, data);
COMBINE_DATA(&m_serial_regs[offset]); if (LOG_NILE)
logerror("%06X:serial_w offset %03X = %08X & %08X\n", m_cpu_space->device().safe_pc(), offset>>1, data, mem_mask);
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);
} }

View File

@ -9,6 +9,8 @@
#include "pci.h" #include "pci.h"
#include "cpu/mips/mips3.h" #include "cpu/mips/mips3.h"
#include "machine/ins8250.h"
#include "bus/rs232/rs232.h"
#define MCFG_VRC5074_ADD(_tag, _cpu_tag) \ #define MCFG_VRC5074_ADD(_tag, _cpu_tag) \
MCFG_PCI_HOST_ADD(_tag, VRC5074, 0x1033005a, 0x04, 0x00000000) \ MCFG_PCI_HOST_ADD(_tag, VRC5074, 0x1033005a, 0x04, 0x00000000) \
@ -25,7 +27,9 @@ public:
static constexpr unsigned SYSTEM_CLOCK = 100000000; static constexpr unsigned SYSTEM_CLOCK = 100000000;
vrc5074_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); vrc5074_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
required_device<ns16550_device> m_uart;
virtual void device_add_mconfig(machine_config &config) override;
virtual void reset_all_mappings() 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, 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; 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_READ32_MEMBER (target1_r);
DECLARE_WRITE32_MEMBER(target1_w); DECLARE_WRITE32_MEMBER(target1_w);
// Serial port
DECLARE_WRITE_LINE_MEMBER(uart_irq_callback);
protected: protected:
address_space *m_cpu_space; address_space *m_cpu_space;
virtual space_config_vector memory_space_config() const override; virtual space_config_vector memory_space_config() const override;
@ -103,7 +110,6 @@ private:
address_map_delegate m_cs_maps[7]; address_map_delegate m_cs_maps[7];
uint32_t m_cpu_regs[0x1ff / 4]; uint32_t m_cpu_regs[0x1ff / 4];
uint32_t m_serial_regs[0x40 / 4];
uint16_t m_nile_irq_state; uint16_t m_nile_irq_state;
void setup_pci_space(); void setup_pci_space();