From f4ec28a9a79d3c9bd4f962bb0aa712776afd54c1 Mon Sep 17 00:00:00 2001 From: "R. Belmont" Date: Mon, 20 Jan 2014 20:11:36 +0000 Subject: [PATCH] (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). --- src/mess/machine/isa.c | 207 +++++++++++++++++++++++++++++++++-------- src/mess/machine/isa.h | 39 +++++++- 2 files changed, 205 insertions(+), 41 deletions(-) diff --git a/src/mess/machine/isa.c b/src/mess/machine/isa.c index a4c843dff0a..259f3f46555 100644 --- a/src/mess/machine/isa.c +++ b/src/mess/machine/isa.c @@ -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(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(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(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) { } + + diff --git a/src/mess/machine/isa.h b/src/mess/machine/isa.h index 99898bafa1e..c8e895f0af6 100644 --- a/src/mess/machine/isa.h +++ b/src/mess/machine/isa.h @@ -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 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 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 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();