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_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);
}

View File

@ -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<ns16550_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();