trunk/src/emu/bus/lpci/i82371ab.c
r0 | r241729 | |
| 1 | /*************************************************************************** |
| 2 | |
| 3 | Intel 82371AB PCI IDE ISA Xcelerator (PIIX4) |
| 4 | |
| 5 | Part of the Intel 430TX chipset |
| 6 | |
| 7 | - Integrated IDE Controller |
| 8 | - Enhanced DMA Controller based on two 82C37 |
| 9 | - Interrupt Controller based on two 82C59 |
| 10 | - Timers based on 82C54 |
| 11 | - USB |
| 12 | - SMBus |
| 13 | - Real Time Clock based on MC146818 |
| 14 | |
| 15 | ***************************************************************************/ |
| 16 | |
| 17 | #include "emu.h" |
| 18 | #include "i82371ab.h" |
| 19 | |
| 20 | const device_type I82371AB = &device_creator<i82371ab_device>; |
| 21 | |
| 22 | |
| 23 | i82371ab_device::i82371ab_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 24 | : southbridge_device(mconfig, I82371AB, "Intel 82371AB", tag, owner, clock, "i82371ab", __FILE__), |
| 25 | pci_device_interface( mconfig, *this ) |
| 26 | { |
| 27 | } |
| 28 | |
| 29 | UINT32 i82371ab_device::pci_isa_r(device_t *busdevice, int offset, UINT32 mem_mask) |
| 30 | { |
| 31 | UINT32 result = m_regs[0][offset] | |
| 32 | m_regs[0][offset+1] << 8 | |
| 33 | m_regs[0][offset+2] << 16| |
| 34 | m_regs[0][offset+3] << 24; |
| 35 | |
| 36 | logerror("i82371ab_pci_isa_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask); |
| 37 | |
| 38 | return result; |
| 39 | } |
| 40 | |
| 41 | void i82371ab_device::pci_isa_w(device_t *busdevice, int offset, UINT32 data, UINT32 mem_mask) |
| 42 | { |
| 43 | UINT32 cdata = 0; |
| 44 | int i; |
| 45 | COMBINE_DATA(&cdata); |
| 46 | |
| 47 | logerror("i82371ab_pci_isa_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask); |
| 48 | |
| 49 | for(i = 0; i < 4; i++, offset++, cdata >>= 8) |
| 50 | { |
| 51 | switch (offset) |
| 52 | { |
| 53 | case 0x04: |
| 54 | /* clear reserved bits */ |
| 55 | m_regs[0][offset] = cdata & 0x05; |
| 56 | break; |
| 57 | case 0x06: |
| 58 | /* set new status */ |
| 59 | m_regs[0][offset] |= 0x80; |
| 60 | break; |
| 61 | case 0x07: |
| 62 | m_regs[0][offset] |= 0x02; |
| 63 | break; |
| 64 | } |
| 65 | } |
| 66 | } |
| 67 | |
| 68 | UINT32 i82371ab_device::pci_ide_r(device_t *busdevice, int offset, UINT32 mem_mask) |
| 69 | { |
| 70 | UINT32 result = m_regs[1][offset] | |
| 71 | m_regs[1][offset+1] << 8 | |
| 72 | m_regs[1][offset+2] << 16| |
| 73 | m_regs[1][offset+3] << 24; |
| 74 | |
| 75 | logerror("i82371ab_pci_ide_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask); |
| 76 | |
| 77 | return result; |
| 78 | } |
| 79 | |
| 80 | void i82371ab_device::pci_ide_w(device_t *busdevice, int offset, UINT32 data, UINT32 mem_mask) |
| 81 | { |
| 82 | UINT32 cdata = 0; |
| 83 | int i; |
| 84 | COMBINE_DATA(&cdata); |
| 85 | |
| 86 | logerror("i82371ab_pci_isa_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask); |
| 87 | |
| 88 | for(i = 0; i < 4; i++, offset++, cdata >>= 8) |
| 89 | { |
| 90 | switch (offset) |
| 91 | { |
| 92 | case 0x04: |
| 93 | /* clear reserved bits */ |
| 94 | m_regs[1][offset] = cdata & 0x05; |
| 95 | break; |
| 96 | case 0x06: |
| 97 | /* set new status */ |
| 98 | m_regs[1][offset] |= 0x80; |
| 99 | break; |
| 100 | case 0x07: |
| 101 | m_regs[1][offset] |= 0x02; |
| 102 | break; |
| 103 | } |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | UINT32 i82371ab_device::pci_usb_r(device_t *busdevice, int offset, UINT32 mem_mask) |
| 108 | { |
| 109 | UINT32 result = m_regs[2][offset] | |
| 110 | m_regs[2][offset+1] << 8 | |
| 111 | m_regs[2][offset+2] << 16| |
| 112 | m_regs[2][offset+3] << 24; |
| 113 | |
| 114 | logerror("i82371ab_pci_usb_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask); |
| 115 | |
| 116 | return result; |
| 117 | } |
| 118 | |
| 119 | void i82371ab_device::pci_usb_w(device_t *busdevice, int offset, UINT32 data, UINT32 mem_mask) |
| 120 | { |
| 121 | UINT32 cdata = 0; |
| 122 | int i; |
| 123 | COMBINE_DATA(&cdata); |
| 124 | |
| 125 | logerror("i82371ab_pci_isa_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask); |
| 126 | |
| 127 | for(i = 0; i < 4; i++, offset++, cdata >>= 8) |
| 128 | { |
| 129 | switch (offset) |
| 130 | { |
| 131 | case 0x04: |
| 132 | /* clear reserved bits */ |
| 133 | m_regs[2][offset] = cdata & 0x05; |
| 134 | break; |
| 135 | case 0x06: |
| 136 | /* set new status */ |
| 137 | m_regs[2][offset] |= 0x80; |
| 138 | break; |
| 139 | case 0x07: |
| 140 | m_regs[2][offset] |= 0x02; |
| 141 | break; |
| 142 | } |
| 143 | } |
| 144 | } |
| 145 | |
| 146 | UINT32 i82371ab_device::pci_acpi_r(device_t *busdevice, int offset, UINT32 mem_mask) |
| 147 | { |
| 148 | UINT32 result = m_regs[3][offset] | |
| 149 | m_regs[3][offset+1] << 8 | |
| 150 | m_regs[3][offset+2] << 16| |
| 151 | m_regs[3][offset+3] << 24; |
| 152 | |
| 153 | logerror("i82371ab_pci_acpi_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask); |
| 154 | |
| 155 | return result; |
| 156 | } |
| 157 | |
| 158 | void i82371ab_device::pci_acpi_w(device_t *busdevice, int offset, UINT32 data, UINT32 mem_mask) |
| 159 | { |
| 160 | UINT32 cdata = 0; |
| 161 | int i; |
| 162 | COMBINE_DATA(&cdata); |
| 163 | |
| 164 | logerror("i82371ab_pci_isa_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask); |
| 165 | |
| 166 | for(i = 0; i < 4; i++, offset++, cdata >>= 8) |
| 167 | { |
| 168 | switch (offset) |
| 169 | { |
| 170 | case 0x04: |
| 171 | /* clear reserved bits */ |
| 172 | m_regs[3][offset] = cdata & 0x05; |
| 173 | break; |
| 174 | case 0x06: |
| 175 | /* set new status */ |
| 176 | m_regs[3][offset] |= 0x80; |
| 177 | break; |
| 178 | case 0x07: |
| 179 | m_regs[3][offset] |= 0x02; |
| 180 | break; |
| 181 | } |
| 182 | } |
| 183 | } |
| 184 | |
| 185 | UINT32 i82371ab_device::pci_read(pci_bus_device *pcibus, int function, int offset, UINT32 mem_mask) |
| 186 | { |
| 187 | switch (function) |
| 188 | { |
| 189 | case 0: return pci_isa_r(pcibus, offset, mem_mask); |
| 190 | case 1: return pci_ide_r(pcibus, offset, mem_mask); |
| 191 | case 2: return pci_usb_r(pcibus, offset, mem_mask); |
| 192 | case 3: return pci_acpi_r(pcibus, offset, mem_mask); |
| 193 | } |
| 194 | |
| 195 | logerror("i82371ab_pci_read: read from undefined function %d\n", function); |
| 196 | |
| 197 | return 0; |
| 198 | } |
| 199 | |
| 200 | void i82371ab_device::pci_write(pci_bus_device *pcibus, int function, int offset, UINT32 data, UINT32 mem_mask) |
| 201 | { |
| 202 | switch (function) |
| 203 | { |
| 204 | case 0: pci_isa_w(pcibus, offset, data, mem_mask); break; |
| 205 | case 1: pci_ide_w(pcibus, offset, data, mem_mask); break; |
| 206 | case 2: pci_usb_w(pcibus, offset, data, mem_mask); break; |
| 207 | case 3: pci_acpi_w(pcibus, offset, data, mem_mask); break; |
| 208 | } |
| 209 | } |
| 210 | |
| 211 | //------------------------------------------------- |
| 212 | // device_start - device-specific startup |
| 213 | //------------------------------------------------- |
| 214 | |
| 215 | void i82371ab_device::device_start() |
| 216 | { |
| 217 | southbridge_device::device_start(); |
| 218 | /* setup save states */ |
| 219 | save_item(NAME(m_regs)); |
| 220 | } |
| 221 | |
| 222 | //------------------------------------------------- |
| 223 | // device_reset - device-specific reset |
| 224 | //------------------------------------------------- |
| 225 | |
| 226 | void i82371ab_device::device_reset() |
| 227 | { |
| 228 | southbridge_device::device_reset(); |
| 229 | memset(m_regs, 0, sizeof(m_regs)); |
| 230 | UINT32 (*regs32)[64] = (UINT32 (*)[64])(m_regs); |
| 231 | |
| 232 | /* isa */ |
| 233 | regs32[0][0x00] = 0x71108086; |
| 234 | regs32[0][0x04] = 0x00000000; |
| 235 | regs32[0][0x08] = 0x06010000; |
| 236 | regs32[0][0x0c] = 0x00800000; |
| 237 | |
| 238 | /* ide */ |
| 239 | regs32[1][0x00] = 0x71118086; |
| 240 | regs32[1][0x04] = 0x02800000; |
| 241 | regs32[1][0x08] = 0x01018000; |
| 242 | regs32[1][0x0c] = 0x00000000; |
| 243 | |
| 244 | /* usb */ |
| 245 | regs32[2][0x00] = 0x71128086; |
| 246 | regs32[2][0x04] = 0x02800000; |
| 247 | regs32[2][0x08] = 0x0c030000; |
| 248 | regs32[2][0x0c] = 0x00000000; |
| 249 | |
| 250 | /* acpi */ |
| 251 | regs32[3][0x00] = 0x71138086; |
| 252 | regs32[3][0x04] = 0x02800000; |
| 253 | regs32[3][0x08] = 0x06800000; |
| 254 | regs32[3][0x0c] = 0x02800000; |
| 255 | } |
trunk/src/emu/bus/lpci/i82371sb.c
r0 | r241729 | |
| 1 | /*************************************************************************** |
| 2 | |
| 3 | Intel 82371SB PCI IDE ISA Xcelerator (PIIX3) |
| 4 | |
| 5 | Part of the Intel 430TX chipset |
| 6 | |
| 7 | - Integrated IDE Controller |
| 8 | - Enhanced DMA Controller based on two 82C37 |
| 9 | - Interrupt Controller based on two 82C59 |
| 10 | - Timers based on 82C54 |
| 11 | - USB |
| 12 | - SMBus |
| 13 | - Real Time Clock based on MC146818 |
| 14 | |
| 15 | ***************************************************************************/ |
| 16 | |
| 17 | #include "emu.h" |
| 18 | #include "i82371sb.h" |
| 19 | |
| 20 | |
| 21 | /*************************************************************************** |
| 22 | IMPLEMENTATION |
| 23 | ***************************************************************************/ |
| 24 | |
| 25 | const device_type I82371SB = &device_creator<i82371sb_device>; |
| 26 | |
| 27 | |
| 28 | i82371sb_device::i82371sb_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 29 | : southbridge_device(mconfig, I82371SB, "Intel 82371SB", tag, owner, clock, "i82371sb", __FILE__), |
| 30 | pci_device_interface( mconfig, *this ) |
| 31 | { |
| 32 | } |
| 33 | |
| 34 | UINT32 i82371sb_device::pci_isa_r(device_t *busdevice,int offset, UINT32 mem_mask) |
| 35 | { |
| 36 | UINT32 result = m_regs[0][offset]; |
| 37 | |
| 38 | //logerror("i82371sb_pci_isa_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask); |
| 39 | |
| 40 | return result; |
| 41 | } |
| 42 | |
| 43 | void i82371sb_device::pci_isa_w(device_t *busdevice, int offset, UINT32 data, UINT32 mem_mask) |
| 44 | { |
| 45 | //logerror("i82371sb_pci_isa_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask); |
| 46 | |
| 47 | switch (offset) |
| 48 | { |
| 49 | case 0x04: |
| 50 | COMBINE_DATA(&m_regs[0][offset]); |
| 51 | |
| 52 | /* clear reserved bits */ |
| 53 | m_regs[0][offset] &= 0x00000005; |
| 54 | |
| 55 | /* set new status */ |
| 56 | m_regs[0][offset] |= 0x02800000; |
| 57 | |
| 58 | break; |
| 59 | } |
| 60 | } |
| 61 | |
| 62 | UINT32 i82371sb_device::pci_ide_r(device_t *busdevice, int offset, UINT32 mem_mask) |
| 63 | { |
| 64 | //logerror("i82371sb_pci_ide_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask); |
| 65 | UINT32 result = m_regs[1][offset]; |
| 66 | return result; |
| 67 | } |
| 68 | |
| 69 | void i82371sb_device::pci_ide_w(device_t *busdevice, int offset, UINT32 data, UINT32 mem_mask) |
| 70 | { |
| 71 | //logerror("i82371sb_pci_ide_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask); |
| 72 | |
| 73 | switch (offset) |
| 74 | { |
| 75 | case 0x04: |
| 76 | COMBINE_DATA(&m_regs[1][offset]); |
| 77 | |
| 78 | /* clear reserved bits */ |
| 79 | m_regs[1][offset] &= 0x00000005; |
| 80 | |
| 81 | /* set new status */ |
| 82 | m_regs[1][offset] |= 0x02800000; |
| 83 | |
| 84 | break; |
| 85 | } |
| 86 | } |
| 87 | |
| 88 | UINT32 i82371sb_device::pci_usb_r(device_t *busdevice, int offset, UINT32 mem_mask) |
| 89 | { |
| 90 | UINT32 result = m_regs[2][offset]; |
| 91 | |
| 92 | //logerror("i82371sb_pci_usb_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask); |
| 93 | |
| 94 | return result; |
| 95 | } |
| 96 | |
| 97 | void i82371sb_device::pci_usb_w(device_t *busdevice, int offset, UINT32 data, UINT32 mem_mask) |
| 98 | { |
| 99 | //logerror("i82371sb_pci_usb_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask); |
| 100 | |
| 101 | switch (offset) |
| 102 | { |
| 103 | case 0x04: |
| 104 | COMBINE_DATA(&m_regs[2][offset]); |
| 105 | |
| 106 | /* clear reserved bits */ |
| 107 | m_regs[2][offset] &= 0x00000005; |
| 108 | |
| 109 | /* set new status */ |
| 110 | m_regs[2][offset] |= 0x02800000; |
| 111 | |
| 112 | break; |
| 113 | } |
| 114 | } |
| 115 | |
| 116 | UINT32 i82371sb_device::pci_read(pci_bus_device *pcibus, int function, int offset, UINT32 mem_mask) |
| 117 | { |
| 118 | switch (function) |
| 119 | { |
| 120 | case 0: return pci_isa_r(pcibus, offset, mem_mask); |
| 121 | case 1: return pci_ide_r(pcibus, offset, mem_mask); |
| 122 | case 2: return pci_usb_r(pcibus, offset, mem_mask); |
| 123 | } |
| 124 | |
| 125 | //logerror("i82371sb_pci_read: read from undefined function %d\n", function); |
| 126 | |
| 127 | return 0; |
| 128 | } |
| 129 | |
| 130 | void i82371sb_device::pci_write(pci_bus_device *pcibus, int function, int offset, UINT32 data, UINT32 mem_mask) |
| 131 | { |
| 132 | switch (function) |
| 133 | { |
| 134 | case 0: pci_isa_w(pcibus, offset, data, mem_mask); break; |
| 135 | case 1: pci_ide_w(pcibus, offset, data, mem_mask); break; |
| 136 | case 2: pci_usb_w(pcibus, offset, data, mem_mask); break; |
| 137 | } |
| 138 | //logerror("i82371sb_pci_write: write to undefined function %d\n", function); |
| 139 | } |
| 140 | |
| 141 | //------------------------------------------------- |
| 142 | // device_start - device-specific startup |
| 143 | //------------------------------------------------- |
| 144 | |
| 145 | void i82371sb_device::device_start() |
| 146 | { |
| 147 | southbridge_device::device_start(); |
| 148 | /* setup save states */ |
| 149 | save_item(NAME(m_regs)); |
| 150 | } |
| 151 | |
| 152 | //------------------------------------------------- |
| 153 | // device_reset - device-specific reset |
| 154 | //------------------------------------------------- |
| 155 | |
| 156 | void i82371sb_device::device_reset() |
| 157 | { |
| 158 | southbridge_device::device_reset(); |
| 159 | |
| 160 | memset(m_regs, 0, sizeof(m_regs)); |
| 161 | |
| 162 | /* isa */ |
| 163 | m_regs[0][0x00] = 0x70008086; |
| 164 | m_regs[0][0x04] = 0x00000000; |
| 165 | m_regs[0][0x08] = 0x06010000; |
| 166 | m_regs[0][0x0c] = 0x00800000; |
| 167 | |
| 168 | /* ide */ |
| 169 | m_regs[1][0x00] = 0x70108086; |
| 170 | m_regs[1][0x04] = 0x02800000; |
| 171 | m_regs[1][0x08] = 0x01018000; |
| 172 | m_regs[1][0x0c] = 0x00000000; |
| 173 | |
| 174 | /* usb */ |
| 175 | m_regs[2][0x00] = 0x70208086; |
| 176 | m_regs[2][0x04] = 0x02800000; |
| 177 | m_regs[2][0x08] = 0x0c030000; |
| 178 | m_regs[2][0x0c] = 0x00000000; |
| 179 | } |
trunk/src/emu/bus/lpci/i82439tx.c
r0 | r241729 | |
| 1 | /*************************************************************************** |
| 2 | |
| 3 | Intel 82439TX System Controller (MTXC) |
| 4 | |
| 5 | ***************************************************************************/ |
| 6 | |
| 7 | #include "emu.h" |
| 8 | #include "i82439tx.h" |
| 9 | |
| 10 | /*************************************************************************** |
| 11 | IMPLEMENTATION |
| 12 | ***************************************************************************/ |
| 13 | |
| 14 | const device_type I82439TX = &device_creator<i82439tx_device>; |
| 15 | |
| 16 | |
| 17 | i82439tx_device::i82439tx_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 18 | : northbridge_device(mconfig, I82439TX, "Intel 82439TX", tag, owner, clock, "i82439tx", __FILE__), |
| 19 | pci_device_interface( mconfig, *this ), |
| 20 | m_cpu_tag( NULL ), |
| 21 | m_region_tag( NULL ) |
| 22 | { |
| 23 | } |
| 24 | |
| 25 | void i82439tx_device::i82439tx_configure_memory(UINT8 val, offs_t begin, offs_t end) |
| 26 | { |
| 27 | switch (val & 0x03) |
| 28 | { |
| 29 | case 0: |
| 30 | m_space->install_rom(begin, end, m_rom + (begin - 0xc0000)); |
| 31 | m_space->nop_write(begin, end); |
| 32 | break; |
| 33 | case 1: |
| 34 | m_space->install_rom(begin, end, m_bios_ram + (begin - 0xc0000) / 4); |
| 35 | m_space->nop_write(begin, end); |
| 36 | break; |
| 37 | case 2: |
| 38 | m_space->install_rom(begin, end, m_rom + (begin - 0xc0000)); |
| 39 | m_space->install_writeonly(begin, end, m_bios_ram + (begin - 0xc0000) / 4); |
| 40 | break; |
| 41 | case 3: |
| 42 | m_space->install_ram(begin, end, m_bios_ram + (begin - 0xc0000) / 4); |
| 43 | break; |
| 44 | } |
| 45 | } |
| 46 | |
| 47 | |
| 48 | /*************************************************************************** |
| 49 | PCI INTERFACE |
| 50 | ***************************************************************************/ |
| 51 | |
| 52 | UINT32 i82439tx_device::pci_read(pci_bus_device *pcibus, int function, int offset, UINT32 mem_mask) |
| 53 | { |
| 54 | UINT32 result = 0; |
| 55 | |
| 56 | if (function != 0) |
| 57 | return 0; |
| 58 | |
| 59 | switch(offset) |
| 60 | { |
| 61 | case 0x00: /* vendor/device ID */ |
| 62 | result = 0x71008086; |
| 63 | break; |
| 64 | |
| 65 | case 0x08: /* revision identification register and class code register*/ |
| 66 | result = 0x06000001; |
| 67 | break; |
| 68 | |
| 69 | case 0x04: /* PCI command register */ |
| 70 | case 0x0C: |
| 71 | case 0x10: /* reserved */ |
| 72 | case 0x14: /* reserved */ |
| 73 | case 0x18: /* reserved */ |
| 74 | case 0x1C: /* reserved */ |
| 75 | case 0x20: /* reserved */ |
| 76 | case 0x24: /* reserved */ |
| 77 | case 0x28: /* reserved */ |
| 78 | case 0x2C: /* reserved */ |
| 79 | case 0x30: /* reserved */ |
| 80 | case 0x34: /* reserved */ |
| 81 | case 0x38: /* reserved */ |
| 82 | case 0x3C: /* reserved */ |
| 83 | case 0x40: /* reserved */ |
| 84 | case 0x44: /* reserved */ |
| 85 | case 0x48: /* reserved */ |
| 86 | case 0x4C: /* reserved */ |
| 87 | case 0x50: |
| 88 | case 0x54: |
| 89 | case 0x58: |
| 90 | case 0x5C: |
| 91 | case 0x60: |
| 92 | case 0x64: |
| 93 | case 0x68: |
| 94 | case 0x6C: |
| 95 | case 0x70: |
| 96 | case 0x74: |
| 97 | case 0x78: |
| 98 | case 0x7C: |
| 99 | case 0x80: |
| 100 | case 0x84: |
| 101 | case 0x88: |
| 102 | case 0x8C: |
| 103 | case 0x90: |
| 104 | case 0x94: |
| 105 | case 0x98: |
| 106 | case 0x9C: |
| 107 | case 0xA0: |
| 108 | case 0xA4: |
| 109 | case 0xA8: |
| 110 | case 0xAC: |
| 111 | case 0xB0: |
| 112 | case 0xB4: |
| 113 | case 0xB8: |
| 114 | case 0xBC: |
| 115 | case 0xC0: |
| 116 | case 0xC4: |
| 117 | case 0xC8: |
| 118 | case 0xCC: |
| 119 | case 0xD0: |
| 120 | case 0xD4: |
| 121 | case 0xD8: |
| 122 | case 0xDC: |
| 123 | case 0xE0: |
| 124 | case 0xE4: |
| 125 | case 0xE8: |
| 126 | case 0xEC: |
| 127 | case 0xF0: |
| 128 | case 0xF4: |
| 129 | case 0xF8: |
| 130 | case 0xFC: |
| 131 | assert(((offset - 0x50) / 4) >= 0 && ((offset - 0x50) / 4) < ARRAY_LENGTH(m_regs)); |
| 132 | result = m_regs[(offset - 0x50) / 4]; |
| 133 | break; |
| 134 | |
| 135 | default: |
| 136 | fatalerror("i82439tx_pci_read(): Unexpected PCI read 0x%02X\n", offset); |
| 137 | } |
| 138 | return result; |
| 139 | } |
| 140 | |
| 141 | void i82439tx_device::pci_write(pci_bus_device *pcibus, int function, int offset, UINT32 data, UINT32 mem_mask) |
| 142 | { |
| 143 | if (function != 0) |
| 144 | return; |
| 145 | |
| 146 | switch(offset) |
| 147 | { |
| 148 | case 0x00: /* vendor/device ID */ |
| 149 | case 0x10: /* reserved */ |
| 150 | case 0x14: /* reserved */ |
| 151 | case 0x18: /* reserved */ |
| 152 | case 0x1C: /* reserved */ |
| 153 | case 0x20: /* reserved */ |
| 154 | case 0x24: /* reserved */ |
| 155 | case 0x28: /* reserved */ |
| 156 | case 0x2C: /* reserved */ |
| 157 | case 0x30: /* reserved */ |
| 158 | case 0x3C: /* reserved */ |
| 159 | case 0x40: /* reserved */ |
| 160 | case 0x44: /* reserved */ |
| 161 | case 0x48: /* reserved */ |
| 162 | case 0x4C: /* reserved */ |
| 163 | /* read only */ |
| 164 | break; |
| 165 | |
| 166 | case 0x04: /* PCI command register */ |
| 167 | case 0x0C: |
| 168 | case 0x50: |
| 169 | case 0x54: |
| 170 | case 0x58: |
| 171 | case 0x5C: |
| 172 | case 0x60: |
| 173 | case 0x64: |
| 174 | case 0x68: |
| 175 | case 0x6C: |
| 176 | case 0x70: |
| 177 | case 0x74: |
| 178 | case 0x78: |
| 179 | case 0x7C: |
| 180 | case 0x80: |
| 181 | case 0x84: |
| 182 | case 0x88: |
| 183 | case 0x8C: |
| 184 | case 0x90: |
| 185 | case 0x94: |
| 186 | case 0x98: |
| 187 | case 0x9C: |
| 188 | case 0xA0: |
| 189 | case 0xA4: |
| 190 | case 0xA8: |
| 191 | case 0xAC: |
| 192 | case 0xB0: |
| 193 | case 0xB4: |
| 194 | case 0xB8: |
| 195 | case 0xBC: |
| 196 | case 0xC0: |
| 197 | case 0xC4: |
| 198 | case 0xC8: |
| 199 | case 0xCC: |
| 200 | case 0xD0: |
| 201 | case 0xD4: |
| 202 | case 0xD8: |
| 203 | case 0xDC: |
| 204 | case 0xE0: |
| 205 | case 0xE4: |
| 206 | case 0xE8: |
| 207 | case 0xEC: |
| 208 | case 0xF0: |
| 209 | case 0xF4: |
| 210 | case 0xF8: |
| 211 | case 0xFC: |
| 212 | switch(offset) |
| 213 | { |
| 214 | case 0x58: |
| 215 | if ((mem_mask & 0x0000f000)) |
| 216 | i82439tx_configure_memory(data >> 12, 0xf0000, 0xfffff); |
| 217 | if ((mem_mask & 0x000f0000)) |
| 218 | i82439tx_configure_memory(data >> 16, 0xc0000, 0xc3fff); |
| 219 | if ((mem_mask & 0x00f00000)) |
| 220 | i82439tx_configure_memory(data >> 20, 0xc4000, 0xc7fff); |
| 221 | if ((mem_mask & 0x0f000000)) |
| 222 | i82439tx_configure_memory(data >> 24, 0xc8000, 0xccfff); |
| 223 | if ((mem_mask & 0xf0000000)) |
| 224 | i82439tx_configure_memory(data >> 28, 0xcc000, 0xcffff); |
| 225 | break; |
| 226 | |
| 227 | case 0x5C: |
| 228 | if ((mem_mask & 0x0000000f)) |
| 229 | i82439tx_configure_memory(data >> 0, 0xd0000, 0xd3fff); |
| 230 | if ((mem_mask & 0x000000f0)) |
| 231 | i82439tx_configure_memory(data >> 4, 0xd4000, 0xd7fff); |
| 232 | if ((mem_mask & 0x00000f00)) |
| 233 | i82439tx_configure_memory(data >> 8, 0xd8000, 0xdbfff); |
| 234 | if ((mem_mask & 0x0000f000)) |
| 235 | i82439tx_configure_memory(data >> 12, 0xdc000, 0xdffff); |
| 236 | if ((mem_mask & 0x000f0000)) |
| 237 | i82439tx_configure_memory(data >> 16, 0xe0000, 0xe3fff); |
| 238 | if ((mem_mask & 0x00f00000)) |
| 239 | i82439tx_configure_memory(data >> 20, 0xe4000, 0xe7fff); |
| 240 | if ((mem_mask & 0x0f000000)) |
| 241 | i82439tx_configure_memory(data >> 24, 0xe8000, 0xecfff); |
| 242 | if ((mem_mask & 0xf0000000)) |
| 243 | i82439tx_configure_memory(data >> 28, 0xec000, 0xeffff); |
| 244 | break; |
| 245 | } |
| 246 | |
| 247 | assert(((offset - 0x50) / 4) >= 0 && ((offset - 0x50) / 4) < ARRAY_LENGTH(m_regs)); |
| 248 | COMBINE_DATA(&m_regs[(offset - 0x50) / 4]); |
| 249 | break; |
| 250 | |
| 251 | default: |
| 252 | fatalerror("i82439tx_pci_write(): Unexpected PCI write 0x%02X <-- 0x%08X\n", offset, data); |
| 253 | } |
| 254 | } |
| 255 | |
| 256 | //------------------------------------------------- |
| 257 | // device_start - device-specific startup |
| 258 | //------------------------------------------------- |
| 259 | |
| 260 | void i82439tx_device::device_start() |
| 261 | { |
| 262 | northbridge_device::device_start(); |
| 263 | /* get address space we are working on */ |
| 264 | device_t *cpu = machine().device(m_cpu_tag); |
| 265 | assert(cpu != NULL); |
| 266 | |
| 267 | m_space = &cpu->memory().space(AS_PROGRAM); |
| 268 | |
| 269 | /* get rom region */ |
| 270 | m_rom = machine().root_device().memregion(m_region_tag)->base(); |
| 271 | |
| 272 | /* setup save states */ |
| 273 | save_item(NAME(m_regs)); |
| 274 | save_item(NAME(m_bios_ram)); |
| 275 | } |
| 276 | |
| 277 | //------------------------------------------------- |
| 278 | // device_reset - device-specific reset |
| 279 | //------------------------------------------------- |
| 280 | |
| 281 | void i82439tx_device::device_reset() |
| 282 | { |
| 283 | northbridge_device::device_reset(); |
| 284 | /* setup initial values */ |
| 285 | m_regs[0x00] = 0x14020000; |
| 286 | m_regs[0x01] = 0x01520000; |
| 287 | m_regs[0x02] = 0x00000000; |
| 288 | m_regs[0x03] = 0x00000000; |
| 289 | m_regs[0x04] = 0x02020202; |
| 290 | m_regs[0x05] = 0x00000002; |
| 291 | m_regs[0x06] = 0x00000000; |
| 292 | m_regs[0x07] = 0x00000000; |
| 293 | |
| 294 | memset(m_bios_ram, 0, sizeof(m_bios_ram)); |
| 295 | |
| 296 | /* configure initial memory state */ |
| 297 | i82439tx_configure_memory(0, 0xf0000, 0xfffff); |
| 298 | i82439tx_configure_memory(0, 0xc0000, 0xc3fff); |
| 299 | i82439tx_configure_memory(0, 0xc4000, 0xc7fff); |
| 300 | i82439tx_configure_memory(0, 0xc8000, 0xccfff); |
| 301 | i82439tx_configure_memory(0, 0xcc000, 0xcffff); |
| 302 | i82439tx_configure_memory(0, 0xd0000, 0xd3fff); |
| 303 | i82439tx_configure_memory(0, 0xd4000, 0xd7fff); |
| 304 | i82439tx_configure_memory(0, 0xd8000, 0xdbfff); |
| 305 | i82439tx_configure_memory(0, 0xdc000, 0xdffff); |
| 306 | i82439tx_configure_memory(0, 0xe0000, 0xe3fff); |
| 307 | i82439tx_configure_memory(0, 0xe4000, 0xe7fff); |
| 308 | i82439tx_configure_memory(0, 0xe8000, 0xecfff); |
| 309 | i82439tx_configure_memory(0, 0xec000, 0xeffff); |
| 310 | } |
trunk/src/emu/bus/lpci/mpc105.c
r0 | r241729 | |
| 1 | /*************************************************************************** |
| 2 | |
| 3 | mpc105.h |
| 4 | |
| 5 | Motorola MPC105 PCI bridge |
| 6 | |
| 7 | ***************************************************************************/ |
| 8 | |
| 9 | #include "emu.h" |
| 10 | #include "mpc105.h" |
| 11 | #include "machine/ram.h" |
| 12 | |
| 13 | #define LOG_MPC105 0 |
| 14 | |
| 15 | //************************************************************************** |
| 16 | // DEVICE DEFINITIONS |
| 17 | //************************************************************************** |
| 18 | |
| 19 | const device_type MPC105 = &device_creator<mpc105_device>; |
| 20 | |
| 21 | |
| 22 | //************************************************************************** |
| 23 | // LIVE DEVICE |
| 24 | //************************************************************************** |
| 25 | |
| 26 | //------------------------------------------------- |
| 27 | // mpc105_device - constructor |
| 28 | //------------------------------------------------- |
| 29 | |
| 30 | mpc105_device::mpc105_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 31 | : device_t(mconfig, MPC105, "MPC105", tag, owner, clock, "mpc105", __FILE__), |
| 32 | pci_device_interface( mconfig, *this ), |
| 33 | m_cpu_tag(NULL), |
| 34 | m_bank_base_default(0) |
| 35 | { |
| 36 | } |
| 37 | |
| 38 | //------------------------------------------------- |
| 39 | // device_start - device-specific startup |
| 40 | //------------------------------------------------- |
| 41 | |
| 42 | void mpc105_device::device_start() |
| 43 | { |
| 44 | m_maincpu = machine().device<cpu_device>(m_cpu_tag); |
| 45 | } |
| 46 | |
| 47 | //------------------------------------------------- |
| 48 | // device_reset - device-specific reset |
| 49 | //------------------------------------------------- |
| 50 | |
| 51 | void mpc105_device::device_reset() |
| 52 | { |
| 53 | m_bank_base = m_bank_base_default; |
| 54 | m_bank_enable = 0; |
| 55 | memset(m_bank_registers,0,sizeof(m_bank_registers)); |
| 56 | } |
| 57 | |
| 58 | //------------------------------------------------- |
| 59 | // update_memory - MMU update |
| 60 | //------------------------------------------------- |
| 61 | |
| 62 | void mpc105_device::update_memory() |
| 63 | { |
| 64 | int bank; |
| 65 | offs_t begin, end; |
| 66 | char bank_str[10]; |
| 67 | |
| 68 | if (LOG_MPC105) |
| 69 | logerror("mpc105_update_memory(machine): Updating memory (bank enable=0x%02X)\n", m_bank_enable); |
| 70 | |
| 71 | if (m_bank_base > 0) |
| 72 | { |
| 73 | address_space &space = m_maincpu->space(AS_PROGRAM); |
| 74 | |
| 75 | /* first clear everything out */ |
| 76 | space.nop_read(0x00000000, 0x3FFFFFFF); |
| 77 | space.nop_read(0x00000000, 0x3FFFFFFF); |
| 78 | } |
| 79 | |
| 80 | for (bank = 0; bank < MPC105_MEMORYBANK_COUNT; bank++) |
| 81 | { |
| 82 | if (m_bank_enable & (1 << bank)) |
| 83 | { |
| 84 | begin = (((m_bank_registers[(bank / 4) + 0] >> (bank % 4) * 8)) & 0xFF) << 20 |
| 85 | | (((m_bank_registers[(bank / 4) + 2] >> (bank % 4) * 8)) & 0x03) << 28; |
| 86 | |
| 87 | end = (((m_bank_registers[(bank / 4) + 4] >> (bank % 4) * 8)) & 0xFF) << 20 |
| 88 | | (((m_bank_registers[(bank / 4) + 6] >> (bank % 4) * 8)) & 0x03) << 28 |
| 89 | | 0x000FFFFF; |
| 90 | |
| 91 | end = MIN(end, begin + machine().device<ram_device>(RAM_TAG)->size() - 1); |
| 92 | |
| 93 | if ((begin + 0x100000) <= end) |
| 94 | { |
| 95 | if (LOG_MPC105) |
| 96 | 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)); |
| 97 | |
| 98 | if (m_bank_base > 0) |
| 99 | { |
| 100 | sprintf(bank_str,"bank%d",bank + m_bank_base); |
| 101 | membank(bank_str)->set_base(machine().device<ram_device>(RAM_TAG)->pointer()); |
| 102 | } |
| 103 | } |
| 104 | } |
| 105 | } |
| 106 | } |
| 107 | |
| 108 | //------------------------------------------------- |
| 109 | // pci_read - implementation of PCI read |
| 110 | //------------------------------------------------- |
| 111 | |
| 112 | UINT32 mpc105_device::pci_read(pci_bus_device *pcibus, int function, int offset, UINT32 mem_mask) |
| 113 | { |
| 114 | UINT32 result; |
| 115 | |
| 116 | if (function != 0) |
| 117 | return 0; |
| 118 | |
| 119 | switch(offset) |
| 120 | { |
| 121 | case 0x00: /* vendor/device ID */ |
| 122 | result = 0x00011057; |
| 123 | break; |
| 124 | |
| 125 | case 0x08: |
| 126 | result = 0x06000000; |
| 127 | break; |
| 128 | |
| 129 | case 0x80: /* memory starting address 1 */ |
| 130 | case 0x84: /* memory starting address 2 */ |
| 131 | case 0x88: /* extended memory starting address 1 */ |
| 132 | case 0x8C: /* extended memory starting address 2 */ |
| 133 | case 0x90: /* memory ending address 1 */ |
| 134 | case 0x94: /* memory ending address 2 */ |
| 135 | case 0x98: /* extended memory ending address 1 */ |
| 136 | case 0x9C: /* extended memory ending address 2 */ |
| 137 | result = m_bank_registers[(offset - 0x80) / 4]; |
| 138 | break; |
| 139 | |
| 140 | case 0xA0: /* memory enable */ |
| 141 | result = m_bank_enable; |
| 142 | break; |
| 143 | |
| 144 | case 0xA8: /* processor interface configuration 1 */ |
| 145 | /* TODO: Fix me! */ |
| 146 | switch(/*cpu_getactivecpu()*/0) |
| 147 | { |
| 148 | case 0: |
| 149 | result = 0xFF000010; |
| 150 | break; |
| 151 | |
| 152 | case 1: |
| 153 | result = 0xFF008010; |
| 154 | break; |
| 155 | |
| 156 | default: |
| 157 | fatalerror("Unknown CPU\n"); |
| 158 | } |
| 159 | break; |
| 160 | |
| 161 | case 0xAC: /* processor interface configuration 1 */ |
| 162 | result = 0x000C060C; |
| 163 | break; |
| 164 | |
| 165 | case 0xF0: /* memory control configuration 1 */ |
| 166 | result = 0xFF020000; |
| 167 | break; |
| 168 | case 0xF4: /* memory control configuration 2 */ |
| 169 | result = 0x00000003; |
| 170 | break; |
| 171 | case 0xF8: /* memory control configuration 3 */ |
| 172 | result = 0x00000000; |
| 173 | break; |
| 174 | case 0xFC: /* memory control configuration 4 */ |
| 175 | result = 0x00100000; |
| 176 | break; |
| 177 | |
| 178 | default: |
| 179 | result = 0; |
| 180 | break; |
| 181 | } |
| 182 | return result; |
| 183 | } |
| 184 | |
| 185 | //------------------------------------------------- |
| 186 | // pci_write - implementation of PCI write |
| 187 | //------------------------------------------------- |
| 188 | |
| 189 | void mpc105_device::pci_write(pci_bus_device *pcibus, int function, int offset, UINT32 data, UINT32 mem_mask) |
| 190 | { |
| 191 | int i; |
| 192 | if (function != 0) |
| 193 | return; |
| 194 | |
| 195 | switch(offset) |
| 196 | { |
| 197 | case 0x80: /* memory starting address 1 */ |
| 198 | case 0x84: /* memory starting address 2 */ |
| 199 | case 0x88: /* extended memory starting address 1 */ |
| 200 | case 0x8C: /* extended memory starting address 2 */ |
| 201 | case 0x90: /* memory ending address 1 */ |
| 202 | case 0x94: /* memory ending address 2 */ |
| 203 | case 0x98: /* extended memory ending address 1 */ |
| 204 | case 0x9C: /* extended memory ending address 2 */ |
| 205 | i = (offset - 0x80) / 4; |
| 206 | if (m_bank_registers[i] != data) |
| 207 | { |
| 208 | m_bank_registers[i] = data; |
| 209 | update_memory(); |
| 210 | } |
| 211 | break; |
| 212 | |
| 213 | case 0xA0: /* memory enable */ |
| 214 | if (m_bank_enable != (UINT8) data) |
| 215 | { |
| 216 | m_bank_enable = (UINT8) data; |
| 217 | update_memory(); |
| 218 | } |
| 219 | break; |
| 220 | |
| 221 | case 0xF0: /* memory control configuration 1 */ |
| 222 | case 0xF4: /* memory control configuration 2 */ |
| 223 | case 0xF8: /* memory control configuration 3 */ |
| 224 | case 0xFC: /* memory control configuration 4 */ |
| 225 | break; |
| 226 | |
| 227 | case 0xA8: /* processor interface configuration 1 */ |
| 228 | //fatalerror("mpc105_pci_write(): Unexpected PCI write 0x%02X <-- 0x%08X\n", offset, data); |
| 229 | break; |
| 230 | } |
| 231 | } |
trunk/src/emu/bus/lpci/pci.c
r0 | r241729 | |
| 1 | /*************************************************************************** |
| 2 | |
| 3 | pci.c |
| 4 | |
| 5 | PCI bus |
| 6 | |
| 7 | The PCI bus is a 32-bit bus introduced by Intel, so it is little endian |
| 8 | |
| 9 | Control word: |
| 10 | bit 31: Enable bit |
| 11 | bits 30-24: Reserved |
| 12 | bits 23-16: PCI bus number |
| 13 | bits 15-11: PCI device number |
| 14 | bits 10- 8: PCI function number |
| 15 | bits 7- 0: Offset address |
| 16 | |
| 17 | Standard PCI registers: |
| 18 | 0x00 2 Vendor ID |
| 19 | 0x02 2 Device ID |
| 20 | 0x04 2 PCI Command |
| 21 | 0x06 2 PCI Status |
| 22 | 0x08 1 Revision ID |
| 23 | 0x09 1 Programming Interface |
| 24 | 0x0A 1 Subclass Code |
| 25 | 0x0B 1 Class Code |
| 26 | |
| 27 | Class Code/Subclass Code/Programming Interface |
| 28 | 0x00XXXX Pre-PCI 2.0 devices |
| 29 | 0x000000 Non-VGA device |
| 30 | 0x000101 VGA device |
| 31 | 0x01XXXX Storage Controller |
| 32 | 0x010000 SCSI |
| 33 | 0x0101XX IDE |
| 34 | 0x0102XX Floppy |
| 35 | 0x0103XX IPI |
| 36 | 0x0104XX RAID |
| 37 | 0x0180XX Other |
| 38 | 0x02XXXX Network Card |
| 39 | 0x020000 Ethernet |
| 40 | 0x020100 Tokenring |
| 41 | 0x020200 FDDI |
| 42 | 0x020300 ATM |
| 43 | 0x028000 Other |
| 44 | 0x03XXXX Display Controller |
| 45 | 0x030000 VGA |
| 46 | 0x030001 8514 Compatible |
| 47 | 0x030100 XGA |
| 48 | 0x038000 Other |
| 49 | 0x04XXXX Multimedia |
| 50 | 0x040000 Video |
| 51 | 0x040100 Audio |
| 52 | 0x048000 Other |
| 53 | 0x05XXXX Memory Controller |
| 54 | 0x050000 RAM |
| 55 | 0x050100 Flash |
| 56 | 0x058000 Other |
| 57 | 0x06XXXX Bridge |
| 58 | 0x060000 Host/PCI |
| 59 | 0x060100 PCI/ISA |
| 60 | 0x060200 PCI/EISA |
| 61 | 0x060300 PCI/Micro Channel |
| 62 | 0x060400 PCI/PCI |
| 63 | 0x060500 PCI/PCMCIA |
| 64 | 0x060600 PCI/NuBus |
| 65 | 0x060700 PCI/CardBus |
| 66 | 0x068000 Other |
| 67 | |
| 68 | Information on PCI vendors can be found at http://www.pcidatabase.com/ |
| 69 | |
| 70 | ***************************************************************************/ |
| 71 | |
| 72 | #include "emu.h" |
| 73 | #include "pci.h" |
| 74 | |
| 75 | #define LOG_PCI 0 |
| 76 | |
| 77 | //************************************************************************** |
| 78 | // GLOBAL VARIABLES |
| 79 | //************************************************************************** |
| 80 | |
| 81 | const device_type PCI_BUS = &device_creator<pci_bus_device>; |
| 82 | |
| 83 | //************************************************************************** |
| 84 | // LIVE DEVICE |
| 85 | //************************************************************************** |
| 86 | |
| 87 | //------------------------------------------------- |
| 88 | // pci_bus_device - constructor |
| 89 | //------------------------------------------------- |
| 90 | pci_bus_device::pci_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 91 | device_t(mconfig, PCI_BUS, "PCI Bus", tag, owner, clock, "pci_bus", __FILE__), |
| 92 | m_father(NULL) |
| 93 | { |
| 94 | for (int i = 0; i < ARRAY_LENGTH(m_devtag); i++) { |
| 95 | m_devtag[i]= NULL; |
| 96 | } |
| 97 | m_siblings_count = 0; |
| 98 | } |
| 99 | |
| 100 | /*************************************************************************** |
| 101 | INLINE FUNCTIONS |
| 102 | ***************************************************************************/ |
| 103 | |
| 104 | READ32_MEMBER( pci_bus_device::read ) |
| 105 | { |
| 106 | UINT32 result = 0xffffffff; |
| 107 | int function, reg; |
| 108 | |
| 109 | offset %= 2; |
| 110 | |
| 111 | switch (offset) |
| 112 | { |
| 113 | case 0: |
| 114 | result = m_address; |
| 115 | break; |
| 116 | |
| 117 | case 1: |
| 118 | if (m_devicenum != -1) |
| 119 | { |
| 120 | if (m_busnumaddr->m_device[m_devicenum] != NULL) |
| 121 | { |
| 122 | function = (m_address >> 8) & 0x07; |
| 123 | reg = (m_address >> 0) & 0xfc; |
| 124 | result = m_busnumaddr->m_device[m_devicenum]->pci_read(m_busnumaddr, function, reg, mem_mask); |
| 125 | } |
| 126 | } |
| 127 | break; |
| 128 | } |
| 129 | |
| 130 | if (LOG_PCI) |
| 131 | logerror("read('%s'): offset=%d result=0x%08X\n", tag(), offset, result); |
| 132 | |
| 133 | return result; |
| 134 | } |
| 135 | |
| 136 | |
| 137 | |
| 138 | pci_bus_device *pci_bus_device::pci_search_bustree(int busnum, int devicenum, pci_bus_device *pcibus) |
| 139 | { |
| 140 | int a; |
| 141 | pci_bus_device *ret; |
| 142 | |
| 143 | if (pcibus->m_busnum == busnum) |
| 144 | { |
| 145 | return pcibus; |
| 146 | } |
| 147 | for (a = 0; a < pcibus->m_siblings_count; a++) |
| 148 | { |
| 149 | ret = pci_search_bustree(busnum, devicenum, pcibus->m_siblings[a]); |
| 150 | if (ret != NULL) |
| 151 | return ret; |
| 152 | } |
| 153 | return NULL; |
| 154 | } |
| 155 | |
| 156 | |
| 157 | |
| 158 | WRITE32_MEMBER( pci_bus_device::write ) |
| 159 | { |
| 160 | offset %= 2; |
| 161 | |
| 162 | if (LOG_PCI) |
| 163 | logerror("write('%s'): offset=%d data=0x%08X\n", tag(), offset, data); |
| 164 | |
| 165 | switch (offset) |
| 166 | { |
| 167 | case 0: |
| 168 | m_address = data; |
| 169 | |
| 170 | /* lookup current device */ |
| 171 | if (m_address & 0x80000000) |
| 172 | { |
| 173 | int busnum = (m_address >> 16) & 0xff; |
| 174 | int devicenum = (m_address >> 11) & 0x1f; |
| 175 | m_busnumaddr = pci_search_bustree(busnum, devicenum, this); |
| 176 | if (m_busnumaddr != NULL) |
| 177 | { |
| 178 | m_busnumber = busnum; |
| 179 | m_devicenum = devicenum; |
| 180 | } |
| 181 | else |
| 182 | m_devicenum = -1; |
| 183 | if (LOG_PCI) |
| 184 | logerror(" bus:%d device:%d\n", busnum, devicenum); |
| 185 | } |
| 186 | break; |
| 187 | |
| 188 | case 1: |
| 189 | if (m_devicenum != -1) |
| 190 | { |
| 191 | if (m_busnumaddr->m_device[m_devicenum] != NULL) |
| 192 | { |
| 193 | int function = (m_address >> 8) & 0x07; |
| 194 | int reg = (m_address >> 0) & 0xfc; |
| 195 | m_busnumaddr->m_device[m_devicenum]->pci_write(m_busnumaddr, function, reg, data, mem_mask); |
| 196 | } |
| 197 | if (LOG_PCI) |
| 198 | logerror(" function:%d register:%d\n", (m_address >> 8) & 0x07, (m_address >> 0) & 0xfc); |
| 199 | } |
| 200 | break; |
| 201 | } |
| 202 | } |
| 203 | |
| 204 | |
| 205 | |
| 206 | READ64_MEMBER(pci_bus_device::read_64be) |
| 207 | { |
| 208 | UINT64 result = 0; |
| 209 | mem_mask = FLIPENDIAN_INT64(mem_mask); |
| 210 | if (ACCESSING_BITS_0_31) |
| 211 | result |= (UINT64)read(space, offset * 2 + 0, mem_mask >> 0) << 0; |
| 212 | if (ACCESSING_BITS_32_63) |
| 213 | result |= (UINT64)read(space, offset * 2 + 1, mem_mask >> 32) << 32; |
| 214 | return FLIPENDIAN_INT64(result); |
| 215 | } |
| 216 | |
| 217 | WRITE64_MEMBER(pci_bus_device::write_64be) |
| 218 | { |
| 219 | data = FLIPENDIAN_INT64(data); |
| 220 | mem_mask = FLIPENDIAN_INT64(mem_mask); |
| 221 | if (ACCESSING_BITS_0_31) |
| 222 | write(space, offset * 2 + 0, data >> 0, mem_mask >> 0); |
| 223 | if (ACCESSING_BITS_32_63) |
| 224 | write(space, offset * 2 + 1, data >> 32, mem_mask >> 32); |
| 225 | } |
| 226 | |
| 227 | |
| 228 | void pci_bus_device::add_sibling(pci_bus_device *sibling, int busnum) |
| 229 | { |
| 230 | m_siblings[m_siblings_count] = sibling; |
| 231 | m_siblings_busnum[m_siblings_count] = busnum; |
| 232 | m_siblings_count++; |
| 233 | } |
| 234 | |
| 235 | |
| 236 | //------------------------------------------------- |
| 237 | // device_post_load - handle updating after a |
| 238 | // restore |
| 239 | //------------------------------------------------- |
| 240 | |
| 241 | void pci_bus_device::device_post_load() |
| 242 | { |
| 243 | if (m_devicenum != -1) |
| 244 | { |
| 245 | m_busnumaddr = pci_search_bustree(m_busnumber, m_devicenum, this); |
| 246 | } |
| 247 | } |
| 248 | |
| 249 | //------------------------------------------------- |
| 250 | // device_start - device-specific startup |
| 251 | //------------------------------------------------- |
| 252 | |
| 253 | void pci_bus_device::device_start() |
| 254 | { |
| 255 | /* store a pointer back to the device */ |
| 256 | m_devicenum = -1; |
| 257 | |
| 258 | char id[3]; |
| 259 | /* find all our devices */ |
| 260 | for (int i = 0; i < ARRAY_LENGTH(m_devtag); i++) |
| 261 | { |
| 262 | sprintf(id, "%d", i); |
| 263 | pci_connector *conn = downcast<pci_connector *>(subdevice(id)); |
| 264 | if (conn!=NULL) |
| 265 | m_device[i] = conn->get_device(); |
| 266 | else |
| 267 | m_device[i] = NULL; |
| 268 | } |
| 269 | |
| 270 | if (m_father != NULL) { |
| 271 | pci_bus_device *father = machine().device<pci_bus_device>(m_father); |
| 272 | if (father) |
| 273 | father->add_sibling(this, m_busnum); |
| 274 | } |
| 275 | |
| 276 | /* register pci states */ |
| 277 | save_item(NAME(m_address)); |
| 278 | save_item(NAME(m_devicenum)); |
| 279 | save_item(NAME(m_busnum)); |
| 280 | } |
| 281 | |
| 282 | |
| 283 | //------------------------------------------------- |
| 284 | // device_reset - device-specific reset |
| 285 | //------------------------------------------------- |
| 286 | |
| 287 | void pci_bus_device::device_reset() |
| 288 | { |
| 289 | /* reset the drive state */ |
| 290 | m_devicenum = -1; |
| 291 | m_address = 0; |
| 292 | } |
| 293 | |
| 294 | //------------------------------------------------- |
| 295 | // pci_device_interface - constructor |
| 296 | //------------------------------------------------- |
| 297 | |
| 298 | pci_device_interface::pci_device_interface(const machine_config &mconfig, device_t &device) |
| 299 | : device_slot_card_interface(mconfig, device) |
| 300 | { |
| 301 | } |
| 302 | |
| 303 | //------------------------------------------------- |
| 304 | // ~pci_device_interface - destructor |
| 305 | //------------------------------------------------- |
| 306 | |
| 307 | pci_device_interface::~pci_device_interface() |
| 308 | { |
| 309 | } |
| 310 | |
| 311 | |
| 312 | const device_type PCI_CONNECTOR = &device_creator<pci_connector>; |
| 313 | |
| 314 | |
| 315 | pci_connector::pci_connector(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 316 | device_t(mconfig, PCI_CONNECTOR, "PCI device connector abstraction", tag, owner, clock, "pci_connector", __FILE__), |
| 317 | device_slot_interface(mconfig, *this) |
| 318 | { |
| 319 | } |
| 320 | |
| 321 | pci_connector::~pci_connector() |
| 322 | { |
| 323 | } |
| 324 | |
| 325 | void pci_connector::device_start() |
| 326 | { |
| 327 | } |
| 328 | |
| 329 | pci_device_interface *pci_connector::get_device() |
| 330 | { |
| 331 | return dynamic_cast<pci_device_interface *>(get_card_device()); |
| 332 | } |
trunk/src/emu/bus/lpci/southbridge.c
r0 | r241729 | |
| 1 | /*************************************************************************** |
| 2 | |
| 3 | Southbridge implementation |
| 4 | |
| 5 | ***************************************************************************/ |
| 6 | |
| 7 | #include "emu.h" |
| 8 | #include "cpu/i386/i386.h" |
| 9 | #include "southbridge.h" |
| 10 | #include "bus/pc_kbd/keyboards.h" |
| 11 | |
| 12 | |
| 13 | static SLOT_INTERFACE_START(pc_isa_onboard) |
| 14 | SLOT_INTERFACE("comat", ISA8_COM_AT) |
| 15 | SLOT_INTERFACE("lpt", ISA8_LPT) |
| 16 | SLOT_INTERFACE("fdcsmc", ISA8_FDC_SMC) |
| 17 | SLOT_INTERFACE_END |
| 18 | |
| 19 | static MACHINE_CONFIG_FRAGMENT( southbridge ) |
| 20 | MCFG_DEVICE_ADD("pit8254", PIT8254, 0) |
| 21 | MCFG_PIT8253_CLK0(4772720/4) /* heartbeat IRQ */ |
| 22 | MCFG_PIT8253_OUT0_HANDLER(WRITELINE(southbridge_device, at_pit8254_out0_changed)) |
| 23 | MCFG_PIT8253_CLK1(4772720/4) /* dram refresh */ |
| 24 | MCFG_PIT8253_OUT1_HANDLER(WRITELINE(southbridge_device, at_pit8254_out1_changed)) |
| 25 | MCFG_PIT8253_CLK2(4772720/4) /* pio port c pin 4, and speaker polling enough */ |
| 26 | MCFG_PIT8253_OUT2_HANDLER(WRITELINE(southbridge_device, at_pit8254_out2_changed)) |
| 27 | |
| 28 | MCFG_DEVICE_ADD( "dma8237_1", AM9517A, XTAL_14_31818MHz/3 ) |
| 29 | MCFG_I8237_OUT_HREQ_CB(DEVWRITELINE("dma8237_2", am9517a_device, dreq0_w)) |
| 30 | MCFG_I8237_OUT_EOP_CB(WRITELINE(southbridge_device, at_dma8237_out_eop)) |
| 31 | MCFG_I8237_IN_MEMR_CB(READ8(southbridge_device, pc_dma_read_byte)) |
| 32 | MCFG_I8237_OUT_MEMW_CB(WRITE8(southbridge_device, pc_dma_write_byte)) |
| 33 | MCFG_I8237_IN_IOR_0_CB(READ8(southbridge_device, pc_dma8237_0_dack_r)) |
| 34 | MCFG_I8237_IN_IOR_1_CB(READ8(southbridge_device, pc_dma8237_1_dack_r)) |
| 35 | MCFG_I8237_IN_IOR_2_CB(READ8(southbridge_device, pc_dma8237_2_dack_r)) |
| 36 | MCFG_I8237_IN_IOR_3_CB(READ8(southbridge_device, pc_dma8237_3_dack_r)) |
| 37 | MCFG_I8237_OUT_IOW_0_CB(WRITE8(southbridge_device, pc_dma8237_0_dack_w)) |
| 38 | MCFG_I8237_OUT_IOW_1_CB(WRITE8(southbridge_device, pc_dma8237_1_dack_w)) |
| 39 | MCFG_I8237_OUT_IOW_2_CB(WRITE8(southbridge_device, pc_dma8237_2_dack_w)) |
| 40 | MCFG_I8237_OUT_IOW_3_CB(WRITE8(southbridge_device, pc_dma8237_3_dack_w)) |
| 41 | MCFG_I8237_OUT_DACK_0_CB(WRITELINE(southbridge_device, pc_dack0_w)) |
| 42 | MCFG_I8237_OUT_DACK_1_CB(WRITELINE(southbridge_device, pc_dack1_w)) |
| 43 | MCFG_I8237_OUT_DACK_2_CB(WRITELINE(southbridge_device, pc_dack2_w)) |
| 44 | MCFG_I8237_OUT_DACK_3_CB(WRITELINE(southbridge_device, pc_dack3_w)) |
| 45 | |
| 46 | MCFG_DEVICE_ADD( "dma8237_2", AM9517A, XTAL_14_31818MHz/3 ) |
| 47 | MCFG_I8237_OUT_HREQ_CB(WRITELINE(southbridge_device, pc_dma_hrq_changed)) |
| 48 | MCFG_I8237_IN_MEMR_CB(READ8(southbridge_device, pc_dma_read_word)) |
| 49 | MCFG_I8237_OUT_MEMW_CB(WRITE8(southbridge_device, pc_dma_write_word)) |
| 50 | MCFG_I8237_IN_IOR_1_CB(READ8(southbridge_device, pc_dma8237_5_dack_r)) |
| 51 | MCFG_I8237_IN_IOR_2_CB(READ8(southbridge_device, pc_dma8237_6_dack_r)) |
| 52 | MCFG_I8237_IN_IOR_3_CB(READ8(southbridge_device, pc_dma8237_7_dack_r)) |
| 53 | MCFG_I8237_OUT_IOW_1_CB(WRITE8(southbridge_device, pc_dma8237_5_dack_w)) |
| 54 | MCFG_I8237_OUT_IOW_2_CB(WRITE8(southbridge_device, pc_dma8237_6_dack_w)) |
| 55 | MCFG_I8237_OUT_IOW_3_CB(WRITE8(southbridge_device, pc_dma8237_7_dack_w)) |
| 56 | MCFG_I8237_OUT_DACK_0_CB(WRITELINE(southbridge_device, pc_dack4_w)) |
| 57 | MCFG_I8237_OUT_DACK_1_CB(WRITELINE(southbridge_device, pc_dack5_w)) |
| 58 | MCFG_I8237_OUT_DACK_2_CB(WRITELINE(southbridge_device, pc_dack6_w)) |
| 59 | MCFG_I8237_OUT_DACK_3_CB(WRITELINE(southbridge_device, pc_dack7_w)) |
| 60 | |
| 61 | MCFG_PIC8259_ADD( "pic8259_master", INPUTLINE(":maincpu", 0), VCC, READ8(southbridge_device, get_slave_ack) ) |
| 62 | MCFG_PIC8259_ADD( "pic8259_slave", DEVWRITELINE("pic8259_master", pic8259_device, ir2_w), GND, NULL ) |
| 63 | |
| 64 | MCFG_DEVICE_ADD("keybc", AT_KEYBOARD_CONTROLLER, XTAL_12MHz) |
| 65 | MCFG_AT_KEYBOARD_CONTROLLER_SYSTEM_RESET_CB(INPUTLINE(":maincpu", INPUT_LINE_RESET)) |
| 66 | MCFG_AT_KEYBOARD_CONTROLLER_GATE_A20_CB(INPUTLINE(":maincpu", INPUT_LINE_A20)) |
| 67 | MCFG_AT_KEYBOARD_CONTROLLER_INPUT_BUFFER_FULL_CB(DEVWRITELINE("pic8259_master", pic8259_device, ir1_w)) |
| 68 | MCFG_AT_KEYBOARD_CONTROLLER_KEYBOARD_CLOCK_CB(DEVWRITELINE("pc_kbdc", pc_kbdc_device, clock_write_from_mb)) |
| 69 | MCFG_AT_KEYBOARD_CONTROLLER_KEYBOARD_DATA_CB(DEVWRITELINE("pc_kbdc", pc_kbdc_device, data_write_from_mb)) |
| 70 | MCFG_DEVICE_ADD("pc_kbdc", PC_KBDC, 0) |
| 71 | MCFG_PC_KBDC_OUT_CLOCK_CB(DEVWRITELINE("keybc", at_keyboard_controller_device, keyboard_clock_w)) |
| 72 | MCFG_PC_KBDC_OUT_DATA_CB(DEVWRITELINE("keybc", at_keyboard_controller_device, keyboard_data_w)) |
| 73 | MCFG_PC_KBDC_SLOT_ADD("pc_kbdc", "kbd", pc_at_keyboards, STR_KBD_MICROSOFT_NATURAL) |
| 74 | |
| 75 | MCFG_DS12885_ADD("rtc") |
| 76 | MCFG_MC146818_IRQ_HANDLER(DEVWRITELINE("pic8259_slave", pic8259_device, ir0_w)) |
| 77 | MCFG_MC146818_CENTURY_INDEX(0x32) |
| 78 | |
| 79 | MCFG_BUS_MASTER_IDE_CONTROLLER_ADD("ide", ata_devices, "hdd", NULL, false) |
| 80 | MCFG_ATA_INTERFACE_IRQ_HANDLER(DEVWRITELINE("pic8259_slave", pic8259_device, ir6_w)) |
| 81 | MCFG_BUS_MASTER_IDE_CONTROLLER_SPACE(":maincpu", AS_PROGRAM) |
| 82 | |
| 83 | MCFG_BUS_MASTER_IDE_CONTROLLER_ADD("ide2", ata_devices, "cdrom", NULL, false) |
| 84 | MCFG_ATA_INTERFACE_IRQ_HANDLER(DEVWRITELINE("pic8259_slave", pic8259_device, ir7_w)) |
| 85 | MCFG_BUS_MASTER_IDE_CONTROLLER_SPACE(":maincpu", AS_PROGRAM) |
| 86 | |
| 87 | /* sound hardware */ |
| 88 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 89 | MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0) |
| 90 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) |
| 91 | |
| 92 | MCFG_DEVICE_ADD("isabus", ISA16, 0) |
| 93 | MCFG_ISA16_CPU(":maincpu") |
| 94 | MCFG_ISA_OUT_IRQ2_CB(DEVWRITELINE("pic8259_slave", pic8259_device, ir2_w)) // in place of irq 2 on at irq 9 is used |
| 95 | MCFG_ISA_OUT_IRQ3_CB(DEVWRITELINE("pic8259_master", pic8259_device, ir3_w)) |
| 96 | MCFG_ISA_OUT_IRQ4_CB(DEVWRITELINE("pic8259_master", pic8259_device, ir4_w)) |
| 97 | MCFG_ISA_OUT_IRQ5_CB(DEVWRITELINE("pic8259_master", pic8259_device, ir5_w)) |
| 98 | MCFG_ISA_OUT_IRQ6_CB(DEVWRITELINE("pic8259_master", pic8259_device, ir6_w)) |
| 99 | MCFG_ISA_OUT_IRQ7_CB(DEVWRITELINE("pic8259_master", pic8259_device, ir7_w)) |
| 100 | MCFG_ISA_OUT_IRQ10_CB(DEVWRITELINE("pic8259_slave", pic8259_device, ir3_w)) |
| 101 | MCFG_ISA_OUT_IRQ11_CB(DEVWRITELINE("pic8259_slave", pic8259_device, ir4_w)) |
| 102 | MCFG_ISA_OUT_IRQ12_CB(DEVWRITELINE("pic8259_slave", pic8259_device, ir5_w)) |
| 103 | MCFG_ISA_OUT_IRQ14_CB(DEVWRITELINE("pic8259_slave", pic8259_device, ir6_w)) |
| 104 | MCFG_ISA_OUT_IRQ15_CB(DEVWRITELINE("pic8259_slave", pic8259_device, ir7_w)) |
| 105 | MCFG_ISA_OUT_DRQ0_CB(DEVWRITELINE("dma8237_1", am9517a_device, dreq0_w)) |
| 106 | MCFG_ISA_OUT_DRQ1_CB(DEVWRITELINE("dma8237_1", am9517a_device, dreq1_w)) |
| 107 | MCFG_ISA_OUT_DRQ2_CB(DEVWRITELINE("dma8237_1", am9517a_device, dreq2_w)) |
| 108 | MCFG_ISA_OUT_DRQ3_CB(DEVWRITELINE("dma8237_1", am9517a_device, dreq3_w)) |
| 109 | MCFG_ISA_OUT_DRQ5_CB(DEVWRITELINE("dma8237_2", am9517a_device, dreq1_w)) |
| 110 | MCFG_ISA_OUT_DRQ6_CB(DEVWRITELINE("dma8237_2", am9517a_device, dreq2_w)) |
| 111 | MCFG_ISA_OUT_DRQ7_CB(DEVWRITELINE("dma8237_2", am9517a_device, dreq3_w)) |
| 112 | // on board devices |
| 113 | MCFG_ISA16_SLOT_ADD("isabus","board1", pc_isa_onboard, "fdcsmc", true) |
| 114 | MCFG_ISA16_SLOT_ADD("isabus","board2", pc_isa_onboard, "comat", true) |
| 115 | MCFG_ISA16_SLOT_ADD("isabus","board3", pc_isa_onboard, "lpt", true) |
| 116 | MACHINE_CONFIG_END |
| 117 | |
| 118 | //------------------------------------------------- |
| 119 | // machine_config_additions - device-specific |
| 120 | // machine configurations |
| 121 | //------------------------------------------------- |
| 122 | |
| 123 | machine_config_constructor southbridge_device::device_mconfig_additions() const |
| 124 | { |
| 125 | return MACHINE_CONFIG_NAME( southbridge ); |
| 126 | } |
| 127 | |
| 128 | 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) |
| 129 | : device_t(mconfig, type, name, tag, owner, clock, shortname, source), |
| 130 | m_maincpu(*this, ":maincpu"), |
| 131 | m_pic8259_master(*this, "pic8259_master"), |
| 132 | m_pic8259_slave(*this, "pic8259_slave"), |
| 133 | m_dma8237_1(*this, "dma8237_1"), |
| 134 | m_dma8237_2(*this, "dma8237_2"), |
| 135 | m_pit8254(*this, "pit8254"), |
| 136 | m_keybc(*this, "keybc"), |
| 137 | m_isabus(*this, "isabus"), |
| 138 | m_speaker(*this, "speaker"), |
| 139 | m_ds12885(*this, "rtc"), |
| 140 | m_pc_kbdc(*this, "pc_kbdc"), |
| 141 | m_ide(*this, "ide"), |
| 142 | m_ide2(*this, "ide2") |
| 143 | { |
| 144 | } |
| 145 | /********************************************************** |
| 146 | * |
| 147 | * Init functions |
| 148 | * |
| 149 | **********************************************************/ |
| 150 | |
| 151 | /// HACK: the memory system cannot cope with mixing the 8 bit device map from the fdc with a 32 bit handler |
| 152 | READ8_MEMBER(southbridge_device::ide_read_cs1_r) |
| 153 | { |
| 154 | return m_ide->read_cs1(space, 1, (UINT32) 0xff0000) >> 16; |
| 155 | } |
| 156 | |
| 157 | WRITE8_MEMBER(southbridge_device::ide_write_cs1_w) |
| 158 | { |
| 159 | m_ide->write_cs1(space, 1, (UINT32) data << 16, (UINT32) 0xff0000); |
| 160 | } |
| 161 | |
| 162 | READ8_MEMBER(southbridge_device::ide2_read_cs1_r) |
| 163 | { |
| 164 | return m_ide2->read_cs1(space, 1, (UINT32) 0xff0000) >> 16; |
| 165 | } |
| 166 | |
| 167 | WRITE8_MEMBER(southbridge_device::ide2_write_cs1_w) |
| 168 | { |
| 169 | m_ide2->write_cs1(space, 1, (UINT32) data << 16, (UINT32) 0xff0000); |
| 170 | } |
| 171 | |
| 172 | //------------------------------------------------- |
| 173 | // device_start - device-specific startup |
| 174 | //------------------------------------------------- |
| 175 | |
| 176 | void southbridge_device::device_start() |
| 177 | { |
| 178 | address_space& spaceio = machine().device(":maincpu")->memory().space(AS_IO); |
| 179 | |
| 180 | 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); |
| 181 | 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); |
| 182 | spaceio.install_readwrite_handler(0x0040, 0x005f, read8_delegate(FUNC(pit8254_device::read),&(*m_pit8254)), write8_delegate(FUNC(pit8254_device::write),&(*m_pit8254)), 0xffffffff); |
| 183 | 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); |
| 184 | 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); |
| 185 | spaceio.install_readwrite_handler(0x0070, 0x007f, read8_delegate(FUNC(ds12885_device::read),&(*m_ds12885)), write8_delegate(FUNC(ds12885_device::write),&(*m_ds12885)), 0xffffffff); |
| 186 | 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); |
| 187 | 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); |
| 188 | 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); |
| 189 | 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); |
| 190 | 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); |
| 191 | // HACK: this works if you take out the (non working) fdc |
| 192 | // 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); |
| 193 | // 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); |
| 194 | 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); |
| 195 | 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); |
| 196 | spaceio.nop_readwrite(0x00e0, 0x00ef); |
| 197 | } |
| 198 | |
| 199 | //------------------------------------------------- |
| 200 | // device_reset - device-specific reset |
| 201 | //------------------------------------------------- |
| 202 | |
| 203 | void southbridge_device::device_reset() |
| 204 | { |
| 205 | m_at_spkrdata = 0; |
| 206 | m_pit_out2 = 0; |
| 207 | m_dma_channel = -1; |
| 208 | m_cur_eop = false; |
| 209 | m_nmi_enabled = 0; |
| 210 | m_refresh = false; |
| 211 | } |
| 212 | |
| 213 | |
| 214 | /************************************************************* |
| 215 | * |
| 216 | * pic8259 configuration |
| 217 | * |
| 218 | *************************************************************/ |
| 219 | READ8_MEMBER( southbridge_device::get_slave_ack ) |
| 220 | { |
| 221 | if (offset==2) // IRQ = 2 |
| 222 | return m_pic8259_slave->acknowledge(); |
| 223 | |
| 224 | return 0x00; |
| 225 | } |
| 226 | |
| 227 | /************************************************************************* |
| 228 | * |
| 229 | * PC Speaker related |
| 230 | * |
| 231 | *************************************************************************/ |
| 232 | |
| 233 | void southbridge_device::at_speaker_set_spkrdata(UINT8 data) |
| 234 | { |
| 235 | m_at_spkrdata = data ? 1 : 0; |
| 236 | m_speaker->level_w(m_at_spkrdata & m_pit_out2); |
| 237 | } |
| 238 | |
| 239 | |
| 240 | |
| 241 | /************************************************************* |
| 242 | * |
| 243 | * pit8254 configuration |
| 244 | * |
| 245 | *************************************************************/ |
| 246 | |
| 247 | WRITE_LINE_MEMBER( southbridge_device::at_pit8254_out0_changed ) |
| 248 | { |
| 249 | if (m_pic8259_master) |
| 250 | m_pic8259_master->ir0_w(state); |
| 251 | } |
| 252 | |
| 253 | WRITE_LINE_MEMBER( southbridge_device::at_pit8254_out1_changed ) |
| 254 | { |
| 255 | if(state) |
| 256 | m_refresh = !m_refresh; |
| 257 | } |
| 258 | |
| 259 | WRITE_LINE_MEMBER( southbridge_device::at_pit8254_out2_changed ) |
| 260 | { |
| 261 | m_pit_out2 = state ? 1 : 0; |
| 262 | m_speaker->level_w(m_at_spkrdata & m_pit_out2); |
| 263 | } |
| 264 | |
| 265 | /************************************************************************* |
| 266 | * |
| 267 | * PC DMA stuff |
| 268 | * |
| 269 | *************************************************************************/ |
| 270 | |
| 271 | READ8_MEMBER( southbridge_device::at_page8_r ) |
| 272 | { |
| 273 | UINT8 data = m_at_pages[offset % 0x10]; |
| 274 | |
| 275 | switch(offset % 8) |
| 276 | { |
| 277 | case 1: |
| 278 | data = m_dma_offset[BIT(offset, 3)][2]; |
| 279 | break; |
| 280 | case 2: |
| 281 | data = m_dma_offset[BIT(offset, 3)][3]; |
| 282 | break; |
| 283 | case 3: |
| 284 | data = m_dma_offset[BIT(offset, 3)][1]; |
| 285 | break; |
| 286 | case 7: |
| 287 | data = m_dma_offset[BIT(offset, 3)][0]; |
| 288 | break; |
| 289 | } |
| 290 | return data; |
| 291 | } |
| 292 | |
| 293 | |
| 294 | WRITE8_MEMBER( southbridge_device::at_page8_w ) |
| 295 | { |
| 296 | m_at_pages[offset % 0x10] = data; |
| 297 | |
| 298 | switch(offset % 8) |
| 299 | { |
| 300 | case 1: |
| 301 | m_dma_offset[BIT(offset, 3)][2] = data; |
| 302 | break; |
| 303 | case 2: |
| 304 | m_dma_offset[BIT(offset, 3)][3] = data; |
| 305 | break; |
| 306 | case 3: |
| 307 | m_dma_offset[BIT(offset, 3)][1] = data; |
| 308 | break; |
| 309 | case 7: |
| 310 | m_dma_offset[BIT(offset, 3)][0] = data; |
| 311 | break; |
| 312 | } |
| 313 | } |
| 314 | |
| 315 | |
| 316 | WRITE_LINE_MEMBER( southbridge_device::pc_dma_hrq_changed ) |
| 317 | { |
| 318 | m_maincpu->set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE); |
| 319 | |
| 320 | /* Assert HLDA */ |
| 321 | m_dma8237_2->hack_w( state ); |
| 322 | } |
| 323 | |
| 324 | READ8_MEMBER(southbridge_device::pc_dma_read_byte) |
| 325 | { |
| 326 | address_space& prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space |
| 327 | if(m_dma_channel == -1) |
| 328 | return 0xff; |
| 329 | UINT8 result; |
| 330 | offs_t page_offset = (((offs_t) m_dma_offset[0][m_dma_channel]) << 16) & 0xFF0000; |
| 331 | |
| 332 | result = prog_space.read_byte(page_offset + offset); |
| 333 | return result; |
| 334 | } |
| 335 | |
| 336 | |
| 337 | WRITE8_MEMBER(southbridge_device::pc_dma_write_byte) |
| 338 | { |
| 339 | address_space& prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space |
| 340 | if(m_dma_channel == -1) |
| 341 | return; |
| 342 | offs_t page_offset = (((offs_t) m_dma_offset[0][m_dma_channel]) << 16) & 0xFF0000; |
| 343 | |
| 344 | prog_space.write_byte(page_offset + offset, data); |
| 345 | } |
| 346 | |
| 347 | |
| 348 | READ8_MEMBER(southbridge_device::pc_dma_read_word) |
| 349 | { |
| 350 | address_space& prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space |
| 351 | if(m_dma_channel == -1) |
| 352 | return 0xff; |
| 353 | UINT16 result; |
| 354 | offs_t page_offset = (((offs_t) m_dma_offset[1][m_dma_channel & 3]) << 16) & 0xFE0000; |
| 355 | |
| 356 | result = prog_space.read_word(page_offset + ( offset << 1 ) ); |
| 357 | m_dma_high_byte = result & 0xFF00; |
| 358 | |
| 359 | return result & 0xFF; |
| 360 | } |
| 361 | |
| 362 | |
| 363 | WRITE8_MEMBER(southbridge_device::pc_dma_write_word) |
| 364 | { |
| 365 | address_space& prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space |
| 366 | if(m_dma_channel == -1) |
| 367 | return; |
| 368 | offs_t page_offset = (((offs_t) m_dma_offset[1][m_dma_channel & 3]) << 16) & 0xFE0000; |
| 369 | |
| 370 | prog_space.write_word(page_offset + ( offset << 1 ), m_dma_high_byte | data); |
| 371 | } |
| 372 | |
| 373 | |
| 374 | READ8_MEMBER( southbridge_device::pc_dma8237_0_dack_r ) { return m_isabus->dack_r(0); } |
| 375 | READ8_MEMBER( southbridge_device::pc_dma8237_1_dack_r ) { return m_isabus->dack_r(1); } |
| 376 | READ8_MEMBER( southbridge_device::pc_dma8237_2_dack_r ) { return m_isabus->dack_r(2); } |
| 377 | READ8_MEMBER( southbridge_device::pc_dma8237_3_dack_r ) { return m_isabus->dack_r(3); } |
| 378 | READ8_MEMBER( southbridge_device::pc_dma8237_5_dack_r ) { return m_isabus->dack_r(5); } |
| 379 | READ8_MEMBER( southbridge_device::pc_dma8237_6_dack_r ) { return m_isabus->dack_r(6); } |
| 380 | READ8_MEMBER( southbridge_device::pc_dma8237_7_dack_r ) { return m_isabus->dack_r(7); } |
| 381 | |
| 382 | |
| 383 | WRITE8_MEMBER( southbridge_device::pc_dma8237_0_dack_w ){ m_isabus->dack_w(0, data); } |
| 384 | WRITE8_MEMBER( southbridge_device::pc_dma8237_1_dack_w ){ m_isabus->dack_w(1, data); } |
| 385 | WRITE8_MEMBER( southbridge_device::pc_dma8237_2_dack_w ){ m_isabus->dack_w(2, data); } |
| 386 | WRITE8_MEMBER( southbridge_device::pc_dma8237_3_dack_w ){ m_isabus->dack_w(3, data); } |
| 387 | WRITE8_MEMBER( southbridge_device::pc_dma8237_5_dack_w ){ m_isabus->dack_w(5, data); } |
| 388 | WRITE8_MEMBER( southbridge_device::pc_dma8237_6_dack_w ){ m_isabus->dack_w(6, data); } |
| 389 | WRITE8_MEMBER( southbridge_device::pc_dma8237_7_dack_w ){ m_isabus->dack_w(7, data); } |
| 390 | |
| 391 | WRITE_LINE_MEMBER( southbridge_device::at_dma8237_out_eop ) |
| 392 | { |
| 393 | m_cur_eop = state == ASSERT_LINE; |
| 394 | if(m_dma_channel != -1) |
| 395 | m_isabus->eop_w(m_dma_channel, m_cur_eop ? ASSERT_LINE : CLEAR_LINE ); |
| 396 | } |
| 397 | |
| 398 | void southbridge_device::pc_select_dma_channel(int channel, bool state) |
| 399 | { |
| 400 | if(!state) { |
| 401 | m_dma_channel = channel; |
| 402 | if(m_cur_eop) |
| 403 | m_isabus->eop_w(channel, ASSERT_LINE ); |
| 404 | |
| 405 | } else if(m_dma_channel == channel) { |
| 406 | m_dma_channel = -1; |
| 407 | if(m_cur_eop) |
| 408 | m_isabus->eop_w(channel, CLEAR_LINE ); |
| 409 | } |
| 410 | } |
| 411 | |
| 412 | |
| 413 | WRITE_LINE_MEMBER( southbridge_device::pc_dack0_w ) { pc_select_dma_channel(0, state); } |
| 414 | WRITE_LINE_MEMBER( southbridge_device::pc_dack1_w ) { pc_select_dma_channel(1, state); } |
| 415 | WRITE_LINE_MEMBER( southbridge_device::pc_dack2_w ) { pc_select_dma_channel(2, state); } |
| 416 | WRITE_LINE_MEMBER( southbridge_device::pc_dack3_w ) { pc_select_dma_channel(3, state); } |
| 417 | WRITE_LINE_MEMBER( southbridge_device::pc_dack4_w ) { m_dma8237_1->hack_w( state ? 0 : 1); } // it's inverted |
| 418 | WRITE_LINE_MEMBER( southbridge_device::pc_dack5_w ) { pc_select_dma_channel(5, state); } |
| 419 | WRITE_LINE_MEMBER( southbridge_device::pc_dack6_w ) { pc_select_dma_channel(6, state); } |
| 420 | WRITE_LINE_MEMBER( southbridge_device::pc_dack7_w ) { pc_select_dma_channel(7, state); } |
| 421 | |
| 422 | READ8_MEMBER( southbridge_device::at_portb_r ) |
| 423 | { |
| 424 | UINT8 data = m_at_speaker; |
| 425 | data &= ~0xd0; /* AT BIOS don't likes this being set */ |
| 426 | |
| 427 | /* 0x10 is the dram refresh line bit on the 5170, just a timer here, 15.085us. */ |
| 428 | data |= m_refresh ? 0x10 : 0; |
| 429 | |
| 430 | if (m_pit_out2) |
| 431 | data |= 0x20; |
| 432 | else |
| 433 | data &= ~0x20; /* ps2m30 wants this */ |
| 434 | |
| 435 | return data; |
| 436 | } |
| 437 | |
| 438 | WRITE8_MEMBER( southbridge_device::at_portb_w ) |
| 439 | { |
| 440 | m_at_speaker = data; |
| 441 | m_pit8254->write_gate2(BIT(data, 0)); |
| 442 | at_speaker_set_spkrdata( BIT(data, 1)); |
| 443 | m_channel_check = BIT(data, 3); |
| 444 | m_isabus->set_nmi_state((m_nmi_enabled==0) && (m_channel_check==0)); |
| 445 | } |
| 446 | |
| 447 | READ8_MEMBER( southbridge_device::at_dma8237_2_r ) |
| 448 | { |
| 449 | return m_dma8237_2->read( space, offset / 2); |
| 450 | } |
| 451 | |
| 452 | WRITE8_MEMBER( southbridge_device::at_dma8237_2_w ) |
| 453 | { |
| 454 | m_dma8237_2->write( space, offset / 2, data); |
| 455 | } |
| 456 | |
| 457 | READ8_MEMBER( southbridge_device::at_keybc_r ) |
| 458 | { |
| 459 | switch (offset) |
| 460 | { |
| 461 | case 0: return m_keybc->data_r(space, 0); |
| 462 | case 1: return at_portb_r(space, 0); |
| 463 | } |
| 464 | |
| 465 | return 0xff; |
| 466 | } |
| 467 | |
| 468 | WRITE8_MEMBER( southbridge_device::at_keybc_w ) |
| 469 | { |
| 470 | switch (offset) |
| 471 | { |
| 472 | case 0: m_keybc->data_w(space, 0, data); break; |
| 473 | case 1: at_portb_w(space, 0, data); break; |
| 474 | } |
| 475 | } |
| 476 | |
| 477 | |
| 478 | WRITE8_MEMBER( southbridge_device::write_rtc ) |
| 479 | { |
| 480 | if (offset==0) { |
| 481 | m_nmi_enabled = BIT(data,7); |
| 482 | m_isabus->set_nmi_state((m_nmi_enabled==0) && (m_channel_check==0)); |
| 483 | m_ds12885->write(space,0,data); |
| 484 | } |
| 485 | else { |
| 486 | m_ds12885->write(space,offset,data); |
| 487 | } |
| 488 | } |
trunk/src/emu/bus/lpci/southbridge.h
r0 | r241729 | |
| 1 | #pragma once |
| 2 | |
| 3 | #ifndef __SOUTHBRIDGE_H__ |
| 4 | #define __SOUTHBRIDGE_H__ |
| 5 | |
| 6 | #include "emu.h" |
| 7 | |
| 8 | #include "machine/ins8250.h" |
| 9 | #include "machine/ds128x.h" |
| 10 | #include "machine/pic8259.h" |
| 11 | #include "machine/pit8253.h" |
| 12 | |
| 13 | #include "machine/ataintf.h" |
| 14 | #include "machine/at_keybc.h" |
| 15 | |
| 16 | #include "imagedev/harddriv.h" |
| 17 | #include "pci.h" |
| 18 | |
| 19 | #include "sound/dac.h" |
| 20 | #include "sound/speaker.h" |
| 21 | #include "machine/ram.h" |
| 22 | #include "machine/nvram.h" |
| 23 | #include "bus/isa/isa.h" |
| 24 | #include "bus/isa/isa_cards.h" |
| 25 | |
| 26 | #include "machine/pc_lpt.h" |
| 27 | #include "bus/pc_kbd/pc_kbdc.h" |
| 28 | |
| 29 | #include "machine/am9517a.h" |
| 30 | |
| 31 | //************************************************************************** |
| 32 | // TYPE DEFINITIONS |
| 33 | //************************************************************************** |
| 34 | |
| 35 | // ======================> southbridge_device |
| 36 | |
| 37 | class southbridge_device : |
| 38 | public device_t |
| 39 | { |
| 40 | public: |
| 41 | // construction/destruction |
| 42 | 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); |
| 43 | |
| 44 | // optional information overrides |
| 45 | virtual machine_config_constructor device_mconfig_additions() const; |
| 46 | |
| 47 | protected: |
| 48 | // device-level overrides |
| 49 | virtual void device_start(); |
| 50 | virtual void device_reset(); |
| 51 | public: |
| 52 | |
| 53 | required_device<cpu_device> m_maincpu; |
| 54 | required_device<pic8259_device> m_pic8259_master; |
| 55 | required_device<pic8259_device> m_pic8259_slave; |
| 56 | required_device<am9517a_device> m_dma8237_1; |
| 57 | required_device<am9517a_device> m_dma8237_2; |
| 58 | required_device<pit8254_device> m_pit8254; |
| 59 | required_device<at_keyboard_controller_device> m_keybc; |
| 60 | required_device<isa16_device> m_isabus; |
| 61 | required_device<speaker_sound_device> m_speaker; |
| 62 | required_device<ds12885_device> m_ds12885; |
| 63 | required_device<pc_kbdc_device> m_pc_kbdc; |
| 64 | required_device<bus_master_ide_controller_device> m_ide; |
| 65 | required_device<bus_master_ide_controller_device> m_ide2; |
| 66 | DECLARE_READ8_MEMBER(at_page8_r); |
| 67 | DECLARE_WRITE8_MEMBER(at_page8_w); |
| 68 | DECLARE_READ8_MEMBER(at_portb_r); |
| 69 | DECLARE_WRITE8_MEMBER(at_portb_w); |
| 70 | DECLARE_READ8_MEMBER(get_slave_ack); |
| 71 | DECLARE_WRITE_LINE_MEMBER(at_pit8254_out0_changed); |
| 72 | DECLARE_WRITE_LINE_MEMBER(at_pit8254_out1_changed); |
| 73 | DECLARE_WRITE_LINE_MEMBER(at_pit8254_out2_changed); |
| 74 | DECLARE_WRITE_LINE_MEMBER(pc_dma_hrq_changed); |
| 75 | DECLARE_READ8_MEMBER(pc_dma8237_0_dack_r); |
| 76 | DECLARE_READ8_MEMBER(pc_dma8237_1_dack_r); |
| 77 | DECLARE_READ8_MEMBER(pc_dma8237_2_dack_r); |
| 78 | DECLARE_READ8_MEMBER(pc_dma8237_3_dack_r); |
| 79 | DECLARE_READ8_MEMBER(pc_dma8237_5_dack_r); |
| 80 | DECLARE_READ8_MEMBER(pc_dma8237_6_dack_r); |
| 81 | DECLARE_READ8_MEMBER(pc_dma8237_7_dack_r); |
| 82 | DECLARE_WRITE8_MEMBER(pc_dma8237_0_dack_w); |
| 83 | DECLARE_WRITE8_MEMBER(pc_dma8237_1_dack_w); |
| 84 | DECLARE_WRITE8_MEMBER(pc_dma8237_2_dack_w); |
| 85 | DECLARE_WRITE8_MEMBER(pc_dma8237_3_dack_w); |
| 86 | DECLARE_WRITE8_MEMBER(pc_dma8237_5_dack_w); |
| 87 | DECLARE_WRITE8_MEMBER(pc_dma8237_6_dack_w); |
| 88 | DECLARE_WRITE8_MEMBER(pc_dma8237_7_dack_w); |
| 89 | DECLARE_WRITE_LINE_MEMBER(at_dma8237_out_eop); |
| 90 | DECLARE_WRITE_LINE_MEMBER(pc_dack0_w); |
| 91 | DECLARE_WRITE_LINE_MEMBER(pc_dack1_w); |
| 92 | DECLARE_WRITE_LINE_MEMBER(pc_dack2_w); |
| 93 | DECLARE_WRITE_LINE_MEMBER(pc_dack3_w); |
| 94 | DECLARE_WRITE_LINE_MEMBER(pc_dack4_w); |
| 95 | DECLARE_WRITE_LINE_MEMBER(pc_dack5_w); |
| 96 | DECLARE_WRITE_LINE_MEMBER(pc_dack6_w); |
| 97 | DECLARE_WRITE_LINE_MEMBER(pc_dack7_w); |
| 98 | DECLARE_READ8_MEMBER(ide_read_cs1_r); |
| 99 | DECLARE_WRITE8_MEMBER(ide_write_cs1_w); |
| 100 | DECLARE_READ8_MEMBER(ide2_read_cs1_r); |
| 101 | DECLARE_WRITE8_MEMBER(ide2_write_cs1_w); |
| 102 | DECLARE_READ8_MEMBER(at_dma8237_2_r); |
| 103 | DECLARE_WRITE8_MEMBER(at_dma8237_2_w); |
| 104 | DECLARE_READ8_MEMBER(at_keybc_r); |
| 105 | DECLARE_WRITE8_MEMBER(at_keybc_w); |
| 106 | DECLARE_WRITE8_MEMBER(write_rtc); |
| 107 | DECLARE_READ8_MEMBER(pc_dma_read_byte); |
| 108 | DECLARE_WRITE8_MEMBER(pc_dma_write_byte); |
| 109 | DECLARE_READ8_MEMBER(pc_dma_read_word); |
| 110 | DECLARE_WRITE8_MEMBER(pc_dma_write_word); |
| 111 | protected: |
| 112 | UINT8 m_at_spkrdata; |
| 113 | UINT8 m_pit_out2; |
| 114 | int m_dma_channel; |
| 115 | bool m_cur_eop; |
| 116 | UINT8 m_dma_offset[2][4]; |
| 117 | UINT8 m_at_pages[0x10]; |
| 118 | UINT16 m_dma_high_byte; |
| 119 | UINT8 m_at_speaker; |
| 120 | bool m_refresh; |
| 121 | void at_speaker_set_spkrdata(UINT8 data); |
| 122 | |
| 123 | UINT8 m_channel_check; |
| 124 | UINT8 m_nmi_enabled; |
| 125 | |
| 126 | void pc_select_dma_channel(int channel, bool state); |
| 127 | }; |
| 128 | |
| 129 | #endif /* __SOUTHBRIDGE_H__ */ |
trunk/src/emu/machine/lpci.c
r0 | r241729 | |
| 1 | /*************************************************************************** |
| 2 | |
| 3 | machine/lpci.c |
| 4 | |
| 5 | Legacy PCI bus |
| 6 | |
| 7 | The PCI bus is a 32-bit bus introduced by Intel, so it is little endian |
| 8 | |
| 9 | Control word: |
| 10 | bit 31: Enable bit |
| 11 | bits 30-24: Reserved |
| 12 | bits 23-16: PCI bus number |
| 13 | bits 15-11: PCI device number |
| 14 | bits 10- 8: PCI function number |
| 15 | bits 7- 0: Offset address |
| 16 | |
| 17 | Standard PCI registers: |
| 18 | 0x00 2 Vendor ID |
| 19 | 0x02 2 Device ID |
| 20 | 0x04 2 PCI Command |
| 21 | 0x06 2 PCI Status |
| 22 | 0x08 1 Revision ID |
| 23 | 0x09 1 Programming Interface |
| 24 | 0x0A 1 Subclass Code |
| 25 | 0x0B 1 Class Code |
| 26 | |
| 27 | Class Code/Subclass Code/Programming Interface |
| 28 | 0x00XXXX Pre-PCI 2.0 devices |
| 29 | 0x000000 Non-VGA device |
| 30 | 0x000101 VGA device |
| 31 | 0x01XXXX Storage Controller |
| 32 | 0x010000 SCSI |
| 33 | 0x0101XX IDE |
| 34 | 0x0102XX Floppy |
| 35 | 0x0103XX IPI |
| 36 | 0x0104XX RAID |
| 37 | 0x0180XX Other |
| 38 | 0x02XXXX Network Card |
| 39 | 0x020000 Ethernet |
| 40 | 0x020100 Tokenring |
| 41 | 0x020200 FDDI |
| 42 | 0x020300 ATM |
| 43 | 0x028000 Other |
| 44 | 0x03XXXX Display Controller |
| 45 | 0x030000 VGA |
| 46 | 0x030001 8514 Compatible |
| 47 | 0x030100 XGA |
| 48 | 0x038000 Other |
| 49 | 0x04XXXX Multimedia |
| 50 | 0x040000 Video |
| 51 | 0x040100 Audio |
| 52 | 0x048000 Other |
| 53 | 0x05XXXX Memory Controller |
| 54 | 0x050000 RAM |
| 55 | 0x050100 Flash |
| 56 | 0x058000 Other |
| 57 | 0x06XXXX Bridge |
| 58 | 0x060000 Host/PCI |
| 59 | 0x060100 PCI/ISA |
| 60 | 0x060200 PCI/EISA |
| 61 | 0x060300 PCI/Micro Channel |
| 62 | 0x060400 PCI/PCI |
| 63 | 0x060500 PCI/PCMCIA |
| 64 | 0x060600 PCI/NuBus |
| 65 | 0x060700 PCI/CardBus |
| 66 | 0x068000 Other |
| 67 | |
| 68 | Information on PCI vendors can be found at http://www.pcidatabase.com/ |
| 69 | |
| 70 | ***************************************************************************/ |
| 71 | |
| 72 | #include "emu.h" |
| 73 | #include "machine/lpci.h" |
| 74 | |
| 75 | #define LOG_PCI 0 |
| 76 | |
| 77 | //************************************************************************** |
| 78 | // GLOBAL VARIABLES |
| 79 | //************************************************************************** |
| 80 | |
| 81 | const device_type PCI_BUS_LEGACY = &device_creator<pci_bus_legacy_device>; |
| 82 | |
| 83 | //************************************************************************** |
| 84 | // LIVE DEVICE |
| 85 | //************************************************************************** |
| 86 | |
| 87 | //------------------------------------------------- |
| 88 | // pci_bus_legacy_device - constructor |
| 89 | //------------------------------------------------- |
| 90 | pci_bus_legacy_device::pci_bus_legacy_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 91 | device_t(mconfig, PCI_BUS_LEGACY, "PCI Bus Legacy", tag, owner, clock, "pci_bus_legacy", __FILE__), |
| 92 | m_father(NULL) |
| 93 | { |
| 94 | for (int i = 0; i < ARRAY_LENGTH(m_devtag); i++) { |
| 95 | m_devtag[i]= NULL; |
| 96 | m_read_callback[i] = NULL; |
| 97 | m_write_callback[i] = NULL; |
| 98 | } |
| 99 | m_siblings_count = 0; |
| 100 | } |
| 101 | |
| 102 | /*************************************************************************** |
| 103 | INLINE FUNCTIONS |
| 104 | ***************************************************************************/ |
| 105 | |
| 106 | READ32_MEMBER( pci_bus_legacy_device::read ) |
| 107 | { |
| 108 | UINT32 result = 0xffffffff; |
| 109 | int function, reg; |
| 110 | |
| 111 | offset %= 2; |
| 112 | |
| 113 | switch (offset) |
| 114 | { |
| 115 | case 0: |
| 116 | result = m_address; |
| 117 | break; |
| 118 | |
| 119 | case 1: |
| 120 | if (m_devicenum != -1) |
| 121 | { |
| 122 | pci_read_func read = m_busnumaddr->m_read_callback[m_devicenum]; |
| 123 | if (read != NULL) |
| 124 | { |
| 125 | function = (m_address >> 8) & 0x07; |
| 126 | reg = (m_address >> 0) & 0xfc; |
| 127 | result = (*read)(m_busnumaddr, m_busnumaddr->m_device[m_devicenum], function, reg, mem_mask); |
| 128 | } |
| 129 | } |
| 130 | break; |
| 131 | } |
| 132 | |
| 133 | if (LOG_PCI) |
| 134 | logerror("read('%s'): offset=%d result=0x%08X\n", tag(), offset, result); |
| 135 | |
| 136 | return result; |
| 137 | } |
| 138 | |
| 139 | |
| 140 | |
| 141 | pci_bus_legacy_device *pci_bus_legacy_device::pci_search_bustree(int busnum, int devicenum, pci_bus_legacy_device *pcibus) |
| 142 | { |
| 143 | int a; |
| 144 | pci_bus_legacy_device *ret; |
| 145 | |
| 146 | if (pcibus->m_busnum == busnum) |
| 147 | { |
| 148 | return pcibus; |
| 149 | } |
| 150 | for (a = 0; a < pcibus->m_siblings_count; a++) |
| 151 | { |
| 152 | ret = pci_search_bustree(busnum, devicenum, pcibus->m_siblings[a]); |
| 153 | if (ret != NULL) |
| 154 | return ret; |
| 155 | } |
| 156 | return NULL; |
| 157 | } |
| 158 | |
| 159 | |
| 160 | |
| 161 | WRITE32_MEMBER( pci_bus_legacy_device::write ) |
| 162 | { |
| 163 | offset %= 2; |
| 164 | |
| 165 | if (LOG_PCI) |
| 166 | logerror("write('%s'): offset=%d data=0x%08X\n", tag(), offset, data); |
| 167 | |
| 168 | switch (offset) |
| 169 | { |
| 170 | case 0: |
| 171 | m_address = data; |
| 172 | |
| 173 | /* lookup current device */ |
| 174 | if (m_address & 0x80000000) |
| 175 | { |
| 176 | int busnum = (m_address >> 16) & 0xff; |
| 177 | int devicenum = (m_address >> 11) & 0x1f; |
| 178 | m_busnumaddr = pci_search_bustree(busnum, devicenum, this); |
| 179 | if (m_busnumaddr != NULL) |
| 180 | { |
| 181 | m_busnumber = busnum; |
| 182 | m_devicenum = devicenum; |
| 183 | } |
| 184 | else |
| 185 | m_devicenum = -1; |
| 186 | if (LOG_PCI) |
| 187 | logerror(" bus:%d device:%d\n", busnum, devicenum); |
| 188 | } |
| 189 | break; |
| 190 | |
| 191 | case 1: |
| 192 | if (m_devicenum != -1) |
| 193 | { |
| 194 | pci_write_func write = m_busnumaddr->m_write_callback[m_devicenum]; |
| 195 | if (write != NULL) |
| 196 | { |
| 197 | int function = (m_address >> 8) & 0x07; |
| 198 | int reg = (m_address >> 0) & 0xfc; |
| 199 | (*write)(m_busnumaddr, m_busnumaddr->m_device[m_devicenum], function, reg, data, mem_mask); |
| 200 | } |
| 201 | if (LOG_PCI) |
| 202 | logerror(" function:%d register:%d\n", (m_address >> 8) & 0x07, (m_address >> 0) & 0xfc); |
| 203 | } |
| 204 | break; |
| 205 | } |
| 206 | } |
| 207 | |
| 208 | |
| 209 | |
| 210 | READ64_MEMBER(pci_bus_legacy_device::read_64be) |
| 211 | { |
| 212 | UINT64 result = 0; |
| 213 | mem_mask = FLIPENDIAN_INT64(mem_mask); |
| 214 | if (ACCESSING_BITS_0_31) |
| 215 | result |= (UINT64)read(space, offset * 2 + 0, mem_mask >> 0) << 0; |
| 216 | if (ACCESSING_BITS_32_63) |
| 217 | result |= (UINT64)read(space, offset * 2 + 1, mem_mask >> 32) << 32; |
| 218 | return FLIPENDIAN_INT64(result); |
| 219 | } |
| 220 | |
| 221 | WRITE64_MEMBER(pci_bus_legacy_device::write_64be) |
| 222 | { |
| 223 | data = FLIPENDIAN_INT64(data); |
| 224 | mem_mask = FLIPENDIAN_INT64(mem_mask); |
| 225 | if (ACCESSING_BITS_0_31) |
| 226 | write(space, offset * 2 + 0, data >> 0, mem_mask >> 0); |
| 227 | if (ACCESSING_BITS_32_63) |
| 228 | write(space, offset * 2 + 1, data >> 32, mem_mask >> 32); |
| 229 | } |
| 230 | |
| 231 | |
| 232 | void pci_bus_legacy_device::add_sibling(pci_bus_legacy_device *sibling, int busnum) |
| 233 | { |
| 234 | m_siblings[m_siblings_count] = sibling; |
| 235 | m_siblings_busnum[m_siblings_count] = busnum; |
| 236 | m_siblings_count++; |
| 237 | } |
| 238 | |
| 239 | |
| 240 | //------------------------------------------------- |
| 241 | // device_post_load - handle updating after a |
| 242 | // restore |
| 243 | //------------------------------------------------- |
| 244 | |
| 245 | void pci_bus_legacy_device::device_post_load() |
| 246 | { |
| 247 | if (m_devicenum != -1) |
| 248 | { |
| 249 | m_busnumaddr = pci_search_bustree(m_busnumber, m_devicenum, this); |
| 250 | } |
| 251 | } |
| 252 | |
| 253 | //------------------------------------------------- |
| 254 | // device_start - device-specific startup |
| 255 | //------------------------------------------------- |
| 256 | |
| 257 | void pci_bus_legacy_device::device_start() |
| 258 | { |
| 259 | /* store a pointer back to the device */ |
| 260 | m_devicenum = -1; |
| 261 | |
| 262 | /* find all our devices */ |
| 263 | for (int i = 0; i < ARRAY_LENGTH(m_devtag); i++) |
| 264 | if (m_devtag[i] != NULL) |
| 265 | m_device[i] = machine().device(m_devtag[i]); |
| 266 | |
| 267 | if (m_father != NULL) { |
| 268 | pci_bus_legacy_device *father = machine().device<pci_bus_legacy_device>(m_father); |
| 269 | if (father) |
| 270 | father->add_sibling(this, m_busnum); |
| 271 | } |
| 272 | |
| 273 | /* register pci states */ |
| 274 | save_item(NAME(m_address)); |
| 275 | save_item(NAME(m_devicenum)); |
| 276 | save_item(NAME(m_busnum)); |
| 277 | } |
| 278 | |
| 279 | |
| 280 | //------------------------------------------------- |
| 281 | // device_reset - device-specific reset |
| 282 | //------------------------------------------------- |
| 283 | |
| 284 | void pci_bus_legacy_device::device_reset() |
| 285 | { |
| 286 | /* reset the drive state */ |
| 287 | m_devicenum = -1; |
| 288 | m_address = 0; |
| 289 | } |
trunk/src/emu/machine/pci.c
r241728 | r241729 | |
1 | | /*************************************************************************** |
| 1 | #include "pci.h" |
2 | 2 | |
3 | | machine/pci.c |
| 3 | const device_type PCI_ROOT = &device_creator<pci_root_device>; |
| 4 | const device_type PCI_BRIDGE = &device_creator<pci_bridge_device>; |
4 | 5 | |
5 | | PCI bus |
| 6 | DEVICE_ADDRESS_MAP_START(config_map, 32, pci_device) |
| 7 | ADDRESS_MAP_END |
6 | 8 | |
7 | | The PCI bus is a 32-bit bus introduced by Intel, so it is little endian |
| 9 | pci_device::pci_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) |
| 10 | : device_t(mconfig, type, name, tag, owner, clock, shortname, source) |
| 11 | { |
| 12 | main_id = 0xffffffff; |
| 13 | revision = 0x00; |
| 14 | pclass = 0xffffff; |
| 15 | subdevice_id = 0xffffffff; |
| 16 | } |
8 | 17 | |
9 | | Control word: |
10 | | bit 31: Enable bit |
11 | | bits 30-24: Reserved |
12 | | bits 23-16: PCI bus number |
13 | | bits 15-11: PCI device number |
14 | | bits 10- 8: PCI function number |
15 | | bits 7- 0: Offset address |
| 18 | void pci_device::set_ids(UINT32 _main_id, UINT8 _revision, UINT32 _pclass, UINT32 _subdevice_id) |
| 19 | { |
| 20 | main_id = _main_id; |
| 21 | revision = _revision; |
| 22 | pclass = _pclass; |
| 23 | subdevice_id = _subdevice_id; |
| 24 | } |
16 | 25 | |
17 | | Standard PCI registers: |
18 | | 0x00 2 Vendor ID |
19 | | 0x02 2 Device ID |
20 | | 0x04 2 PCI Command |
21 | | 0x06 2 PCI Status |
22 | | 0x08 1 Revision ID |
23 | | 0x09 1 Programming Interface |
24 | | 0x0A 1 Subclass Code |
25 | | 0x0B 1 Class Code |
| 26 | void pci_device::device_start() |
| 27 | { |
| 28 | } |
26 | 29 | |
27 | | Class Code/Subclass Code/Programming Interface |
28 | | 0x00XXXX Pre-PCI 2.0 devices |
29 | | 0x000000 Non-VGA device |
30 | | 0x000101 VGA device |
31 | | 0x01XXXX Storage Controller |
32 | | 0x010000 SCSI |
33 | | 0x0101XX IDE |
34 | | 0x0102XX Floppy |
35 | | 0x0103XX IPI |
36 | | 0x0104XX RAID |
37 | | 0x0180XX Other |
38 | | 0x02XXXX Network Card |
39 | | 0x020000 Ethernet |
40 | | 0x020100 Tokenring |
41 | | 0x020200 FDDI |
42 | | 0x020300 ATM |
43 | | 0x028000 Other |
44 | | 0x03XXXX Display Controller |
45 | | 0x030000 VGA |
46 | | 0x030001 8514 Compatible |
47 | | 0x030100 XGA |
48 | | 0x038000 Other |
49 | | 0x04XXXX Multimedia |
50 | | 0x040000 Video |
51 | | 0x040100 Audio |
52 | | 0x048000 Other |
53 | | 0x05XXXX Memory Controller |
54 | | 0x050000 RAM |
55 | | 0x050100 Flash |
56 | | 0x058000 Other |
57 | | 0x06XXXX Bridge |
58 | | 0x060000 Host/PCI |
59 | | 0x060100 PCI/ISA |
60 | | 0x060200 PCI/EISA |
61 | | 0x060300 PCI/Micro Channel |
62 | | 0x060400 PCI/PCI |
63 | | 0x060500 PCI/PCMCIA |
64 | | 0x060600 PCI/NuBus |
65 | | 0x060700 PCI/CardBus |
66 | | 0x068000 Other |
| 30 | void pci_device::device_reset() |
| 31 | { |
| 32 | } |
67 | 33 | |
68 | | Information on PCI vendors can be found at http://www.pcidatabase.com/ |
| 34 | void pci_device::scan_sub_devices(pci_device **devices, dynamic_array<pci_device *> &all, dynamic_array<pci_device *> &bridges, device_t *root) |
| 35 | { |
| 36 | } |
69 | 37 | |
70 | | ***************************************************************************/ |
| 38 | void pci_device::reset_all_mappings() |
| 39 | { |
| 40 | } |
71 | 41 | |
72 | | #include "emu.h" |
73 | | #include "machine/pci.h" |
| 42 | void pci_device::map_device(UINT64 memory_window_start, UINT64 memory_window_end, UINT64 memory_offset, address_space *memory_space, |
| 43 | UINT64 io_window_start, UINT64 io_window_end, UINT64 io_offset, address_space *io_space) |
| 44 | { |
| 45 | map_extra(memory_window_start, memory_window_end, memory_offset, memory_space, |
| 46 | io_window_start, io_window_end, io_offset, io_space); |
| 47 | } |
74 | 48 | |
75 | | #define LOG_PCI 0 |
| 49 | void pci_device::map_extra(UINT64 memory_window_start, UINT64 memory_window_end, UINT64 memory_offset, address_space *memory_space, |
| 50 | UINT64 io_window_start, UINT64 io_window_end, UINT64 io_offset, address_space *io_space) |
| 51 | { |
| 52 | } |
76 | 53 | |
77 | | //************************************************************************** |
78 | | // GLOBAL VARIABLES |
79 | | //************************************************************************** |
| 54 | void pci_device::map_config(UINT8 device, address_space *config_space) |
| 55 | { |
| 56 | config_space->install_device(device << 12, (device << 12) | 0xfff, *this, &pci_device::config_map); |
| 57 | } |
80 | 58 | |
81 | | const device_type PCI_BUS_LEGACY = &device_creator<pci_bus_legacy_device>; |
| 59 | void pci_device::add_map(UINT64 size, int flags, address_map_delegate &map) |
| 60 | { |
| 61 | logerror("Device %s (%s) has 0x%llx bytes of %s named %s\n", tag(), name(), size, flags & M_IO ? "io" : "memory", map.name()); |
| 62 | } |
82 | 63 | |
83 | | //************************************************************************** |
84 | | // LIVE DEVICE |
85 | | //************************************************************************** |
| 64 | agp_device::agp_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) |
| 65 | : pci_device(mconfig, type, name, tag, owner, clock, shortname, source) |
| 66 | { |
| 67 | } |
86 | 68 | |
87 | | //------------------------------------------------- |
88 | | // pci_bus_legacy_device - constructor |
89 | | //------------------------------------------------- |
90 | | pci_bus_legacy_device::pci_bus_legacy_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
91 | | device_t(mconfig, PCI_BUS_LEGACY, "PCI Bus Legacy", tag, owner, clock, "pci_bus_legacy", __FILE__), |
92 | | m_father(NULL) |
| 69 | void agp_device::device_start() |
93 | 70 | { |
94 | | for (int i = 0; i < ARRAY_LENGTH(m_devtag); i++) { |
95 | | m_devtag[i]= NULL; |
96 | | m_read_callback[i] = NULL; |
97 | | m_write_callback[i] = NULL; |
98 | | } |
99 | | m_siblings_count = 0; |
| 71 | pci_device::device_start(); |
100 | 72 | } |
101 | 73 | |
102 | | /*************************************************************************** |
103 | | INLINE FUNCTIONS |
104 | | ***************************************************************************/ |
105 | | |
106 | | READ32_MEMBER( pci_bus_legacy_device::read ) |
| 74 | void agp_device::device_reset() |
107 | 75 | { |
108 | | UINT32 result = 0xffffffff; |
109 | | int function, reg; |
| 76 | pci_device::device_reset(); |
| 77 | } |
110 | 78 | |
111 | | offset %= 2; |
112 | 79 | |
113 | | switch (offset) |
114 | | { |
115 | | case 0: |
116 | | result = m_address; |
117 | | break; |
118 | 80 | |
119 | | case 1: |
120 | | if (m_devicenum != -1) |
121 | | { |
122 | | pci_read_func read = m_busnumaddr->m_read_callback[m_devicenum]; |
123 | | if (read != NULL) |
124 | | { |
125 | | function = (m_address >> 8) & 0x07; |
126 | | reg = (m_address >> 0) & 0xfc; |
127 | | result = (*read)(m_busnumaddr, m_busnumaddr->m_device[m_devicenum], function, reg, mem_mask); |
128 | | } |
129 | | } |
130 | | break; |
131 | | } |
| 81 | pci_bridge_device::pci_bridge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 82 | : pci_device(mconfig, PCI_BRIDGE, "PCI-PCI Bridge", tag, owner, clock, "pci_bridge", __FILE__), |
| 83 | device_memory_interface(mconfig, *this), |
| 84 | configure_space_config("configuration_space", ENDIANNESS_LITTLE, 32, 20) |
| 85 | { |
| 86 | } |
132 | 87 | |
133 | | if (LOG_PCI) |
134 | | logerror("read('%s'): offset=%d result=0x%08X\n", tag(), offset, result); |
| 88 | pci_bridge_device::pci_bridge_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) |
| 89 | : pci_device(mconfig, type, name, tag, owner, clock, shortname, source), |
| 90 | device_memory_interface(mconfig, *this), |
| 91 | configure_space_config("configuration_space", ENDIANNESS_LITTLE, 32, 20) |
| 92 | { |
| 93 | } |
135 | 94 | |
136 | | return result; |
| 95 | const address_space_config *pci_bridge_device::memory_space_config(address_spacenum spacenum) const |
| 96 | { |
| 97 | return spacenum == AS_PROGRAM ? &configure_space_config : NULL; |
137 | 98 | } |
138 | 99 | |
| 100 | device_t *pci_bridge_device::bus_root() |
| 101 | { |
| 102 | return this; |
| 103 | } |
139 | 104 | |
140 | | |
141 | | pci_bus_legacy_device *pci_bus_legacy_device::pci_search_bustree(int busnum, int devicenum, pci_bus_legacy_device *pcibus) |
| 105 | void pci_bridge_device::device_start() |
142 | 106 | { |
143 | | int a; |
144 | | pci_bus_legacy_device *ret; |
| 107 | pci_device::device_start(); |
145 | 108 | |
146 | | if (pcibus->m_busnum == busnum) |
147 | | { |
148 | | return pcibus; |
| 109 | for(int i=0; i<32*8; i++) |
| 110 | sub_devices[i] = NULL; |
| 111 | |
| 112 | for(device_t *d = bus_root()->first_subdevice(); d != NULL; d = d->next()) { |
| 113 | if(d == this) |
| 114 | continue; |
| 115 | const char *t = d->tag(); |
| 116 | int l = strlen(t); |
| 117 | if(l <= 4 || t[l-5] != ':' || t[l-2] != '.') |
| 118 | continue; |
| 119 | int id = strtol(t+l-4, 0, 16); |
| 120 | int fct = t[l-1] - '0'; |
| 121 | sub_devices[(id << 3) | fct] = downcast<pci_device *>(d); |
149 | 122 | } |
150 | | for (a = 0; a < pcibus->m_siblings_count; a++) |
151 | | { |
152 | | ret = pci_search_bustree(busnum, devicenum, pcibus->m_siblings[a]); |
153 | | if (ret != NULL) |
154 | | return ret; |
155 | | } |
156 | | return NULL; |
| 123 | for(int i=0; i<32*8; i++) |
| 124 | if(sub_devices[i]) { |
| 125 | all_devices.append(sub_devices[i]); |
| 126 | pci_bridge_device *bridge = dynamic_cast<pci_bridge_device *>(sub_devices[i]); |
| 127 | if(bridge) |
| 128 | all_bridges.append(bridge); |
| 129 | } |
157 | 130 | } |
158 | 131 | |
| 132 | void pci_bridge_device::device_reset() |
| 133 | { |
| 134 | pci_device::device_reset(); |
| 135 | regenerate_config_mapping(); |
| 136 | } |
159 | 137 | |
| 138 | void pci_bridge_device::reset_all_mappings() |
| 139 | { |
| 140 | for(int i=0; i != all_devices.count(); i++) |
| 141 | all_devices[i]->reset_all_mappings(); |
| 142 | } |
160 | 143 | |
161 | | WRITE32_MEMBER( pci_bus_legacy_device::write ) |
| 144 | |
| 145 | void pci_bridge_device::map_device(UINT64 memory_window_start, UINT64 memory_window_end, UINT64 memory_offset, address_space *memory_space, |
| 146 | UINT64 io_window_start, UINT64 io_window_end, UINT64 io_offset, address_space *io_space) |
162 | 147 | { |
163 | | offset %= 2; |
| 148 | for(int i = all_devices.count()-1; i>=0; i--) |
| 149 | all_devices[i]->map_device(memory_window_start, memory_window_end, memory_offset, memory_space, |
| 150 | io_window_start, io_window_end, io_offset, io_space); |
164 | 151 | |
165 | | if (LOG_PCI) |
166 | | logerror("write('%s'): offset=%d data=0x%08X\n", tag(), offset, data); |
| 152 | map_extra(memory_window_start, memory_window_end, memory_offset, memory_space, |
| 153 | io_window_start, io_window_end, io_offset, io_space); |
| 154 | } |
167 | 155 | |
168 | | switch (offset) |
169 | | { |
170 | | case 0: |
171 | | m_address = data; |
172 | 156 | |
173 | | /* lookup current device */ |
174 | | if (m_address & 0x80000000) |
175 | | { |
176 | | int busnum = (m_address >> 16) & 0xff; |
177 | | int devicenum = (m_address >> 11) & 0x1f; |
178 | | m_busnumaddr = pci_search_bustree(busnum, devicenum, this); |
179 | | if (m_busnumaddr != NULL) |
180 | | { |
181 | | m_busnumber = busnum; |
182 | | m_devicenum = devicenum; |
183 | | } |
184 | | else |
185 | | m_devicenum = -1; |
186 | | if (LOG_PCI) |
187 | | logerror(" bus:%d device:%d\n", busnum, devicenum); |
188 | | } |
189 | | break; |
| 157 | void pci_bridge_device::regenerate_config_mapping() |
| 158 | { |
| 159 | address_space *config_space = &space(AS_PROGRAM); |
| 160 | config_space->unmap_readwrite(0x00000, 0xfffff); |
| 161 | for(int i=0; i<32*8; i++) |
| 162 | if(sub_devices[i]) |
| 163 | sub_devices[i]->map_config(i, config_space); |
| 164 | } |
190 | 165 | |
191 | | case 1: |
192 | | if (m_devicenum != -1) |
193 | | { |
194 | | pci_write_func write = m_busnumaddr->m_write_callback[m_devicenum]; |
195 | | if (write != NULL) |
196 | | { |
197 | | int function = (m_address >> 8) & 0x07; |
198 | | int reg = (m_address >> 0) & 0xfc; |
199 | | (*write)(m_busnumaddr, m_busnumaddr->m_device[m_devicenum], function, reg, data, mem_mask); |
200 | | } |
201 | | if (LOG_PCI) |
202 | | logerror(" function:%d register:%d\n", (m_address >> 8) & 0x07, (m_address >> 0) & 0xfc); |
203 | | } |
204 | | break; |
205 | | } |
| 166 | |
| 167 | agp_bridge_device::agp_bridge_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) |
| 168 | : pci_bridge_device(mconfig, type, name, tag, owner, clock, shortname, source) |
| 169 | { |
206 | 170 | } |
207 | 171 | |
| 172 | void agp_bridge_device::device_start() |
| 173 | { |
| 174 | pci_bridge_device::device_start(); |
| 175 | } |
208 | 176 | |
| 177 | void agp_bridge_device::device_reset() |
| 178 | { |
| 179 | pci_bridge_device::device_reset(); |
| 180 | } |
209 | 181 | |
210 | | READ64_MEMBER(pci_bus_legacy_device::read_64be) |
| 182 | |
| 183 | |
| 184 | DEVICE_ADDRESS_MAP_START(io_configuration_access_map, 32, pci_host_device) |
| 185 | AM_RANGE(0xcf8, 0xcfb) AM_READWRITE(config_address_r, config_address_w) |
| 186 | AM_RANGE(0xcfc, 0xcff) AM_READWRITE(config_data_r, config_data_w) |
| 187 | ADDRESS_MAP_END |
| 188 | |
| 189 | |
| 190 | pci_host_device::pci_host_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) |
| 191 | : pci_bridge_device(mconfig, type, name, tag, owner, clock, shortname, source) |
211 | 192 | { |
212 | | UINT64 result = 0; |
213 | | mem_mask = FLIPENDIAN_INT64(mem_mask); |
214 | | if (ACCESSING_BITS_0_31) |
215 | | result |= (UINT64)read(space, offset * 2 + 0, mem_mask >> 0) << 0; |
216 | | if (ACCESSING_BITS_32_63) |
217 | | result |= (UINT64)read(space, offset * 2 + 1, mem_mask >> 32) << 32; |
218 | | return FLIPENDIAN_INT64(result); |
219 | 193 | } |
220 | 194 | |
221 | | WRITE64_MEMBER(pci_bus_legacy_device::write_64be) |
| 195 | device_t *pci_host_device::bus_root() |
222 | 196 | { |
223 | | data = FLIPENDIAN_INT64(data); |
224 | | mem_mask = FLIPENDIAN_INT64(mem_mask); |
225 | | if (ACCESSING_BITS_0_31) |
226 | | write(space, offset * 2 + 0, data >> 0, mem_mask >> 0); |
227 | | if (ACCESSING_BITS_32_63) |
228 | | write(space, offset * 2 + 1, data >> 32, mem_mask >> 32); |
| 197 | return owner(); |
229 | 198 | } |
230 | 199 | |
| 200 | void pci_host_device::device_start() |
| 201 | { |
| 202 | pci_bridge_device::device_start(); |
231 | 203 | |
232 | | void pci_bus_legacy_device::add_sibling(pci_bus_legacy_device *sibling, int busnum) |
| 204 | memory_window_start = memory_window_end = memory_offset = 0; |
| 205 | io_window_start = io_window_end = io_offset = 0; |
| 206 | } |
| 207 | |
| 208 | void pci_host_device::device_reset() |
233 | 209 | { |
234 | | m_siblings[m_siblings_count] = sibling; |
235 | | m_siblings_busnum[m_siblings_count] = busnum; |
236 | | m_siblings_count++; |
| 210 | pci_bridge_device::device_reset(); |
| 211 | for(int i=0; i != all_devices.count(); i++) |
| 212 | all_devices[i]->reset_all_mappings(); |
| 213 | regenerate_mapping(); |
| 214 | |
| 215 | config_address = 0; |
237 | 216 | } |
238 | 217 | |
| 218 | void pci_host_device::regenerate_mapping() |
| 219 | { |
| 220 | memory_space->unmap_readwrite(memory_window_start, memory_window_end); |
| 221 | io_space->unmap_readwrite(io_window_start, io_window_end); |
239 | 222 | |
240 | | //------------------------------------------------- |
241 | | // device_post_load - handle updating after a |
242 | | // restore |
243 | | //------------------------------------------------- |
| 223 | map_device(memory_window_start, memory_window_end, memory_offset, memory_space, |
| 224 | io_window_start, io_window_end, io_offset, io_space); |
| 225 | } |
244 | 226 | |
245 | | void pci_bus_legacy_device::device_post_load() |
| 227 | void pci_host_device::regenerate_config_mapping() |
246 | 228 | { |
247 | | if (m_devicenum != -1) |
248 | | { |
249 | | m_busnumaddr = pci_search_bustree(m_busnumber, m_devicenum, this); |
250 | | } |
| 229 | pci_bridge_device::regenerate_config_mapping(); |
| 230 | map_config(0, &space(AS_PROGRAM)); |
251 | 231 | } |
252 | 232 | |
253 | | //------------------------------------------------- |
254 | | // device_start - device-specific startup |
255 | | //------------------------------------------------- |
| 233 | READ32_MEMBER(pci_host_device::config_address_r) |
| 234 | { |
| 235 | return config_address; |
| 236 | } |
256 | 237 | |
257 | | void pci_bus_legacy_device::device_start() |
| 238 | WRITE32_MEMBER(pci_host_device::config_address_w) |
258 | 239 | { |
259 | | /* store a pointer back to the device */ |
260 | | m_devicenum = -1; |
| 240 | COMBINE_DATA(&config_address); |
| 241 | } |
261 | 242 | |
262 | | /* find all our devices */ |
263 | | for (int i = 0; i < ARRAY_LENGTH(m_devtag); i++) |
264 | | if (m_devtag[i] != NULL) |
265 | | m_device[i] = machine().device(m_devtag[i]); |
| 243 | READ32_MEMBER(pci_host_device::config_data_r) |
| 244 | { |
| 245 | return config_address & 0x80000000 ? config_read((config_address >> 16) & 0xff, (config_address >> 8) & 0xff, config_address & 0xfc, mem_mask) : 0xffffffff; |
| 246 | } |
266 | 247 | |
267 | | if (m_father != NULL) { |
268 | | pci_bus_legacy_device *father = machine().device<pci_bus_legacy_device>(m_father); |
269 | | if (father) |
270 | | father->add_sibling(this, m_busnum); |
271 | | } |
| 248 | WRITE32_MEMBER(pci_host_device::config_data_w) |
| 249 | { |
| 250 | if(config_address & 0x80000000) |
| 251 | config_write((config_address >> 16) & 0xff, (config_address >> 8) & 0xff, config_address & 0xfc, data, mem_mask); |
| 252 | } |
272 | 253 | |
273 | | /* register pci states */ |
274 | | save_item(NAME(m_address)); |
275 | | save_item(NAME(m_devicenum)); |
276 | | save_item(NAME(m_busnum)); |
| 254 | UINT32 pci_host_device::config_read(UINT8 bus, UINT8 device, UINT16 reg, UINT32 mem_mask) |
| 255 | { |
| 256 | UINT32 data = 0xffffffff; |
| 257 | if(!bus) { |
| 258 | if(sub_devices[device]) { |
| 259 | data = space(AS_PROGRAM).read_dword((device << 12) | reg, mem_mask); |
| 260 | logerror("config_read %02x:%02x.%x:%02x %08x @ %08x\n", bus, device >> 3, device & 7, reg, data, mem_mask); |
| 261 | } |
| 262 | } else |
| 263 | abort(); |
| 264 | |
| 265 | return data; |
277 | 266 | } |
278 | 267 | |
| 268 | void pci_host_device::config_write(UINT8 bus, UINT8 device, UINT16 reg, UINT32 data, UINT32 mem_mask) |
| 269 | { |
| 270 | if(!bus) { |
| 271 | if(sub_devices[device]) { |
| 272 | space(AS_PROGRAM).write_dword((device << 12) | reg, data, mem_mask); |
| 273 | logerror("config_write %02x:%02x.%x:%02x %08x @ %08x\n", bus, device >> 3, device & 7, reg, data, mem_mask); |
| 274 | } |
| 275 | } else |
| 276 | abort(); |
| 277 | } |
279 | 278 | |
280 | | //------------------------------------------------- |
281 | | // device_reset - device-specific reset |
282 | | //------------------------------------------------- |
283 | 279 | |
284 | | void pci_bus_legacy_device::device_reset() |
| 280 | pci_root_device::pci_root_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 281 | : device_t(mconfig, PCI_ROOT,"PCI virtual root", tag, owner, clock, "pci_root", __FILE__) |
285 | 282 | { |
286 | | /* reset the drive state */ |
287 | | m_devicenum = -1; |
288 | | m_address = 0; |
289 | 283 | } |
| 284 | |
| 285 | void pci_root_device::device_start() |
| 286 | { |
| 287 | } |
| 288 | |
| 289 | void pci_root_device::device_reset() |
| 290 | { |
| 291 | } |
trunk/src/emu/machine/pci.h
r241728 | r241729 | |
1 | | /*************************************************************************** |
| 1 | #ifndef PCI_H |
| 2 | #define PCI_H |
2 | 3 | |
3 | | machine/pci.h |
| 4 | #include "emu.h" |
4 | 5 | |
5 | | PCI bus |
| 6 | #define MCFG_PCI_ROOT_ADD(_tag) \ |
| 7 | MCFG_DEVICE_ADD(_tag, PCI_ROOT, 0) |
6 | 8 | |
7 | | ***************************************************************************/ |
| 9 | #define MCFG_PCI_DEVICE_ADD(_tag, _type, _main_id, _revision, _pclass, _subdevice_id) \ |
| 10 | MCFG_DEVICE_ADD(_tag, _type, 0) \ |
| 11 | downcast<pci_device *>(device)->set_ids(_main_id, _revision, _pclass, _subdevice_id); |
8 | 12 | |
9 | | #ifndef PCI_H |
10 | | #define PCI_H |
| 13 | #define MCFG_AGP_DEVICE_ADD(_tag, _type, _main_id, _revision, _subdevice_id) \ |
| 14 | MCFG_PCI_DEVICE_ADD(_tag, _type, _main_id, _revision, 0x030000, _subdevice_id) |
11 | 15 | |
12 | | //************************************************************************** |
13 | | // TYPE DEFINITIONS |
14 | | //************************************************************************** |
| 16 | #define MCFG_PCI_HOST_ADD(_tag, _type, _main_id, _revision, _subdevice_id) \ |
| 17 | MCFG_PCI_DEVICE_ADD(_tag, _type, _main_id, _revision, 0x060000, _subdevice_id) |
15 | 18 | |
16 | | typedef UINT32 (*pci_read_func)(device_t *pcibus, device_t *device, int function, int reg, UINT32 mem_mask); |
17 | | typedef void (*pci_write_func)(device_t *pcibus, device_t *device, int function, int reg, UINT32 data, UINT32 mem_mask); |
| 19 | #define MCFG_PCI_BRIDGE_ADD(_tag, _main_id, _revision) \ |
| 20 | MCFG_PCI_DEVICE_ADD(_tag, PCI_BRIDGE, _main_id, _revision, 0x060400, 0x00000000) |
18 | 21 | |
19 | | // ======================> pci_bus_legacy_device |
| 22 | #define MCFG_AGP_BRIDGE_ADD(_tag, _type, _main_id, _revision) \ |
| 23 | MCFG_PCI_DEVICE_ADD(_tag, _type, _main_id, _revision, 0x060400, 0x00000000) |
20 | 24 | |
21 | | class pci_bus_legacy_device : public device_t |
22 | | { |
| 25 | class pci_device : public device_t { |
23 | 26 | public: |
24 | | // construction/destruction |
25 | | pci_bus_legacy_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 27 | pci_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); |
26 | 28 | |
27 | | DECLARE_READ32_MEMBER( read ); |
28 | | DECLARE_WRITE32_MEMBER( write ); |
| 29 | void set_ids(UINT32 main_id, UINT8 revision, UINT32 pclass, UINT32 subdevice_id); |
29 | 30 | |
30 | | DECLARE_READ64_MEMBER( read_64be ); |
31 | | DECLARE_WRITE64_MEMBER( write_64be ); |
| 31 | virtual void reset_all_mappings(); |
| 32 | virtual void map_device(UINT64 memory_window_start, UINT64 memory_window_end, UINT64 memory_offset, address_space *memory_space, |
| 33 | UINT64 io_window_start, UINT64 io_window_end, UINT64 io_offset, address_space *io_space); |
| 34 | virtual void map_extra(UINT64 memory_window_start, UINT64 memory_window_end, UINT64 memory_offset, address_space *memory_space, |
| 35 | UINT64 io_window_start, UINT64 io_window_end, UINT64 io_offset, address_space *io_space); |
32 | 36 | |
33 | | void set_busnum(int busnum) { m_busnum = busnum; } |
34 | | void set_father(const char *father) { m_father = father; } |
35 | | void set_device(int num, const char *tag, pci_read_func read_func, pci_write_func write_func) { |
36 | | m_devtag[num] = tag; m_read_callback[num] = read_func; m_write_callback[num] = write_func; } |
| 37 | void map_config(UINT8 device, address_space *config_space); |
37 | 38 | |
38 | | pci_bus_legacy_device *pci_search_bustree(int busnum, int devicenum, pci_bus_legacy_device *pcibus); |
39 | | void add_sibling(pci_bus_legacy_device *sibling, int busnum); |
| 39 | virtual DECLARE_ADDRESS_MAP(config_map, 32); |
40 | 40 | |
41 | 41 | protected: |
42 | | // device-level overrides |
| 42 | enum { |
| 43 | M_MEM = 0, |
| 44 | M_IO = 1, |
| 45 | M_64D = 2, |
| 46 | M_64A = 4, |
| 47 | M_PREF = 8 |
| 48 | }; |
| 49 | |
| 50 | UINT32 main_id, subdevice_id; |
| 51 | UINT32 pclass; |
| 52 | UINT8 revision; |
| 53 | |
43 | 54 | virtual void device_start(); |
44 | 55 | virtual void device_reset(); |
45 | | virtual void device_post_load(); |
46 | 56 | |
| 57 | static void scan_sub_devices(pci_device **devices, dynamic_array<pci_device *> &all, dynamic_array<pci_device *> &bridges, device_t *root); |
| 58 | |
| 59 | void add_map(UINT64 size, int flags, address_map_delegate &map); |
| 60 | template <typename T> void add_map(UINT64 size, int flags, void (T::*map)(address_map &map, device_t &device), const char *name) { |
| 61 | address_map_delegate delegate(map, name, static_cast<T *>(this)); |
| 62 | add_map(size, flags, delegate); |
| 63 | } |
| 64 | }; |
| 65 | |
| 66 | class agp_device : public pci_device { |
| 67 | public: |
| 68 | agp_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); |
| 69 | |
| 70 | protected: |
| 71 | virtual void device_start(); |
| 72 | virtual void device_reset(); |
| 73 | }; |
| 74 | |
| 75 | class pci_bridge_device : public pci_device, public device_memory_interface { |
| 76 | public: |
| 77 | pci_bridge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 78 | pci_bridge_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); |
| 79 | |
| 80 | virtual void map_device(UINT64 memory_window_start, UINT64 memory_window_end, UINT64 memory_offset, address_space *memory_space, |
| 81 | UINT64 io_window_start, UINT64 io_window_end, UINT64 io_offset, address_space *io_space); |
| 82 | virtual void reset_all_mappings(); |
| 83 | |
| 84 | protected: |
| 85 | pci_device *sub_devices[32*8]; |
| 86 | dynamic_array<pci_device *> all_devices; |
| 87 | dynamic_array<pci_device *> all_bridges; |
| 88 | |
| 89 | virtual void device_start(); |
| 90 | virtual void device_reset(); |
| 91 | virtual const address_space_config *memory_space_config(address_spacenum spacenum) const; |
| 92 | |
| 93 | virtual device_t *bus_root(); |
| 94 | virtual void regenerate_config_mapping(); |
| 95 | |
47 | 96 | private: |
48 | | UINT8 m_busnum; |
49 | | const char * m_devtag[32]; |
50 | | pci_read_func m_read_callback[32]; |
51 | | pci_write_func m_write_callback[32]; |
52 | | const char * m_father; |
53 | | device_t * m_device[32]; |
54 | | pci_bus_legacy_device * m_siblings[8]; |
55 | | UINT8 m_siblings_busnum[8]; |
56 | | int m_siblings_count; |
| 97 | address_space_config configure_space_config; |
| 98 | }; |
57 | 99 | |
58 | | offs_t m_address; |
59 | | INT8 m_devicenum; // device number we are addressing |
60 | | INT8 m_busnumber; // pci bus number we are addressing |
61 | | pci_bus_legacy_device * m_busnumaddr; // pci bus we are addressing |
| 100 | class agp_bridge_device : public pci_bridge_device { |
| 101 | public: |
| 102 | agp_bridge_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); |
| 103 | |
| 104 | protected: |
| 105 | virtual void device_start(); |
| 106 | virtual void device_reset(); |
62 | 107 | }; |
63 | 108 | |
64 | | // device type definition |
65 | | extern const device_type PCI_BUS_LEGACY; |
| 109 | class pci_host_device : public pci_bridge_device { |
| 110 | public: |
| 111 | DECLARE_ADDRESS_MAP(io_configuration_access_map, 32); |
66 | 112 | |
| 113 | pci_host_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); |
67 | 114 | |
68 | | /*************************************************************************** |
69 | | DEVICE CONFIGURATION MACROS |
70 | | ***************************************************************************/ |
| 115 | protected: |
| 116 | address_space *memory_space, *io_space; |
71 | 117 | |
72 | | #define MCFG_PCI_BUS_LEGACY_ADD(_tag, _busnum) \ |
73 | | MCFG_DEVICE_ADD(_tag, PCI_BUS_LEGACY, 0) \ |
74 | | downcast<pci_bus_legacy_device *>(device)->set_busnum(_busnum); |
75 | | #define MCFG_PCI_BUS_LEGACY_DEVICE(_devnum, _devtag, _configread, _configwrite) \ |
76 | | downcast<pci_bus_legacy_device *>(device)->set_device(_devnum, _devtag,_configread,_configwrite); |
77 | | #define MCFG_PCI_BUS_LEGACY_SIBLING(_father_tag) \ |
78 | | downcast<pci_bus_legacy_device *>(device)->set_father(_father_tag); |
| 118 | UINT64 memory_window_start, memory_window_end, memory_offset; |
| 119 | UINT64 io_window_start, io_window_end, io_offset; |
79 | 120 | |
| 121 | virtual void device_start(); |
| 122 | virtual void device_reset(); |
80 | 123 | |
81 | | #endif /* PCI_H */ |
| 124 | virtual device_t *bus_root(); |
| 125 | |
| 126 | UINT32 config_address; |
| 127 | |
| 128 | DECLARE_READ32_MEMBER(config_address_r); |
| 129 | DECLARE_WRITE32_MEMBER(config_address_w); |
| 130 | DECLARE_READ32_MEMBER(config_data_r); |
| 131 | DECLARE_WRITE32_MEMBER(config_data_w); |
| 132 | |
| 133 | UINT32 config_read(UINT8 bus, UINT8 device, UINT16 reg, UINT32 mem_mask); |
| 134 | void config_write(UINT8 bus, UINT8 device, UINT16 reg, UINT32 data, UINT32 mem_mask); |
| 135 | |
| 136 | void regenerate_mapping(); |
| 137 | virtual void regenerate_config_mapping(); |
| 138 | }; |
| 139 | |
| 140 | class pci_root_device : public device_t { |
| 141 | public: |
| 142 | pci_root_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 143 | |
| 144 | protected: |
| 145 | virtual void device_start(); |
| 146 | virtual void device_reset(); |
| 147 | }; |
| 148 | |
| 149 | extern const device_type PCI_ROOT; |
| 150 | extern const device_type PCI_BRIDGE; |
| 151 | |
| 152 | #endif |
trunk/src/mame/drivers/lindbergh.c
r241728 | r241729 | |
221 | 221 | |
222 | 222 | #include "emu.h" |
223 | 223 | #include "cpu/i386/i386.h" |
224 | | #include "machine/pcshare.h" |
225 | | #include "machine/pckeybrd.h" |
226 | | #include "video/pc_vga.h" |
227 | 224 | #include "machine/pci.h" |
| 225 | #include "machine/i82875p.h" |
| 226 | #include "machine/i6300esb.h" |
| 227 | #include "machine/pci-usb.h" |
| 228 | #include "machine/pci-apic.h" |
| 229 | #include "machine/pci-sata.h" |
| 230 | #include "machine/pci-smbus.h" |
| 231 | #include "machine/i82541.h" |
| 232 | #include "machine/segabb.h" |
| 233 | #include "sound/pci-ac97.h" |
| 234 | #include "sound/sb0400.h" |
| 235 | #include "video/gf6800gt.h" |
228 | 236 | |
229 | | class lindbergh_state : public pcat_base_state |
| 237 | class lindbergh_state : public driver_device |
230 | 238 | { |
231 | 239 | public: |
232 | 240 | lindbergh_state(const machine_config &mconfig, device_type type, const char *tag); |
r241728 | r241729 | |
235 | 243 | virtual void machine_reset(); |
236 | 244 | }; |
237 | 245 | |
| 246 | #if 0 |
238 | 247 | static ADDRESS_MAP_START(lindbergh_map, AS_PROGRAM, 32, lindbergh_state) |
239 | 248 | AM_RANGE(0x00000000, 0x0009ffff) AM_RAM |
240 | | AM_RANGE(0x000a0000, 0x000bffff) AM_DEVREADWRITE8("vga", vga_device, mem_r, mem_w, 0xffffffff) |
241 | | AM_RANGE(0x000c0000, 0x000cffff) AM_ROM AM_REGION("vid_bios", 0) |
| 249 | // AM_RANGE(0x000a0000, 0x000bffff) AM_DEVREADWRITE8("vga", vga_device, mem_r, mem_w, 0xffffffff) |
| 250 | // AM_RANGE(0x000c0000, 0x000cffff) AM_ROM AM_REGION("vid_bios", 0) |
242 | 251 | // 0xd0000 - 0xdffff tested, wants 0x414d ("AM") in there |
243 | 252 | AM_RANGE(0x000f0000, 0x000fffff) AM_ROM AM_REGION("mb_bios", 0xf0000) |
244 | | AM_RANGE(0xfd000000, 0xfd3fffff) AM_ROM AM_REGION("jvs_bios", 0) /* Hack to see the data */ |
| 253 | // AM_RANGE(0xfd000000, 0xfd3fffff) AM_ROM AM_REGION("jvs_bios", 0) /* Hack to see the data */ |
245 | 254 | AM_RANGE(0xfff00000, 0xffffffff) AM_ROM AM_REGION("mb_bios", 0) /* System BIOS */ |
246 | 255 | ADDRESS_MAP_END |
247 | 256 | |
248 | 257 | static ADDRESS_MAP_START(lindbergh_io, AS_IO, 32, lindbergh_state) |
249 | | AM_IMPORT_FROM(pcat32_io_common) |
| 258 | // AM_IMPORT_FROM(pcat32_io_common) |
250 | 259 | |
251 | | AM_RANGE(0x00e8, 0x00ef) AM_NOP |
252 | | AM_RANGE(0x0cf8, 0x0cff) AM_DEVREADWRITE("pcibus", pci_bus_legacy_device, read, write) |
| 260 | // AM_RANGE(0x00e8, 0x00ef) AM_NOP |
| 261 | // AM_RANGE(0x0cf8, 0x0cff) AM_DEVREADWRITE("pcibus", pci_bus_legacy_device, read, write) |
253 | 262 | ADDRESS_MAP_END |
| 263 | #endif |
254 | 264 | |
255 | | lindbergh_state::lindbergh_state(const machine_config &mconfig, device_type type, const char *tag) : pcat_base_state(mconfig, type, tag) |
| 265 | lindbergh_state::lindbergh_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) |
256 | 266 | { |
257 | 267 | } |
258 | 268 | |
r241728 | r241729 | |
267 | 277 | static MACHINE_CONFIG_START(lindbergh, lindbergh_state) |
268 | 278 | // MCFG_CPU_ADD("maincpu", PENTIUM, 2800000000U) /* Actually Celeron D at 2,8 GHz */ |
269 | 279 | MCFG_CPU_ADD("maincpu", PENTIUM4, 28000000U*5) /* Actually Celeron D at 2,8 GHz */ |
270 | | MCFG_CPU_PROGRAM_MAP(lindbergh_map) |
271 | | MCFG_CPU_IO_MAP(lindbergh_io) |
272 | | MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE("pic8259_1", pic8259_device, inta_cb) |
| 280 | // MCFG_CPU_PROGRAM_MAP(lindbergh_map) |
| 281 | // MCFG_CPU_IO_MAP(lindbergh_io) |
| 282 | // MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE("pic8259_1", pic8259_device, inta_cb) |
273 | 283 | |
274 | | MCFG_FRAGMENT_ADD( pcat_common ) |
275 | | MCFG_FRAGMENT_ADD( pcvideo_vga ) |
| 284 | // MCFG_FRAGMENT_ADD( pcat_common ) |
| 285 | // MCFG_FRAGMENT_ADD( pcvideo_vga ) |
276 | 286 | |
277 | | MCFG_PCI_BUS_LEGACY_ADD("pcibus", 0) |
| 287 | // MCFG_PCI_BUS_LEGACY_ADD("pcibus", 0) |
| 288 | |
| 289 | MCFG_PCI_ROOT_ADD( ":pci") |
| 290 | MCFG_I82875P_HOST_ADD( ":pci:00.0", 0x103382c0, ":maincpu", 512*1024*1024) |
| 291 | MCFG_I82875P_AGP_ADD( ":pci:01.0") |
| 292 | MCFG_GEFORCE_6800GT_ADD( ":pci:01.0:00.0", 0x10de0204) |
| 293 | MCFG_PCI_BRIDGE_ADD( ":pci:1c.0", 0x808625ae, 0x02) |
| 294 | MCFG_I82541PI_ADD( ":pci:1c.0:00.0", 0x103382c0) |
| 295 | MCFG_USB_UHCI_ADD( ":pci:1d.0", 0x808625a9, 0x02, 0x103382c0) |
| 296 | MCFG_USB_UHCI_ADD( ":pci:1d.1", 0x808625aa, 0x02, 0x103382c0) |
| 297 | MCFG_I6300ESB_WATCHDOG_ADD( ":pci:1d.4", 0x103382c0) |
| 298 | MCFG_APIC_ADD( ":pci:1d.5", 0x808625ac, 0x02, 0x103382c0) |
| 299 | MCFG_USB_EHCI_ADD( ":pci:1d.7", 0x808625ad, 0x02, 0x103382c0) |
| 300 | MCFG_PCI_BRIDGE_ADD( ":pci:1e.0", 0x8086244e, 0x0a) |
| 301 | MCFG_SB0400_ADD( ":pci:1e.0:02.0", 0x11021101) |
| 302 | MCFG_SEGA_LINDBERGH_BASEBOARD_ADD(":pci:1e.0:03.0") |
| 303 | MCFG_I6300ESB_LPC_ADD( ":pci:1f.0") |
| 304 | MCFG_SATA_ADD( ":pci:1f.2", 0x808625a3, 0x02, 0x103382c0) |
| 305 | MCFG_SMBUS_ADD( ":pci:1f.3", 0x808625a4, 0x02, 0x103382c0) |
| 306 | MCFG_AC97_ADD( ":pci:1f.5", 0x808625a6, 0x02, 0x103382c0) |
278 | 307 | MACHINE_CONFIG_END |
279 | 308 | |
280 | 309 | ROM_START(lindbios) |
281 | | ROM_REGION32_LE(0x100000, "mb_bios", 0) // location 3j7 |
| 310 | ROM_REGION32_LE(0x100000, ":pci:1f.0", 0) // PC bios, location 3j7 |
282 | 311 | ROM_SYSTEM_BIOS(0, "bios0", "6.0.0010 alternate version") |
283 | 312 | ROMX_LOAD("6.0.0010a.bin", 0x00000, 0x100000, CRC(10dd9b76) SHA1(1fdf1f921bc395846a7c3180fbdbc4ca287a9670), ROM_BIOS(1) ) |
284 | 313 | ROM_SYSTEM_BIOS(1, "bios1", "6.0.0009") |
r241728 | r241729 | |
287 | 316 | ROMX_LOAD("6.0.0010.bin", 0x00000, 0x100000, CRC(ea2bf888) SHA1(c9c5b6f0d4f4f36620939b15dd2f128a74347e37), ROM_BIOS(3) ) |
288 | 317 | |
289 | 318 | |
290 | | ROM_REGION(0x400000, "jvs_bios", 0) |
| 319 | ROM_REGION(0x400000, ":pci:1e.0:03.0", 0) // Baseboard MPC firmware |
291 | 320 | ROM_LOAD("fpr-24370b.ic6", 0x000000, 0x400000, CRC(c3b021a4) SHA1(1b6938a50fe0e4ae813864649eb103838c399ac0)) |
292 | 321 | |
293 | | ROM_REGION(0x10000, "vid_bios", 0) |
| 322 | ROM_REGION32_LE(0x10000, ":pci:01.0:00.0", 0) // Geforce bios extension (custom or standard?) |
294 | 323 | ROM_LOAD("vid_bios.u504", 0x00000, 0x10000, CRC(f78d14d7) SHA1(f129787e487984edd23bf344f2e9500c85052275)) |
295 | 324 | ROM_END |
296 | 325 | |
297 | | GAME(1999, lindbios, 0, lindbergh, at_keyboard, driver_device, 0, ROT0, "Sega Lindbergh", "Sega Lindbergh Bios", GAME_IS_SKELETON) |
| 326 | GAME(1999, lindbios, 0, lindbergh, 0, driver_device, 0, ROT0, "Sega Lindbergh", "Sega Lindbergh Bios", GAME_IS_SKELETON) |