pci: Add save state support. (nw)

pci-ide: Allow for setting the top 12 decode address bits in legacy mode. (nw)
pci-ide: Add save state support. (nw)
pci9050: Add save state support. (nw)
vrc4373: Add save state support. (nw)
gt64xxx: Remove address map trampolines. (nw)
gt64xxx: Add save state support. (nw)
atlantis: Add save state support. (nw)
This commit is contained in:
Ted Green 2017-05-05 10:54:28 -06:00
parent c61e1ba31a
commit eef01e78d6
9 changed files with 117 additions and 94 deletions

View File

@ -24,6 +24,9 @@ DEVICE_ADDRESS_MAP_START(cpu_map, 32, gt64xxx_device)
AM_RANGE(0x00000000, 0x00000cff) AM_READWRITE( cpu_if_r, cpu_if_w)
ADDRESS_MAP_END
DEVICE_ADDRESS_MAP_START(empty, 32, gt64xxx_device)
ADDRESS_MAP_END
gt64xxx_device::gt64xxx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: pci_host_device(mconfig, GT64XXX, "Galileo GT-64XXX System Controller", tag, owner, clock, "gt64xxx", __FILE__),
m_be(0), m_autoconfig(0), m_irq_num(-1),
@ -32,14 +35,15 @@ gt64xxx_device::gt64xxx_device(const machine_config &mconfig, const char *tag, d
m_romRegion(*this, "rom"),
m_updateRegion(*this, "update")
{
for (int csIndex = 0; csIndex < 4; csIndex++) {
m_cs_devices[csIndex] = nullptr;
}
}
void gt64xxx_device::set_cs_map(int id, address_map_constructor map, const char *name, device_t *device)
void gt64xxx_device::set_map(int id, const address_map_delegate &map, 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;
m_cs_maps[id] = map;
m_cs_devices[id] = device;
}
const address_space_config *gt64xxx_device::memory_space_config(address_spacenum spacenum) const
@ -68,6 +72,10 @@ void gt64xxx_device::device_start()
// Leave the timer disabled.
m_dma_timer->adjust(attotime::never, 0, DMA_TIMER_PERIOD);
// Reserve 8MB RAM
m_ram[0].reserve(0x00800000 / 4);
m_ram[0].resize(0x00800000 / 4);
// ROM
uint32_t romSize = m_romRegion->bytes();
m_cpu_space->install_rom (0x1fc00000, 0x1fc00000 + romSize - 1, m_romRegion->base());
@ -89,6 +97,31 @@ void gt64xxx_device::device_start()
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));
// Save states
save_item(NAME(m_pci_stall_state));
save_item(NAME(m_retry_count));
save_item(NAME(m_pci_cpu_stalled));
save_item(NAME(m_cpu_stalled_offset));
save_item(NAME(m_cpu_stalled_data));
save_item(NAME(m_cpu_stalled_mem_mask));
save_item(NAME(m_prev_addr));
save_item(NAME(m_reg));
for (int i = 0; i < ARRAY_LENGTH(m_timer); i++) {
save_item(NAME(m_timer[i].active), i);
save_item(NAME(m_timer[i].count), i);
}
save_item(NAME(m_dma_active));
// m_ram[4]
save_pointer(NAME(m_ram[0].data()), 0x00800000 / 4);
save_item(NAME(m_last_dma));
machine().save().register_postload(save_prepost_delegate(FUNC(gt64xxx_device::map_cpu_space), this));
}
void gt64xxx_device::postload()
{
map_cpu_space();
remap_cb();
}
void gt64xxx_device::device_reset()
@ -170,12 +203,14 @@ void gt64xxx_device::map_cpu_space()
logerror("%s: map_cpu_space cpu_reg start: %08X end: %08X\n", tag(), winStart, winEnd);
// RAS[0:3]
m_ram[0].resize(0x00800000 / 4);
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_ram[ramIndex].resize((winEnd + 1 - winStart) / 4);
if (m_ram[ramIndex].size()>0)
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_t), false, m_ram[ramIndex].data());
if (LOG_GALILEO)
@ -183,27 +218,15 @@ void gt64xxx_device::map_cpu_space()
}
// 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 &);
static const tramp_t trampolines[4] = {
&gt64xxx_device::map_trampoline<0>,
&gt64xxx_device::map_trampoline<1>,
&gt64xxx_device::map_trampoline<2>,
&gt64xxx_device::map_trampoline<3>
};
for (int ramIndex = 0; ramIndex < 4; ++ramIndex)
for (int csIndex = 0; csIndex < 4; ++csIndex)
{
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);
}
winStart = (m_reg[GREG_CS_2_0_LO + 0x10 / 4 * (csIndex / 3)] << 21) | (m_reg[GREG_CS0_LO + 0x8 / 4 * csIndex] << 20);
winEnd = (m_reg[GREG_CS_2_0_LO + 0x10 / 4 * (csIndex / 3)] << 21) | (m_reg[GREG_CS0_HI + 0x8 / 4 * csIndex] << 20) | 0xfffff;
m_cpu_space->install_device_delegate(winStart, winEnd, *m_cs_devices[csIndex], m_cs_maps[csIndex]);
if (LOG_GALILEO)
logerror("%s: map_cpu_space cs[%i] start: %08X end: %08X\n", tag(), csIndex, winStart, winEnd);
}
// PCI IO Window
winStart = m_reg[GREG_PCI_IO_LO]<<21;
winEnd = (m_reg[GREG_PCI_IO_LO]<<21) | (m_reg[GREG_PCI_IO_HI]<<21) | 0x1fffff;
@ -388,7 +411,7 @@ WRITE32_MEMBER (gt64xxx_device::master_mem1_w)
// PCI Master IO
READ32_MEMBER (gt64xxx_device::master_io_r)
{
uint32_t result = this->space(AS_IO).read_dword((m_reg[GREG_PCI_IO_LO]<<21) | (offset*4), mem_mask);
uint32_t result = this->space(AS_IO).read_dword((m_reg[GREG_PCI_IO_LO] << 21) | (offset * 4), 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);
@ -397,10 +420,10 @@ READ32_MEMBER (gt64xxx_device::master_io_r)
}
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);
this->space(AS_IO).write_dword((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);
logerror("%06X:galileo pci io write to offset %08X = %08X & %08X\n", space.device().safe_pc(), (m_reg[GREG_PCI_IO_LO] << 21) | (offset * 4), data, mem_mask);
}
}

