Fixed clipping of device address maps if the size of the map caused the end address to wrap. Added a proof of concept implementation of a address map bank device, which allows you to bank memory maps. Hooked it up to Taito GNET as an example [smf]

This commit is contained in:
smf- 2013-05-31 17:56:43 +00:00
parent 84ffcf912b
commit 449f957700
6 changed files with 194 additions and 41 deletions

2
.gitattributes vendored
View File

@ -1191,6 +1191,8 @@ src/emu/machine/at45dbxx.c svneol=native#text/plain
src/emu/machine/at45dbxx.h svneol=native#text/plain
src/emu/machine/ay31015.c svneol=native#text/plain
src/emu/machine/ay31015.h svneol=native#text/plain
src/emu/machine/bankdev.c svneol=native#text/plain
src/emu/machine/bankdev.h svneol=native#text/plain
src/emu/machine/cdp1852.c svneol=native#text/plain
src/emu/machine/cdp1852.h svneol=native#text/plain
src/emu/machine/cdp1871.c svneol=native#text/plain

View File

@ -790,7 +790,7 @@ void address_map::uplift_submaps(running_machine &machine, device_t &device, dev
subentry->m_addrend = entry->m_addrstart + (end_offset / slot_count) * databytes + databytes - 1;
// Clip the entry to the end of the range
if (subentry->m_addrend > entry->m_addrend)
if (subentry->m_addrend > entry->m_addrend || subentry->m_addrend < entry->m_addrstart)
subentry->m_addrend = entry->m_addrend;
// Detect special unhandled case (range straddling

View File

@ -173,6 +173,7 @@ EMUMACHINEOBJS = \
$(EMUMACHINE)/at29040a.o \
$(EMUMACHINE)/at45dbxx.o \
$(EMUMACHINE)/ay31015.o \
$(EMUMACHINE)/bankdev.o \
$(EMUMACHINE)/cdp1852.o \
$(EMUMACHINE)/cdp1871.o \
$(EMUMACHINE)/com8116.o \

93
src/emu/machine/bankdev.c Normal file
View File

@ -0,0 +1,93 @@
#include "bankdev.h"
// device type definition
const device_type ADDRESS_MAP_BANK = &device_creator<address_map_bank_device>;
address_map_bank_device::address_map_bank_device( const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock )
: device_t(mconfig, ADDRESS_MAP_BANK, "Address Map Bank", tag, owner, clock),
device_memory_interface(mconfig, *this),
m_endianness(ENDIANNESS_NATIVE),
m_databus_width(0),
m_addrbus_width(32),
m_stride(1),
m_offset(0)
{
}
DEVICE_ADDRESS_MAP_START(amap8, 8, address_map_bank_device)
AM_RANGE(0x00000000, 0xffffffff) AM_READWRITE(read8, write8)
ADDRESS_MAP_END
DEVICE_ADDRESS_MAP_START(amap16, 16, address_map_bank_device)
AM_RANGE(0x00000000, 0xffffffff) AM_READWRITE(read16, write16) /// TODO: fix memory.c bug that ignores the upper limit on the AM_DEVICE
ADDRESS_MAP_END
DEVICE_ADDRESS_MAP_START(amap32, 32, address_map_bank_device)
AM_RANGE(0x00000000, 0xffffffff) AM_READWRITE(read32, write32)
ADDRESS_MAP_END
DEVICE_ADDRESS_MAP_START(amap64, 64, address_map_bank_device)
AM_RANGE(0x00000000, 0xffffffff) AM_READWRITE(read64, write64)
ADDRESS_MAP_END
WRITE8_MEMBER(address_map_bank_device::write8)
{
m_program->write_byte(m_offset + offset, data);
}
WRITE16_MEMBER(address_map_bank_device::write16)
{
m_program->write_word(m_offset + (offset * 2), data, mem_mask);
}
WRITE32_MEMBER(address_map_bank_device::write32)
{
m_program->write_dword(m_offset + (offset * 4), data, mem_mask);
}
WRITE64_MEMBER(address_map_bank_device::write64)
{
m_program->write_qword(m_offset + (offset * 8), data, mem_mask);
}
READ8_MEMBER(address_map_bank_device::read8)
{
return m_program->read_byte(m_offset + offset);
}
READ16_MEMBER(address_map_bank_device::read16)
{
return m_program->read_word(m_offset + (offset * 2), mem_mask);
}
READ32_MEMBER(address_map_bank_device::read32)
{
return m_program->read_dword(m_offset + (offset * 4), mem_mask);
}
READ64_MEMBER(address_map_bank_device::read64)
{
return m_program->read_qword(m_offset + (offset * 8), mem_mask);
}
void address_map_bank_device::device_config_complete()
{
m_program_config = address_space_config( "program", m_endianness, m_databus_width, m_addrbus_width );
}
void address_map_bank_device::device_start()
{
m_program = &space(AS_PROGRAM);
save_item(NAME(m_offset));
}
void address_map_bank_device::device_reset()
{
m_offset = 0;
}
void address_map_bank_device::set_bank(offs_t bank)
{
m_offset = bank * m_stride;
}

67
src/emu/machine/bankdev.h Normal file
View File

@ -0,0 +1,67 @@
#include "emu.h"
#define MCFG_ADDRESS_MAP_BANK_ENDIANNESS(_endianness) \
address_map_bank_device::set_endianness(*device, _endianness);
#define MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(_databus_width) \
address_map_bank_device::set_databus_width(*device, _databus_width);
#define MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(_addrbus_width) \
address_map_bank_device::set_addrbus_width(*device, _addrbus_width);
#define MCFG_ADDRESS_MAP_BANK_STRIDE(_stride) \
address_map_bank_device::set_stride(*device, _stride);
class address_map_bank_device :
public device_t,
public device_memory_interface
{
public:
// construction/destruction
address_map_bank_device( const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock );
// static configuration helpers
static void set_endianness(device_t &device, endianness_t endianness) { downcast<address_map_bank_device &>(device).m_endianness = endianness; }
static void set_databus_width(device_t &device, UINT8 databus_width) { downcast<address_map_bank_device &>(device).m_databus_width = databus_width; }
static void set_addrbus_width(device_t &device, UINT8 addrbus_width) { downcast<address_map_bank_device &>(device).m_addrbus_width = addrbus_width; }
static void set_stride(device_t &device, UINT32 stride) { downcast<address_map_bank_device &>(device).m_stride = stride; }
DECLARE_ADDRESS_MAP(amap8, 8);
DECLARE_ADDRESS_MAP(amap16, 16);
DECLARE_ADDRESS_MAP(amap32, 32);
DECLARE_ADDRESS_MAP(amap64, 64);
DECLARE_WRITE8_MEMBER(write8);
DECLARE_WRITE16_MEMBER(write16);
DECLARE_WRITE32_MEMBER(write32);
DECLARE_WRITE64_MEMBER(write64);
DECLARE_READ8_MEMBER(read8);
DECLARE_READ16_MEMBER(read16);
DECLARE_READ32_MEMBER(read32);
DECLARE_READ64_MEMBER(read64);
void set_bank(offs_t offset);
protected:
virtual void device_start();
virtual void device_config_complete();
virtual void device_reset();
// device_memory_interface overrides
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return (spacenum == AS_PROGRAM) ? &m_program_config : NULL; }
private:
// internal state
endianness_t m_endianness;
UINT8 m_databus_width;
UINT8 m_addrbus_width;
UINT32 m_stride;
address_space_config m_program_config;
address_space *m_program;
offs_t m_offset;
};
// device type definition
extern const device_type ADDRESS_MAP_BANK;

