mame/src/mess/machine/i82439tx.c

332 lines
8.0 KiB
C

/***************************************************************************
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),
pci_device_interface( mconfig, *this )
{
}
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:
result = m_regs[(offset - 0x50) / 4];
break;
default:
fatalerror("i82439tx_pci_read(): Unexpected PCI read 0x%02X\n", offset);
break;
}
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;
}
COMBINE_DATA(&m_regs[(offset - 0x50) / 4]);
break;
default:
fatalerror("i82439tx_pci_write(): Unexpected PCI write 0x%02X <-- 0x%08X\n", offset, data);
break;
}
}
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void i82439tx_device::device_config_complete()
{
// inherit a copy of the static data
const i82439tx_interface *intf = reinterpret_cast<const i82439tx_interface *>(static_config());
if (intf != NULL)
{
*static_cast<i82439tx_interface *>(this) = *intf;
}
// or initialize to defaults if none provided
else
{
memset(&m_cputag, 0, sizeof(m_cputag));
memset(&m_rom_region, 0, sizeof(m_rom_region));
}
m_shortname = "i82439tx";
}
//-------------------------------------------------
// 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_cputag);
assert(cpu != NULL);
m_space = cpu->memory().space(AS_PROGRAM);
/* get rom region */
m_rom = machine().root_device().memregion(m_rom_region)->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;
/* 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);
}