View File

@ -14,7 +14,7 @@
// Supports R4600/4650/4700/R5000 CPUs
#define MCFG_GT64010_ADD(_tag, _cpu_tag, _clock, _irq_num) \
MCFG_PCI_HOST_ADD(_tag, GT64XXX, 0x014611ab, 0x03, 0x00000000) \
MCFG_PCI_HOST_ADD(_tag, GT64XXX, 0x11ab0146, 0x03, 0x00000000) \
downcast<gt64xxx_device *>(device)->set_cpu_tag(_cpu_tag); \
downcast<gt64xxx_device *>(device)->set_clock(_clock); \
downcast<gt64xxx_device *>(device)->set_irq_num(_irq_num);
@ -36,7 +36,7 @@
downcast<gt64xxx_device *>(device)->set_irq_info(_irq_num);
#define MCFG_GT64XXX_SET_CS(_cs_num, _map) \
downcast<gt64xxx_device *>(device)->set_cs_map(_cs_num, ADDRESS_MAP_NAME(_map), #_map, owner);
downcast<gt64xxx_device *>(device)->set_map(_cs_num, address_map_delegate(ADDRESS_MAP_NAME(_map), #_map), owner);
/*************************************
*
@ -166,36 +166,26 @@
#define GINT_TARABORT_SHIFT (19)
#define GINT_RETRYCTR_SHIFT (20)
/*************************************
* Structures
*************************************/
struct galileo_timer
{
emu_timer * timer;
uint32_t count;
uint8_t active;
};
struct galileo_addr_map
{
uint32_t low_addr;
uint32_t 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:
struct galileo_timer
{
emu_timer * timer;
uint32_t count;
uint8_t active;
};
struct galileo_addr_map
{
uint32_t low_addr;
uint32_t high_addr;
address_space* space;
galileo_addr_map() : low_addr(0xffffffff), high_addr(0x0) {}
};
gt64xxx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual void reset_all_mappings() override;
@ -243,8 +233,8 @@ public:
// 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);
void set_map(int id, const address_map_delegate &map, device_t *device);
void postload(void);
protected:
address_space *m_cpu_space;
virtual const address_space_config *memory_space_config(address_spacenum spacenum) const override;
@ -272,6 +262,7 @@ private:
optional_memory_region m_updateRegion;
DECLARE_ADDRESS_MAP(cpu_map, 32);
DECLARE_ADDRESS_MAP(empty, 32);
void map_cpu_space();
@ -290,16 +281,8 @@ private:
std::vector<uint32_t> m_ram[4];
// Chip Select
galileo_device_map m_cs_map[4];
template<int id> void map_trampoline(::address_map &map) {
m_cs_map[id].map(map);
}
template <typename T> void install_cs_map(offs_t addrstart, offs_t addrend, void (T::*map)(::address_map &map), const char *name) {
//address_map_delegate delegate(map, name, static_cast<T *>(this));
address_map_delegate delegate(map, name, static_cast<T *>(this));
m_cpu_space->install_device_delegate(addrstart, addrend, *this, delegate);
}
device_t *m_cs_devices[4];
address_map_delegate m_cs_maps[4];
void update_irqs();

View File

@ -10,7 +10,8 @@ ide_pci_device::ide_pci_device(const machine_config &mconfig, const char *tag, d
m_ide(*this, "ide"),
m_ide2(*this, "ide2"),
m_irq_num(-1),
m_irq_handler(*this)
m_irq_handler(*this),
m_legacy_top(0x000)
{
}
@ -74,13 +75,13 @@ void ide_pci_device::device_start()
pci_device::device_start();
add_map(8, M_IO, FUNC(ide_pci_device::chan1_data_command_map));
bank_infos[0].adr = 0x1f0;
bank_infos[0].adr = (m_legacy_top << 20) | 0x1f0;
add_map(4, M_IO, FUNC(ide_pci_device::chan1_control_map));
bank_infos[1].adr = 0x3f4;
bank_infos[1].adr = (m_legacy_top << 20) | 0x3f4;
add_map(8, M_IO, FUNC(ide_pci_device::chan2_data_command_map));
bank_infos[2].adr = 0x170;
bank_infos[2].adr = (m_legacy_top << 20) | 0x170;
add_map(4, M_IO, FUNC(ide_pci_device::chan2_control_map));
bank_infos[3].adr = 0x374;
bank_infos[3].adr = (m_legacy_top << 20) | 0x374;
add_map(16, M_IO, FUNC(ide_pci_device::bus_master_map));
bank_infos[4].adr = 0xf00;
@ -171,16 +172,12 @@ WRITE8_MEMBER(ide_pci_device::prog_if_w)
// Map Primary IDE Channel
if (pclass & 0x1) {
// PCI Mode
// Enabling BAR 4 in legacy mode
bank_infos[4].flags &= ~M_DISABLED;
pci_device::address_base_w(space, 0, pci_bar[0]);
pci_device::address_base_w(space, 1, pci_bar[1]);
} else {
// Legacy Mode
// Disabling BAR 4 in legacy mode
bank_infos[4].flags |= M_DISABLED;
pci_device::address_base_w(space, 0, 0x1f0);
pci_device::address_base_w(space, 1, 0x3f4);
pci_device::address_base_w(space, 0, (m_legacy_top << 20) | 0x1f0);
pci_device::address_base_w(space, 1, (m_legacy_top << 20) | 0x3f4);
}
// Map Primary IDE Channel
if (pclass & 0x4) {
@ -190,8 +187,8 @@ WRITE8_MEMBER(ide_pci_device::prog_if_w)
}
else {
// Legacy Mode
pci_device::address_base_w(space, 2, 0x170);
pci_device::address_base_w(space, 3, 0x374);
pci_device::address_base_w(space, 2, (m_legacy_top << 20) | 0x170);
pci_device::address_base_w(space, 3, (m_legacy_top << 20) | 0x374);
}
}
if (1)
@ -223,19 +220,17 @@ WRITE32_MEMBER(ide_pci_device::address_base_w)
// Bits 0 (primary) and 2 (secondary) control if the mapping is legacy or BAR
switch (offset) {
case 0: case 1:
if ((pclass & 0x1) == 1)
if (pclass & 0x1)
pci_device::address_base_w(space, offset, data);
break;
case 2: case 3:
if ((pclass & 0x4) == 1)
if (pclass & 0x4)
pci_device::address_base_w(space, offset, data);
break;
default:
// Only the first 4 bars are controlled by pif
pci_device::address_base_w(space, offset, data);
// Not sure what to do for the bus master ide BAR in legacy mode
// prog_if_w will disable register in legacy mode
if ((pclass & 0x5) == 0)
logerror("Mapping bar[%i] in legacy mode\n", offset);
}
logerror("Mapping bar[%i] = %08x\n", offset, data);
}
}

View File

@ -27,6 +27,10 @@ TODO:
#define MCFG_IDE_PCI_IRQ_HANDLER(_devcb) \
devcb = &ide_pci_device::set_irq_handler(*device, DEVCB_##_devcb);
// This will set the top 12 bits for address decoding in legacy mode. Needed for seattle driver.
#define MCFG_IDE_PCI_SET_LEGACY_TOP(_val) \
downcast<ide_pci_device *>(device)->set_legacy_top(_val);
class ide_pci_device : public pci_device {
public:
ide_pci_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
@ -40,7 +44,7 @@ public:
DECLARE_WRITE32_MEMBER(ide2_write_cs1);
void set_irq_info(const char *tag, const int irq_num);
template<class _Object> static devcb_base &set_irq_handler(device_t &device, _Object object) { return downcast<ide_pci_device &>(device).m_irq_handler.set_callback(object); }
void set_legacy_top(int val) { m_legacy_top = val & 0xfff; };
protected:
virtual void device_start() override;
virtual void device_reset() override;
@ -54,6 +58,8 @@ private:
int m_irq_num;
devcb_write_line m_irq_handler;
uint32_t pci_bar[6];
// Bits 31-20 for legacy mode hack
uint32_t m_legacy_top;
uint32_t m_config_data[0x10];
DECLARE_ADDRESS_MAP(chan1_data_command_map, 32);

View File

@ -103,6 +103,12 @@ void pci_device::device_start()
expansion_rom_size = 0;
expansion_rom_base = 0;
for (int i = 0; i < ARRAY_LENGTH(bank_infos); i++) {
save_item(NAME(bank_infos[i].adr), i);
}
save_item(NAME(command));
save_item(NAME(command_mask));
save_item(NAME(status));
save_item(NAME(intr_line));
save_item(NAME(intr_pin));
}
@ -836,6 +842,9 @@ void pci_host_device::device_start()
io_window_start = io_window_end = io_offset = 0;
reset_all_mappings();
save_item(NAME(config_address));
}
void pci_host_device::device_reset()

View File

@ -91,7 +91,6 @@ void pci9050_device::postload(void)
remap_rom();
for (int id = 0; id < 4; id++)
remap_local(id);
remap_cb();
}
void pci9050_device::device_reset()

View File

@ -62,9 +62,10 @@ void vrc4373_device::device_start()
status = 0x0280;
// Reserve 8M for ram
m_ram.reserve(0x00800000 / 4);
m_ram.resize(m_ram_size);
// Reserve 32M for simm[0]
m_simm[0].reserve(0x02000000 / 4);
m_simm[0].resize(m_simm0_size / 4);
// ROM
uint32_t romSize = m_romRegion->bytes();
m_cpu_space->install_rom(0x1fc00000, 0x1fc00000 + romSize - 1, m_romRegion->base());
@ -92,7 +93,13 @@ void vrc4373_device::device_start()
save_item(NAME(m_pci_io_laddr));
save_item(NAME(m_target1_laddr));
save_item(NAME(m_target2_laddr));
machine().save().register_postload(save_prepost_delegate(FUNC(vrc4373_device::map_cpu_space), this));
machine().save().register_postload(save_prepost_delegate(FUNC(vrc4373_device::postload), this));
}
void vrc4373_device::postload()
{
map_cpu_space();
//remap_cb();
}
void vrc4373_device::device_reset()