View File

@ -325,6 +325,7 @@ Type 3 (PCMCIA Compact Flash Adaptor + Compact Flash card, sealed together with
#include "machine/znsec.h"
#include "machine/zndip.h"
#include "machine/idectrl.h"
#include "machine/bankdev.h"
#include "machine/mb3773.h"
#include "sound/spu.h"
#include "audio/taito_zm.h"
@ -339,18 +340,11 @@ public:
m_zndip(*this,"maincpu:sio0:zndip"),
m_card(*this,"card"),
m_maincpu(*this, "maincpu"),
m_mn10200(*this, "mn10200") {
m_mn10200(*this, "mn10200"),
m_flashbank(*this, "flashbank")
{
}
required_device<znsec_device> m_znsec0;
required_device<znsec_device> m_znsec1;
required_device<zndip_device> m_zndip;
required_device<ide_controller_device> m_card;
intel_te28f160_device *m_biosflash;
intel_e28f400_device *m_pgmflash;
intel_te28f160_device *m_sndflash[3];
unsigned char m_cis[512];
int m_locked;
@ -388,9 +382,14 @@ public:
DECLARE_MACHINE_RESET(coh3002t);
void rf5c296_reg_w(ATTR_UNUSED UINT8 reg, UINT8 data);
UINT8 rf5c296_reg_r(ATTR_UNUSED UINT8 reg);
void install_handlers(int mode);
required_device<znsec_device> m_znsec0;
required_device<znsec_device> m_znsec1;
required_device<zndip_device> m_zndip;
required_device<ide_controller_device> m_card;
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_mn10200;
required_device<address_map_bank_device> m_flashbank;
};
@ -496,24 +495,6 @@ WRITE16_MEMBER(taitogn_state::rf5c296_mem_w)
}
}
void taitogn_state::install_handlers(int mode)
{
address_space &a = m_maincpu->space(AS_PROGRAM);
if(mode == 0) {
// Mode 0 has access to the subbios, the mn102 flash and the rf5c296 mem zone
a.install_readwrite_handler(0x1f000000, 0x1f1fffff, read16_delegate(FUNC(intelfsh16_device::read),m_biosflash), write16_delegate(FUNC(intel_te28f160_device::write),m_biosflash), 0xffffffff);
a.install_readwrite_handler(0x1f200000, 0x1f2fffff, read16_delegate(FUNC(taitogn_state::rf5c296_mem_r),this), write16_delegate(FUNC(taitogn_state::rf5c296_mem_w),this), 0xffffffff);
a.install_readwrite_handler(0x1f300000, 0x1f37ffff, read16_delegate(FUNC(intelfsh16_device::read),m_pgmflash), write16_delegate(FUNC(intelfsh16_device::write),m_pgmflash), 0xffffffff);
a.nop_readwrite(0x1f380000, 0x1f5fffff);
} else {
// Mode 1 has access to the 3 samples flashes
a.install_readwrite_handler(0x1f000000, 0x1f1fffff, read16_delegate(FUNC(intelfsh16_device::read),m_sndflash[0]), write16_delegate(FUNC(intelfsh16_device::write),m_sndflash[0]), 0xffffffff);
a.install_readwrite_handler(0x1f200000, 0x1f3fffff, read16_delegate(FUNC(intelfsh16_device::read),m_sndflash[1]), write16_delegate(FUNC(intelfsh16_device::write),m_sndflash[1]), 0xffffffff);
a.install_readwrite_handler(0x1f400000, 0x1f5fffff, read16_delegate(FUNC(intelfsh16_device::read),m_sndflash[2]), write16_delegate(FUNC(intelfsh16_device::write),m_sndflash[2]), 0xffffffff);
}
}
// Misc. controls
READ8_MEMBER(taitogn_state::control_r)
@ -551,7 +532,7 @@ WRITE8_MEMBER(taitogn_state::control_w)
#endif
if((p ^ m_control) & 0x04)
install_handlers(m_control & 4 ? 1 : 0);
m_flashbank->set_bank(m_control & 4 ? 1 : 0);
}
WRITE16_MEMBER(taitogn_state::control2_w)
@ -684,12 +665,6 @@ READ8_MEMBER(taitogn_state::gnet_mahjong_panel_r)
DRIVER_INIT_MEMBER(taitogn_state,coh3002t)
{
m_biosflash = machine().device<intel_te28f160_device>("biosflash");
m_pgmflash = machine().device<intel_e28f400_device>("pgmflash");
m_sndflash[0] = machine().device<intel_te28f160_device>("sndflash0");
m_sndflash[1] = machine().device<intel_te28f160_device>("sndflash1");
m_sndflash[2] = machine().device<intel_te28f160_device>("sndflash2");
m_znsec0->init(tt10);
m_znsec1->init(tt16);
@ -708,7 +683,6 @@ DRIVER_INIT_MEMBER(taitogn_state,coh3002t_mp)
MACHINE_RESET_MEMBER(taitogn_state,coh3002t)
{
m_locked = 0x1ff;
install_handlers(0);
m_control = 0;
m_card->reset();
@ -719,9 +693,7 @@ MACHINE_RESET_MEMBER(taitogn_state,coh3002t)
}
static ADDRESS_MAP_START( taitogn_map, AS_PROGRAM, 32, taitogn_state )
// AM_RANGE(0x1f000000, 0x1f1fffff) AM_DEVREADWRITE16("sndflash0", intelfsh16_device, read, write, 0xffffffff)
// AM_RANGE(0x1f200000, 0x1f3fffff) AM_DEVREADWRITE16("sndflash1", intelfsh16_device, read, write, 0xffffffff)
// AM_RANGE(0x1f400000, 0x1f5fffff) AM_DEVREADWRITE16("sndflash2", intelfsh16_device, read, write, 0xffffffff)
AM_RANGE(0x1f000000, 0x1f7fffff) AM_DEVICE16("flashbank", address_map_bank_device, amap16, 0xffffffff)
AM_RANGE(0x1fa00000, 0x1fa00003) AM_READ_PORT("P1")
AM_RANGE(0x1fa00100, 0x1fa00103) AM_READ_PORT("P2")
AM_RANGE(0x1fa00200, 0x1fa00203) AM_READ_PORT("SERVICE")
@ -742,6 +714,18 @@ static ADDRESS_MAP_START( taitogn_map, AS_PROGRAM, 32, taitogn_state )
AM_RANGE(0x1fbe0000, 0x1fbe01ff) AM_RAM // 256 bytes com zone with the mn102, low bytes of words only, with additional comm at 1fb80000
ADDRESS_MAP_END
static ADDRESS_MAP_START( flashbank_map, AS_PROGRAM, 16, taitogn_state )
// Bank 0 has access to the subbios, the mn102 flash and the rf5c296 mem zone
AM_RANGE(0x00000000, 0x001fffff) AM_DEVREADWRITE("biosflash", intelfsh16_device, read, write)
AM_RANGE(0x00200000, 0x002fffff) AM_READWRITE( rf5c296_mem_r, rf5c296_mem_w )
AM_RANGE(0x00300000, 0x0037ffff) AM_DEVREADWRITE("pgmflash", intelfsh16_device, read, write)
// Bank 1 has access to the 3 samples flashes
AM_RANGE(0x08000000, 0x081fffff) AM_DEVREADWRITE("sndflash0", intelfsh16_device, read, write)
AM_RANGE(0x08200000, 0x083fffff) AM_DEVREADWRITE("sndflash1", intelfsh16_device, read, write)
AM_RANGE(0x08400000, 0x085fffff) AM_DEVREADWRITE("sndflash2", intelfsh16_device, read, write)
ADDRESS_MAP_END
static MACHINE_CONFIG_START( coh3002t, taitogn_state )
/* basic machine hardware */
@ -773,6 +757,12 @@ static MACHINE_CONFIG_START( coh3002t, taitogn_state )
MCFG_MB3773_ADD("mb3773")
MCFG_DEVICE_ADD("flashbank", ADDRESS_MAP_BANK, 0)
MCFG_DEVICE_PROGRAM_MAP(flashbank_map)
MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE)
MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16)
MCFG_ADDRESS_MAP_BANK_STRIDE(0x8000000)
MCFG_INTEL_TE28F160_ADD("biosflash")
MCFG_INTEL_E28F400_ADD("pgmflash")
MCFG_INTEL_TE28F160_ADD("sndflash0")