(MESS) ISA bus can now use its own address spaces instead of taking over a CPU's. [R. Belmont]

nw: touch src/mess/machine/isa*.c for best compile/link/run results.  This is completely untested for 16-bit buses, but it works well for 8-bit (stand by for demo commit).
This commit is contained in:
R. Belmont 2014-01-20 20:11:36 +00:00
parent 39ce01ce50
commit f4ec28a9a7
2 changed files with 205 additions and 41 deletions

View File

@ -105,6 +105,13 @@ void isa8_device::static_set_cputag(device_t &device, const char *tag)
isa.m_cputag = tag;
}
void isa8_device::static_set_custom_spaces(device_t &device)
{
isa8_device &isa = downcast<isa8_device &>(device);
isa.m_allocspaces = true;
}
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
@ -146,6 +153,11 @@ void isa8_device::device_config_complete()
isa8_device::isa8_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, ISA8, "ISA8", tag, owner, clock, "isa8", __FILE__),
device_memory_interface(mconfig, *this),
m_program_config("ISA 8-bit program", ENDIANNESS_LITTLE, 8, 24, 0, NULL),
m_io_config("ISA 8-bit I/O", ENDIANNESS_LITTLE, 8, 16, 0, NULL),
m_program16_config("ISA 16-bit program", ENDIANNESS_LITTLE, 16, 24, 0, NULL),
m_io16_config("ISA 16-bit I/O", ENDIANNESS_LITTLE, 16, 16, 0, NULL),
m_write_iochck(*this)
{
for(int i=0;i<8;i++)
@ -154,10 +166,17 @@ isa8_device::isa8_device(const machine_config &mconfig, const char *tag, device_
m_dma_eop[i] = false;
}
m_nmi_enabled = false;
m_iowidth = m_prgwidth = 0;
m_allocspaces = false;
}
isa8_device::isa8_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) :
device_t(mconfig, type, name, tag, owner, clock, shortname, source),
device_memory_interface(mconfig, *this),
m_program_config("ISA 8-bit program", ENDIANNESS_LITTLE, 8, 24, 0, NULL),
m_io_config("ISA 8-bit I/O", ENDIANNESS_LITTLE, 8, 16, 0, NULL),
m_program16_config("ISA 16-bit program", ENDIANNESS_LITTLE, 16, 24, 0, NULL),
m_io16_config("ISA 16-bit I/O", ENDIANNESS_LITTLE, 16, 16, 0, NULL),
m_write_iochck(*this)
{
for(int i=0;i<8;i++)
@ -166,6 +185,28 @@ isa8_device::isa8_device(const machine_config &mconfig, device_type type, const
m_dma_eop[i] = false;
}
m_nmi_enabled = false;
m_iowidth = m_prgwidth = 0;
m_allocspaces = false;
}
READ8_MEMBER(isa8_device::prog_r)
{
return m_prgspace->read_byte(offset);
}
WRITE8_MEMBER(isa8_device::prog_w)
{
m_prgspace->write_byte(offset, data);
}
READ8_MEMBER(isa8_device::io_r)
{
return m_iospace->read_byte(offset);
}
WRITE8_MEMBER(isa8_device::io_w)
{
m_iospace->write_byte(offset, data);
}
void isa8_device::set_dma_channel(UINT8 channel, device_isa8_card_interface *dev, bool do_eop)
@ -192,6 +233,23 @@ void isa8_device::device_start()
m_out_drq1_func.resolve(m_out_drq1_cb, *this);
m_out_drq2_func.resolve(m_out_drq2_cb, *this);
m_out_drq3_func.resolve(m_out_drq3_cb, *this);
m_maincpu = subdevice<cpu_device>(m_cputag);
if (m_allocspaces)
{
// use our 8-bit spaces. isa16_device::device_start will override if 16-bit.
m_iospace = &space(AS_IO);
m_prgspace = &space(AS_PROGRAM);
m_iowidth = m_prgwidth = 8;
}
else // use host CPU's program and I/O spaces directly
{
m_iospace = &m_maincpu->space(AS_IO);
m_iowidth = m_maincpu->space_config(AS_IO)->m_databus_width;
m_prgspace = &m_maincpu->space(AS_PROGRAM);
m_prgwidth = m_maincpu->space_config(AS_PROGRAM)->m_databus_width;
}
}
//-------------------------------------------------
@ -205,26 +263,42 @@ void isa8_device::device_reset()
void isa8_device::install_space(address_spacenum spacenum, offs_t start, offs_t end, offs_t mask, offs_t mirror, read8_space_func rhandler, const char* rhandler_name, write8_space_func whandler, const char *whandler_name)
{
int buswidth = m_maincpu->space_config(spacenum)->m_databus_width;
address_space &space = m_maincpu->space(spacenum);
int buswidth;
address_space *space;
if (spacenum == AS_IO)
{
space = m_iospace;
buswidth = m_iowidth;
}
else if (spacenum == AS_PROGRAM)
{
space = m_prgspace;
buswidth = m_prgwidth;
}
else
{
fatalerror("Unknown space passed to isa8_device::install_space!\n");
}
switch(buswidth)
{
case 8:
space.install_legacy_readwrite_handler(start, end, mask, mirror, rhandler, rhandler_name, whandler, whandler_name,0);
space->install_legacy_readwrite_handler(start, end, mask, mirror, rhandler, rhandler_name, whandler, whandler_name,0);
break;
case 16:
space.install_legacy_readwrite_handler(start, end, mask, mirror, rhandler, rhandler_name, whandler, whandler_name,0xffff);
space->install_legacy_readwrite_handler(start, end, mask, mirror, rhandler, rhandler_name, whandler, whandler_name,0xffff);
break;
case 32:
if ((start % 4) == 0) {
if ((end-start)==1) {
space.install_legacy_readwrite_handler(start, end+2, mask, mirror, rhandler, rhandler_name, whandler, whandler_name,0x0000ffff);
space->install_legacy_readwrite_handler(start, end+2, mask, mirror, rhandler, rhandler_name, whandler, whandler_name,0x0000ffff);
} else {
space.install_legacy_readwrite_handler(start, end, mask, mirror, rhandler, rhandler_name, whandler, whandler_name,0xffffffff);
space->install_legacy_readwrite_handler(start, end, mask, mirror, rhandler, rhandler_name, whandler, whandler_name,0xffffffff);
}
} else {
// we handle just misalligned by 2
space.install_legacy_readwrite_handler(start-2, end, mask, mirror, rhandler, rhandler_name, whandler, whandler_name,0xffff0000);
space->install_legacy_readwrite_handler(start-2, end, mask, mirror, rhandler, rhandler_name, whandler, whandler_name,0xffff0000);
}
break;
default:
@ -236,26 +310,42 @@ void isa8_device::install_space(address_spacenum spacenum, offs_t start, offs_t
void isa8_device::install_space(address_spacenum spacenum, offs_t start, offs_t end, offs_t mask, offs_t mirror, read8_delegate rhandler, write8_delegate whandler)
{
int buswidth = m_maincpu->space_config(spacenum)->m_databus_width;
address_space &space = m_maincpu->space(spacenum);
int buswidth;
address_space *space;
if (spacenum == AS_IO)
{
space = m_iospace;
buswidth = m_iowidth;
}
else if (spacenum == AS_PROGRAM)
{
space = m_prgspace;
buswidth = m_prgwidth;
}
else
{
fatalerror("Unknown space passed to isa8_device::install_space!\n");
}
switch(buswidth)
{
case 8:
space.install_readwrite_handler(start, end, mask, mirror, rhandler, whandler, 0);
space->install_readwrite_handler(start, end, mask, mirror, rhandler, whandler, 0);
break;
case 16:
space.install_readwrite_handler(start, end, mask, mirror, rhandler, whandler, 0xffff);
space->install_readwrite_handler(start, end, mask, mirror, rhandler, whandler, 0xffff);
break;
case 32:
if ((start % 4) == 0) {
if ((end-start)==1) {
space.install_readwrite_handler(start, end+2, mask, mirror, rhandler, whandler, 0x0000ffff);
space->install_readwrite_handler(start, end+2, mask, mirror, rhandler, whandler, 0x0000ffff);
} else {
space.install_readwrite_handler(start, end, mask, mirror, rhandler, whandler, 0xffffffff);
space->install_readwrite_handler(start, end, mask, mirror, rhandler, whandler, 0xffffffff);
}
} else {
// we handle just misalligned by 2
space.install_readwrite_handler(start-2, end, mask, mirror, rhandler, whandler, 0xffff0000);
space->install_readwrite_handler(start-2, end, mask, mirror, rhandler, whandler, 0xffff0000);
}
break;
default:
@ -267,26 +357,42 @@ void isa8_device::install_space(address_spacenum spacenum, offs_t start, offs_t
void isa8_device::install_space(address_spacenum spacenum, device_t *dev, offs_t start, offs_t end, offs_t mask, offs_t mirror, read8_device_func rhandler, const char* rhandler_name, write8_device_func whandler, const char *whandler_name)
{
int buswidth = m_maincpu->space_config(spacenum)->m_databus_width;
address_space &space = m_maincpu->space(spacenum);
int buswidth;
address_space *space;
if (spacenum == AS_IO)
{
space = m_iospace;
buswidth = m_iowidth;
}
else if (spacenum == AS_PROGRAM)
{
space = m_prgspace;
buswidth = m_prgwidth;
}
else
{
fatalerror("Unknown space passed to isa8_device::install_space!\n");
}
switch(buswidth)
{
case 8:
space.install_legacy_readwrite_handler(*dev, start, end, mask, mirror, rhandler, rhandler_name, whandler, whandler_name,0);
space->install_legacy_readwrite_handler(*dev, start, end, mask, mirror, rhandler, rhandler_name, whandler, whandler_name,0);
break;
case 16:
space.install_legacy_readwrite_handler(*dev, start, end, mask, mirror, rhandler, rhandler_name, whandler, whandler_name,0xffff);
space->install_legacy_readwrite_handler(*dev, start, end, mask, mirror, rhandler, rhandler_name, whandler, whandler_name,0xffff);
break;
case 32:
if ((start % 4) == 0) {
if ((end-start)==1) {
space.install_legacy_readwrite_handler(*dev, start, end+2, mask, mirror, rhandler, rhandler_name, whandler, whandler_name,0x0000ffff);
space->install_legacy_readwrite_handler(*dev, start, end+2, mask, mirror, rhandler, rhandler_name, whandler, whandler_name,0x0000ffff);
} else {
space.install_legacy_readwrite_handler(*dev, start, end, mask, mirror, rhandler, rhandler_name, whandler, whandler_name,0xffffffff);
space->install_legacy_readwrite_handler(*dev, start, end, mask, mirror, rhandler, rhandler_name, whandler, whandler_name,0xffffffff);
}
} else {
// we handle just misalligned by 2
space.install_legacy_readwrite_handler(*dev, start-2, end, mask, mirror, rhandler, rhandler_name, whandler, whandler_name,0xffff0000);
space->install_legacy_readwrite_handler(*dev, start-2, end, mask, mirror, rhandler, rhandler_name, whandler, whandler_name,0xffff0000);
}
break;
default:
@ -322,15 +428,13 @@ void isa8_device::install_device(offs_t start, offs_t end, offs_t mask, offs_t m
void isa8_device::install_bank(offs_t start, offs_t end, offs_t mask, offs_t mirror, const char *tag, UINT8 *data)
{
address_space &space = m_maincpu->space(AS_PROGRAM);
space.install_readwrite_bank(start, end, mask, mirror, tag );
m_prgspace->install_readwrite_bank(start, end, mask, mirror, tag );
machine().root_device().membank(tag)->set_base(data);
}
void isa8_device::unmap_bank(offs_t start, offs_t end, offs_t mask, offs_t mirror)
{
address_space &space = m_maincpu->space(AS_PROGRAM);
space.unmap_readwrite(start, end, mask, mirror);
m_prgspace->unmap_readwrite(start, end, mask, mirror);
}
void isa8_device::install_rom(device_t *dev, offs_t start, offs_t end, offs_t mask, offs_t mirror, const char *tag, const char *region)
@ -341,25 +445,22 @@ void isa8_device::install_rom(device_t *dev, offs_t start, offs_t end, offs_t ma
UINT8 *dest = machine().root_device().memregion("isa")->base() + start - 0xc0000;
memcpy(dest,src, end - start + 1);
} else {
address_space &space = m_maincpu->space(AS_PROGRAM);
space.install_read_bank(start, end, mask, mirror, tag);
space.unmap_write(start, end, mask, mirror);
m_prgspace->install_read_bank(start, end, mask, mirror, tag);
m_prgspace->unmap_write(start, end, mask, mirror);
machine().root_device().membank(tag)->set_base(machine().root_device().memregion(dev->subtag(tempstring, region))->base());
}
}
void isa8_device::unmap_rom(offs_t start, offs_t end, offs_t mask, offs_t mirror)
{
address_space &space = m_maincpu->space(AS_PROGRAM);
space.unmap_read(start, end, mask, mirror);
m_prgspace->unmap_read(start, end, mask, mirror);
}
bool isa8_device::is_option_rom_space_available(offs_t start, int size)
{
m_maincpu = machine().device<cpu_device>(m_cputag);
address_space &space = m_maincpu->space(AS_PROGRAM);
for(int i = 0; i < size; i += 4096) // 4KB granularity should be enough
if(space.get_read_ptr(start + i)) return false;
if(m_prgspace->get_read_ptr(start + i)) return false;
return true;
}
@ -544,27 +645,35 @@ void isa16_device::device_start()
m_out_drq5_func.resolve(m_out_drq5_cb, *this);
m_out_drq6_func.resolve(m_out_drq6_cb, *this);
m_out_drq7_func.resolve(m_out_drq7_cb, *this);
// use 16-bit spaces for ISA16
if (m_allocspaces)
{
m_iospace = &space(AS_IO);
m_prgspace = &space(AS_PROGRAM);
m_iowidth = m_prgwidth = 16;
}
}
void isa16_device::install16_device(offs_t start, offs_t end, offs_t mask, offs_t mirror, read16_delegate rhandler, write16_delegate whandler)
{
int buswidth = m_maincpu->space_config(AS_PROGRAM)->m_databus_width;
int buswidth = m_prgwidth;
switch(buswidth)
{
case 16:
m_maincpu->space(AS_IO).install_readwrite_handler(start, end, mask, mirror, rhandler, whandler, 0);
m_iospace->install_readwrite_handler(start, end, mask, mirror, rhandler, whandler, 0);
break;
case 32:
m_maincpu->space(AS_IO).install_readwrite_handler(start, end, mask, mirror, rhandler, whandler, 0xffffffff);
m_iospace->install_readwrite_handler(start, end, mask, mirror, rhandler, whandler, 0xffffffff);
if ((start % 4) == 0) {
if ((end-start)==1) {
m_maincpu->space(AS_IO).install_readwrite_handler(start, end+2, mask, mirror, rhandler, whandler, 0x0000ffff);
m_iospace->install_readwrite_handler(start, end+2, mask, mirror, rhandler, whandler, 0x0000ffff);
} else {
m_maincpu->space(AS_IO).install_readwrite_handler(start, end, mask, mirror, rhandler, whandler, 0xffffffff);
m_iospace->install_readwrite_handler(start, end, mask, mirror, rhandler, whandler, 0xffffffff);
}
} else {
// we handle just misalligned by 2
m_maincpu->space(AS_IO).install_readwrite_handler(start-2, end, mask, mirror, rhandler, whandler, 0xffff0000);
m_iospace->install_readwrite_handler(start-2, end, mask, mirror, rhandler, whandler, 0xffff0000);
}
break;
@ -574,6 +683,26 @@ void isa16_device::install16_device(offs_t start, offs_t end, offs_t mask, offs_
}
}
READ16_MEMBER(isa16_device::prog16_r)
{
return m_prgspace->read_word(offset, mem_mask);
}
WRITE16_MEMBER(isa16_device::prog16_w)
{
m_prgspace->write_word(offset, data, mem_mask);
}
READ16_MEMBER(isa16_device::io16_r)
{
return m_iospace->read_word(offset, mem_mask);
}
WRITE16_MEMBER(isa16_device::io16_w)
{
m_iospace->write_word(offset, data, mem_mask);
}
// interrupt request from isa card
WRITE_LINE_MEMBER( isa16_device::irq10_w ) { m_out_irq10_func(state); }
WRITE_LINE_MEMBER( isa16_device::irq11_w ) { m_out_irq11_func(state); }
@ -631,3 +760,5 @@ UINT16 device_isa16_card_interface::dack16_r(int line)
void device_isa16_card_interface::dack16_w(int line,UINT16 data)
{
}

View File

@ -76,6 +76,9 @@
MCFG_DEVICE_ADD(_tag, ISA8, 0) \
MCFG_DEVICE_CONFIG(_config) \
isa8_device::static_set_cputag(*device, _cputag);
// include this in a driver to have ISA allocate it's own address spaces (e.g. non-x86)
#define MCFG_ISA8_BUS_CUSTOM_SPACES() \
isa8_device::static_set_custom_spaces(*device);
#define MCFG_ISA8_SLOT_ADD(_isatag, _tag, _slot_intf, _def_slot, _fixed) \
MCFG_DEVICE_ADD(_tag, ISA8_SLOT, 0) \
MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _fixed) \
@ -84,6 +87,8 @@
MCFG_DEVICE_ADD(_tag, ISA16, 0) \
MCFG_DEVICE_CONFIG(_config) \
isa8_device::static_set_cputag(*device, _cputag);
#define MCFG_ISA16_BUS_CUSTOM_SPACES() \
isa8_device::static_set_custom_spaces(*device);
#define MCFG_ISA16_SLOT_ADD(_isatag, _tag, _slot_intf, _def_slot, _fixed) \
MCFG_DEVICE_ADD(_tag, ISA16_SLOT, 0) \
MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _fixed) \
@ -138,7 +143,8 @@ struct isa8bus_interface
class device_isa8_card_interface;
// ======================> isa8_device
class isa8_device : public device_t,
public isa8bus_interface
public isa8bus_interface,
public device_memory_interface
{
public:
// construction/destruction
@ -146,13 +152,17 @@ public:
isa8_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);
// inline configuration
static void static_set_cputag(device_t &device, const char *tag);
static void static_set_custom_spaces(device_t &device);
template<class _iochck> void set_iochck_callback(_iochck iochck) { m_write_iochck.set_callback(iochck); }
virtual const address_space_config *memory_space_config(address_spacenum spacenum) const { return (spacenum == AS_PROGRAM) ? &m_program_config : &m_io_config; }
ATTR_DEPRECATED void install_device(device_t *dev, offs_t start, offs_t end, offs_t mask, offs_t mirror, read8_device_func rhandler, const char* rhandler_name, write8_device_func whandler, const char *whandler_name);
void install_device(offs_t start, offs_t end, offs_t mask, offs_t mirror, read8_delegate rhandler, write8_delegate whandler);
ATTR_DEPRECATED void install_device(offs_t start, offs_t end, offs_t mask, offs_t mirror, read8_space_func rhandler, const char* rhandler_name, write8_space_func whandler, const char *whandler_name);
template<typename T> void install_device(offs_t addrstart, offs_t addrend, T &device, void (T::*map)(address_map &map, device_t &device), int bits = 8, UINT64 unitmask = U64(0xffffffffffffffff)) {
m_maincpu->space(AS_IO).install_device(addrstart, addrend, device, map, bits, unitmask);
template<typename T> void install_device(offs_t addrstart, offs_t addrend, T &device, void (T::*map)(class address_map &map, device_t &device), int bits = 8, UINT64 unitmask = U64(0xffffffffffffffff))
{
m_iospace->install_device(addrstart, addrend, device, map, bits, unitmask);
}
void install_bank(offs_t start, offs_t end, offs_t mask, offs_t mirror, const char *tag, UINT8 *data);
void install_rom(device_t *dev, offs_t start, offs_t end, offs_t mask, offs_t mirror, const char *tag, const char *region);
@ -173,6 +183,12 @@ public:
DECLARE_WRITE_LINE_MEMBER( drq2_w );
DECLARE_WRITE_LINE_MEMBER( drq3_w );
// 8 bit accessors for ISA-defined address spaces
DECLARE_READ8_MEMBER(prog_r);
DECLARE_WRITE8_MEMBER(prog_w);
DECLARE_READ8_MEMBER(io_r);
DECLARE_WRITE8_MEMBER(io_w);
UINT8 dack_r(int line);
void dack_w(int line,UINT8 data);
void eop_w(int channels, int state);
@ -181,6 +197,9 @@ public:
void set_nmi_state(bool enabled) { m_nmi_enabled = enabled; }
virtual void set_dma_channel(UINT8 channel, device_isa8_card_interface *dev, bool do_eop);
const address_space_config m_program_config, m_io_config, m_program16_config, m_io16_config;
protected:
ATTR_DEPRECATED void install_space(address_spacenum spacenum, device_t *dev, offs_t start, offs_t end, offs_t mask, offs_t mirror, read8_device_func rhandler, const char* rhandler_name, write8_device_func whandler, const char *whandler_name);
ATTR_DEPRECATED void install_space(address_spacenum spacenum, offs_t start, offs_t end, offs_t mask, offs_t mirror, read8_space_func rhandler, const char* rhandler_name, write8_space_func whandler, const char *whandler_name);
@ -194,6 +213,11 @@ protected:
// internal state
cpu_device *m_maincpu;
// address spaces
address_space *m_iospace, *m_prgspace;
int m_iowidth, m_prgwidth;
bool m_allocspaces;
devcb_resolved_write_line m_out_irq2_func;
devcb_resolved_write_line m_out_irq3_func;
devcb_resolved_write_line m_out_irq4_func;
@ -299,6 +323,9 @@ public:
void install16_device(offs_t start, offs_t end, offs_t mask, offs_t mirror, read16_delegate rhandler, write16_delegate whandler);
// for ISA16, return the 16-bit configs instead
virtual const address_space_config *memory_space_config(address_spacenum spacenum) const { return (spacenum == AS_PROGRAM) ? &m_program16_config : &m_io16_config; }
DECLARE_WRITE_LINE_MEMBER( irq10_w );
DECLARE_WRITE_LINE_MEMBER( irq11_w );
DECLARE_WRITE_LINE_MEMBER( irq12_w );
@ -313,6 +340,12 @@ public:
UINT16 dack16_r(int line);
void dack16_w(int line,UINT16 data);
// 16 bit accessors for ISA-defined address spaces
DECLARE_READ16_MEMBER(prog16_r);
DECLARE_WRITE16_MEMBER(prog16_w);
DECLARE_READ16_MEMBER(io16_r);
DECLARE_WRITE16_MEMBER(io16_w);
protected:
// device-level overrides
virtual void device_start();