diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index 42a51a6c1e4..1d061199208 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -1737,6 +1737,8 @@ if (MACHINES["PCI"]~=null) then MAME_DIR .. "src/devices/machine/pci-usb.h", MAME_DIR .. "src/devices/machine/pci-sata.cpp", MAME_DIR .. "src/devices/machine/pci-sata.h", + MAME_DIR .. "src/devices/machine/pci-ide.cpp", + MAME_DIR .. "src/devices/machine/pci-ide.h", MAME_DIR .. "src/devices/machine/pci-apic.cpp", MAME_DIR .. "src/devices/machine/pci-apic.h", MAME_DIR .. "src/devices/machine/pci-smbus.cpp", diff --git a/src/devices/machine/gt64xxx.cpp b/src/devices/machine/gt64xxx.cpp index 4c096af6a3e..c7a4af83633 100644 --- a/src/devices/machine/gt64xxx.cpp +++ b/src/devices/machine/gt64xxx.cpp @@ -8,9 +8,9 @@ * *************************************/ #define LOG_GALILEO (0) -#define LOG_REG (0) #define LOG_TIMERS (0) #define LOG_DMA (0) +#define LOG_PCI (0) const device_type GT64XXX = &device_creator; @@ -28,10 +28,19 @@ gt64xxx_device::gt64xxx_device(const machine_config &mconfig, const char *tag, d m_be(0), m_autoconfig(0), m_irq_num(-1), m_mem_config("memory_space", ENDIANNESS_LITTLE, 32, 32), m_io_config("io_space", ENDIANNESS_LITTLE, 32, 32), - m_region(*this, DEVICE_SELF) + m_romRegion(*this, "rom"), + m_updateRegion(*this, "update"), m_cs_map(4) { } +void gt64xxx_device::set_cs_map(int id, address_map_constructor map, const char *name, device_t *device) +{ + m_cs_map[id].enable = true; + m_cs_map[id].name = name; + m_cs_map[id].device = device; + m_cs_map[id].map = map; +} + const address_space_config *gt64xxx_device::memory_space_config(address_spacenum spacenum) const { return (spacenum == AS_PROGRAM) ? pci_bridge_device::memory_space_config(spacenum) : (spacenum == AS_DATA) ? &m_mem_config : (spacenum == AS_IO) ? &m_io_config : nullptr; @@ -53,11 +62,35 @@ void gt64xxx_device::device_start() io_offset = 0x00000000; status = 0x0; - // ROM size = 4 MB - m_cpu_space->install_rom (0x1fc00000, 0x1fffffff, m_region->base()); + //dma_addr_map.reserve(static_cast(proc_addr_bank::ADDR_NUM)); + dma_addr_map.resize(static_cast(proc_addr_bank::ADDR_NUM)); - // MIPS drc - m_cpu->add_fastram(0x1fc00000, 0x1fffffff, TRUE, m_region->base()); + // DMA timer + m_dma_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gt64xxx_device::perform_dma), this)); + // Leave the timer disabled. + m_dma_timer->adjust(attotime::never, 0, DMA_TIMER_PERIOD); + + // ROM + UINT32 romSize = m_romRegion->bytes(); + m_cpu_space->install_rom (0x1fc00000, 0x1fc00000 + romSize - 1, m_romRegion->base()); + // ROM MIPS DRC + m_cpu->add_fastram(0x1fc00000, 0x1fc00000 + romSize - 1, TRUE, m_romRegion->base()); + if (LOG_GALILEO) + logerror("%s: gt64xxx_device::device_start ROM Mapped size: 0x%08X start: 0x1fc00000 end: %08X\n", tag(), romSize, 0x1fc00000 + romSize - 1); + + // Update region address is based on seattle driver + if (m_updateRegion) { + romSize = m_updateRegion->bytes(); + m_cpu_space->install_rom(0x1fd00000, 0x1fd00000 + romSize - 1, m_updateRegion->base()); + if (LOG_GALILEO) + logerror("%s: gt64xxx_device::device_start UPDATE Mapped size: 0x%08X start: 0x1fd00000 end: %08X\n", tag(), romSize, 0x1fd00000 + romSize - 1); + } + + /* allocate timers for the galileo */ + m_timer[0].timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gt64xxx_device::timer_callback), this)); + m_timer[1].timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gt64xxx_device::timer_callback), this)); + m_timer[2].timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gt64xxx_device::timer_callback), this)); + m_timer[3].timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gt64xxx_device::timer_callback), this)); } void gt64xxx_device::device_reset() @@ -105,6 +138,12 @@ void gt64xxx_device::device_reset() map_cpu_space(); regenerate_config_mapping(); + + m_dma_active = 0; + m_dma_timer->adjust(attotime::never); + m_last_dma = 0; + + m_prev_addr = 0; } void gt64xxx_device::map_cpu_space() @@ -125,14 +164,40 @@ void gt64xxx_device::map_cpu_space() if (LOG_GALILEO) logerror("%s: map_cpu_space cpu_reg start: %08X end: %08X\n", tag(), winStart, winEnd); - // Ras0 - winStart = (m_reg[GREG_RAS_1_0_LO]<<21) | (m_reg[GREG_RAS0_LO]<<20); - winEnd = (m_reg[GREG_RAS_1_0_LO]<<21) | (m_reg[GREG_RAS0_HI]<<20) | 0xfffff; - m_ram[0].resize((winEnd+1-winStart)/4); - m_cpu_space->install_ram(winStart, winEnd, &m_ram[0][0]); - m_cpu->add_fastram(winStart, m_ram[0].size()*sizeof(m_ram[0][0]), FALSE, &m_ram[0][0]); - if (LOG_GALILEO) - logerror("%s: map_cpu_space ras0 start: %08X end: %08X\n", tag(), winStart, winEnd); + // RAS[0:3] + for (int ramIndex = 0; ramIndex < 4; ++ramIndex) + { + winStart = (m_reg[GREG_RAS_1_0_LO + 0x10 / 4 * (ramIndex/2)] << 21) | (m_reg[GREG_RAS0_LO + 0x8 / 4 * ramIndex] << 20); + winEnd = (m_reg[GREG_RAS_1_0_LO + 0x10 / 4 * (ramIndex / 2)] << 21) | (m_reg[GREG_RAS0_HI + 0x8 / 4 * ramIndex] << 20) | 0xfffff; + m_ram[ramIndex].resize((winEnd + 1 - winStart) / 4); + m_cpu_space->install_ram(winStart, winEnd, m_ram[ramIndex].data()); + //m_cpu->add_fastram(winStart, m_ram[ramIndex].size() * sizeof(m_ram[ramIndex][0]), FALSE, &m_ram[ramIndex][0]); + //m_cpu->add_fastram(winStart, m_ram[ramIndex].size() * sizeof(UINT32), FALSE, m_ram[ramIndex].data()); + if (LOG_GALILEO) + logerror("%s: map_cpu_space ras[%i] start: %08X end: %08X\n", tag(), ramIndex, winStart, winEnd); + } + + // CS[0:3] + //m_cpu_space->install_device_delegate(0x16000000, 0x17ffffff, machine().root_device(), m_cs_map[3].map); + typedef void (gt64xxx_device::*tramp_t)(::address_map &, device_t &); + static const tramp_t trampolines[4] = { + >64xxx_device::map_trampoline<0>, + >64xxx_device::map_trampoline<1>, + >64xxx_device::map_trampoline<2>, + >64xxx_device::map_trampoline<3> + }; + for (int ramIndex = 0; ramIndex < 4; ++ramIndex) + { + if (m_cs_map[ramIndex].enable) + { + winStart = (m_reg[GREG_CS_2_0_LO + 0x10 / 4 * (ramIndex / 3)] << 21) | (m_reg[GREG_CS0_LO + 0x8 / 4 * ramIndex] << 20); + winEnd = (m_reg[GREG_CS_2_0_LO + 0x10 / 4 * (ramIndex / 3)] << 21) | (m_reg[GREG_CS0_HI + 0x8 / 4 * ramIndex] << 20) | 0xfffff; + install_cs_map(winStart, winEnd, trampolines[ramIndex], m_cs_map[ramIndex].name); + if (LOG_GALILEO) + logerror("%s: map_cpu_space cs[%i] start: %08X end: %08X\n", tag(), ramIndex, winStart, winEnd); + } + } + // PCI IO Window winStart = m_reg[GREG_PCI_IO_LO]<<21; @@ -158,25 +223,79 @@ void gt64xxx_device::map_cpu_space() if (LOG_GALILEO) logerror("%s: map_cpu_space pci_mem1 start: %08X end: %08X\n", tag(), winStart, winEnd); + // Setup the address mapping table for DMA lookups + for (size_t index = 0; index < proc_addr_bank::ADDR_NUM; ++index) + { + if (index < proc_addr_bank::ADDR_PCI_MEM1) { + dma_addr_map[index].low_addr = (m_reg[GREG_RAS_1_0_LO + 0x10 / 4 * index] << 21); + dma_addr_map[index].high_addr = (dma_addr_map[index].low_addr & 0xf0000000) | (m_reg[GREG_RAS_1_0_HI + 0x10 / 4 * index] << 21) | 0x1fffff; + } + else { + dma_addr_map[index].low_addr = (m_reg[GREG_PCI_MEM1_LO] << 21); + dma_addr_map[index].high_addr = (dma_addr_map[index].low_addr & 0xf0000000) | (m_reg[GREG_PCI_MEM1_HI] << 21) | 0x1fffff; + } + + switch (index) { + case proc_addr_bank::ADDR_PCI_IO: + dma_addr_map[index].space = &this->space(AS_IO); + break; + case proc_addr_bank::ADDR_PCI_MEM0: + case proc_addr_bank::ADDR_PCI_MEM1: + dma_addr_map[index].space = &this->space(AS_DATA); + break; + default: + dma_addr_map[index].space = m_cpu_space; + break; + } + } } void gt64xxx_device::map_extra(UINT64 memory_window_start, UINT64 memory_window_end, UINT64 memory_offset, address_space *memory_space, UINT64 io_window_start, UINT64 io_window_end, UINT64 io_offset, address_space *io_space) { - /* + int ramIndex; UINT32 winStart, winEnd, winSize; - - // PCI Target Window 1 - if (m_cpu_regs[NREG_PCITW1]&0x1000) { - winStart = m_cpu_regs[NREG_PCITW1]&0xffe00000; - winEnd = winStart | (~(0xf0000000 | (((m_cpu_regs[NREG_PCITW1]>>13)&0x7f)<<21))); - winSize = winEnd - winStart + 1; - memory_space->install_read_handler(winStart, winEnd, 0, 0, read32_delegate(FUNC(gt64xxx_device::target1_r), this)); - memory_space->install_write_handler(winStart, winEnd, 0, 0, write32_delegate(FUNC(gt64xxx_device::target1_w), this)); - if (LOG_GALILEO) - logerror("%s: map_extra Target Window 1 start=%08X end=%08X size=%08X laddr=%08X\n", tag(), winStart, winEnd, winSize, m_target1_laddr); - } - */ + + // Not sure if GREG_RAS_1_0_LO should be added on PCI address map side. + // RAS0 + ramIndex = 0; + winStart = (m_reg[GREG_RAS_1_0_LO + 0x10 / 4 * (ramIndex / 2)] << 21) | (m_reg[GREG_RAS0_LO + 0x8 / 4 * ramIndex] << 20); + winEnd = (m_reg[GREG_RAS_1_0_LO + 0x10 / 4 * (ramIndex / 2)] << 21) | (m_reg[GREG_RAS0_HI + 0x8 / 4 * ramIndex] << 20) | 0xfffff; + winSize = winEnd - winStart + 1; + memory_space->install_read_handler(winStart, winEnd, 0, 0, read32_delegate(FUNC(gt64xxx_device::ras_0_r), this)); + memory_space->install_write_handler(winStart, winEnd, 0, 0, write32_delegate(FUNC(gt64xxx_device::ras_0_w), this)); + if (LOG_GALILEO) + logerror("%s: map_extra RAS0 start=%08X end=%08X size=%08X\n", tag(), winStart, winEnd, winSize); + + // RAS1 + ramIndex = 1; + winStart = (m_reg[GREG_RAS_1_0_LO + 0x10 / 4 * (ramIndex / 2)] << 21) | (m_reg[GREG_RAS0_LO + 0x8 / 4 * ramIndex] << 20); + winEnd = (m_reg[GREG_RAS_1_0_LO + 0x10 / 4 * (ramIndex / 2)] << 21) | (m_reg[GREG_RAS0_HI + 0x8 / 4 * ramIndex] << 20) | 0xfffff; + winSize = winEnd - winStart + 1; + memory_space->install_read_handler(winStart, winEnd, 0, 0, read32_delegate(FUNC(gt64xxx_device::ras_1_r), this)); + memory_space->install_write_handler(winStart, winEnd, 0, 0, write32_delegate(FUNC(gt64xxx_device::ras_1_w), this)); + if (LOG_GALILEO) + logerror("%s: map_extra RAS1 start=%08X end=%08X size=%08X\n", tag(), winStart, winEnd, winSize); + + // RAS2 + ramIndex = 2; + winStart = (m_reg[GREG_RAS_1_0_LO + 0x10 / 4 * (ramIndex / 2)] << 21) | (m_reg[GREG_RAS0_LO + 0x8 / 4 * ramIndex] << 20); + winEnd = (m_reg[GREG_RAS_1_0_LO + 0x10 / 4 * (ramIndex / 2)] << 21) | (m_reg[GREG_RAS0_HI + 0x8 / 4 * ramIndex] << 20) | 0xfffff; + winSize = winEnd - winStart + 1; + memory_space->install_read_handler(winStart, winEnd, 0, 0, read32_delegate(FUNC(gt64xxx_device::ras_2_r), this)); + memory_space->install_write_handler(winStart, winEnd, 0, 0, write32_delegate(FUNC(gt64xxx_device::ras_2_w), this)); + if (LOG_GALILEO) + logerror("%s: map_extra RAS2 start=%08X end=%08X size=%08X\n", tag(), winStart, winEnd, winSize); + + // RAS3 + ramIndex = 3; + winStart = (m_reg[GREG_RAS_1_0_LO + 0x10 / 4 * (ramIndex / 2)] << 21) | (m_reg[GREG_RAS0_LO + 0x8 / 4 * ramIndex] << 20); + winEnd = (m_reg[GREG_RAS_1_0_LO + 0x10 / 4 * (ramIndex / 2)] << 21) | (m_reg[GREG_RAS0_HI + 0x8 / 4 * ramIndex] << 20) | 0xfffff; + winSize = winEnd - winStart + 1; + memory_space->install_read_handler(winStart, winEnd, 0, 0, read32_delegate(FUNC(gt64xxx_device::ras_3_r), this)); + memory_space->install_write_handler(winStart, winEnd, 0, 0, write32_delegate(FUNC(gt64xxx_device::ras_3_w), this)); + if (LOG_GALILEO) + logerror("%s: map_extra RAS3 start=%08X end=%08X size=%08X\n", tag(), winStart, winEnd, winSize); } void gt64xxx_device::reset_all_mappings() @@ -201,14 +320,14 @@ WRITE32_MEMBER (gt64xxx_device::pci_config_w) READ32_MEMBER (gt64xxx_device::master_mem0_r) { UINT32 result = this->space(AS_DATA).read_dword((m_reg[GREG_PCI_MEM0_LO]<<21) | (offset*4), mem_mask); - if (LOG_GALILEO) + if (LOG_PCI) logerror("%06X:galileo pci mem0 read from offset %08X = %08X & %08X\n", space.device().safe_pc(), (m_reg[GREG_PCI_MEM0_LO]<<21) | (offset*4), result, mem_mask); return result; } WRITE32_MEMBER (gt64xxx_device::master_mem0_w) { this->space(AS_DATA).write_dword((m_reg[GREG_PCI_MEM0_LO]<<21) | (offset*4), data, mem_mask); - if (LOG_GALILEO) + if (LOG_PCI) logerror("%06X:galileo pci mem0 write to offset %08X = %08X & %08X\n", space.device().safe_pc(), (m_reg[GREG_PCI_MEM0_LO]<<21) | (offset*4), data, mem_mask); } @@ -216,14 +335,14 @@ WRITE32_MEMBER (gt64xxx_device::master_mem0_w) READ32_MEMBER (gt64xxx_device::master_mem1_r) { UINT32 result = this->space(AS_DATA).read_dword((m_reg[GREG_PCI_MEM1_LO]<<21) | (offset*4), mem_mask); - if (LOG_GALILEO) + if (LOG_PCI) logerror("%06X:galileo pci mem1 read from offset %08X = %08X & %08X\n", space.device().safe_pc(), (m_reg[GREG_PCI_MEM1_LO]<<21) | (offset*4), result, mem_mask); return result; } WRITE32_MEMBER (gt64xxx_device::master_mem1_w) { this->space(AS_DATA).write_dword((m_reg[GREG_PCI_MEM1_LO]<<21) | (offset*4), data, mem_mask); - if (LOG_GALILEO) + if (LOG_PCI) logerror("%06X:galileo pci mem1 write to offset %08X = %08X & %08X\n", space.device().safe_pc(), (m_reg[GREG_PCI_MEM1_LO]<<21) | (offset*4), data, mem_mask); } @@ -231,15 +350,79 @@ WRITE32_MEMBER (gt64xxx_device::master_mem1_w) READ32_MEMBER (gt64xxx_device::master_io_r) { UINT32 result = this->space(AS_IO).read_dword((m_reg[GREG_PCI_IO_LO]<<21) | (offset*4), mem_mask); - if (LOG_GALILEO) - logerror("%06X:galileo pci io read from offset %08X = %08X & %08X\n", space.device().safe_pc(), (m_reg[GREG_PCI_IO_LO]<<21) | (offset*4), result, mem_mask); + if (LOG_PCI && m_prev_addr != offset) { + m_prev_addr = offset; + logerror("%06X:galileo pci io read from offset %08X = %08X & %08X\n", space.device().safe_pc(), (m_reg[GREG_PCI_IO_LO] << 21) | (offset * 4), result, mem_mask); + } return result; } WRITE32_MEMBER (gt64xxx_device::master_io_w) { this->space(AS_IO).write_dword((m_reg[GREG_PCI_IO_LO]<<21) | (offset*4), data, mem_mask); - if (LOG_GALILEO) - logerror("%06X:galileo pciio write to offset %08X = %08X & %08X\n", space.device().safe_pc(), (m_reg[GREG_PCI_IO_LO]<<21) | (offset*4), data, mem_mask); + if (LOG_PCI && m_prev_addr != offset) { + m_prev_addr = offset; + logerror("%06X:galileo pciio write to offset %08X = %08X & %08X\n", space.device().safe_pc(), (m_reg[GREG_PCI_IO_LO] << 21) | (offset * 4), data, mem_mask); + } +} + +READ32_MEMBER(gt64xxx_device::ras_0_r) +{ + UINT32 result = m_ram[0][offset]; + if (LOG_PCI) + logerror("%06X:galileo ras_0 read from offset %08X = %08X & %08X\n", space.device().safe_pc(), offset * 4, result, mem_mask); + return result; +} + +WRITE32_MEMBER(gt64xxx_device::ras_0_w) +{ + COMBINE_DATA(&m_ram[0][offset]); + if (LOG_PCI) + logerror("%06X:galileo ras_0 write to offset %08X = %08X & %08X\n", space.device().safe_pc(), offset * 4, data, mem_mask); +} + +READ32_MEMBER(gt64xxx_device::ras_1_r) +{ + UINT32 result = m_ram[1][offset]; + if (LOG_PCI) + logerror("%06X:galileo ras_0 read from offset %08X = %08X & %08X\n", space.device().safe_pc(), offset * 4, result, mem_mask); + return result; +} + +WRITE32_MEMBER(gt64xxx_device::ras_1_w) +{ + COMBINE_DATA(&m_ram[1][offset]); + if (LOG_PCI) + logerror("%06X:galileo ras_0 write to offset %08X = %08X & %08X\n", space.device().safe_pc(), offset * 4, data, mem_mask); +} + +READ32_MEMBER(gt64xxx_device::ras_2_r) +{ + UINT32 result = m_ram[2][offset]; + if (LOG_PCI) + logerror("%06X:galileo ras_0 read from offset %08X = %08X & %08X\n", space.device().safe_pc(), offset * 4, result, mem_mask); + return result; +} + +WRITE32_MEMBER(gt64xxx_device::ras_2_w) +{ + COMBINE_DATA(&m_ram[2][offset]); + if (LOG_PCI) + logerror("%06X:galileo ras_0 write to offset %08X = %08X & %08X\n", space.device().safe_pc(), offset * 4, data, mem_mask); +} + +READ32_MEMBER(gt64xxx_device::ras_3_r) +{ + UINT32 result = m_ram[3][offset]; + if (LOG_PCI) + logerror("%06X:galileo ras_0 read from offset %08X = %08X & %08X\n", space.device().safe_pc(), offset * 4, result, mem_mask); + return result; +} + +WRITE32_MEMBER(gt64xxx_device::ras_3_w) +{ + COMBINE_DATA(&m_ram[3][offset]); + if (LOG_PCI) + logerror("%06X:galileo ras_0 write to offset %08X = %08X & %08X\n", space.device().safe_pc(), offset * 4, data, mem_mask); } @@ -267,7 +450,7 @@ READ32_MEMBER (gt64xxx_device::cpu_if_r) } /* eat some time for those which poll this register */ - space.device().execute().eat_cycles(100); + //space.device().execute().eat_cycles(100); if (LOG_TIMERS) logerror("%08X:hires_timer_r = %08X\n", space.device().safe_pc(), result); @@ -277,10 +460,15 @@ READ32_MEMBER (gt64xxx_device::cpu_if_r) case GREG_PCI_COMMAND: // code at 40188 loops until this returns non-zero in bit 0 //result = 0x0001; + // bit 0 => byte swap + // bit 2:1 => SyncMode, 00 = PCLK=[0,33], 01 = PCLK>=TClk/2, 10 = PCLK = TCLK/2 + result = (result & ~0x1) | (m_be ^ 0x1); break; case GREG_CONFIG_DATA: result = config_data_r(space, offset); + if (LOG_GALILEO) + logerror("%08X:Galileo GREG_CONFIG_DATA read from offset %03X = %08X\n", space.device().safe_pc(), offset*4, result); break; case GREG_CONFIG_ADDRESS: @@ -317,22 +505,24 @@ WRITE32_MEMBER(gt64xxx_device::cpu_if_w) /* switch off the offset for special cases */ switch (offset) { - case GREG_RAS_1_0_LO: - case GREG_RAS_1_0_HI: - case GREG_RAS_3_2_LO: - case GREG_RAS_3_2_HI: - case GREG_CS_2_0_LO: - case GREG_CS_2_0_HI: - case GREG_CS_3_BOOT_LO: - case GREG_CS_3_BOOT_HI: - case GREG_PCI_IO_LO: - case GREG_PCI_IO_HI: - case GREG_PCI_MEM0_LO: - case GREG_PCI_MEM0_HI: + //case GREG_RAS_1_0_LO: + //case GREG_RAS_1_0_HI: + //case GREG_RAS_3_2_LO: + //case GREG_RAS_3_2_HI: + //case GREG_CS_2_0_LO: + //case GREG_CS_2_0_HI: + //case GREG_CS_3_BOOT_LO: + //case GREG_CS_3_BOOT_HI: + //case GREG_PCI_IO_LO: + //case GREG_PCI_IO_HI: + //case GREG_PCI_MEM0_LO: + //case GREG_PCI_MEM0_HI: case GREG_INTERNAL_SPACE: - case GREG_PCI_MEM1_LO: - case GREG_PCI_MEM1_HI: + //case GREG_PCI_MEM1_LO: + //case GREG_PCI_MEM1_HI: + case GREG_CS3_HI: map_cpu_space(); + remap_cb(); if (LOG_GALILEO) logerror("%08X:Galileo Memory Map data write to offset %03X = %08X & %08X\n", space.device().safe_pc(), offset*4, data, mem_mask); break; @@ -344,9 +534,6 @@ WRITE32_MEMBER(gt64xxx_device::cpu_if_w) { int which = offset % 4; - if (LOG_DMA) - logerror("%08X:Galileo write to offset %03X = %08X & %08X\n", space.device().safe_pc(), offset*4, data, mem_mask); - /* keep the read only activity bit */ m_reg[offset] &= ~0x4000; m_reg[offset] |= (oldata & 0x4000); @@ -357,8 +544,18 @@ WRITE32_MEMBER(gt64xxx_device::cpu_if_w) m_reg[offset] &= ~0x2000; /* if enabling, start the DMA */ - if (!(oldata & 0x1000) && (data & 0x1000)) - perform_dma(space, which); + if (!(oldata & 0x1000) && (data & 0x1000) && !(m_dma_active & (1<adjust(attotime::zero, 0, DMA_TIMER_PERIOD); + m_dma_active |= (1<< which); + //perform_dma(space, which); + if (LOG_DMA) + logerror("%08X:Galileo starting DMA Chan %i\n", space.device().safe_pc(), which); + } + if (LOG_GALILEO) + logerror("%08X:Galileo write to offset %03X = %08X & %08X\n", space.device().safe_pc(), offset * 4, data, mem_mask); break; } @@ -428,9 +625,30 @@ WRITE32_MEMBER(gt64xxx_device::cpu_if_w) break; case GREG_CONFIG_ADDRESS: - pci_host_device::config_address_w(space, offset, data); + // Type 0 config transactions signalled by Bus Num = 0 and Device Num != 0 + // Bits 15:11 get mapped into device number for configuration + UINT32 modData; + if (0 && (data & 0xff0000) == 0x0 && (data & 0xf800)) { + // Type 0 transaction + modData = 0; + // Select the device based on one hot bit + for (int i = 11; i<16; i++) { + if ((data >> i) & 0x1) { + // One hot encoding, bit 11 will mean device 1 + modData = i - 10; + break; + } + } + // Re-organize into Type 1 transaction for bus 0 (local bus) + modData = (modData << 11) | (data & 0x7ff) | (0x80000000); + } + else { + // Type 1 transaction, no modification needed + modData = data; + } + pci_host_device::config_address_w(space, offset, modData); if (LOG_GALILEO) - logerror("%08X:Galileo PCI config address write to offset %03X = %08X & %08X\n", space.device().safe_pc(), offset*4, data, mem_mask); + logerror("%08X:Galileo PCI config address write to offset %03X = %08X & %08X origData = %08X\n", space.device().safe_pc(), offset*4, modData, mem_mask, data); break; case GREG_DMA0_COUNT: case GREG_DMA1_COUNT: case GREG_DMA2_COUNT: case GREG_DMA3_COUNT: @@ -464,8 +682,8 @@ void gt64xxx_device::update_irqs() if (m_irq_num != -1) m_cpu->set_input_line(m_irq_num, state); - if (LOG_GALILEO) - logerror("Galileo IRQ %s\n", (state == ASSERT_LINE) ? "asserted" : "cleared"); + if (1 && LOG_GALILEO) + logerror("Galileo IRQ %s irqNum: %i state = %08X mask = %08X\n", (state == ASSERT_LINE) ? "asserted" : "cleared", m_irq_num, m_reg[GREG_INT_STATE], m_reg[GREG_INT_MASK]); } @@ -498,6 +716,15 @@ TIMER_CALLBACK_MEMBER(gt64xxx_device::timer_callback) * Galileo DMA handler * *************************************/ +address_space* gt64xxx_device::dma_decode_address(UINT32 &addr) +{ + for (size_t index = 0; index < proc_addr_bank::ADDR_NUM; ++index) + { + if (addr >= dma_addr_map[index].low_addr && addr <= dma_addr_map[index].high_addr) + return dma_addr_map[index].space; + } + return nullptr; +} int gt64xxx_device::dma_fetch_next(address_space &space, int which) { @@ -539,16 +766,33 @@ int gt64xxx_device::dma_fetch_next(address_space &space, int which) } -void gt64xxx_device::perform_dma(address_space &space, int which) +TIMER_CALLBACK_MEMBER (gt64xxx_device::perform_dma) { - do + // Cycle through the channels + int which = -1; + for (int i = 1; i <= 4; i++) + { + which = (m_last_dma + i) % 4; + if ((m_dma_active & (1 << which)) && (m_reg[GREG_DMA0_CONTROL + which] & 0x1000)) + break; + + } + // Save which dma is processed for arbitration next time + m_last_dma = which; + + if (which==-1) + { + logerror("gt64xxx_device::perform_dma Warning! DMA Timer called with no pending DMA. m_dma_active = %08X\n", m_dma_active); + } else { offs_t srcaddr = m_reg[GREG_DMA0_SOURCE + which]; offs_t dstaddr = m_reg[GREG_DMA0_DEST + which]; UINT32 bytesleft = m_reg[GREG_DMA0_COUNT + which] & 0xffff; + address_space* srcSpace = dma_decode_address(srcaddr); + address_space* dstSpace = dma_decode_address(dstaddr); + int srcinc, dstinc; - m_dma_active = which; m_reg[GREG_DMA0_CONTROL + which] |= 0x5000; /* determine src/dst inc */ @@ -570,32 +814,50 @@ void gt64xxx_device::perform_dma(address_space &space, int which) if (LOG_DMA) logerror("Performing DMA%d: src=%08X dst=%08X bytes=%04X sinc=%d dinc=%d\n", which, srcaddr, dstaddr, bytesleft, srcinc, dstinc); + int burstCount = 0; /* standard transfer */ - while (bytesleft > 0) + while (bytesleft > 0 && burstCount < DMA_BURST_SIZE) + { + if (bytesleft < 4) { - space.write_byte(dstaddr, space.read_byte(srcaddr)); + //space.write_byte(dstaddr, space.read_byte(srcaddr)); + dstSpace->write_byte(dstaddr, srcSpace->read_byte(srcaddr)); srcaddr += srcinc; dstaddr += dstinc; bytesleft--; } - + else { + //space.write_byte(dstaddr, space.read_byte(srcaddr)); + dstSpace->write_dword(dstaddr, srcSpace->read_dword(srcaddr)); + srcaddr += srcinc * 4; + dstaddr += dstinc * 4; + bytesleft -= 4; + } + burstCount++; + } /* not verified, but seems logical these should be updated byte the end */ m_reg[GREG_DMA0_SOURCE + which] = srcaddr; m_reg[GREG_DMA0_DEST + which] = dstaddr; m_reg[GREG_DMA0_COUNT + which] = (m_reg[GREG_DMA0_COUNT + which] & ~0xffff) | bytesleft; - m_dma_active = -1; /* if we did not hit zero, punt and return later */ if (bytesleft != 0) + { return; - + } /* interrupt? */ if (!(m_reg[GREG_DMA0_CONTROL + which] & 0x400)) { m_reg[GREG_INT_STATE] |= 1 << (GINT_DMA0COMP_SHIFT + which); update_irqs(); } - } while (dma_fetch_next(space, which)); - m_reg[GREG_DMA0_CONTROL + which] &= ~0x5000; + // Fetch the next dma for this channel (to be performed next scheduled burst) + if (dma_fetch_next(*m_cpu_space, which) == 0) + { + m_dma_active &= ~(1 << which); + // Turn off the timer + m_dma_timer->adjust(attotime::never); + } + } } diff --git a/src/devices/machine/gt64xxx.h b/src/devices/machine/gt64xxx.h index 6653c9ca552..91846a8fab7 100644 --- a/src/devices/machine/gt64xxx.h +++ b/src/devices/machine/gt64xxx.h @@ -3,10 +3,7 @@ // Galileo GT-64xxx System Controller // Skeleton code based off seattle machine driver. // TODO: -// Testing -// Need PCI to be able to have a target delay a dma transfer -// Add PCI target maps -// Add PCI Func 1 calls +// Need PCI to be able to have a target delay (pci bus stall) a dma transfer // Configurable byte swapping on cpu and pci busses. #ifndef GT64XXX_H @@ -16,34 +13,42 @@ #include "cpu/mips/mips3.h" // Supports R4600/4650/4700/R5000 CPUs -#define MCFG_GT64010_ADD(_tag, _cpu_tag, _clock) \ +#define MCFG_GT64010_ADD(_tag, _cpu_tag, _clock, _irq_num) \ MCFG_PCI_HOST_ADD(_tag, GT64XXX, 0x014611ab, 0x03, 0x00000000) \ downcast(device)->set_cpu_tag(_cpu_tag); \ - downcast(device)->set_clock(_clock); + downcast(device)->set_clock(_clock); \ + downcast(device)->set_irq_num(_irq_num); // Supports the following 32-bit bus CPUs: // IDT RC4640 and RC4650 (in 32-bit mode) // QED RM523X // NEC/Toshiba VR4300 -#define MCFG_GT64111_ADD(_tag, _cpu_tag, _clock) \ +#define MCFG_GT64111_ADD(_tag, _cpu_tag, _clock, _irq_num) \ MCFG_PCI_DEVICE_ADD(_tag, GT64XXX, 0x414611ab, 0x10, 0x058000, 0x00000000) \ downcast(device)->set_cpu_tag(_cpu_tag); \ - downcast(device)->set_clock(_clock); + downcast(device)->set_clock(_clock); \ + downcast(device)->set_irq_num(_irq_num); #define MCFG_GT64XXX_SET_BE_CPU(_be) \ downcast(device)->set_be(_be); -#define MCFG_GT64XXX__IRQ_ADD(_irq_num) \ +#define MCFG_GT64XXX_IRQ_ADD(_irq_num) \ downcast(device)->set_irq_info(_irq_num); +#define MCFG_GT64XXX_SET_CS(_cs_num, _map) \ + downcast(device)->set_cs_map(_cs_num, ADDRESS_MAP_NAME(_map), #_map, owner); + /************************************* * * Galileo constants * *************************************/ -//#define SYSTEM_CLOCK 50000000 #define TIMER_PERIOD attotime::from_hz(m_clock) +#define PCI_BUS_CLOCK 33000000 +// Number of dma words to transfer at a time, real hardware configurable between 8-32 +#define DMA_BURST_SIZE 32 +#define DMA_TIMER_PERIOD attotime::from_hz(PCI_BUS_CLOCK / 48) /* Galileo registers - 0x000-0x3ff */ #define GREG_CPU_CONFIG (0x000/4) @@ -161,6 +166,7 @@ #define GINT_TARABORT_SHIFT (19) #define GINT_RETRYCTR_SHIFT (20) + /************************************* * Structures *************************************/ @@ -171,6 +177,22 @@ struct galileo_timer UINT8 active; }; +struct galileo_addr_map +{ + UINT32 low_addr; + UINT32 high_addr; + address_space* space; + galileo_addr_map() : low_addr(0xffffffff), high_addr(0x0) {} +}; + +struct galileo_device_map +{ + bool enable; + const char *name; + device_t *device; + address_map_constructor map; + galileo_device_map() : enable(false), device(nullptr) {} +}; class gt64xxx_device : public pci_host_device { public: @@ -181,12 +203,10 @@ public: UINT64 io_window_start, UINT64 io_window_end, UINT64 io_offset, address_space *io_space) override; void set_cpu_tag(const char *tag) { cpu_tag = tag;} - void set_cpu_tag(const UINT32 clock) { m_clock = clock;} void set_clock(const UINT32 clock) {m_clock = clock;} void set_be(const int be) {m_be = be;} void set_autoconfig(const int autoconfig) {m_autoconfig = autoconfig;} - void set_irq_info(const int irq_num) {m_irq_num = irq_num;} - + void set_irq_num(const int irq_num) {m_irq_num = irq_num;} virtual DECLARE_ADDRESS_MAP(config_map, 32) override; // pci bus @@ -207,14 +227,21 @@ public: DECLARE_WRITE32_MEMBER(master_io_w); // devices - DECLARE_READ32_MEMBER (ras_1_0_r); - DECLARE_WRITE32_MEMBER(ras_1_0_w); - DECLARE_READ32_MEMBER (ras_3_2_r); - DECLARE_WRITE32_MEMBER(ras_3_2_w); - DECLARE_READ32_MEMBER (cs_2_0_r); - DECLARE_WRITE32_MEMBER(cs_2_0_w); - DECLARE_READ32_MEMBER (cs_boot_3_r); - DECLARE_WRITE32_MEMBER(cs_boot_3_w); + DECLARE_READ32_MEMBER (ras_0_r); + DECLARE_WRITE32_MEMBER(ras_0_w); + DECLARE_READ32_MEMBER(ras_1_r); + DECLARE_WRITE32_MEMBER(ras_1_w); + DECLARE_READ32_MEMBER(ras_2_r); + DECLARE_WRITE32_MEMBER(ras_2_w); + DECLARE_READ32_MEMBER(ras_3_r); + DECLARE_WRITE32_MEMBER(ras_3_w); + DECLARE_READ32_MEMBER (cs_0_r); + DECLARE_WRITE32_MEMBER(cs_0_w); + + // Enums + enum proc_addr_bank {ADDR_RAS1_0, ADDR_RAS3_2, ADDR_CS2_0, ADDR_CS3_BCS, ADDR_PCI_IO, ADDR_PCI_MEM0, ADDR_PCI_MEM1, ADDR_NUM}; + + void set_cs_map(int id, address_map_constructor map, const char *name, device_t *device); protected: address_space *m_cpu_space; @@ -222,6 +249,7 @@ protected: virtual void device_start() override; virtual void device_reset() override; + private: mips3_device *m_cpu; const char *cpu_tag; @@ -231,17 +259,20 @@ private: address_space_config m_mem_config, m_io_config; - required_memory_region m_region; + required_memory_region m_romRegion; + optional_memory_region m_updateRegion; DECLARE_ADDRESS_MAP(cpu_map, 32); void map_cpu_space(); + UINT32 m_prev_addr; /* raw register data */ UINT32 m_reg[0xd00/4]; /* timer info */ galileo_timer m_timer[4]; + TIMER_CALLBACK_MEMBER(timer_callback); /* DMA info */ INT8 m_dma_active; @@ -249,10 +280,26 @@ private: // Ram std::vector m_ram[4]; - TIMER_CALLBACK_MEMBER(timer_callback); + // Chip Select + std::vector m_cs_map; + + template void map_trampoline(::address_map &map, device_t &device) { + m_cs_map[id].map(map, *m_cs_map[id].device); + } + template void install_cs_map(offs_t addrstart, offs_t addrend, void (T::*map)(::address_map &map, device_t &device), const char *name) { + //address_map_delegate delegate(map, name, static_cast(this)); + address_map_delegate delegate(map, name, static_cast(this)); + m_cpu_space->install_device_delegate(addrstart, addrend, *this, delegate); + } + void update_irqs(); + + int m_last_dma; + emu_timer* m_dma_timer; + std::vector dma_addr_map; int dma_fetch_next(address_space &space, int which); - void perform_dma(address_space &space, int which); + TIMER_CALLBACK_MEMBER(perform_dma); + address_space* dma_decode_address(UINT32 &addr); }; diff --git a/src/devices/machine/pci-ide.cpp b/src/devices/machine/pci-ide.cpp new file mode 100644 index 00000000000..5e89535d13c --- /dev/null +++ b/src/devices/machine/pci-ide.cpp @@ -0,0 +1,157 @@ +// license:BSD-3-Clause +// copyright-holders:Ted Green +#include "pci-ide.h" + +const device_type IDE_PCI = &device_creator; + +ide_pci_device::ide_pci_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : pci_device(mconfig, IDE_PCI, "IDE PCI interface", tag, owner, clock, "ide_pci", __FILE__), + m_ide(*this, "ide"), + m_ide2(*this, "ide2"), + m_irq_num(-1) +{ +} + +DEVICE_ADDRESS_MAP_START(config_map, 32, ide_pci_device) + AM_RANGE(0x10, 0x17) AM_WRITE(address_base_w) + AM_RANGE(0x40, 0x5f) AM_READWRITE(pcictrl_r, pcictrl_w) + AM_INHERIT_FROM(pci_device::config_map) +ADDRESS_MAP_END + +DEVICE_ADDRESS_MAP_START(chan1_data_command_map, 32, ide_pci_device) + AM_RANGE(0x0, 0x7) AM_DEVREADWRITE("ide", bus_master_ide_controller_device, read_cs0, write_cs0) +ADDRESS_MAP_END + +DEVICE_ADDRESS_MAP_START(chan1_control_map, 32, ide_pci_device) + AM_RANGE(0x0, 0x3) AM_READWRITE(ide_read_cs1, ide_write_cs1) +ADDRESS_MAP_END + +DEVICE_ADDRESS_MAP_START(chan2_data_command_map, 32, ide_pci_device) + AM_RANGE(0x0, 0x7) AM_DEVREADWRITE("ide2", bus_master_ide_controller_device, read_cs0, write_cs0) +ADDRESS_MAP_END + +DEVICE_ADDRESS_MAP_START(chan2_control_map, 32, ide_pci_device) + AM_RANGE(0x0, 0x3) AM_READWRITE(ide2_read_cs1, ide2_write_cs1) +ADDRESS_MAP_END + +DEVICE_ADDRESS_MAP_START(bus_master_map, 32, ide_pci_device) + AM_RANGE(0x0, 0x7) AM_DEVREADWRITE("ide", bus_master_ide_controller_device, bmdma_r, bmdma_w) + AM_RANGE(0x8, 0xf) AM_DEVREADWRITE("ide2", bus_master_ide_controller_device, bmdma_r, bmdma_w) +ADDRESS_MAP_END + +static MACHINE_CONFIG_FRAGMENT(pci_ide) + MCFG_BUS_MASTER_IDE_CONTROLLER_ADD("ide", ata_devices, "hdd", nullptr, true) + MCFG_ATA_INTERFACE_IRQ_HANDLER(WRITELINE(ide_pci_device, ide_interrupt)) + //MCFG_BUS_MASTER_IDE_CONTROLLER_SPACE(":maincpu", AS_PROGRAM) + MCFG_BUS_MASTER_IDE_CONTROLLER_SPACE(":pci:00.0", AS_DATA) + MCFG_BUS_MASTER_IDE_CONTROLLER_ADD("ide2", ata_devices, nullptr, "cdrom", true) + MCFG_ATA_INTERFACE_IRQ_HANDLER(WRITELINE(ide_pci_device, ide_interrupt)) + //MCFG_BUS_MASTER_IDE_CONTROLLER_SPACE(":maincpu", AS_PROGRAM) + MCFG_BUS_MASTER_IDE_CONTROLLER_SPACE(":pci:00.0", AS_DATA) +MACHINE_CONFIG_END + +machine_config_constructor ide_pci_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME(pci_ide); +} + +void ide_pci_device::set_irq_info(const char *tag, const int irq_num) +{ + m_cpu_tag = tag; + m_irq_num = irq_num; +} + +void ide_pci_device::device_start() +{ + m_cpu = machine().device(m_cpu_tag); + + pci_device::device_start(); + + add_map(8, M_IO, FUNC(ide_pci_device::chan1_data_command_map)); + bank_infos[0].adr = 0x1f0; + add_map(4, M_IO, FUNC(ide_pci_device::chan1_control_map)); + bank_infos[1].adr = 0x3f4; + add_map(8, M_IO, FUNC(ide_pci_device::chan2_data_command_map)); + bank_infos[2].adr = 0x170; + add_map(4, M_IO, FUNC(ide_pci_device::chan2_control_map)); + bank_infos[3].adr = 0x374; + add_map(16, M_IO, FUNC(ide_pci_device::bus_master_map)); + bank_infos[4].adr = 0xf00; +} + +void ide_pci_device::device_reset() +{ + pci_device::device_reset(); +} + +READ32_MEMBER(ide_pci_device::ide_read_cs1) +{ + // PCI offset starts at 0x3f4, idectrl expects 0x3f0 + UINT32 data = 0; + data = m_ide->read_cs1(space, ++offset, mem_mask); + return data; +} + +WRITE32_MEMBER(ide_pci_device::ide_write_cs1) +{ + // PCI offset starts at 0x3f4, idectrl expects 0x3f0 + m_ide->write_cs1(space, ++offset, data, mem_mask); +} + +READ32_MEMBER(ide_pci_device::ide2_read_cs1) +{ + // PCI offset starts at 0x374, idectrl expects 0x370 + UINT32 data = 0; + data = m_ide2->read_cs1(space, ++offset, mem_mask); + return data; +} + +WRITE32_MEMBER(ide_pci_device::ide2_write_cs1) +{ + // PCI offset starts at 0x374, idectrl expects 0x370 + m_ide2->write_cs1(space, ++offset, data, mem_mask); +} + +WRITE_LINE_MEMBER(ide_pci_device::ide_interrupt) +{ + if (m_irq_num != -1) { + m_cpu->set_input_line(m_irq_num, state); + } + if (0) + logerror("%s:ide_interrupt %i set to %i\n", machine().describe_context(), m_irq_num, state); +} + +READ32_MEMBER(ide_pci_device::pcictrl_r) +{ + return m_config_data[offset]; +} + +WRITE32_MEMBER(ide_pci_device::pcictrl_w) +{ + COMBINE_DATA(&m_config_data[offset]); +} + +WRITE32_MEMBER(ide_pci_device::address_base_w) +{ + if (1) { + // Bits 0 (ide) and 2 (ide2) control if the mapping is legacy or BAR + switch (offset) { + case 0: + if ((pclass & 0x1) == 0) + data = (data & 0xfffff000) | 0x1f0; + break; + case 1: + if ((pclass & 0x1) == 0) + data = (data & 0xfffff000) | 0x3f4; + break; + case 2: + if ((pclass & 0x4) == 0) + data = (data & 0xfffff000) | 0x170; + break; + default: + if ((pclass & 0x4) == 0) + data = (data & 0xfffff000) | 0x374; + } + } + pci_device::address_base_w(space, offset, data); +} diff --git a/src/devices/machine/pci-ide.h b/src/devices/machine/pci-ide.h new file mode 100644 index 00000000000..3a6beea21eb --- /dev/null +++ b/src/devices/machine/pci-ide.h @@ -0,0 +1,65 @@ +// license:BSD-3-Clause +// copyright-holders:Ted Green +/*************************************************************************** + +pci-ide.h + +Generic PCI IDE controller implementation. +Based on datasheet for National Semiconductor PC87415 + +TODO: + Add pci configuration write to PIF byte +***************************************************************************/ + +#ifndef PCI_IDE_H +#define PCI_IDE_H + +#include "pci.h" +#include "idectrl.h" + +#define MCFG_IDE_PCI_ADD(_tag, _main_id, _revision, _subdevice_id) \ + MCFG_PCI_DEVICE_ADD(_tag, IDE_PCI, _main_id, _revision, 0x01018a, _subdevice_id) + +#define MCFG_IDE_PCI_IRQ_ADD(_cpu_tag, _irq_num) \ + downcast(device)->set_irq_info(_cpu_tag, _irq_num); + +class ide_pci_device : public pci_device { +public: + ide_pci_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + required_device m_ide; + required_device m_ide2; + virtual DECLARE_ADDRESS_MAP(config_map, 32) override; + DECLARE_WRITE_LINE_MEMBER(ide_interrupt); + DECLARE_READ32_MEMBER(ide_read_cs1); + DECLARE_WRITE32_MEMBER(ide_write_cs1); + DECLARE_READ32_MEMBER(ide2_read_cs1); + DECLARE_WRITE32_MEMBER(ide2_write_cs1); + void set_irq_info(const char *tag, const int irq_num); + +protected: + virtual void device_start() override; + virtual void device_reset() override; + + // optional information overrides + virtual machine_config_constructor device_mconfig_additions() const override; + +private: + const char *m_cpu_tag; + cpu_device *m_cpu; + int m_irq_num; + int m_irq_status; + + UINT32 m_config_data[0x10]; + DECLARE_ADDRESS_MAP(chan1_data_command_map, 32); + DECLARE_ADDRESS_MAP(chan1_control_map, 32); + DECLARE_ADDRESS_MAP(chan2_data_command_map, 32); + DECLARE_ADDRESS_MAP(chan2_control_map, 32); + DECLARE_ADDRESS_MAP(bus_master_map, 32); + DECLARE_READ32_MEMBER(pcictrl_r); + DECLARE_WRITE32_MEMBER(pcictrl_w); + DECLARE_WRITE32_MEMBER(address_base_w); +}; + +extern const device_type IDE_PCI; + +#endif diff --git a/src/devices/video/voodoo_pci.cpp b/src/devices/video/voodoo_pci.cpp index 9d34442f08b..8d1242713f8 100644 --- a/src/devices/video/voodoo_pci.cpp +++ b/src/devices/video/voodoo_pci.cpp @@ -106,11 +106,17 @@ void voodoo_pci_device::device_start() pci_device::device_start(); if (m_type<=TYPE_VOODOO_2) { add_map(16*1024*1024, M_MEM | M_PREF, FUNC(voodoo_pci_device::voodoo_reg_map)); + bank_infos[0].adr = 0xff000000; } else { add_map(32*1024*1024, M_MEM, FUNC(voodoo_pci_device::banshee_reg_map)); add_map(32*1024*1024, M_MEM, FUNC(voodoo_pci_device::lfb_map)); add_map(256, M_IO, FUNC(voodoo_pci_device::io_map)); + bank_infos[0].adr = 0xf8000000; + bank_infos[1].adr = 0xf8000008; + bank_infos[2].adr = 0xfffffff0; } + + save_item(NAME(m_pcictrl_reg)); } void voodoo_pci_device::device_reset()