mirror of
https://github.com/holub/mame
synced 2025-04-24 09:20:02 +03:00
xbox_pci.cpp: smbus controller actually supports two buses (nw)
This commit is contained in:
parent
a5d6b7c5b8
commit
6605110fad
@ -119,8 +119,10 @@ public:
|
||||
|
||||
auto interrupt_handler() { return m_interrupt_handler.bind(); }
|
||||
|
||||
DECLARE_READ32_MEMBER(smbus_r);
|
||||
DECLARE_WRITE32_MEMBER(smbus_w);
|
||||
DECLARE_READ32_MEMBER(smbus0_r);
|
||||
DECLARE_WRITE32_MEMBER(smbus0_w);
|
||||
DECLARE_READ32_MEMBER(smbus1_r);
|
||||
DECLARE_WRITE32_MEMBER(smbus1_w);
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
@ -137,10 +139,12 @@ private:
|
||||
int rw;
|
||||
smbus_interface *devices[128];
|
||||
uint32_t words[256 / 4];
|
||||
} smbusst;
|
||||
} smbusst[2];
|
||||
void smbus_io0(address_map &map);
|
||||
void smbus_io1(address_map &map);
|
||||
void smbus_io2(address_map &map);
|
||||
uint32_t smbus_read(int bus, offs_t offset, uint32_t mem_mask);
|
||||
void smbus_write(int bus, offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(MCPX_SMBUS, mcpx_smbus_device)
|
||||
|
@ -853,9 +853,9 @@ void xbox_base_state::xbox_base(machine_config &config)
|
||||
NV2A_RAM(config, ":pci:00.3", 0);
|
||||
MCPX_ISALPC(config, ":pci:01.0", 0, 0).interrupt_output().set(FUNC(xbox_base_state::maincpu_interrupt));
|
||||
MCPX_SMBUS(config, ":pci:01.1", 0).interrupt_handler().set(FUNC(xbox_base_state::smbus_interrupt_changed));
|
||||
XBOX_PIC16LC(config, ":pci:01.1:10", 0);
|
||||
XBOX_CX25871(config, ":pci:01.1:45", 0);
|
||||
XBOX_EEPROM(config, ":pci:01.1:54", 0);
|
||||
XBOX_PIC16LC(config, ":pci:01.1:110", 0); // these 3 are on smbus number 1
|
||||
XBOX_CX25871(config, ":pci:01.1:145", 0);
|
||||
XBOX_EEPROM(config, ":pci:01.1:154", 0);
|
||||
MCPX_OHCI(config, ":pci:02.0", 0).interrupt_handler().set(FUNC(xbox_base_state::ohci_usb_interrupt_changed));
|
||||
MCPX_OHCI(config, ":pci:03.0", 0);
|
||||
MCPX_ETH(config, ":pci:04.0", 0);
|
||||
|
@ -291,12 +291,12 @@ DEFINE_DEVICE_TYPE(MCPX_SMBUS, mcpx_smbus_device, "mcpx_smbus", "MCPX SMBus Cont
|
||||
|
||||
void mcpx_smbus_device::smbus_io0(address_map &map)
|
||||
{
|
||||
map(0x00000000, 0x0000000f).noprw();
|
||||
map(0x00000000, 0x0000000f).rw(FUNC(mcpx_smbus_device::smbus0_r), FUNC(mcpx_smbus_device::smbus0_w));
|
||||
}
|
||||
|
||||
void mcpx_smbus_device::smbus_io1(address_map &map)
|
||||
{
|
||||
map(0x00000000, 0x0000000f).rw(FUNC(mcpx_smbus_device::smbus_r), FUNC(mcpx_smbus_device::smbus_w));
|
||||
map(0x00000000, 0x0000000f).rw(FUNC(mcpx_smbus_device::smbus1_r), FUNC(mcpx_smbus_device::smbus1_w));
|
||||
}
|
||||
|
||||
void mcpx_smbus_device::smbus_io2(address_map &map)
|
||||
@ -322,8 +322,9 @@ void mcpx_smbus_device::device_start()
|
||||
add_map(0x00000020, M_IO, FUNC(mcpx_smbus_device::smbus_io2));
|
||||
bank_infos[2].adr = 0xc200;
|
||||
memset(&smbusst, 0, sizeof(smbusst));
|
||||
for (int n = 0; n < 128; n++)
|
||||
smbusst.devices[n] = nullptr;
|
||||
for (int b = 0; b < 2; b++)
|
||||
for (int a = 0; a < 128; a++)
|
||||
smbusst[b].devices[a] = nullptr;
|
||||
for (device_t &d : subdevices())
|
||||
{
|
||||
const char *t = d.tag();
|
||||
@ -336,12 +337,16 @@ void mcpx_smbus_device::device_start()
|
||||
{
|
||||
l++;
|
||||
int address = strtol(t + l, nullptr, 16);
|
||||
if ((address > 0) && (address < 128))
|
||||
int bus;
|
||||
|
||||
bus = address >> 8;
|
||||
address = address & 0xff;
|
||||
if ((address > 0) && (address < 128) && (bus >= 0) && (bus <= 1))
|
||||
{
|
||||
if (smbusst.devices[address] == nullptr)
|
||||
if (smbusst[bus].devices[address] == nullptr)
|
||||
{
|
||||
smbus_interface *i = dynamic_cast<smbus_interface *>(&d);
|
||||
smbusst.devices[address] = i;
|
||||
smbusst[bus].devices[address] = i;
|
||||
}
|
||||
else
|
||||
logerror("Duplicate address for SMBus device with tag %s\n", t);
|
||||
@ -359,44 +364,44 @@ void mcpx_smbus_device::device_reset()
|
||||
pci_device::device_reset();
|
||||
}
|
||||
|
||||
READ32_MEMBER(mcpx_smbus_device::smbus_r)
|
||||
uint32_t mcpx_smbus_device::smbus_read(int bus, offs_t offset, uint32_t mem_mask)
|
||||
{
|
||||
if (offset == 0) // 0 smbus status
|
||||
smbusst.words[offset] = (smbusst.words[offset] & ~0xffff) | ((smbusst.status & 0xffff) << 0);
|
||||
smbusst[bus].words[offset] = (smbusst[bus].words[offset] & ~0xffff) | ((smbusst[bus].status & 0xffff) << 0);
|
||||
if (offset == 1) // 6 smbus data
|
||||
smbusst.words[offset] = (smbusst.words[offset] & ~(0xffff << 16)) | ((smbusst.data & 0xffff) << 16);
|
||||
return smbusst.words[offset];
|
||||
smbusst[bus].words[offset] = (smbusst[bus].words[offset] & ~(0xffff << 16)) | ((smbusst[bus].data & 0xffff) << 16);
|
||||
return smbusst[bus].words[offset];
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(mcpx_smbus_device::smbus_w)
|
||||
void mcpx_smbus_device::smbus_write(int bus, offs_t offset, uint32_t data, uint32_t mem_mask)
|
||||
{
|
||||
COMBINE_DATA(smbusst.words);
|
||||
COMBINE_DATA(smbusst[bus].words);
|
||||
if ((offset == 0) && (ACCESSING_BITS_0_7 || ACCESSING_BITS_8_15)) // 0 smbus status
|
||||
{
|
||||
if (!((smbusst.status ^ data) & 0x10)) // clearing interrupt
|
||||
if (!((smbusst[bus].status ^ data) & 0x10)) // clearing interrupt
|
||||
{
|
||||
if (m_interrupt_handler)
|
||||
m_interrupt_handler(0);
|
||||
}
|
||||
smbusst.status &= ~data;
|
||||
smbusst[bus].status &= ~data;
|
||||
}
|
||||
if ((offset == 0) && ACCESSING_BITS_16_23) // 2 smbus control
|
||||
{
|
||||
data = data >> 16;
|
||||
smbusst.control = data;
|
||||
int cycletype = smbusst.control & 7;
|
||||
if (smbusst.control & 8) { // start
|
||||
smbusst[bus].control = data;
|
||||
int cycletype = smbusst[bus].control & 7;
|
||||
if (smbusst[bus].control & 8) { // start
|
||||
if ((cycletype & 6) == 2)
|
||||
{
|
||||
if (smbusst.devices[smbusst.address])
|
||||
if (smbusst.rw == 0)
|
||||
smbusst.devices[smbusst.address]->execute_command(smbusst.command, smbusst.rw, smbusst.data);
|
||||
if (smbusst[bus].devices[smbusst[bus].address])
|
||||
if (smbusst[bus].rw == 0)
|
||||
smbusst[bus].devices[smbusst[bus].address]->execute_command(smbusst[bus].command, smbusst[bus].rw, smbusst[bus].data);
|
||||
else
|
||||
smbusst.data = smbusst.devices[smbusst.address]->execute_command(smbusst.command, smbusst.rw, smbusst.data);
|
||||
smbusst[bus].data = smbusst[bus].devices[smbusst[bus].address]->execute_command(smbusst[bus].command, smbusst[bus].rw, smbusst[bus].data);
|
||||
else
|
||||
logerror("SMBUS: access to missing device at address %d\n", smbusst.address);
|
||||
smbusst.status |= 0x10;
|
||||
if (smbusst.control & 0x10)
|
||||
logerror("SMBUS: access to missing device at bus %d address %d\n", bus, smbusst[bus].address);
|
||||
smbusst[bus].status |= 0x10;
|
||||
if (smbusst[bus].control & 0x10)
|
||||
{
|
||||
if (m_interrupt_handler)
|
||||
m_interrupt_handler(1);
|
||||
@ -406,16 +411,36 @@ WRITE32_MEMBER(mcpx_smbus_device::smbus_w)
|
||||
}
|
||||
if ((offset == 1) && ACCESSING_BITS_0_7) // 4 smbus address
|
||||
{
|
||||
smbusst.address = data >> 1;
|
||||
smbusst.rw = data & 1;
|
||||
smbusst[bus].address = data >> 1;
|
||||
smbusst[bus].rw = data & 1;
|
||||
}
|
||||
if ((offset == 1) && (ACCESSING_BITS_16_23 || ACCESSING_BITS_16_31)) // 6 smbus data
|
||||
{
|
||||
data = data >> 16;
|
||||
smbusst.data = data;
|
||||
smbusst[bus].data = data;
|
||||
}
|
||||
if ((offset == 2) && ACCESSING_BITS_0_7) // 8 smbus command
|
||||
smbusst.command = data;
|
||||
smbusst[bus].command = data;
|
||||
}
|
||||
|
||||
READ32_MEMBER(mcpx_smbus_device::smbus0_r)
|
||||
{
|
||||
return smbus_read(0, offset, mem_mask);
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(mcpx_smbus_device::smbus0_w)
|
||||
{
|
||||
smbus_write(0, offset, data, mem_mask);
|
||||
}
|
||||
|
||||
READ32_MEMBER(mcpx_smbus_device::smbus1_r)
|
||||
{
|
||||
return smbus_read(1, offset, mem_mask);
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(mcpx_smbus_device::smbus1_w)
|
||||
{
|
||||
smbus_write(1, offset, data, mem_mask);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user