summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/lpci/i82439tx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/lpci/i82439tx.cpp')
-rw-r--r--src/devices/bus/lpci/i82439tx.cpp312
1 files changed, 312 insertions, 0 deletions
diff --git a/src/devices/bus/lpci/i82439tx.cpp b/src/devices/bus/lpci/i82439tx.cpp
new file mode 100644
index 00000000000..108302045d9
--- /dev/null
+++ b/src/devices/bus/lpci/i82439tx.cpp
@@ -0,0 +1,312 @@
+// license:BSD-3-Clause
+// copyright-holders:Miodrag Milanovic
+/***************************************************************************
+
+ Intel 82439TX System Controller (MTXC)
+
+***************************************************************************/
+
+#include "emu.h"
+#include "i82439tx.h"
+
+/***************************************************************************
+ IMPLEMENTATION
+***************************************************************************/
+
+const device_type I82439TX = &device_creator<i82439tx_device>;
+
+
+i82439tx_device::i82439tx_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : northbridge_device(mconfig, I82439TX, "Intel 82439TX", tag, owner, clock, "i82439tx", __FILE__),
+ pci_device_interface( mconfig, *this ),
+ m_cpu_tag( NULL ),
+ m_region_tag( NULL )
+{
+}
+
+void i82439tx_device::i82439tx_configure_memory(UINT8 val, offs_t begin, offs_t end)
+{
+ switch (val & 0x03)
+ {
+ case 0:
+ m_space->install_rom(begin, end, m_rom + (begin - 0xc0000));
+ m_space->nop_write(begin, end);
+ break;
+ case 1:
+ m_space->install_rom(begin, end, m_bios_ram + (begin - 0xc0000) / 4);
+ m_space->nop_write(begin, end);
+ break;
+ case 2:
+ m_space->install_rom(begin, end, m_rom + (begin - 0xc0000));
+ m_space->install_writeonly(begin, end, m_bios_ram + (begin - 0xc0000) / 4);
+ break;
+ case 3:
+ m_space->install_ram(begin, end, m_bios_ram + (begin - 0xc0000) / 4);
+ break;
+ }
+}
+
+
+/***************************************************************************
+ PCI INTERFACE
+***************************************************************************/
+
+UINT32 i82439tx_device::pci_read(pci_bus_device *pcibus, int function, int offset, UINT32 mem_mask)
+{
+ UINT32 result = 0;
+
+ if (function != 0)
+ return 0;
+
+ switch(offset)
+ {
+ case 0x00: /* vendor/device ID */
+ result = 0x71008086;
+ break;
+
+ case 0x08: /* revision identification register and class code register*/
+ result = 0x06000001;
+ break;
+
+ case 0x04: /* PCI command register */
+ case 0x0C:
+ case 0x10: /* reserved */
+ case 0x14: /* reserved */
+ case 0x18: /* reserved */
+ case 0x1C: /* reserved */
+ case 0x20: /* reserved */
+ case 0x24: /* reserved */
+ case 0x28: /* reserved */
+ case 0x2C: /* reserved */
+ case 0x30: /* reserved */
+ case 0x34: /* reserved */
+ case 0x38: /* reserved */
+ case 0x3C: /* reserved */
+ case 0x40: /* reserved */
+ case 0x44: /* reserved */
+ case 0x48: /* reserved */
+ case 0x4C: /* reserved */
+ case 0x50:
+ case 0x54:
+ case 0x58:
+ case 0x5C:
+ case 0x60:
+ case 0x64:
+ case 0x68:
+ case 0x6C:
+ case 0x70:
+ case 0x74:
+ case 0x78:
+ case 0x7C:
+ case 0x80:
+ case 0x84:
+ case 0x88:
+ case 0x8C:
+ case 0x90:
+ case 0x94:
+ case 0x98:
+ case 0x9C:
+ case 0xA0:
+ case 0xA4:
+ case 0xA8:
+ case 0xAC:
+ case 0xB0:
+ case 0xB4:
+ case 0xB8:
+ case 0xBC:
+ case 0xC0:
+ case 0xC4:
+ case 0xC8:
+ case 0xCC:
+ case 0xD0:
+ case 0xD4:
+ case 0xD8:
+ case 0xDC:
+ case 0xE0:
+ case 0xE4:
+ case 0xE8:
+ case 0xEC:
+ case 0xF0:
+ case 0xF4:
+ case 0xF8:
+ case 0xFC:
+ assert(((offset - 0x50) / 4) >= 0 && ((offset - 0x50) / 4) < ARRAY_LENGTH(m_regs));
+ result = m_regs[(offset - 0x50) / 4];
+ break;
+
+ default:
+ fatalerror("i82439tx_pci_read(): Unexpected PCI read 0x%02X\n", offset);
+ }
+ return result;
+}
+
+void i82439tx_device::pci_write(pci_bus_device *pcibus, int function, int offset, UINT32 data, UINT32 mem_mask)
+{
+ if (function != 0)
+ return;
+
+ switch(offset)
+ {
+ case 0x00: /* vendor/device ID */
+ case 0x10: /* reserved */
+ case 0x14: /* reserved */
+ case 0x18: /* reserved */
+ case 0x1C: /* reserved */
+ case 0x20: /* reserved */
+ case 0x24: /* reserved */
+ case 0x28: /* reserved */
+ case 0x2C: /* reserved */
+ case 0x30: /* reserved */
+ case 0x3C: /* reserved */
+ case 0x40: /* reserved */
+ case 0x44: /* reserved */
+ case 0x48: /* reserved */
+ case 0x4C: /* reserved */
+ /* read only */
+ break;
+
+ case 0x04: /* PCI command register */
+ case 0x0C:
+ case 0x50:
+ case 0x54:
+ case 0x58:
+ case 0x5C:
+ case 0x60:
+ case 0x64:
+ case 0x68:
+ case 0x6C:
+ case 0x70:
+ case 0x74:
+ case 0x78:
+ case 0x7C:
+ case 0x80:
+ case 0x84:
+ case 0x88:
+ case 0x8C:
+ case 0x90:
+ case 0x94:
+ case 0x98:
+ case 0x9C:
+ case 0xA0:
+ case 0xA4:
+ case 0xA8:
+ case 0xAC:
+ case 0xB0:
+ case 0xB4:
+ case 0xB8:
+ case 0xBC:
+ case 0xC0:
+ case 0xC4:
+ case 0xC8:
+ case 0xCC:
+ case 0xD0:
+ case 0xD4:
+ case 0xD8:
+ case 0xDC:
+ case 0xE0:
+ case 0xE4:
+ case 0xE8:
+ case 0xEC:
+ case 0xF0:
+ case 0xF4:
+ case 0xF8:
+ case 0xFC:
+ switch(offset)
+ {
+ case 0x58:
+ if ((mem_mask & 0x0000f000))
+ i82439tx_configure_memory(data >> 12, 0xf0000, 0xfffff);
+ if ((mem_mask & 0x000f0000))
+ i82439tx_configure_memory(data >> 16, 0xc0000, 0xc3fff);
+ if ((mem_mask & 0x00f00000))
+ i82439tx_configure_memory(data >> 20, 0xc4000, 0xc7fff);
+ if ((mem_mask & 0x0f000000))
+ i82439tx_configure_memory(data >> 24, 0xc8000, 0xccfff);
+ if ((mem_mask & 0xf0000000))
+ i82439tx_configure_memory(data >> 28, 0xcc000, 0xcffff);
+ break;
+
+ case 0x5C:
+ if ((mem_mask & 0x0000000f))
+ i82439tx_configure_memory(data >> 0, 0xd0000, 0xd3fff);
+ if ((mem_mask & 0x000000f0))
+ i82439tx_configure_memory(data >> 4, 0xd4000, 0xd7fff);
+ if ((mem_mask & 0x00000f00))
+ i82439tx_configure_memory(data >> 8, 0xd8000, 0xdbfff);
+ if ((mem_mask & 0x0000f000))
+ i82439tx_configure_memory(data >> 12, 0xdc000, 0xdffff);
+ if ((mem_mask & 0x000f0000))
+ i82439tx_configure_memory(data >> 16, 0xe0000, 0xe3fff);
+ if ((mem_mask & 0x00f00000))
+ i82439tx_configure_memory(data >> 20, 0xe4000, 0xe7fff);
+ if ((mem_mask & 0x0f000000))
+ i82439tx_configure_memory(data >> 24, 0xe8000, 0xecfff);
+ if ((mem_mask & 0xf0000000))
+ i82439tx_configure_memory(data >> 28, 0xec000, 0xeffff);
+ break;
+ }
+
+ assert(((offset - 0x50) / 4) >= 0 && ((offset - 0x50) / 4) < ARRAY_LENGTH(m_regs));
+ COMBINE_DATA(&m_regs[(offset - 0x50) / 4]);
+ break;
+
+ default:
+ fatalerror("i82439tx_pci_write(): Unexpected PCI write 0x%02X <-- 0x%08X\n", offset, data);
+ }
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void i82439tx_device::device_start()
+{
+ northbridge_device::device_start();
+ /* get address space we are working on */
+ device_t *cpu = machine().device(m_cpu_tag);
+ assert(cpu != NULL);
+
+ m_space = &cpu->memory().space(AS_PROGRAM);
+
+ /* get rom region */
+ m_rom = machine().root_device().memregion(m_region_tag)->base();
+
+ /* setup save states */
+ save_item(NAME(m_regs));
+ save_item(NAME(m_bios_ram));
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void i82439tx_device::device_reset()
+{
+ northbridge_device::device_reset();
+ /* setup initial values */
+ m_regs[0x00] = 0x14020000;
+ m_regs[0x01] = 0x01520000;
+ m_regs[0x02] = 0x00000000;
+ m_regs[0x03] = 0x00000000;
+ m_regs[0x04] = 0x02020202;
+ m_regs[0x05] = 0x00000002;
+ m_regs[0x06] = 0x00000000;
+ m_regs[0x07] = 0x00000000;
+
+ memset(m_bios_ram, 0, sizeof(m_bios_ram));
+
+ /* configure initial memory state */
+ i82439tx_configure_memory(0, 0xf0000, 0xfffff);
+ i82439tx_configure_memory(0, 0xc0000, 0xc3fff);
+ i82439tx_configure_memory(0, 0xc4000, 0xc7fff);
+ i82439tx_configure_memory(0, 0xc8000, 0xccfff);
+ i82439tx_configure_memory(0, 0xcc000, 0xcffff);
+ i82439tx_configure_memory(0, 0xd0000, 0xd3fff);
+ i82439tx_configure_memory(0, 0xd4000, 0xd7fff);
+ i82439tx_configure_memory(0, 0xd8000, 0xdbfff);
+ i82439tx_configure_memory(0, 0xdc000, 0xdffff);
+ i82439tx_configure_memory(0, 0xe0000, 0xe3fff);
+ i82439tx_configure_memory(0, 0xe4000, 0xe7fff);
+ i82439tx_configure_memory(0, 0xe8000, 0xecfff);
+ i82439tx_configure_memory(0, 0xec000, 0xeffff);
+}