diff options
Diffstat (limited to 'src/mess/machine/i82371ab.c')
-rw-r--r-- | src/mess/machine/i82371ab.c | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/src/mess/machine/i82371ab.c b/src/mess/machine/i82371ab.c new file mode 100644 index 00000000000..81e51538a5a --- /dev/null +++ b/src/mess/machine/i82371ab.c @@ -0,0 +1,263 @@ +/*************************************************************************** + + 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), + 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; + } +} + +static IRQ_CALLBACK(at_irq_callback) +{ + device_t *pic = device->machine().device(":pcibus:1:i82371ab:pic8259_master"); + return pic8259_acknowledge(pic); +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void i82371ab_device::device_start() +{ + southbridge_device::device_start(); + /* setup save states */ + save_item(NAME(m_regs)); + + device_set_irq_callback(machine().device(":maincpu"), at_irq_callback); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void i82371ab_device::device_reset() +{ + southbridge_device::device_reset(); + 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; +} + |