bml3: Overhaul memory management and expansion interface, using views to avoid having expansion cards overwrite the main ROM region

This commit is contained in:
AJR 2023-04-08 10:48:39 -04:00
parent 9dc9d774c0
commit ddfca0cb2c
11 changed files with 157 additions and 101 deletions

View File

@ -104,11 +104,15 @@ bml3bus_device::bml3bus_device(const machine_config &mconfig, const char *tag, d
bml3bus_device::bml3bus_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, type, tag, owner, clock),
m_space(*this, finder_base::DUMMY_TAG, -1, 8),
m_out_nmi_cb(*this),
m_out_irq_cb(*this),
m_out_firq_cb(*this)
{
// clear slots
for (auto & elem : m_device_list)
{
elem = nullptr;
}
}
//-------------------------------------------------
@ -121,12 +125,6 @@ void bml3bus_device::device_start()
m_out_nmi_cb.resolve_safe();
m_out_irq_cb.resolve_safe();
m_out_firq_cb.resolve_safe();
// clear slots
for (auto & elem : m_device_list)
{
elem = nullptr;
}
}
//-------------------------------------------------
@ -152,6 +150,24 @@ void bml3bus_device::add_bml3bus_card(int slot, device_bml3bus_card_interface &c
m_device_list[slot] = &card;
}
void bml3bus_device::map_exrom(address_space_installer &space)
{
for (auto & elem : m_device_list)
{
if (elem != nullptr)
elem->map_exrom(space);
}
}
void bml3bus_device::map_io(address_space_installer &space)
{
for (auto & elem : m_device_list)
{
if (elem != nullptr)
elem->map_io(space);
}
}
void bml3bus_device::set_nmi_line(int state)
{
m_out_nmi_cb(state);

View File

@ -75,13 +75,15 @@ public:
bml3bus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// inline configuration
template <class Object> void set_space(Object &&tag, int spacenum) { m_space.set_tag(std::forward<Object>(tag), spacenum); }
auto nmi_callback() { return m_out_nmi_cb.bind(); }
auto irq_callback() { return m_out_irq_cb.bind(); }
auto firq_callback() { return m_out_firq_cb.bind(); }
device_bml3bus_card_interface *get_bml3bus_card(int slot);
void map_exrom(address_space_installer &space);
void map_io(address_space_installer &space);
DECLARE_WRITE_LINE_MEMBER( nmi_w );
DECLARE_WRITE_LINE_MEMBER( irq_w );
DECLARE_WRITE_LINE_MEMBER( firq_w );
@ -95,15 +97,11 @@ protected:
void add_bml3bus_card(int slot, device_bml3bus_card_interface &card);
address_space &space() const { return *m_space; }
void set_nmi_line(int state);
void set_irq_line(int state);
void set_firq_line(int state);
// internal state
required_address_space m_space;
// line callbacks
devcb_write_line m_out_nmi_cb;
devcb_write_line m_out_irq_cb;
devcb_write_line m_out_firq_cb;
@ -131,7 +129,8 @@ public:
protected:
virtual void interface_pre_start() override;
address_space &space() { return m_bml3bus->space(); }
virtual void map_exrom(address_space_installer &space) { }
virtual void map_io(address_space_installer &space) { }
void raise_slot_nmi() { m_bml3bus->set_nmi_line(ASSERT_LINE); }
void lower_slot_nmi() { m_bml3bus->set_nmi_line(CLEAR_LINE); }

View File

@ -22,10 +22,8 @@
DEFINE_DEVICE_TYPE(BML3BUS_KANJI, bml3bus_kanji_device, "bml3kanji", "Hitachi MP-9740 Kanji Character ROM Card")
#define KANJI_ROM_REGION "kanji_rom"
ROM_START( kanji )
ROM_REGION( 0x20000, KANJI_ROM_REGION, ROMREGION_ERASEFF )
ROM_REGION( 0x20000, "kanji_rom", ROMREGION_ERASEFF )
ROM_LOAD("kanji.rom", 0x00000, 0x20000, BAD_DUMP CRC(de99a726) SHA1(65fead5d0d779b242f6e0ac25fcc9899dc343101))
ROM_END
@ -61,7 +59,8 @@ void bml3bus_kanji_device::bml3_kanji_w(offs_t offset, uint8_t data)
bml3bus_kanji_device::bml3bus_kanji_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, BML3BUS_KANJI, tag, owner, clock),
device_bml3bus_card_interface(mconfig, *this), m_kanji_addr(0), m_rom(nullptr)
device_bml3bus_card_interface(mconfig, *this), m_kanji_addr(0),
m_rom(*this, "kanji_rom")
{
}
@ -72,11 +71,13 @@ bml3bus_kanji_device::bml3bus_kanji_device(const machine_config &mconfig, const
void bml3bus_kanji_device::device_start()
{
m_rom = memregion(KANJI_ROM_REGION)->base();
save_item(NAME(m_kanji_addr));
}
void bml3bus_kanji_device::map_io(address_space_installer &space)
{
// install into memory
address_space &space_prg = space();
space_prg.install_readwrite_handler(0xff75, 0xff76, read8sm_delegate(*this, FUNC(bml3bus_kanji_device::bml3_kanji_r)), write8sm_delegate(*this, FUNC(bml3bus_kanji_device::bml3_kanji_w)));
space.install_readwrite_handler(0xff75, 0xff76, read8sm_delegate(*this, FUNC(bml3bus_kanji_device::bml3_kanji_r)), write8sm_delegate(*this, FUNC(bml3bus_kanji_device::bml3_kanji_w)));
}
void bml3bus_kanji_device::device_reset()

View File

@ -37,10 +37,12 @@ protected:
// optional information overrides
virtual const tiny_rom_entry *device_rom_region() const override;
virtual void map_io(address_space_installer &space) override;
uint16_t m_kanji_addr;
private:
uint8_t *m_rom;
required_region_ptr<uint8_t> m_rom;
};
// device type definition