View File

@ -77,6 +77,7 @@ public:
virtual void reset_all_mappings() override;
virtual void map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space,
uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space) override;
void postload(void);
void set_cpu_tag(const char *tag);
void set_ram_size(const int size) { m_ram_size = size; };

View File

@ -928,7 +928,7 @@ DRIVER_INIT_MEMBER(atlantis_state,mwskins)
*
*************************************/
GAME( 2000, mwskins, 0, mwskins, mwskins, atlantis_state, mwskins, ROT0, "Midway", "Skins Game (1.06)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
GAME( 2000, mwskinsa, mwskins, mwskins, mwskins, atlantis_state, mwskins, ROT0, "Midway", "Skins Game (1.06, alt)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
GAME( 2000, mwskinso, mwskins, mwskins, mwskins, atlantis_state, mwskins, ROT0, "Midway", "Skins Game (1.04)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
GAME( 2000, mwskinst, mwskins, mwskins, mwskins, atlantis_state, mwskins, ROT0, "Midway", "Skins Game Tournament Edition", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
GAME( 2000, mwskins, 0, mwskins, mwskins, atlantis_state, mwskins, ROT0, "Midway", "Skins Game (1.06)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 2000, mwskinsa, mwskins, mwskins, mwskins, atlantis_state, mwskins, ROT0, "Midway", "Skins Game (1.06, alt)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE)
GAME( 2000, mwskinso, mwskins, mwskins, mwskins, atlantis_state, mwskins, ROT0, "Midway", "Skins Game (1.04)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE)
GAME( 2000, mwskinst, mwskins, mwskins, mwskins, atlantis_state, mwskins, ROT0, "Midway", "Skins Game Tournament Edition", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE)