summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/bus/lpci
diff options
context:
space:
mode:
author Olivier Galibert <galibert@pobox.com>2014-11-03 17:00:25 +0100
committer Olivier Galibert <galibert@pobox.com>2014-11-05 13:28:48 +0100
commitf975ef079a135fe3bdc19c0a70cd41178ffff5d8 (patch)
tree02e852ce8692fbf66121a2225af04d033c3f3947 /src/emu/bus/lpci
parent749dbb5f4a9faac3758c7d1eca09038e76007c03 (diff)
Experiments in PCI land [O. Galibert]
Diffstat (limited to 'src/emu/bus/lpci')
-rw-r--r--src/emu/bus/lpci/cirrus.c162
-rw-r--r--src/emu/bus/lpci/cirrus.h39
-rw-r--r--src/emu/bus/lpci/i82371ab.c255
-rw-r--r--src/emu/bus/lpci/i82371ab.h51
-rw-r--r--src/emu/bus/lpci/i82371sb.c179
-rw-r--r--src/emu/bus/lpci/i82371sb.h48
-rw-r--r--src/emu/bus/lpci/i82439tx.c310
-rw-r--r--src/emu/bus/lpci/i82439tx.h57
-rw-r--r--src/emu/bus/lpci/mpc105.c231
-rw-r--r--src/emu/bus/lpci/mpc105.h58
-rw-r--r--src/emu/bus/lpci/northbridge.c46
-rw-r--r--src/emu/bus/lpci/northbridge.h32
-rw-r--r--src/emu/bus/lpci/pci.c332
-rw-r--r--src/emu/bus/lpci/pci.h110
-rw-r--r--src/emu/bus/lpci/southbridge.c488
-rw-r--r--src/emu/bus/lpci/southbridge.h129
16 files changed, 2527 insertions, 0 deletions
diff --git a/src/emu/bus/lpci/cirrus.c b/src/emu/bus/lpci/cirrus.c
new file mode 100644
index 00000000000..ac001b09b74
--- /dev/null
+++ b/src/emu/bus/lpci/cirrus.c
@@ -0,0 +1,162 @@
+/***************************************************************************
+
+ video/cirrus.c
+
+ Cirrus SVGA card emulation (preliminary)
+
+ Cirrus has the following additional registers that are not present in
+ conventional VGA:
+
+ SEQ 06h: Unlock Cirrus registers; write 12h to unlock registers,
+ and read 12h back to confirm Cirrus presence.
+ SEQ 07h
+ bit 3-1: Pixel depth
+ 0x00 8 bpp
+ 0x02 16 bpp (double vert clock)
+ 0x04 24 bpp
+ 0x06 16 bpp
+ 0x08 32 bpp
+ bit 0: VGA/SVGA (0=VGA, 1=SVGA)
+ SEQ 0Fh
+ bit 7: Bankswitch enable
+ bits 4-3: Memory size
+ 0x00 256K
+ 0x08 512K
+ 0x10 1M
+ 0x18 2M
+ SEQ 12h: Hardware Cursor
+
+
+
+
+ GC 09h: Set 64k bank (bits 3-0 only)
+ GC 20h: Blit Width (bits 7-0)
+ GC 21h: Blit Width (bits 12-8)
+ GC 22h: Blit Height (bits 7-0)
+ GC 23h: Blit Height (bits 12-8)
+ GC 24h: Blit Destination Pitch (bits 7-0)
+ GC 25h: Blit Destination Pitch (bits 12-8)
+ GC 26h: Blit Source Pitch (bits 7-0)
+ GC 27h: Blit Source Pitch (bits 12-8)
+ GC 28h: Blit Destination Address (bits 7-0)
+ GC 29h: Blit Destination Address (bits 15-8)
+ GC 2Ah: Blit Destination Address (bits 21-16)
+ GC 2Ch: Blit Source Address (bits 7-0)
+ GC 2Dh: Blit Source Address (bits 15-8)
+ GC 2Eh: Blit Source Address (bits 21-16)
+ GC 2Fh: Blit Write Mask
+ GC 30h: Blit Mode
+ GC 31h: Blit Status
+ bit 7 - Autostart
+ bit 4 - FIFO Used
+ bit 2 - Blit Reset
+ bit 1 - Blit Started
+ bit 0 - Blit Busy
+ GC 32h: Raster Operation
+ GC 33h: Blit Mode Extension
+ GC 34h: Blit Transparent Color (bits 7-0)
+ GC 35h: Blit Transparent Color (bits 15-8)
+ GC 38h: Blit Transparent Color Mask (bits 7-0)
+ GC 39h: Blit Transparent Color Mask (bits 15-8)
+
+***************************************************************************/
+
+#include "emu.h"
+#include "cirrus.h"
+#include "video/pc_vga.h"
+
+#define LOG_PCIACCESS 0
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type CIRRUS = &device_creator<cirrus_device>;
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// cirrus_device - constructor
+//-------------------------------------------------
+
+cirrus_device::cirrus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, CIRRUS, "CIRRUS", tag, owner, clock, "cirrus", __FILE__),
+ pci_device_interface( mconfig, *this )
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void cirrus_device::device_start()
+{
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void cirrus_device::device_reset()
+{
+}
+
+//-------------------------------------------------
+// pci_read - implementation of PCI read
+//-------------------------------------------------
+
+UINT32 cirrus_device::pci_read(pci_bus_device *pcibus, int function, int offset, UINT32 mem_mask)
+{
+ UINT32 result = 0;
+
+ if (function == 0)
+ {
+ switch(offset)
+ {
+ case 0x00: /* vendor/device ID */
+ result = 0x00A01013;
+ break;
+
+ case 0x08:
+ result = 0x03000000;
+ break;
+
+ case 0x10:
+ result = 0xD0000000;
+ break;
+
+ default:
+ result = 0;
+ break;
+ }
+ }
+
+ if (LOG_PCIACCESS)
+ logerror("cirrus5430_pci_read(): function=%d offset=0x%02X result=0x%04X\n", function, offset, result);
+ return result;
+}
+
+
+//-------------------------------------------------
+// pci_write - implementation of PCI write
+//-------------------------------------------------
+
+void cirrus_device::pci_write(pci_bus_device *pcibus, int function, int offset, UINT32 data, UINT32 mem_mask)
+{
+ if (LOG_PCIACCESS)
+ logerror("cirrus5430_pci_write(): function=%d offset=0x%02X data=0x%04X\n", function, offset, data);
+}
+
+/*************************************
+ *
+ * Ports
+ *
+ *************************************/
+
+WRITE8_MEMBER( cirrus_device::cirrus_42E8_w )
+{
+ if (data & 0x80)
+ machine().device("vga")->reset();
+}
diff --git a/src/emu/bus/lpci/cirrus.h b/src/emu/bus/lpci/cirrus.h
new file mode 100644
index 00000000000..9027f6827e4
--- /dev/null
+++ b/src/emu/bus/lpci/cirrus.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+
+ video/cirrus.h
+
+ Cirrus SVGA card emulation (preliminary)
+
+***************************************************************************/
+
+#ifndef CIRRUS_H
+#define CIRRUS_H
+
+#include "bus/lpci/pci.h"
+
+// ======================> cirrus_device
+
+class cirrus_device : public device_t,
+ public pci_device_interface
+{
+public:
+ // construction/destruction
+ cirrus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ virtual UINT32 pci_read(pci_bus_device *pcibus, int function, int offset, UINT32 mem_mask);
+ virtual void pci_write(pci_bus_device *pcibus, int function, int offset, UINT32 data, UINT32 mem_mask);
+
+ DECLARE_WRITE8_MEMBER( cirrus_42E8_w );
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+private:
+};
+
+
+// device type definition
+extern const device_type CIRRUS;
+
+#endif /* CIRRUS_H */
diff --git a/src/emu/bus/lpci/i82371ab.c b/src/emu/bus/lpci/i82371ab.c
new file mode 100644
index 00000000000..649d1ed3b78
--- /dev/null
+++ b/src/emu/bus/lpci/i82371ab.c
@@ -0,0 +1,255 @@
+/***************************************************************************
+
+ Intel 82371AB PCI IDE ISA Xcelerator (PIIX4)
+
+ Part of the Intel 430TX chipset
+
+ - Integrated IDE Controller
+ - Enhanced DMA Controller based on two 82C37
+ - Interrupt Controller based on two 82C59
+ - Timers based on 82C54
+ - USB
+ - SMBus
+ - Real Time Clock based on MC146818
+
+***************************************************************************/
+
+#include "emu.h"
+#include "i82371ab.h"
+
+const device_type I82371AB = &device_creator<i82371ab_device>;
+
+
+i82371ab_device::i82371ab_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : southbridge_device(mconfig, I82371AB, "Intel 82371AB", tag, owner, clock, "i82371ab", __FILE__),
+ pci_device_interface( mconfig, *this )
+{
+}
+
+UINT32 i82371ab_device::pci_isa_r(device_t *busdevice, int offset, UINT32 mem_mask)
+{
+ UINT32 result = m_regs[0][offset] |
+ m_regs[0][offset+1] << 8 |
+ m_regs[0][offset+2] << 16|
+ m_regs[0][offset+3] << 24;
+
+ logerror("i82371ab_pci_isa_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask);
+
+ return result;
+}
+
+void i82371ab_device::pci_isa_w(device_t *busdevice, int offset, UINT32 data, UINT32 mem_mask)
+{
+ UINT32 cdata = 0;
+ int i;
+ COMBINE_DATA(&cdata);
+
+ logerror("i82371ab_pci_isa_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask);
+
+ for(i = 0; i < 4; i++, offset++, cdata >>= 8)
+ {
+ switch (offset)
+ {
+ case 0x04:
+ /* clear reserved bits */
+ m_regs[0][offset] = cdata & 0x05;
+ break;
+ case 0x06:
+ /* set new status */
+ m_regs[0][offset] |= 0x80;
+ break;
+ case 0x07:
+ m_regs[0][offset] |= 0x02;
+ break;
+ }
+ }
+}
+
+UINT32 i82371ab_device::pci_ide_r(device_t *busdevice, int offset, UINT32 mem_mask)
+{
+ UINT32 result = m_regs[1][offset] |
+ m_regs[1][offset+1] << 8 |
+ m_regs[1][offset+2] << 16|
+ m_regs[1][offset+3] << 24;
+
+ logerror("i82371ab_pci_ide_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask);
+
+ return result;
+}
+
+void i82371ab_device::pci_ide_w(device_t *busdevice, int offset, UINT32 data, UINT32 mem_mask)
+{
+ UINT32 cdata = 0;
+ int i;
+ COMBINE_DATA(&cdata);
+
+ logerror("i82371ab_pci_isa_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask);
+
+ for(i = 0; i < 4; i++, offset++, cdata >>= 8)
+ {
+ switch (offset)
+ {
+ case 0x04:
+ /* clear reserved bits */
+ m_regs[1][offset] = cdata & 0x05;
+ break;
+ case 0x06:
+ /* set new status */
+ m_regs[1][offset] |= 0x80;
+ break;
+ case 0x07:
+ m_regs[1][offset] |= 0x02;
+ break;
+ }
+ }
+}
+
+UINT32 i82371ab_device::pci_usb_r(device_t *busdevice, int offset, UINT32 mem_mask)
+{
+ UINT32 result = m_regs[2][offset] |
+ m_regs[2][offset+1] << 8 |
+ m_regs[2][offset+2] << 16|
+ m_regs[2][offset+3] << 24;
+
+ logerror("i82371ab_pci_usb_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask);
+
+ return result;
+}
+
+void i82371ab_device::pci_usb_w(device_t *busdevice, int offset, UINT32 data, UINT32 mem_mask)
+{
+ UINT32 cdata = 0;
+ int i;
+ COMBINE_DATA(&cdata);
+
+ logerror("i82371ab_pci_isa_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask);
+
+ for(i = 0; i < 4; i++, offset++, cdata >>= 8)
+ {
+ switch (offset)
+ {
+ case 0x04:
+ /* clear reserved bits */
+ m_regs[2][offset] = cdata & 0x05;
+ break;
+ case 0x06:
+ /* set new status */
+ m_regs[2][offset] |= 0x80;
+ break;
+ case 0x07:
+ m_regs[2][offset] |= 0x02;
+ break;
+ }
+ }
+}
+
+UINT32 i82371ab_device::pci_acpi_r(device_t *busdevice, int offset, UINT32 mem_mask)
+{
+ UINT32 result = m_regs[3][offset] |
+ m_regs[3][offset+1] << 8 |
+ m_regs[3][offset+2] << 16|
+ m_regs[3][offset+3] << 24;
+
+ logerror("i82371ab_pci_acpi_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask);
+
+ return result;
+}
+
+void i82371ab_device::pci_acpi_w(device_t *busdevice, int offset, UINT32 data, UINT32 mem_mask)
+{
+ UINT32 cdata = 0;
+ int i;
+ COMBINE_DATA(&cdata);
+
+ logerror("i82371ab_pci_isa_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask);
+
+ for(i = 0; i < 4; i++, offset++, cdata >>= 8)
+ {
+ switch (offset)
+ {
+ case 0x04:
+ /* clear reserved bits */
+ m_regs[3][offset] = cdata & 0x05;
+ break;
+ case 0x06:
+ /* set new status */
+ m_regs[3][offset] |= 0x80;
+ break;
+ case 0x07:
+ m_regs[3][offset] |= 0x02;
+ break;
+ }
+ }
+}
+
+UINT32 i82371ab_device::pci_read(pci_bus_device *pcibus, int function, int offset, UINT32 mem_mask)
+{
+ switch (function)
+ {
+ case 0: return pci_isa_r(pcibus, offset, mem_mask);
+ case 1: return pci_ide_r(pcibus, offset, mem_mask);
+ case 2: return pci_usb_r(pcibus, offset, mem_mask);
+ case 3: return pci_acpi_r(pcibus, offset, mem_mask);
+ }
+
+ logerror("i82371ab_pci_read: read from undefined function %d\n", function);
+
+ return 0;
+}
+
+void i82371ab_device::pci_write(pci_bus_device *pcibus, int function, int offset, UINT32 data, UINT32 mem_mask)
+{
+ switch (function)
+ {
+ case 0: pci_isa_w(pcibus, offset, data, mem_mask); break;
+ case 1: pci_ide_w(pcibus, offset, data, mem_mask); break;
+ case 2: pci_usb_w(pcibus, offset, data, mem_mask); break;
+ case 3: pci_acpi_w(pcibus, offset, data, mem_mask); break;
+ }
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void i82371ab_device::device_start()
+{
+ southbridge_device::device_start();
+ /* setup save states */
+ save_item(NAME(m_regs));
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void i82371ab_device::device_reset()
+{
+ southbridge_device::device_reset();
+ memset(m_regs, 0, sizeof(m_regs));
+ UINT32 (*regs32)[64] = (UINT32 (*)[64])(m_regs);
+
+ /* isa */
+ regs32[0][0x00] = 0x71108086;
+ regs32[0][0x04] = 0x00000000;
+ regs32[0][0x08] = 0x06010000;
+ regs32[0][0x0c] = 0x00800000;
+
+ /* ide */
+ regs32[1][0x00] = 0x71118086;
+ regs32[1][0x04] = 0x02800000;
+ regs32[1][0x08] = 0x01018000;
+ regs32[1][0x0c] = 0x00000000;
+
+ /* usb */
+ regs32[2][0x00] = 0x71128086;
+ regs32[2][0x04] = 0x02800000;
+ regs32[2][0x08] = 0x0c030000;
+ regs32[2][0x0c] = 0x00000000;
+
+ /* acpi */
+ regs32[3][0x00] = 0x71138086;
+ regs32[3][0x04] = 0x02800000;
+ regs32[3][0x08] = 0x06800000;
+ regs32[3][0x0c] = 0x02800000;
+}
diff --git a/src/emu/bus/lpci/i82371ab.h b/src/emu/bus/lpci/i82371ab.h
new file mode 100644
index 00000000000..c90468e0481
--- /dev/null
+++ b/src/emu/bus/lpci/i82371ab.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+
+ Intel 82371AB PCI IDE ISA Xcelerator (PIIX4)
+
+ Part of the Intel 430TX chipset
+
+***************************************************************************/
+
+#ifndef __I82371AB_H__
+#define __I82371AB_H__
+
+#include "pci.h"
+#include "southbridge.h"
+
+// ======================> i82371ab_device
+
+class i82371ab_device : public southbridge_device,
+ public pci_device_interface
+{
+public:
+ // construction/destruction
+ i82371ab_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ virtual UINT32 pci_read(pci_bus_device *pcibus, int function, int offset, UINT32 mem_mask);
+ virtual void pci_write(pci_bus_device *pcibus, int function, int offset, UINT32 data, UINT32 mem_mask);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ UINT32 pci_isa_r(device_t *busdevice, int offset, UINT32 mem_mask);
+ void pci_isa_w(device_t *busdevice, int offset, UINT32 data, UINT32 mem_mask);
+
+ UINT32 pci_ide_r(device_t *busdevice, int offset, UINT32 mem_mask);
+ void pci_ide_w(device_t *busdevice, int offset, UINT32 data, UINT32 mem_mask);
+
+ UINT32 pci_usb_r(device_t *busdevice, int offset, UINT32 mem_mask);
+ void pci_usb_w(device_t *busdevice, int offset, UINT32 data, UINT32 mem_mask);
+
+ UINT32 pci_acpi_r(device_t *busdevice, int offset, UINT32 mem_mask);
+ void pci_acpi_w(device_t *busdevice, int offset, UINT32 data, UINT32 mem_mask);
+
+private:
+ UINT8 m_regs[4][0x100];
+};
+
+// device type definition
+extern const device_type I82371AB;
+
+#endif /* __I82371AB_H__ */
diff --git a/src/emu/bus/lpci/i82371sb.c b/src/emu/bus/lpci/i82371sb.c
new file mode 100644
index 00000000000..7d173663596
--- /dev/null
+++ b/src/emu/bus/lpci/i82371sb.c
@@ -0,0 +1,179 @@
+/***************************************************************************
+
+ Intel 82371SB PCI IDE ISA Xcelerator (PIIX3)
+
+ Part of the Intel 430TX chipset
+
+ - Integrated IDE Controller
+ - Enhanced DMA Controller based on two 82C37
+ - Interrupt Controller based on two 82C59
+ - Timers based on 82C54
+ - USB
+ - SMBus
+ - Real Time Clock based on MC146818
+
+***************************************************************************/
+
+#include "emu.h"
+#include "i82371sb.h"
+
+
+/***************************************************************************
+ IMPLEMENTATION
+***************************************************************************/
+
+const device_type I82371SB = &device_creator<i82371sb_device>;
+
+
+i82371sb_device::i82371sb_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : southbridge_device(mconfig, I82371SB, "Intel 82371SB", tag, owner, clock, "i82371sb", __FILE__),
+ pci_device_interface( mconfig, *this )
+{
+}
+
+UINT32 i82371sb_device::pci_isa_r(device_t *busdevice,int offset, UINT32 mem_mask)
+{
+ UINT32 result = m_regs[0][offset];
+
+ //logerror("i82371sb_pci_isa_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask);
+
+ return result;
+}
+
+void i82371sb_device::pci_isa_w(device_t *busdevice, int offset, UINT32 data, UINT32 mem_mask)
+{
+ //logerror("i82371sb_pci_isa_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask);
+
+ switch (offset)
+ {
+ case 0x04:
+ COMBINE_DATA(&m_regs[0][offset]);
+
+ /* clear reserved bits */
+ m_regs[0][offset] &= 0x00000005;
+
+ /* set new status */
+ m_regs[0][offset] |= 0x02800000;
+
+ break;
+ }
+}
+
+UINT32 i82371sb_device::pci_ide_r(device_t *busdevice, int offset, UINT32 mem_mask)
+{
+ //logerror("i82371sb_pci_ide_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask);
+ UINT32 result = m_regs[1][offset];
+ return result;
+}
+
+void i82371sb_device::pci_ide_w(device_t *busdevice, int offset, UINT32 data, UINT32 mem_mask)
+{
+ //logerror("i82371sb_pci_ide_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask);
+
+ switch (offset)
+ {
+ case 0x04:
+ COMBINE_DATA(&m_regs[1][offset]);
+
+ /* clear reserved bits */
+ m_regs[1][offset] &= 0x00000005;
+
+ /* set new status */
+ m_regs[1][offset] |= 0x02800000;
+
+ break;
+ }
+}
+
+UINT32 i82371sb_device::pci_usb_r(device_t *busdevice, int offset, UINT32 mem_mask)
+{
+ UINT32 result = m_regs[2][offset];
+
+ //logerror("i82371sb_pci_usb_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask);
+
+ return result;
+}
+
+void i82371sb_device::pci_usb_w(device_t *busdevice, int offset, UINT32 data, UINT32 mem_mask)
+{
+ //logerror("i82371sb_pci_usb_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask);
+
+ switch (offset)
+ {
+ case 0x04:
+ COMBINE_DATA(&m_regs[2][offset]);
+
+ /* clear reserved bits */
+ m_regs[2][offset] &= 0x00000005;
+
+ /* set new status */
+ m_regs[2][offset] |= 0x02800000;
+
+ break;
+ }
+}
+
+UINT32 i82371sb_device::pci_read(pci_bus_device *pcibus, int function, int offset, UINT32 mem_mask)
+{
+ switch (function)
+ {
+ case 0: return pci_isa_r(pcibus, offset, mem_mask);
+ case 1: return pci_ide_r(pcibus, offset, mem_mask);
+ case 2: return pci_usb_r(pcibus, offset, mem_mask);
+ }
+
+ //logerror("i82371sb_pci_read: read from undefined function %d\n", function);
+
+ return 0;
+}
+
+void i82371sb_device::pci_write(pci_bus_device *pcibus, int function, int offset, UINT32 data, UINT32 mem_mask)
+{
+ switch (function)
+ {
+ case 0: pci_isa_w(pcibus, offset, data, mem_mask); break;
+ case 1: pci_ide_w(pcibus, offset, data, mem_mask); break;
+ case 2: pci_usb_w(pcibus, offset, data, mem_mask); break;
+ }
+ //logerror("i82371sb_pci_write: write to undefined function %d\n", function);
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void i82371sb_device::device_start()
+{
+ southbridge_device::device_start();
+ /* setup save states */
+ save_item(NAME(m_regs));
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void i82371sb_device::device_reset()
+{
+ southbridge_device::device_reset();
+
+ memset(m_regs, 0, sizeof(m_regs));
+
+ /* isa */
+ m_regs[0][0x00] = 0x70008086;
+ m_regs[0][0x04] = 0x00000000;
+ m_regs[0][0x08] = 0x06010000;
+ m_regs[0][0x0c] = 0x00800000;
+
+ /* ide */
+ m_regs[1][0x00] = 0x70108086;
+ m_regs[1][0x04] = 0x02800000;
+ m_regs[1][0x08] = 0x01018000;
+ m_regs[1][0x0c] = 0x00000000;
+
+ /* usb */
+ m_regs[2][0x00] = 0x70208086;
+ m_regs[2][0x04] = 0x02800000;
+ m_regs[2][0x08] = 0x0c030000;
+ m_regs[2][0x0c] = 0x00000000;
+}
diff --git a/src/emu/bus/lpci/i82371sb.h b/src/emu/bus/lpci/i82371sb.h
new file mode 100644
index 00000000000..c9ccbff9a8c
--- /dev/null
+++ b/src/emu/bus/lpci/i82371sb.h
@@ -0,0 +1,48 @@
+/***************************************************************************
+
+ Intel 82371SB PCI IDE ISA Xcelerator (PIIX3)
+
+ Part of the Intel 430TX chipset
+
+***************************************************************************/
+
+#ifndef __I82371SB_H__
+#define __I82371SB_H__
+
+#include "pci.h"
+#include "southbridge.h"
+
+// ======================> i82371sb_device
+
+class i82371sb_device : public southbridge_device,
+ public pci_device_interface
+{
+public:
+ // construction/destruction
+ i82371sb_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ virtual UINT32 pci_read(pci_bus_device *pcibus, int function, int offset, UINT32 mem_mask);
+ virtual void pci_write(pci_bus_device *pcibus, int function, int offset, UINT32 data, UINT32 mem_mask);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ UINT32 pci_isa_r(device_t *busdevice, int offset, UINT32 mem_mask);
+ void pci_isa_w(device_t *busdevice, int offset, UINT32 data, UINT32 mem_mask);
+
+ UINT32 pci_ide_r(device_t *busdevice, int offset, UINT32 mem_mask);
+ void pci_ide_w(device_t *busdevice, int offset, UINT32 data, UINT32 mem_mask);
+
+ UINT32 pci_usb_r(device_t *busdevice, int offset, UINT32 mem_mask);
+ void pci_usb_w(device_t *busdevice, int offset, UINT32 data, UINT32 mem_mask);
+private:
+ UINT32 m_regs[3][0x400/4];
+};
+
+// device type definition
+extern const device_type I82371SB;
+
+
+#endif /* __I82371SB_H__ */
diff --git a/src/emu/bus/lpci/i82439tx.c b/src/emu/bus/lpci/i82439tx.c
new file mode 100644
index 00000000000..daa612c70ac
--- /dev/null
+++ b/src/emu/bus/lpci/i82439tx.c
@@ -0,0 +1,310 @@
+/***************************************************************************
+
+ 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);
+}
diff --git a/src/emu/bus/lpci/i82439tx.h b/src/emu/bus/lpci/i82439tx.h
new file mode 100644
index 00000000000..3e8d1514e49
--- /dev/null
+++ b/src/emu/bus/lpci/i82439tx.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+
+ Intel 82439TX System Controller (MTXC)
+
+ Part of the Intel 430TX chipset
+
+***************************************************************************/
+
+#ifndef __I82439TX_H__
+#define __I82439TX_H__
+
+#include "pci.h"
+#include "northbridge.h"
+
+#define MCFG_I82439TX_CPU( _tag ) \
+ i82439tx_device::static_set_cpu(*device, _tag);
+
+#define MCFG_I82439TX_REGION( _tag ) \
+ i82439tx_device::static_set_region(*device, _tag);
+
+// ======================> i82439tx_device
+
+class i82439tx_device : public northbridge_device,
+ public pci_device_interface
+{
+public:
+ // construction/destruction
+ i82439tx_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ static void static_set_cpu(device_t &device, const char *tag) { dynamic_cast<i82439tx_device &>(device).m_cpu_tag = tag; }
+ static void static_set_region(device_t &device, const char *tag) { dynamic_cast<i82439tx_device &>(device).m_region_tag = tag; }
+
+ virtual UINT32 pci_read(pci_bus_device *pcibus, int function, int offset, UINT32 mem_mask);
+ virtual void pci_write(pci_bus_device *pcibus, int function, int offset, UINT32 data, UINT32 mem_mask);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ void i82439tx_configure_memory(UINT8 val, offs_t begin, offs_t end);
+
+private:
+ const char *m_cpu_tag;
+ const char *m_region_tag;
+
+ address_space *m_space;
+ UINT8 *m_rom;
+
+ UINT32 m_regs[8];
+ UINT32 m_bios_ram[0x40000 / 4];
+};
+
+// device type definition
+extern const device_type I82439TX;
+
+#endif /* __I82439TX_H__ */
diff --git a/src/emu/bus/lpci/mpc105.c b/src/emu/bus/lpci/mpc105.c
new file mode 100644
index 00000000000..57b448bd49d
--- /dev/null
+++ b/src/emu/bus/lpci/mpc105.c
@@ -0,0 +1,231 @@
+/***************************************************************************
+
+ mpc105.h
+
+ Motorola MPC105 PCI bridge
+
+***************************************************************************/
+
+#include "emu.h"
+#include "mpc105.h"
+#include "machine/ram.h"
+
+#define LOG_MPC105 0
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type MPC105 = &device_creator<mpc105_device>;
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// mpc105_device - constructor
+//-------------------------------------------------
+
+mpc105_device::mpc105_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, MPC105, "MPC105", tag, owner, clock, "mpc105", __FILE__),
+ pci_device_interface( mconfig, *this ),
+ m_cpu_tag(NULL),
+ m_bank_base_default(0)
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void mpc105_device::device_start()
+{
+ m_maincpu = machine().device<cpu_device>(m_cpu_tag);
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void mpc105_device::device_reset()
+{
+ m_bank_base = m_bank_base_default;
+ m_bank_enable = 0;
+ memset(m_bank_registers,0,sizeof(m_bank_registers));
+}
+
+//-------------------------------------------------
+// update_memory - MMU update
+//-------------------------------------------------
+
+void mpc105_device::update_memory()
+{
+ int bank;
+ offs_t begin, end;
+ char bank_str[10];
+
+ if (LOG_MPC105)
+ logerror("mpc105_update_memory(machine): Updating memory (bank enable=0x%02X)\n", m_bank_enable);
+
+ if (m_bank_base > 0)
+ {
+ address_space &space = m_maincpu->space(AS_PROGRAM);
+
+ /* first clear everything out */
+ space.nop_read(0x00000000, 0x3FFFFFFF);
+ space.nop_read(0x00000000, 0x3FFFFFFF);
+ }
+
+ for (bank = 0; bank < MPC105_MEMORYBANK_COUNT; bank++)
+ {
+ if (m_bank_enable & (1 << bank))
+ {
+ begin = (((m_bank_registers[(bank / 4) + 0] >> (bank % 4) * 8)) & 0xFF) << 20
+ | (((m_bank_registers[(bank / 4) + 2] >> (bank % 4) * 8)) & 0x03) << 28;
+
+ end = (((m_bank_registers[(bank / 4) + 4] >> (bank % 4) * 8)) & 0xFF) << 20
+ | (((m_bank_registers[(bank / 4) + 6] >> (bank % 4) * 8)) & 0x03) << 28
+ | 0x000FFFFF;
+
+ end = MIN(end, begin + machine().device<ram_device>(RAM_TAG)->size() - 1);
+
+ if ((begin + 0x100000) <= end)
+ {
+ if (LOG_MPC105)
+ logerror("\tbank #%d [%02d]: 0x%08X - 0x%08X [%p-%p]\n", bank, bank + m_bank_base, begin, end, machine().device<ram_device>(RAM_TAG)->pointer(), machine().device<ram_device>(RAM_TAG)->pointer() + (end - begin));
+
+ if (m_bank_base > 0)
+ {
+ sprintf(bank_str,"bank%d",bank + m_bank_base);
+ membank(bank_str)->set_base(machine().device<ram_device>(RAM_TAG)->pointer());
+ }
+ }
+ }
+ }
+}
+
+//-------------------------------------------------
+// pci_read - implementation of PCI read
+//-------------------------------------------------
+
+UINT32 mpc105_device::pci_read(pci_bus_device *pcibus, int function, int offset, UINT32 mem_mask)
+{
+ UINT32 result;
+
+ if (function != 0)
+ return 0;
+
+ switch(offset)
+ {
+ case 0x00: /* vendor/device ID */
+ result = 0x00011057;
+ break;
+
+ case 0x08:
+ result = 0x06000000;
+ break;
+
+ case 0x80: /* memory starting address 1 */
+ case 0x84: /* memory starting address 2 */
+ case 0x88: /* extended memory starting address 1 */
+ case 0x8C: /* extended memory starting address 2 */
+ case 0x90: /* memory ending address 1 */
+ case 0x94: /* memory ending address 2 */
+ case 0x98: /* extended memory ending address 1 */
+ case 0x9C: /* extended memory ending address 2 */
+ result = m_bank_registers[(offset - 0x80) / 4];
+ break;
+
+ case 0xA0: /* memory enable */
+ result = m_bank_enable;
+ break;
+
+ case 0xA8: /* processor interface configuration 1 */
+ /* TODO: Fix me! */
+ switch(/*cpu_getactivecpu()*/0)
+ {
+ case 0:
+ result = 0xFF000010;
+ break;
+
+ case 1:
+ result = 0xFF008010;
+ break;
+
+ default:
+ fatalerror("Unknown CPU\n");
+ }
+ break;
+
+ case 0xAC: /* processor interface configuration 1 */
+ result = 0x000C060C;
+ break;
+
+ case 0xF0: /* memory control configuration 1 */
+ result = 0xFF020000;
+ break;
+ case 0xF4: /* memory control configuration 2 */
+ result = 0x00000003;
+ break;
+ case 0xF8: /* memory control configuration 3 */
+ result = 0x00000000;
+ break;
+ case 0xFC: /* memory control configuration 4 */
+ result = 0x00100000;
+ break;
+
+ default:
+ result = 0;
+ break;
+ }
+ return result;
+}
+
+//-------------------------------------------------
+// pci_write - implementation of PCI write
+//-------------------------------------------------
+
+void mpc105_device::pci_write(pci_bus_device *pcibus, int function, int offset, UINT32 data, UINT32 mem_mask)
+{
+ int i;
+ if (function != 0)
+ return;
+
+ switch(offset)
+ {
+ case 0x80: /* memory starting address 1 */
+ case 0x84: /* memory starting address 2 */
+ case 0x88: /* extended memory starting address 1 */
+ case 0x8C: /* extended memory starting address 2 */
+ case 0x90: /* memory ending address 1 */
+ case 0x94: /* memory ending address 2 */
+ case 0x98: /* extended memory ending address 1 */
+ case 0x9C: /* extended memory ending address 2 */
+ i = (offset - 0x80) / 4;
+ if (m_bank_registers[i] != data)
+ {
+ m_bank_registers[i] = data;
+ update_memory();
+ }
+ break;
+
+ case 0xA0: /* memory enable */
+ if (m_bank_enable != (UINT8) data)
+ {
+ m_bank_enable = (UINT8) data;
+ update_memory();
+ }
+ break;
+
+ case 0xF0: /* memory control configuration 1 */
+ case 0xF4: /* memory control configuration 2 */
+ case 0xF8: /* memory control configuration 3 */
+ case 0xFC: /* memory control configuration 4 */
+ break;
+
+ case 0xA8: /* processor interface configuration 1 */
+ //fatalerror("mpc105_pci_write(): Unexpected PCI write 0x%02X <-- 0x%08X\n", offset, data);
+ break;
+ }
+}
diff --git a/src/emu/bus/lpci/mpc105.h b/src/emu/bus/lpci/mpc105.h
new file mode 100644
index 00000000000..ae3f4f2b1cc
--- /dev/null
+++ b/src/emu/bus/lpci/mpc105.h
@@ -0,0 +1,58 @@
+/***************************************************************************
+
+ mpc105.h
+
+ Motorola MPC105 PCI bridge
+
+***************************************************************************/
+
+#ifndef MPC105_H
+#define MPC105_H
+
+#include "pci.h"
+
+#define MPC105_MEMORYBANK_COUNT 8
+
+#define MCFG_MPC105_CPU( _tag ) \
+ mpc105_device::static_set_cpu(*device, _tag);
+
+#define MCFG_MPC105_BANK_BASE_DEFAULT( bank_base_default ) \
+ mpc105_device::static_set_bank_base_default(*device, bank_base_default);
+
+// ======================> mpc105_device
+
+class mpc105_device : public device_t,
+ public pci_device_interface
+{
+public:
+ // construction/destruction
+ mpc105_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ static void static_set_cpu(device_t &device, const char *tag) { dynamic_cast<mpc105_device &>(device).m_cpu_tag = tag; }
+ static void static_set_bank_base_default(device_t &device, int bank_base_default) { dynamic_cast<mpc105_device &>(device).m_bank_base_default = bank_base_default; }
+
+ virtual UINT32 pci_read(pci_bus_device *pcibus, int function, int offset, UINT32 mem_mask);
+ virtual void pci_write(pci_bus_device *pcibus, int function, int offset, UINT32 data, UINT32 mem_mask);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ void update_memory();
+
+private:
+ const char *m_cpu_tag;
+ int m_bank_base_default;
+ int m_bank_base;
+ UINT8 m_bank_enable;
+ UINT32 m_bank_registers[8];
+
+ cpu_device* m_maincpu;
+};
+
+
+// device type definition
+extern const device_type MPC105;
+
+#endif /* MPC105_H */
diff --git a/src/emu/bus/lpci/northbridge.c b/src/emu/bus/lpci/northbridge.c
new file mode 100644
index 00000000000..83db12613b9
--- /dev/null
+++ b/src/emu/bus/lpci/northbridge.c
@@ -0,0 +1,46 @@
+/***************************************************************************
+
+ Northbridge implementation
+
+***************************************************************************/
+
+#include "emu.h"
+#include "northbridge.h"
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+northbridge_device::northbridge_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
+ : device_t(mconfig, type, name, tag, owner, clock, shortname, source),
+ m_maincpu(*this, ":maincpu"),
+ m_ram(*this, ":" RAM_TAG)
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void northbridge_device::device_start()
+{
+ address_space& space = machine().device(":maincpu")->memory().space(AS_PROGRAM);
+
+ machine().root_device().membank("bank10")->set_base(m_ram->pointer());
+
+ if (m_ram->size() > 0x0a0000)
+ {
+ offs_t ram_limit = 0x100000 + m_ram->size() - 0x0a0000;
+ space.install_read_bank(0x100000, ram_limit - 1, "bank1");
+ space.install_write_bank(0x100000, ram_limit - 1, "bank1");
+ machine().root_device().membank("bank1")->set_base(m_ram->pointer() + 0xa0000);
+ }
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void northbridge_device::device_reset()
+{
+}
diff --git a/src/emu/bus/lpci/northbridge.h b/src/emu/bus/lpci/northbridge.h
new file mode 100644
index 00000000000..1f0600deaaf
--- /dev/null
+++ b/src/emu/bus/lpci/northbridge.h
@@ -0,0 +1,32 @@
+#pragma once
+
+#ifndef __NORTHBRIDGE_H__
+#define __NORTHBRIDGE_H__
+
+#include "emu.h"
+
+#include "machine/ram.h"
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> northbridge_device
+
+class northbridge_device :
+ public device_t
+{
+public:
+ // construction/destruction
+ northbridge_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+public:
+ required_device<cpu_device> m_maincpu;
+ required_device<ram_device> m_ram;
+
+};
+
+#endif /* __NORTHBRIDGE_H__ */
diff --git a/src/emu/bus/lpci/pci.c b/src/emu/bus/lpci/pci.c
new file mode 100644
index 00000000000..1f13b78dfe4
--- /dev/null
+++ b/src/emu/bus/lpci/pci.c
@@ -0,0 +1,332 @@
+/***************************************************************************
+
+ pci.c
+
+ PCI bus
+
+ The PCI bus is a 32-bit bus introduced by Intel, so it is little endian
+
+ Control word:
+ bit 31: Enable bit
+ bits 30-24: Reserved
+ bits 23-16: PCI bus number
+ bits 15-11: PCI device number
+ bits 10- 8: PCI function number
+ bits 7- 0: Offset address
+
+ Standard PCI registers:
+ 0x00 2 Vendor ID
+ 0x02 2 Device ID
+ 0x04 2 PCI Command
+ 0x06 2 PCI Status
+ 0x08 1 Revision ID
+ 0x09 1 Programming Interface
+ 0x0A 1 Subclass Code
+ 0x0B 1 Class Code
+
+ Class Code/Subclass Code/Programming Interface
+ 0x00XXXX Pre-PCI 2.0 devices
+ 0x000000 Non-VGA device
+ 0x000101 VGA device
+ 0x01XXXX Storage Controller
+ 0x010000 SCSI
+ 0x0101XX IDE
+ 0x0102XX Floppy
+ 0x0103XX IPI
+ 0x0104XX RAID
+ 0x0180XX Other
+ 0x02XXXX Network Card
+ 0x020000 Ethernet
+ 0x020100 Tokenring
+ 0x020200 FDDI
+ 0x020300 ATM
+ 0x028000 Other
+ 0x03XXXX Display Controller
+ 0x030000 VGA
+ 0x030001 8514 Compatible
+ 0x030100 XGA
+ 0x038000 Other
+ 0x04XXXX Multimedia
+ 0x040000 Video
+ 0x040100 Audio
+ 0x048000 Other
+ 0x05XXXX Memory Controller
+ 0x050000 RAM
+ 0x050100 Flash
+ 0x058000 Other
+ 0x06XXXX Bridge
+ 0x060000 Host/PCI
+ 0x060100 PCI/ISA
+ 0x060200 PCI/EISA
+ 0x060300 PCI/Micro Channel
+ 0x060400 PCI/PCI
+ 0x060500 PCI/PCMCIA
+ 0x060600 PCI/NuBus
+ 0x060700 PCI/CardBus
+ 0x068000 Other
+
+ Information on PCI vendors can be found at http://www.pcidatabase.com/
+
+***************************************************************************/
+
+#include "emu.h"
+#include "pci.h"
+
+#define LOG_PCI 0
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type PCI_BUS = &device_creator<pci_bus_device>;
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// pci_bus_device - constructor
+//-------------------------------------------------
+pci_bus_device::pci_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, PCI_BUS, "PCI Bus", tag, owner, clock, "pci_bus", __FILE__),
+ m_father(NULL)
+{
+ for (int i = 0; i < ARRAY_LENGTH(m_devtag); i++) {
+ m_devtag[i]= NULL;
+ }
+ m_siblings_count = 0;
+}
+
+/***************************************************************************
+ INLINE FUNCTIONS
+***************************************************************************/
+
+READ32_MEMBER( pci_bus_device::read )
+{
+ UINT32 result = 0xffffffff;
+ int function, reg;
+
+ offset %= 2;
+
+ switch (offset)
+ {
+ case 0:
+ result = m_address;
+ break;
+
+ case 1:
+ if (m_devicenum != -1)
+ {
+ if (m_busnumaddr->m_device[m_devicenum] != NULL)
+ {
+ function = (m_address >> 8) & 0x07;
+ reg = (m_address >> 0) & 0xfc;
+ result = m_busnumaddr->m_device[m_devicenum]->pci_read(m_busnumaddr, function, reg, mem_mask);
+ }
+ }
+ break;
+ }
+
+ if (LOG_PCI)
+ logerror("read('%s'): offset=%d result=0x%08X\n", tag(), offset, result);
+
+ return result;
+}
+
+
+
+pci_bus_device *pci_bus_device::pci_search_bustree(int busnum, int devicenum, pci_bus_device *pcibus)
+{
+ int a;
+ pci_bus_device *ret;
+
+ if (pcibus->m_busnum == busnum)
+ {
+ return pcibus;
+ }
+ for (a = 0; a < pcibus->m_siblings_count; a++)
+ {
+ ret = pci_search_bustree(busnum, devicenum, pcibus->m_siblings[a]);
+ if (ret != NULL)
+ return ret;
+ }
+ return NULL;
+}
+
+
+
+WRITE32_MEMBER( pci_bus_device::write )
+{
+ offset %= 2;
+
+ if (LOG_PCI)
+ logerror("write('%s'): offset=%d data=0x%08X\n", tag(), offset, data);
+
+ switch (offset)
+ {
+ case 0:
+ m_address = data;
+
+ /* lookup current device */
+ if (m_address & 0x80000000)
+ {
+ int busnum = (m_address >> 16) & 0xff;
+ int devicenum = (m_address >> 11) & 0x1f;
+ m_busnumaddr = pci_search_bustree(busnum, devicenum, this);
+ if (m_busnumaddr != NULL)
+ {
+ m_busnumber = busnum;
+ m_devicenum = devicenum;
+ }
+ else
+ m_devicenum = -1;
+ if (LOG_PCI)
+ logerror(" bus:%d device:%d\n", busnum, devicenum);
+ }
+ break;
+
+ case 1:
+ if (m_devicenum != -1)
+ {
+ if (m_busnumaddr->m_device[m_devicenum] != NULL)
+ {
+ int function = (m_address >> 8) & 0x07;
+ int reg = (m_address >> 0) & 0xfc;
+ m_busnumaddr->m_device[m_devicenum]->pci_write(m_busnumaddr, function, reg, data, mem_mask);
+ }
+ if (LOG_PCI)
+ logerror(" function:%d register:%d\n", (m_address >> 8) & 0x07, (m_address >> 0) & 0xfc);
+ }
+ break;
+ }
+}
+
+
+
+READ64_MEMBER(pci_bus_device::read_64be)
+{
+ UINT64 result = 0;
+ mem_mask = FLIPENDIAN_INT64(mem_mask);
+ if (ACCESSING_BITS_0_31)
+ result |= (UINT64)read(space, offset * 2 + 0, mem_mask >> 0) << 0;
+ if (ACCESSING_BITS_32_63)
+ result |= (UINT64)read(space, offset * 2 + 1, mem_mask >> 32) << 32;
+ return FLIPENDIAN_INT64(result);
+}
+
+WRITE64_MEMBER(pci_bus_device::write_64be)
+{
+ data = FLIPENDIAN_INT64(data);
+ mem_mask = FLIPENDIAN_INT64(mem_mask);
+ if (ACCESSING_BITS_0_31)
+ write(space, offset * 2 + 0, data >> 0, mem_mask >> 0);
+ if (ACCESSING_BITS_32_63)
+ write(space, offset * 2 + 1, data >> 32, mem_mask >> 32);
+}
+
+
+void pci_bus_device::add_sibling(pci_bus_device *sibling, int busnum)
+{
+ m_siblings[m_siblings_count] = sibling;
+ m_siblings_busnum[m_siblings_count] = busnum;
+ m_siblings_count++;
+}
+
+
+//-------------------------------------------------
+// device_post_load - handle updating after a
+// restore
+//-------------------------------------------------
+
+void pci_bus_device::device_post_load()
+{
+ if (m_devicenum != -1)
+ {
+ m_busnumaddr = pci_search_bustree(m_busnumber, m_devicenum, this);
+ }
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void pci_bus_device::device_start()
+{
+ /* store a pointer back to the device */
+ m_devicenum = -1;
+
+ char id[3];
+ /* find all our devices */
+ for (int i = 0; i < ARRAY_LENGTH(m_devtag); i++)
+ {
+ sprintf(id, "%d", i);
+ pci_connector *conn = downcast<pci_connector *>(subdevice(id));
+ if (conn!=NULL)
+ m_device[i] = conn->get_device();
+ else
+ m_device[i] = NULL;
+ }
+
+ if (m_father != NULL) {
+ pci_bus_device *father = machine().device<pci_bus_device>(m_father);
+ if (father)
+ father->add_sibling(this, m_busnum);
+ }
+
+ /* register pci states */
+ save_item(NAME(m_address));
+ save_item(NAME(m_devicenum));
+ save_item(NAME(m_busnum));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void pci_bus_device::device_reset()
+{
+ /* reset the drive state */
+ m_devicenum = -1;
+ m_address = 0;
+}
+
+//-------------------------------------------------
+// pci_device_interface - constructor
+//-------------------------------------------------
+
+pci_device_interface::pci_device_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig, device)
+{
+}
+
+//-------------------------------------------------
+// ~pci_device_interface - destructor
+//-------------------------------------------------
+
+pci_device_interface::~pci_device_interface()
+{
+}
+
+
+const device_type PCI_CONNECTOR = &device_creator<pci_connector>;
+
+
+pci_connector::pci_connector(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, PCI_CONNECTOR, "PCI device connector abstraction", tag, owner, clock, "pci_connector", __FILE__),
+ device_slot_interface(mconfig, *this)
+{
+}
+
+pci_connector::~pci_connector()
+{
+}
+
+void pci_connector::device_start()
+{
+}
+
+pci_device_interface *pci_connector::get_device()
+{
+ return dynamic_cast<pci_device_interface *>(get_card_device());
+}
diff --git a/src/emu/bus/lpci/pci.h b/src/emu/bus/lpci/pci.h
new file mode 100644
index 00000000000..97d7b45d988
--- /dev/null
+++ b/src/emu/bus/lpci/pci.h
@@ -0,0 +1,110 @@
+/***************************************************************************
+
+ pci.h
+
+ PCI bus
+
+***************************************************************************/
+
+#ifndef PCI_H
+#define PCI_H
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+class pci_bus_device;
+
+// ======================> pci_device_interface
+
+class pci_device_interface : public device_slot_card_interface
+{
+public:
+ // construction/destruction
+ pci_device_interface(const machine_config &mconfig, device_t &device);
+ virtual ~pci_device_interface();
+
+ virtual UINT32 pci_read(pci_bus_device *pcibus, int function, int offset, UINT32 mem_mask) = 0;
+ virtual void pci_write(pci_bus_device *pcibus, int function, int offset, UINT32 data, UINT32 mem_mask) = 0;
+private:
+};
+
+class pci_connector: public device_t,
+ public device_slot_interface
+{
+public:
+ pci_connector(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ virtual ~pci_connector();
+
+ pci_device_interface *get_device();
+
+protected:
+ virtual void device_start();
+};
+
+extern const device_type PCI_CONNECTOR;
+
+// ======================> pci_bus_device
+
+class pci_bus_device : public device_t
+{
+public:
+ // construction/destruction
+ pci_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ DECLARE_READ32_MEMBER( read );
+ DECLARE_WRITE32_MEMBER( write );
+
+ DECLARE_READ64_MEMBER( read_64be );
+ DECLARE_WRITE64_MEMBER( write_64be );
+
+ void set_busnum(int busnum) { m_busnum = busnum; }
+ void set_father(const char *father) { m_father = father; }
+ void set_device(int num, const char *tag) {
+ m_devtag[num] = tag; }
+
+ pci_bus_device *pci_search_bustree(int busnum, int devicenum, pci_bus_device *pcibus);
+ void add_sibling(pci_bus_device *sibling, int busnum);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+ virtual void device_post_load();
+
+private:
+ UINT8 m_busnum;
+
+ const char * m_devtag[32];
+ pci_device_interface *m_device[32];
+
+ const char * m_father;
+ pci_bus_device * m_siblings[8];
+ UINT8 m_siblings_busnum[8];
+ int m_siblings_count;
+
+ offs_t m_address;
+ INT8 m_devicenum; // device number we are addressing
+ INT8 m_busnumber; // pci bus number we are addressing
+ pci_bus_device * m_busnumaddr; // pci bus we are addressing
+};
+
+// device type definition
+extern const device_type PCI_BUS;
+
+
+/***************************************************************************
+ DEVICE CONFIGURATION MACROS
+***************************************************************************/
+
+#define MCFG_PCI_BUS_ADD(_tag, _busnum) \
+ MCFG_DEVICE_ADD(_tag, PCI_BUS, 0) \
+ downcast<pci_bus_device *>(device)->set_busnum(_busnum);
+#define MCFG_PCI_BUS_DEVICE(_tag, _slot_intf, _def_slot, _fixed) \
+ MCFG_DEVICE_ADD(_tag, PCI_CONNECTOR, 0) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _fixed)
+
+#define MCFG_PCI_BUS_SIBLING(_father_tag) \
+ downcast<pci_bus_device *>(device)->set_father(_father_tag);
+
+
+#endif /* PCI_H */
diff --git a/src/emu/bus/lpci/southbridge.c b/src/emu/bus/lpci/southbridge.c
new file mode 100644
index 00000000000..d6797fdef06
--- /dev/null
+++ b/src/emu/bus/lpci/southbridge.c
@@ -0,0 +1,488 @@
+/***************************************************************************
+
+ Southbridge implementation
+
+***************************************************************************/
+
+#include "emu.h"
+#include "cpu/i386/i386.h"
+#include "southbridge.h"
+#include "bus/pc_kbd/keyboards.h"
+
+
+static SLOT_INTERFACE_START(pc_isa_onboard)
+ SLOT_INTERFACE("comat", ISA8_COM_AT)
+ SLOT_INTERFACE("lpt", ISA8_LPT)
+ SLOT_INTERFACE("fdcsmc", ISA8_FDC_SMC)
+SLOT_INTERFACE_END
+
+static MACHINE_CONFIG_FRAGMENT( southbridge )
+ MCFG_DEVICE_ADD("pit8254", PIT8254, 0)
+ MCFG_PIT8253_CLK0(4772720/4) /* heartbeat IRQ */
+ MCFG_PIT8253_OUT0_HANDLER(WRITELINE(southbridge_device, at_pit8254_out0_changed))
+ MCFG_PIT8253_CLK1(4772720/4) /* dram refresh */
+ MCFG_PIT8253_OUT1_HANDLER(WRITELINE(southbridge_device, at_pit8254_out1_changed))
+ MCFG_PIT8253_CLK2(4772720/4) /* pio port c pin 4, and speaker polling enough */
+ MCFG_PIT8253_OUT2_HANDLER(WRITELINE(southbridge_device, at_pit8254_out2_changed))
+
+ MCFG_DEVICE_ADD( "dma8237_1", AM9517A, XTAL_14_31818MHz/3 )
+ MCFG_I8237_OUT_HREQ_CB(DEVWRITELINE("dma8237_2", am9517a_device, dreq0_w))
+ MCFG_I8237_OUT_EOP_CB(WRITELINE(southbridge_device, at_dma8237_out_eop))
+ MCFG_I8237_IN_MEMR_CB(READ8(southbridge_device, pc_dma_read_byte))
+ MCFG_I8237_OUT_MEMW_CB(WRITE8(southbridge_device, pc_dma_write_byte))
+ MCFG_I8237_IN_IOR_0_CB(READ8(southbridge_device, pc_dma8237_0_dack_r))
+ MCFG_I8237_IN_IOR_1_CB(READ8(southbridge_device, pc_dma8237_1_dack_r))
+ MCFG_I8237_IN_IOR_2_CB(READ8(southbridge_device, pc_dma8237_2_dack_r))
+ MCFG_I8237_IN_IOR_3_CB(READ8(southbridge_device, pc_dma8237_3_dack_r))
+ MCFG_I8237_OUT_IOW_0_CB(WRITE8(southbridge_device, pc_dma8237_0_dack_w))
+ MCFG_I8237_OUT_IOW_1_CB(WRITE8(southbridge_device, pc_dma8237_1_dack_w))
+ MCFG_I8237_OUT_IOW_2_CB(WRITE8(southbridge_device, pc_dma8237_2_dack_w))
+ MCFG_I8237_OUT_IOW_3_CB(WRITE8(southbridge_device, pc_dma8237_3_dack_w))
+ MCFG_I8237_OUT_DACK_0_CB(WRITELINE(southbridge_device, pc_dack0_w))
+ MCFG_I8237_OUT_DACK_1_CB(WRITELINE(southbridge_device, pc_dack1_w))
+ MCFG_I8237_OUT_DACK_2_CB(WRITELINE(southbridge_device, pc_dack2_w))
+ MCFG_I8237_OUT_DACK_3_CB(WRITELINE(southbridge_device, pc_dack3_w))
+
+ MCFG_DEVICE_ADD( "dma8237_2", AM9517A, XTAL_14_31818MHz/3 )
+ MCFG_I8237_OUT_HREQ_CB(WRITELINE(southbridge_device, pc_dma_hrq_changed))
+ MCFG_I8237_IN_MEMR_CB(READ8(southbridge_device, pc_dma_read_word))
+ MCFG_I8237_OUT_MEMW_CB(WRITE8(southbridge_device, pc_dma_write_word))
+ MCFG_I8237_IN_IOR_1_CB(READ8(southbridge_device, pc_dma8237_5_dack_r))
+ MCFG_I8237_IN_IOR_2_CB(READ8(southbridge_device, pc_dma8237_6_dack_r))
+ MCFG_I8237_IN_IOR_3_CB(READ8(southbridge_device, pc_dma8237_7_dack_r))
+ MCFG_I8237_OUT_IOW_1_CB(WRITE8(southbridge_device, pc_dma8237_5_dack_w))
+ MCFG_I8237_OUT_IOW_2_CB(WRITE8(southbridge_device, pc_dma8237_6_dack_w))
+ MCFG_I8237_OUT_IOW_3_CB(WRITE8(southbridge_device, pc_dma8237_7_dack_w))
+ MCFG_I8237_OUT_DACK_0_CB(WRITELINE(southbridge_device, pc_dack4_w))
+ MCFG_I8237_OUT_DACK_1_CB(WRITELINE(southbridge_device, pc_dack5_w))
+ MCFG_I8237_OUT_DACK_2_CB(WRITELINE(southbridge_device, pc_dack6_w))
+ MCFG_I8237_OUT_DACK_3_CB(WRITELINE(southbridge_device, pc_dack7_w))
+
+ MCFG_PIC8259_ADD( "pic8259_master", INPUTLINE(":maincpu", 0), VCC, READ8(southbridge_device, get_slave_ack) )
+ MCFG_PIC8259_ADD( "pic8259_slave", DEVWRITELINE("pic8259_master", pic8259_device, ir2_w), GND, NULL )
+
+ MCFG_DEVICE_ADD("keybc", AT_KEYBOARD_CONTROLLER, XTAL_12MHz)
+ MCFG_AT_KEYBOARD_CONTROLLER_SYSTEM_RESET_CB(INPUTLINE(":maincpu", INPUT_LINE_RESET))
+ MCFG_AT_KEYBOARD_CONTROLLER_GATE_A20_CB(INPUTLINE(":maincpu", INPUT_LINE_A20))
+ MCFG_AT_KEYBOARD_CONTROLLER_INPUT_BUFFER_FULL_CB(DEVWRITELINE("pic8259_master", pic8259_device, ir1_w))
+ MCFG_AT_KEYBOARD_CONTROLLER_KEYBOARD_CLOCK_CB(DEVWRITELINE("pc_kbdc", pc_kbdc_device, clock_write_from_mb))
+ MCFG_AT_KEYBOARD_CONTROLLER_KEYBOARD_DATA_CB(DEVWRITELINE("pc_kbdc", pc_kbdc_device, data_write_from_mb))
+ MCFG_DEVICE_ADD("pc_kbdc", PC_KBDC, 0)
+ MCFG_PC_KBDC_OUT_CLOCK_CB(DEVWRITELINE("keybc", at_keyboard_controller_device, keyboard_clock_w))
+ MCFG_PC_KBDC_OUT_DATA_CB(DEVWRITELINE("keybc", at_keyboard_controller_device, keyboard_data_w))
+ MCFG_PC_KBDC_SLOT_ADD("pc_kbdc", "kbd", pc_at_keyboards, STR_KBD_MICROSOFT_NATURAL)
+
+ MCFG_DS12885_ADD("rtc")
+ MCFG_MC146818_IRQ_HANDLER(DEVWRITELINE("pic8259_slave", pic8259_device, ir0_w))
+ MCFG_MC146818_CENTURY_INDEX(0x32)
+
+ MCFG_BUS_MASTER_IDE_CONTROLLER_ADD("ide", ata_devices, "hdd", NULL, false)
+ MCFG_ATA_INTERFACE_IRQ_HANDLER(DEVWRITELINE("pic8259_slave", pic8259_device, ir6_w))
+ MCFG_BUS_MASTER_IDE_CONTROLLER_SPACE(":maincpu", AS_PROGRAM)
+
+ MCFG_BUS_MASTER_IDE_CONTROLLER_ADD("ide2", ata_devices, "cdrom", NULL, false)
+ MCFG_ATA_INTERFACE_IRQ_HANDLER(DEVWRITELINE("pic8259_slave", pic8259_device, ir7_w))
+ MCFG_BUS_MASTER_IDE_CONTROLLER_SPACE(":maincpu", AS_PROGRAM)
+
+ /* sound hardware */
+ MCFG_SPEAKER_STANDARD_MONO("mono")
+ MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
+
+ MCFG_DEVICE_ADD("isabus", ISA16, 0)
+ MCFG_ISA16_CPU(":maincpu")
+ MCFG_ISA_OUT_IRQ2_CB(DEVWRITELINE("pic8259_slave", pic8259_device, ir2_w)) // in place of irq 2 on at irq 9 is used
+ MCFG_ISA_OUT_IRQ3_CB(DEVWRITELINE("pic8259_master", pic8259_device, ir3_w))
+ MCFG_ISA_OUT_IRQ4_CB(DEVWRITELINE("pic8259_master", pic8259_device, ir4_w))
+ MCFG_ISA_OUT_IRQ5_CB(DEVWRITELINE("pic8259_master", pic8259_device, ir5_w))
+ MCFG_ISA_OUT_IRQ6_CB(DEVWRITELINE("pic8259_master", pic8259_device, ir6_w))
+ MCFG_ISA_OUT_IRQ7_CB(DEVWRITELINE("pic8259_master", pic8259_device, ir7_w))
+ MCFG_ISA_OUT_IRQ10_CB(DEVWRITELINE("pic8259_slave", pic8259_device, ir3_w))
+ MCFG_ISA_OUT_IRQ11_CB(DEVWRITELINE("pic8259_slave", pic8259_device, ir4_w))
+ MCFG_ISA_OUT_IRQ12_CB(DEVWRITELINE("pic8259_slave", pic8259_device, ir5_w))
+ MCFG_ISA_OUT_IRQ14_CB(DEVWRITELINE("pic8259_slave", pic8259_device, ir6_w))
+ MCFG_ISA_OUT_IRQ15_CB(DEVWRITELINE("pic8259_slave", pic8259_device, ir7_w))
+ MCFG_ISA_OUT_DRQ0_CB(DEVWRITELINE("dma8237_1", am9517a_device, dreq0_w))
+ MCFG_ISA_OUT_DRQ1_CB(DEVWRITELINE("dma8237_1", am9517a_device, dreq1_w))
+ MCFG_ISA_OUT_DRQ2_CB(DEVWRITELINE("dma8237_1", am9517a_device, dreq2_w))
+ MCFG_ISA_OUT_DRQ3_CB(DEVWRITELINE("dma8237_1", am9517a_device, dreq3_w))
+ MCFG_ISA_OUT_DRQ5_CB(DEVWRITELINE("dma8237_2", am9517a_device, dreq1_w))
+ MCFG_ISA_OUT_DRQ6_CB(DEVWRITELINE("dma8237_2", am9517a_device, dreq2_w))
+ MCFG_ISA_OUT_DRQ7_CB(DEVWRITELINE("dma8237_2", am9517a_device, dreq3_w))
+ // on board devices
+ MCFG_ISA16_SLOT_ADD("isabus","board1", pc_isa_onboard, "fdcsmc", true)
+ MCFG_ISA16_SLOT_ADD("isabus","board2", pc_isa_onboard, "comat", true)
+ MCFG_ISA16_SLOT_ADD("isabus","board3", pc_isa_onboard, "lpt", true)
+MACHINE_CONFIG_END
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor southbridge_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( southbridge );
+}
+
+southbridge_device::southbridge_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
+ : device_t(mconfig, type, name, tag, owner, clock, shortname, source),
+ m_maincpu(*this, ":maincpu"),
+ m_pic8259_master(*this, "pic8259_master"),
+ m_pic8259_slave(*this, "pic8259_slave"),
+ m_dma8237_1(*this, "dma8237_1"),
+ m_dma8237_2(*this, "dma8237_2"),
+ m_pit8254(*this, "pit8254"),
+ m_keybc(*this, "keybc"),
+ m_isabus(*this, "isabus"),
+ m_speaker(*this, "speaker"),
+ m_ds12885(*this, "rtc"),
+ m_pc_kbdc(*this, "pc_kbdc"),
+ m_ide(*this, "ide"),
+ m_ide2(*this, "ide2")
+{
+}
+/**********************************************************
+ *
+ * Init functions
+ *
+ **********************************************************/
+
+/// HACK: the memory system cannot cope with mixing the 8 bit device map from the fdc with a 32 bit handler
+READ8_MEMBER(southbridge_device::ide_read_cs1_r)
+{
+ return m_ide->read_cs1(space, 1, (UINT32) 0xff0000) >> 16;
+}
+
+WRITE8_MEMBER(southbridge_device::ide_write_cs1_w)
+{
+ m_ide->write_cs1(space, 1, (UINT32) data << 16, (UINT32) 0xff0000);
+}
+
+READ8_MEMBER(southbridge_device::ide2_read_cs1_r)
+{
+ return m_ide2->read_cs1(space, 1, (UINT32) 0xff0000) >> 16;
+}
+
+WRITE8_MEMBER(southbridge_device::ide2_write_cs1_w)
+{
+ m_ide2->write_cs1(space, 1, (UINT32) data << 16, (UINT32) 0xff0000);
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void southbridge_device::device_start()
+{
+ address_space& spaceio = machine().device(":maincpu")->memory().space(AS_IO);
+
+ spaceio.install_readwrite_handler(0x0000, 0x001f, read8_delegate(FUNC(am9517a_device::read),&(*m_dma8237_1)), write8_delegate(FUNC(am9517a_device::write),&(*m_dma8237_1)), 0xffffffff);
+ spaceio.install_readwrite_handler(0x0020, 0x003f, read8_delegate(FUNC(pic8259_device::read),&(*m_pic8259_master)), write8_delegate(FUNC(pic8259_device::write),&(*m_pic8259_master)), 0xffffffff);
+ spaceio.install_readwrite_handler(0x0040, 0x005f, read8_delegate(FUNC(pit8254_device::read),&(*m_pit8254)), write8_delegate(FUNC(pit8254_device::write),&(*m_pit8254)), 0xffffffff);
+ spaceio.install_readwrite_handler(0x0060, 0x0063, read8_delegate(FUNC(southbridge_device::at_keybc_r),this), write8_delegate(FUNC(southbridge_device::at_keybc_w),this), 0xffffffff);
+ spaceio.install_readwrite_handler(0x0064, 0x0067, read8_delegate(FUNC(at_keyboard_controller_device::status_r),&(*m_keybc)), write8_delegate(FUNC(at_keyboard_controller_device::command_w),&(*m_keybc)), 0xffffffff);
+ spaceio.install_readwrite_handler(0x0070, 0x007f, read8_delegate(FUNC(ds12885_device::read),&(*m_ds12885)), write8_delegate(FUNC(ds12885_device::write),&(*m_ds12885)), 0xffffffff);
+ spaceio.install_readwrite_handler(0x0080, 0x009f, read8_delegate(FUNC(southbridge_device::at_page8_r),this), write8_delegate(FUNC(southbridge_device::at_page8_w),this), 0xffffffff);
+ spaceio.install_readwrite_handler(0x00a0, 0x00bf, read8_delegate(FUNC(pic8259_device::read),&(*m_pic8259_slave)), write8_delegate(FUNC(pic8259_device::write),&(*m_pic8259_slave)), 0xffffffff);
+ spaceio.install_readwrite_handler(0x00c0, 0x00df, read8_delegate(FUNC(southbridge_device::at_dma8237_2_r),this), write8_delegate(FUNC(southbridge_device::at_dma8237_2_w),this), 0xffffffff);
+ spaceio.install_readwrite_handler(0x0170, 0x0177, read32_delegate(FUNC(bus_master_ide_controller_device::read_cs0),&(*m_ide2)), write32_delegate(FUNC(bus_master_ide_controller_device::write_cs0), &(*m_ide2)),0xffffffff);
+ spaceio.install_readwrite_handler(0x01f0, 0x01f7, read32_delegate(FUNC(bus_master_ide_controller_device::read_cs0),&(*m_ide)), write32_delegate(FUNC(bus_master_ide_controller_device::write_cs0), &(*m_ide)),0xffffffff);
+// HACK: this works if you take out the (non working) fdc
+// spaceio.install_readwrite_handler(0x0370, 0x0377, read32_delegate(FUNC(bus_master_ide_controller_device::read_cs1),&(*m_ide2)), write32_delegate(FUNC(bus_master_ide_controller_device::write_cs1), &(*m_ide2)),0xffffffff);
+// spaceio.install_readwrite_handler(0x03f0, 0x03f7, read32_delegate(FUNC(bus_master_ide_controller_device::read_cs1),&(*m_ide)), write32_delegate(FUNC(bus_master_ide_controller_device::write_cs1), &(*m_ide)),0xffffffff);
+ spaceio.install_readwrite_handler(0x0374, 0x0377, read8_delegate(FUNC(southbridge_device::ide2_read_cs1_r),this), write8_delegate(FUNC(southbridge_device::ide2_write_cs1_w), this),0xff0000);
+ spaceio.install_readwrite_handler(0x03f4, 0x03f7, read8_delegate(FUNC(southbridge_device::ide_read_cs1_r),this), write8_delegate(FUNC(southbridge_device::ide_write_cs1_w), this),0xff0000);
+ spaceio.nop_readwrite(0x00e0, 0x00ef);
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void southbridge_device::device_reset()
+{
+ m_at_spkrdata = 0;
+ m_pit_out2 = 0;
+ m_dma_channel = -1;
+ m_cur_eop = false;
+ m_nmi_enabled = 0;
+ m_refresh = false;
+}
+
+
+/*************************************************************
+ *
+ * pic8259 configuration
+ *
+ *************************************************************/
+READ8_MEMBER( southbridge_device::get_slave_ack )
+{
+ if (offset==2) // IRQ = 2
+ return m_pic8259_slave->acknowledge();
+
+ return 0x00;
+}
+
+/*************************************************************************
+ *
+ * PC Speaker related
+ *
+ *************************************************************************/
+
+void southbridge_device::at_speaker_set_spkrdata(UINT8 data)
+{
+ m_at_spkrdata = data ? 1 : 0;
+ m_speaker->level_w(m_at_spkrdata & m_pit_out2);
+}
+
+
+
+/*************************************************************
+ *
+ * pit8254 configuration
+ *
+ *************************************************************/
+
+WRITE_LINE_MEMBER( southbridge_device::at_pit8254_out0_changed )
+{
+ if (m_pic8259_master)
+ m_pic8259_master->ir0_w(state);
+}
+
+WRITE_LINE_MEMBER( southbridge_device::at_pit8254_out1_changed )
+{
+ if(state)
+ m_refresh = !m_refresh;
+}
+
+WRITE_LINE_MEMBER( southbridge_device::at_pit8254_out2_changed )
+{
+ m_pit_out2 = state ? 1 : 0;
+ m_speaker->level_w(m_at_spkrdata & m_pit_out2);
+}
+
+/*************************************************************************
+ *
+ * PC DMA stuff
+ *
+ *************************************************************************/
+
+READ8_MEMBER( southbridge_device::at_page8_r )
+{
+ UINT8 data = m_at_pages[offset % 0x10];
+
+ switch(offset % 8)
+ {
+ case 1:
+ data = m_dma_offset[BIT(offset, 3)][2];
+ break;
+ case 2:
+ data = m_dma_offset[BIT(offset, 3)][3];
+ break;
+ case 3:
+ data = m_dma_offset[BIT(offset, 3)][1];
+ break;
+ case 7:
+ data = m_dma_offset[BIT(offset, 3)][0];
+ break;
+ }
+ return data;
+}
+
+
+WRITE8_MEMBER( southbridge_device::at_page8_w )
+{
+ m_at_pages[offset % 0x10] = data;
+
+ switch(offset % 8)
+ {
+ case 1:
+ m_dma_offset[BIT(offset, 3)][2] = data;
+ break;
+ case 2:
+ m_dma_offset[BIT(offset, 3)][3] = data;
+ break;
+ case 3:
+ m_dma_offset[BIT(offset, 3)][1] = data;
+ break;
+ case 7:
+ m_dma_offset[BIT(offset, 3)][0] = data;
+ break;
+ }
+}
+
+
+WRITE_LINE_MEMBER( southbridge_device::pc_dma_hrq_changed )
+{
+ m_maincpu->set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE);
+
+ /* Assert HLDA */
+ m_dma8237_2->hack_w( state );
+}
+
+READ8_MEMBER(southbridge_device::pc_dma_read_byte)
+{
+ address_space& prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space
+ if(m_dma_channel == -1)
+ return 0xff;
+ UINT8 result;
+ offs_t page_offset = (((offs_t) m_dma_offset[0][m_dma_channel]) << 16) & 0xFF0000;
+
+ result = prog_space.read_byte(page_offset + offset);
+ return result;
+}
+
+
+WRITE8_MEMBER(southbridge_device::pc_dma_write_byte)
+{
+ address_space& prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space
+ if(m_dma_channel == -1)
+ return;
+ offs_t page_offset = (((offs_t) m_dma_offset[0][m_dma_channel]) << 16) & 0xFF0000;
+
+ prog_space.write_byte(page_offset + offset, data);
+}
+
+
+READ8_MEMBER(southbridge_device::pc_dma_read_word)
+{
+ address_space& prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space
+ if(m_dma_channel == -1)
+ return 0xff;
+ UINT16 result;
+ offs_t page_offset = (((offs_t) m_dma_offset[1][m_dma_channel & 3]) << 16) & 0xFE0000;
+
+ result = prog_space.read_word(page_offset + ( offset << 1 ) );
+ m_dma_high_byte = result & 0xFF00;
+
+ return result & 0xFF;
+}
+
+
+WRITE8_MEMBER(southbridge_device::pc_dma_write_word)
+{
+ address_space& prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space
+ if(m_dma_channel == -1)
+ return;
+ offs_t page_offset = (((offs_t) m_dma_offset[1][m_dma_channel & 3]) << 16) & 0xFE0000;
+
+ prog_space.write_word(page_offset + ( offset << 1 ), m_dma_high_byte | data);
+}
+
+
+READ8_MEMBER( southbridge_device::pc_dma8237_0_dack_r ) { return m_isabus->dack_r(0); }
+READ8_MEMBER( southbridge_device::pc_dma8237_1_dack_r ) { return m_isabus->dack_r(1); }
+READ8_MEMBER( southbridge_device::pc_dma8237_2_dack_r ) { return m_isabus->dack_r(2); }
+READ8_MEMBER( southbridge_device::pc_dma8237_3_dack_r ) { return m_isabus->dack_r(3); }
+READ8_MEMBER( southbridge_device::pc_dma8237_5_dack_r ) { return m_isabus->dack_r(5); }
+READ8_MEMBER( southbridge_device::pc_dma8237_6_dack_r ) { return m_isabus->dack_r(6); }
+READ8_MEMBER( southbridge_device::pc_dma8237_7_dack_r ) { return m_isabus->dack_r(7); }
+
+
+WRITE8_MEMBER( southbridge_device::pc_dma8237_0_dack_w ){ m_isabus->dack_w(0, data); }
+WRITE8_MEMBER( southbridge_device::pc_dma8237_1_dack_w ){ m_isabus->dack_w(1, data); }
+WRITE8_MEMBER( southbridge_device::pc_dma8237_2_dack_w ){ m_isabus->dack_w(2, data); }
+WRITE8_MEMBER( southbridge_device::pc_dma8237_3_dack_w ){ m_isabus->dack_w(3, data); }
+WRITE8_MEMBER( southbridge_device::pc_dma8237_5_dack_w ){ m_isabus->dack_w(5, data); }
+WRITE8_MEMBER( southbridge_device::pc_dma8237_6_dack_w ){ m_isabus->dack_w(6, data); }
+WRITE8_MEMBER( southbridge_device::pc_dma8237_7_dack_w ){ m_isabus->dack_w(7, data); }
+
+WRITE_LINE_MEMBER( southbridge_device::at_dma8237_out_eop )
+{
+ m_cur_eop = state == ASSERT_LINE;
+ if(m_dma_channel != -1)
+ m_isabus->eop_w(m_dma_channel, m_cur_eop ? ASSERT_LINE : CLEAR_LINE );
+}
+
+void southbridge_device::pc_select_dma_channel(int channel, bool state)
+{
+ if(!state) {
+ m_dma_channel = channel;
+ if(m_cur_eop)
+ m_isabus->eop_w(channel, ASSERT_LINE );
+
+ } else if(m_dma_channel == channel) {
+ m_dma_channel = -1;
+ if(m_cur_eop)
+ m_isabus->eop_w(channel, CLEAR_LINE );
+ }
+}
+
+
+WRITE_LINE_MEMBER( southbridge_device::pc_dack0_w ) { pc_select_dma_channel(0, state); }
+WRITE_LINE_MEMBER( southbridge_device::pc_dack1_w ) { pc_select_dma_channel(1, state); }
+WRITE_LINE_MEMBER( southbridge_device::pc_dack2_w ) { pc_select_dma_channel(2, state); }
+WRITE_LINE_MEMBER( southbridge_device::pc_dack3_w ) { pc_select_dma_channel(3, state); }
+WRITE_LINE_MEMBER( southbridge_device::pc_dack4_w ) { m_dma8237_1->hack_w( state ? 0 : 1); } // it's inverted
+WRITE_LINE_MEMBER( southbridge_device::pc_dack5_w ) { pc_select_dma_channel(5, state); }
+WRITE_LINE_MEMBER( southbridge_device::pc_dack6_w ) { pc_select_dma_channel(6, state); }
+WRITE_LINE_MEMBER( southbridge_device::pc_dack7_w ) { pc_select_dma_channel(7, state); }
+
+READ8_MEMBER( southbridge_device::at_portb_r )
+{
+ UINT8 data = m_at_speaker;
+ data &= ~0xd0; /* AT BIOS don't likes this being set */
+
+ /* 0x10 is the dram refresh line bit on the 5170, just a timer here, 15.085us. */
+ data |= m_refresh ? 0x10 : 0;
+
+ if (m_pit_out2)
+ data |= 0x20;
+ else
+ data &= ~0x20; /* ps2m30 wants this */
+
+ return data;
+}
+
+WRITE8_MEMBER( southbridge_device::at_portb_w )
+{
+ m_at_speaker = data;
+ m_pit8254->write_gate2(BIT(data, 0));
+ at_speaker_set_spkrdata( BIT(data, 1));
+ m_channel_check = BIT(data, 3);
+ m_isabus->set_nmi_state((m_nmi_enabled==0) && (m_channel_check==0));
+}
+
+READ8_MEMBER( southbridge_device::at_dma8237_2_r )
+{
+ return m_dma8237_2->read( space, offset / 2);
+}
+
+WRITE8_MEMBER( southbridge_device::at_dma8237_2_w )
+{
+ m_dma8237_2->write( space, offset / 2, data);
+}
+
+READ8_MEMBER( southbridge_device::at_keybc_r )
+{
+ switch (offset)
+ {
+ case 0: return m_keybc->data_r(space, 0);
+ case 1: return at_portb_r(space, 0);
+ }
+
+ return 0xff;
+}
+
+WRITE8_MEMBER( southbridge_device::at_keybc_w )
+{
+ switch (offset)
+ {
+ case 0: m_keybc->data_w(space, 0, data); break;
+ case 1: at_portb_w(space, 0, data); break;
+ }
+}
+
+
+WRITE8_MEMBER( southbridge_device::write_rtc )
+{
+ if (offset==0) {
+ m_nmi_enabled = BIT(data,7);
+ m_isabus->set_nmi_state((m_nmi_enabled==0) && (m_channel_check==0));
+ m_ds12885->write(space,0,data);
+ }
+ else {
+ m_ds12885->write(space,offset,data);
+ }
+}
diff --git a/src/emu/bus/lpci/southbridge.h b/src/emu/bus/lpci/southbridge.h
new file mode 100644
index 00000000000..1fde011f414
--- /dev/null
+++ b/src/emu/bus/lpci/southbridge.h
@@ -0,0 +1,129 @@
+#pragma once
+
+#ifndef __SOUTHBRIDGE_H__
+#define __SOUTHBRIDGE_H__
+
+#include "emu.h"
+
+#include "machine/ins8250.h"
+#include "machine/ds128x.h"
+#include "machine/pic8259.h"
+#include "machine/pit8253.h"
+
+#include "machine/ataintf.h"
+#include "machine/at_keybc.h"
+
+#include "imagedev/harddriv.h"
+#include "pci.h"
+
+#include "sound/dac.h"
+#include "sound/speaker.h"
+#include "machine/ram.h"
+#include "machine/nvram.h"
+#include "bus/isa/isa.h"
+#include "bus/isa/isa_cards.h"
+
+#include "machine/pc_lpt.h"
+#include "bus/pc_kbd/pc_kbdc.h"
+
+#include "machine/am9517a.h"
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> southbridge_device
+
+class southbridge_device :
+ public device_t
+{
+public:
+ // construction/destruction
+ southbridge_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
+
+ // optional information overrides
+ virtual machine_config_constructor device_mconfig_additions() const;
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+public:
+
+ required_device<cpu_device> m_maincpu;
+ required_device<pic8259_device> m_pic8259_master;
+ required_device<pic8259_device> m_pic8259_slave;
+ required_device<am9517a_device> m_dma8237_1;
+ required_device<am9517a_device> m_dma8237_2;
+ required_device<pit8254_device> m_pit8254;
+ required_device<at_keyboard_controller_device> m_keybc;
+ required_device<isa16_device> m_isabus;
+ required_device<speaker_sound_device> m_speaker;
+ required_device<ds12885_device> m_ds12885;
+ required_device<pc_kbdc_device> m_pc_kbdc;
+ required_device<bus_master_ide_controller_device> m_ide;
+ required_device<bus_master_ide_controller_device> m_ide2;
+ DECLARE_READ8_MEMBER(at_page8_r);
+ DECLARE_WRITE8_MEMBER(at_page8_w);
+ DECLARE_READ8_MEMBER(at_portb_r);
+ DECLARE_WRITE8_MEMBER(at_portb_w);
+ DECLARE_READ8_MEMBER(get_slave_ack);
+ DECLARE_WRITE_LINE_MEMBER(at_pit8254_out0_changed);
+ DECLARE_WRITE_LINE_MEMBER(at_pit8254_out1_changed);
+ DECLARE_WRITE_LINE_MEMBER(at_pit8254_out2_changed);
+ DECLARE_WRITE_LINE_MEMBER(pc_dma_hrq_changed);
+ DECLARE_READ8_MEMBER(pc_dma8237_0_dack_r);
+ DECLARE_READ8_MEMBER(pc_dma8237_1_dack_r);
+ DECLARE_READ8_MEMBER(pc_dma8237_2_dack_r);
+ DECLARE_READ8_MEMBER(pc_dma8237_3_dack_r);
+ DECLARE_READ8_MEMBER(pc_dma8237_5_dack_r);
+ DECLARE_READ8_MEMBER(pc_dma8237_6_dack_r);
+ DECLARE_READ8_MEMBER(pc_dma8237_7_dack_r);
+ DECLARE_WRITE8_MEMBER(pc_dma8237_0_dack_w);
+ DECLARE_WRITE8_MEMBER(pc_dma8237_1_dack_w);
+ DECLARE_WRITE8_MEMBER(pc_dma8237_2_dack_w);
+ DECLARE_WRITE8_MEMBER(pc_dma8237_3_dack_w);
+ DECLARE_WRITE8_MEMBER(pc_dma8237_5_dack_w);
+ DECLARE_WRITE8_MEMBER(pc_dma8237_6_dack_w);
+ DECLARE_WRITE8_MEMBER(pc_dma8237_7_dack_w);
+ DECLARE_WRITE_LINE_MEMBER(at_dma8237_out_eop);
+ DECLARE_WRITE_LINE_MEMBER(pc_dack0_w);
+ DECLARE_WRITE_LINE_MEMBER(pc_dack1_w);
+ DECLARE_WRITE_LINE_MEMBER(pc_dack2_w);
+ DECLARE_WRITE_LINE_MEMBER(pc_dack3_w);
+ DECLARE_WRITE_LINE_MEMBER(pc_dack4_w);
+ DECLARE_WRITE_LINE_MEMBER(pc_dack5_w);
+ DECLARE_WRITE_LINE_MEMBER(pc_dack6_w);
+ DECLARE_WRITE_LINE_MEMBER(pc_dack7_w);
+ DECLARE_READ8_MEMBER(ide_read_cs1_r);
+ DECLARE_WRITE8_MEMBER(ide_write_cs1_w);
+ DECLARE_READ8_MEMBER(ide2_read_cs1_r);
+ DECLARE_WRITE8_MEMBER(ide2_write_cs1_w);
+ DECLARE_READ8_MEMBER(at_dma8237_2_r);
+ DECLARE_WRITE8_MEMBER(at_dma8237_2_w);
+ DECLARE_READ8_MEMBER(at_keybc_r);
+ DECLARE_WRITE8_MEMBER(at_keybc_w);
+ DECLARE_WRITE8_MEMBER(write_rtc);
+ DECLARE_READ8_MEMBER(pc_dma_read_byte);
+ DECLARE_WRITE8_MEMBER(pc_dma_write_byte);
+ DECLARE_READ8_MEMBER(pc_dma_read_word);
+ DECLARE_WRITE8_MEMBER(pc_dma_write_word);
+protected:
+ UINT8 m_at_spkrdata;
+ UINT8 m_pit_out2;
+ int m_dma_channel;
+ bool m_cur_eop;
+ UINT8 m_dma_offset[2][4];
+ UINT8 m_at_pages[0x10];
+ UINT16 m_dma_high_byte;
+ UINT8 m_at_speaker;
+ bool m_refresh;
+ void at_speaker_set_spkrdata(UINT8 data);
+
+ UINT8 m_channel_check;
+ UINT8 m_nmi_enabled;
+
+ void pc_select_dma_channel(int channel, bool state);
+};
+
+#endif /* __SOUTHBRIDGE_H__ */