View File

@ -38,12 +38,10 @@ WRITE_LINE_MEMBER( bml3bus_mp1802_device::nmi_w )
lower_slot_nmi();
}
#define MP1802_ROM_REGION "mp1802_rom"
ROM_START( mp1802 )
ROM_REGION(0x10000, MP1802_ROM_REGION, 0)
ROM_REGION(0x800, "mp1802_rom", 0)
// MP-1802 disk controller ROM, which replaces part of the system ROM
ROM_LOAD( "mp1802.rom", 0xf800, 0x800, BAD_DUMP CRC(8d0dc101) SHA1(92f7d1cebecafa7472e45c4999520de5c01c6dbc))
ROM_LOAD( "mp1802.rom", 0x000, 0x800, BAD_DUMP CRC(8d0dc101) SHA1(92f7d1cebecafa7472e45c4999520de5c01c6dbc))
ROM_END
@ -113,7 +111,7 @@ bml3bus_mp1802_device::bml3bus_mp1802_device(const machine_config &mconfig, cons
m_fdc(*this, "fdc"),
m_floppy(*this, "fdc:%u", 0U),
m_nmigate(*this, "nmigate"),
m_rom(nullptr)
m_rom(*this, "mp1802_rom")
{
}
@ -124,18 +122,22 @@ bml3bus_mp1802_device::bml3bus_mp1802_device(const machine_config &mconfig, cons
void bml3bus_mp1802_device::device_start()
{
m_rom = memregion(MP1802_ROM_REGION)->base();
// install into memory
address_space &space_prg = space();
space_prg.install_readwrite_handler(0xff00, 0xff03, read8sm_delegate(*m_fdc, FUNC(mb8866_device::read)), write8sm_delegate(*m_fdc, FUNC(mb8866_device::write)));
space_prg.install_readwrite_handler(0xff04, 0xff04, read8smo_delegate(*this, FUNC(bml3bus_mp1802_device::bml3_mp1802_r)), write8smo_delegate(*this, FUNC(bml3bus_mp1802_device::bml3_mp1802_w)));
// overwriting the main ROM (rather than using e.g. install_rom) should mean that bank switches for RAM expansion still work...
uint8_t *mainrom = device().machine().root_device().memregion("maincpu")->base();
memcpy(mainrom + 0xf800, m_rom + 0xf800, 0x800);
}
void bml3bus_mp1802_device::device_reset()
{
bml3_mp1802_w(0);
}
void bml3bus_mp1802_device::map_exrom(address_space_installer &space)
{
space.install_rom(0xf800, 0xfeff, &m_rom[0]);
space.install_rom(0xfff0, 0xffff, &m_rom[0x7f0]);
}
void bml3bus_mp1802_device::map_io(address_space_installer &space)
{
// install into memory
space.install_readwrite_handler(0xff00, 0xff03, read8sm_delegate(*m_fdc, FUNC(mb8866_device::read)), write8sm_delegate(*m_fdc, FUNC(mb8866_device::write)));
space.install_readwrite_handler(0xff04, 0xff04, read8smo_delegate(*this, FUNC(bml3bus_mp1802_device::bml3_mp1802_r)), write8smo_delegate(*this, FUNC(bml3bus_mp1802_device::bml3_mp1802_w)));
}

View File

@ -43,6 +43,9 @@ protected:
virtual void device_add_mconfig(machine_config &config) override;
virtual const tiny_rom_entry *device_rom_region() const override;
virtual void map_exrom(address_space_installer &space) override;
virtual void map_io(address_space_installer &space) override;
private:
DECLARE_WRITE_LINE_MEMBER(nmi_w);
@ -50,7 +53,7 @@ private:
required_device_array<floppy_connector, 4> m_floppy;
required_device<input_merger_device> m_nmigate;
uint8_t *m_rom;
required_region_ptr<uint8_t> m_rom;
};
// device type definition

View File

@ -26,12 +26,10 @@
DEFINE_DEVICE_TYPE(BML3BUS_MP1805, bml3bus_mp1805_device, "bml3mp1805", "Hitachi MP-1805 Floppy Controller Card")
#define MP1805_ROM_REGION "mp1805_rom"
ROM_START( mp1805 )
ROM_REGION(0x10000, MP1805_ROM_REGION, 0)
ROM_REGION(0x800, "mp1805_rom", 0)
// MP-1805 disk controller ROM, which replaces part of the system ROM
ROM_LOAD( "mp1805.rom", 0xf800, 0x0800, BAD_DUMP CRC(b532d8d9) SHA1(6f1160356d5bf64b5926b1fdb60db414edf65f22))
ROM_LOAD( "mp1805.rom", 0x000, 0x800, BAD_DUMP CRC(b532d8d9) SHA1(6f1160356d5bf64b5926b1fdb60db414edf65f22))
ROM_END
// Although the drive is single-sided, D88 images are double-sided,
@ -134,7 +132,8 @@ bml3bus_mp1805_device::bml3bus_mp1805_device(const machine_config &mconfig, cons
device_t(mconfig, BML3BUS_MP1805, tag, owner, clock),
device_bml3bus_card_interface(mconfig, *this),
m_floppy(*this, "%u", 0U),
m_mc6843(*this, "mc6843"), m_rom(nullptr)
m_mc6843(*this, "mc6843"),
m_rom(*this, "mp1805_rom")
{
}
@ -145,16 +144,6 @@ bml3bus_mp1805_device::bml3bus_mp1805_device(const machine_config &mconfig, cons
void bml3bus_mp1805_device::device_start()
{
m_rom = memregion(MP1805_ROM_REGION)->base();
// install into memory
address_space &space_prg = space();
space_prg.install_device(0xff18, 0xff1f, *m_mc6843, &mc6843_device::map);
space_prg.install_readwrite_handler(0xff20, 0xff20, read8smo_delegate(*this, FUNC(bml3bus_mp1805_device::bml3_mp1805_r)), write8smo_delegate(*this, FUNC(bml3bus_mp1805_device::bml3_mp1805_w)));
// overwriting the main ROM (rather than using e.g. install_rom) should mean that bank switches for RAM expansion still work...
uint8_t *mainrom = device().machine().root_device().memregion("maincpu")->base();
memcpy(mainrom + 0xf800, m_rom + 0xf800, 0x800);
save_item(NAME(m_control));
}
@ -162,3 +151,16 @@ void bml3bus_mp1805_device::device_reset()
{
m_control = 0;
}
void bml3bus_mp1805_device::map_exrom(address_space_installer &space)
{
space.install_rom(0xf800, 0xfeff, &m_rom[0]);
space.install_rom(0xfff0, 0xffff, &m_rom[0x7f0]);
}
void bml3bus_mp1805_device::map_io(address_space_installer &space)
{
// install into memory
space.install_device(0xff18, 0xff1f, *m_mc6843, &mc6843_device::map);
space.install_readwrite_handler(0xff20, 0xff20, read8smo_delegate(*this, FUNC(bml3bus_mp1805_device::bml3_mp1805_r)), write8smo_delegate(*this, FUNC(bml3bus_mp1805_device::bml3_mp1805_w)));
}

View File

@ -41,11 +41,14 @@ protected:
virtual void device_add_mconfig(machine_config &config) override;
virtual const tiny_rom_entry *device_rom_region() const override;
virtual void map_exrom(address_space_installer &space) override;
virtual void map_io(address_space_installer &space) override;
private:
required_device_array<floppy_connector, 4> m_floppy;
required_device<mc6843_device> m_mc6843;
private:
uint8_t *m_rom;
required_region_ptr<uint8_t> m_rom;
uint8_t m_control;

View File

@ -95,13 +95,15 @@ bml3bus_rtc_device::bml3bus_rtc_device(const machine_config &mconfig, const char
void bml3bus_rtc_device::device_start()
{
// install into memory
address_space &space_prg = space();
space_prg.install_readwrite_handler(0xff38, 0xff3a, read8sm_delegate(*this, FUNC(bml3bus_rtc_device::bml3_rtc_r)), write8sm_delegate(*this, FUNC(bml3bus_rtc_device::bml3_rtc_w)));
m_addr_latch = 0;
m_data_latch = 0;
save_item(NAME(m_addr_latch));
save_item(NAME(m_data_latch));
}
void bml3bus_rtc_device::map_io(address_space_installer &space)
{
// install into memory
space.install_readwrite_handler(0xff38, 0xff3a, read8sm_delegate(*this, FUNC(bml3bus_rtc_device::bml3_rtc_r)), write8sm_delegate(*this, FUNC(bml3bus_rtc_device::bml3_rtc_w)));
}

View File

@ -39,6 +39,8 @@ protected:
// optional information overrides
virtual void device_add_mconfig(machine_config &config) override;
virtual void map_io(address_space_installer &space) override;
private:
required_device<msm5832_device> m_rtc;

View File

@ -87,6 +87,7 @@ public:
, m_ym2203(*this, "ym2203")
, m_acia(*this, "acia")
, m_palette(*this, "palette")
, m_rom_view(*this, "rom")
, m_banka(*this, "banka")
, m_bankc(*this, "bankc")
, m_banke(*this, "banke")
@ -157,7 +158,6 @@ private:
virtual void machine_start() override;
void m6845_change_clock(u8 setting);
u8 m_crtc_index = 0U;
std::unique_ptr<u8[]> m_extram;
std::unique_ptr<u8[]> m_vram;
std::unique_ptr<u8[]> m_aram;
u8 m_firq_mask = 0U;
@ -172,11 +172,13 @@ private:
optional_device<ym2203_device> m_ym2203;
required_device<acia6850_device> m_acia;
required_device<palette_device> m_palette;
required_memory_bank m_banka;
required_memory_bank m_bankc;
required_memory_bank m_banke;
required_memory_bank m_bankf;
required_memory_bank m_bankg;
memory_view m_rom_view;
//memory_view m_bank4;
memory_view m_banka;
memory_view m_bankc;
memory_view m_banke;
memory_view m_bankf;
memory_view m_bankg;
required_ioport_array<4> m_io_keyboard;
};
@ -369,7 +371,7 @@ void bml3_state::bml3_mem(address_map &map)
map.unmap_value_high();
map(0x0000, 0x03ff).ram();
map(0x0400, 0x43ff).rw(FUNC(bml3_state::vram_r), FUNC(bml3_state::vram_w));
map(0x4400, 0x9fff).ram();
map(0x4400, 0x7fff).ram();
map(0xff40, 0xff46).noprw(); // lots of unknown reads and writes
map(0xffc0, 0xffc3).rw("pia", FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0xffc4, 0xffc5).rw(m_acia, FUNC(acia6850_device::read), FUNC(acia6850_device::write));
@ -404,13 +406,25 @@ void bml3_state::bml3_mem(address_map &map)
// map(0xffe8, 0xffe8) bank register
// map(0xffe9, 0xffe9) IG mode register
// map(0xffea, 0xffea) IG enable register
map(0xa000, 0xfeff).lw8(NAME([this] (offs_t offset, u8 data) { m_extram[offset] = data; }));
map(0xfff0, 0xffff).lw8(NAME([this] (offs_t offset, u8 data) { m_extram[offset+0x5ff0] = data; }));
map(0xa000, 0xbfff).bankr("banka");
map(0xc000, 0xdfff).bankr("bankc");
map(0xe000, 0xefff).bankr("banke");
map(0xf000, 0xfeff).bankr("bankf");
map(0xfff0, 0xffff).bankr("bankg");
map(0x8000, 0xffff).view(m_rom_view);
m_rom_view[0](0xa000, 0xfeff).rom().region("maincpu", 0xa000);
m_rom_view[0](0xfff0, 0xffff).rom().region("maincpu", 0xfff0);
map(0x8000, 0x9fff).ram();
map(0xa000, 0xbfff).view(m_banka);
m_banka[0](0xa000, 0xbfff).readonly().share("rama");
map(0xa000, 0xbfff).writeonly().share("rama");
map(0xc000, 0xdfff).view(m_bankc);
m_bankc[0](0xc000, 0xdfff).readonly().share("ramc");
map(0xc000, 0xdfff).writeonly().share("ramc");
map(0xe000, 0xefff).view(m_banke);
m_banke[0](0xe000, 0xefff).readonly().share("rame");
map(0xe000, 0xefff).writeonly().share("rame");
map(0xf000, 0xfeff).view(m_bankf);
m_bankf[0](0xf000, 0xfeff).readonly().share("ramf");
map(0xf000, 0xfeff).writeonly().share("ramf");
map(0xfff0, 0xffff).view(m_bankg);
m_bankg[0](0xfff0, 0xffff).readonly().share("ramg");
map(0xfff0, 0xffff).writeonly().share("ramg");
#if 0
map(0xff00, 0xff00).rw(FUNC(bml3_state::ym2203_r), FUNC(bml3_state::ym2203_w));
@ -745,11 +759,12 @@ INTERRUPT_GEN_MEMBER(bml3_state::timer_firq)
void bml3_state::machine_start()
{
m_extram = make_unique_clear<u8[]>(0x6000);
m_vram = make_unique_clear<u8[]>(0x4000);
m_aram = make_unique_clear<u8[]>(0x4000);
save_pointer(NAME(m_extram), 0x6000);
m_bml3bus->map_exrom(m_rom_view[0]);
m_bml3bus->map_io(m_maincpu->space(AS_PROGRAM));
save_pointer(NAME(m_vram), 0x4000);
save_pointer(NAME(m_aram), 0x4000);
@ -774,29 +789,17 @@ void bml3_state::machine_start()
save_item(NAME(m_firq_mask));
save_item(NAME(m_firq_status));
save_item(NAME(m_nmi));
u8 *r = m_extram.get();
u8 *m = memregion("maincpu")->base();
m_banka->configure_entry(0, &m[0xa000]);
m_banka->configure_entry(1, r);
m_bankc->configure_entry(0, &m[0xc000]);
m_bankc->configure_entry(1, r+0x2000);
m_banke->configure_entry(0, &m[0xe000]);
m_banke->configure_entry(1, r+0x4000);
m_bankf->configure_entry(0, &m[0xf000]);
m_bankf->configure_entry(1, r+0x5000);
m_bankg->configure_entry(0, &m[0xfff0]);
m_bankg->configure_entry(1, r+0x5ff0);
}
void bml3_state::machine_reset()
{
/* defaults */
m_banka->set_entry(0);
m_bankc->set_entry(0);
m_banke->set_entry(0);
m_bankf->set_entry(0);
m_bankg->set_entry(0);
m_rom_view.select(0);
m_banka.disable();
m_bankc.disable();
m_banke.disable();
m_bankf.disable();
m_bankg.disable();
m_firq_mask = -1; // disable firq
m_psg_latch = 0;
@ -835,17 +838,39 @@ void bml3_state::piaA_w(uint8_t data)
*/
logerror("Check banking PIA A -> %02x\n",data);
if(!BIT(data, 1))
m_banka->set_entry(BIT(data, 6));
if (!BIT(data, 1))
{
if (BIT(data, 6))
m_banka.select(0);
else
m_banka.disable();
}
if(!BIT(data, 2))
m_bankc->set_entry(BIT(data, 7));
if (!BIT(data, 2))
{
if (BIT(data, 7))
m_bankc.select(0);
else
m_bankc.disable();
}
if(!BIT(data, 3))
m_banke->set_entry(BIT(data, 7));
if (!BIT(data, 3))
{
if (BIT(data, 7))
m_banke.select(0);
else
m_banke.disable();
}
m_bankf->set_entry(BIT(data, 0));
m_bankg->set_entry(BIT(data, 1));
if (BIT(data, 0))
m_bankf.select(0);
else
m_bankf.disable();
if (BIT(data, 1))
m_bankg.select(0);
else
m_bankg.disable();
}
WRITE_LINE_MEMBER( bml3_state::acia_rts_w )
@ -935,7 +960,6 @@ void bml3_state::bml3_common(machine_config &config)
/* slot devices */
BML3BUS(config, m_bml3bus, 0);
m_bml3bus->set_space(m_maincpu, AS_PROGRAM);
m_bml3bus->nmi_callback().set_inputline(m_maincpu, INPUT_LINE_NMI);
m_bml3bus->irq_callback().set_inputline(m_maincpu, M6809_IRQ_LINE);
m_bml3bus->firq_callback().set_inputline(m_maincpu, M6809_FIRQ_LINE);