mirror of
https://github.com/holub/mame
synced 2025-04-18 22:49:58 +03:00
x68k: add CZ-7BS1 dma glue logic
This commit is contained in:
parent
ee6cb33f46
commit
a71c0333b7
@ -56,7 +56,7 @@ void x68k_scsiext_device::device_add_mconfig(machine_config &config)
|
|||||||
{
|
{
|
||||||
mb89352_device &spc = downcast<mb89352_device &>(*device);
|
mb89352_device &spc = downcast<mb89352_device &>(*device);
|
||||||
|
|
||||||
spc.set_clock(8'000'000); // ?
|
spc.set_clock(10'000'000 / 2); // 10MHz clock from bus
|
||||||
spc.out_irq_callback().set(*this, FUNC(x68k_scsiext_device::irq_w));
|
spc.out_irq_callback().set(*this, FUNC(x68k_scsiext_device::irq_w));
|
||||||
spc.out_dreq_callback().set(*this, FUNC(x68k_scsiext_device::drq_w));
|
spc.out_dreq_callback().set(*this, FUNC(x68k_scsiext_device::drq_w));
|
||||||
});
|
});
|
||||||
@ -68,16 +68,24 @@ x68k_scsiext_device::x68k_scsiext_device(const machine_config &mconfig, const ch
|
|||||||
, m_slot(nullptr)
|
, m_slot(nullptr)
|
||||||
, m_spc(*this, "scsi:7:spc")
|
, m_spc(*this, "scsi:7:spc")
|
||||||
, m_rom(*this, "scsiexrom")
|
, m_rom(*this, "scsiexrom")
|
||||||
|
, m_drq(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void x68k_scsiext_device::device_start()
|
void x68k_scsiext_device::device_start()
|
||||||
{
|
{
|
||||||
|
save_item(NAME(m_drq));
|
||||||
|
|
||||||
m_slot = dynamic_cast<x68k_expansion_slot_device *>(owner());
|
m_slot = dynamic_cast<x68k_expansion_slot_device *>(owner());
|
||||||
|
|
||||||
m_slot->space().install_rom(0xea0020,0xea1fff, m_rom.target());
|
m_slot->space().install_rom(0xea0020,0xea1fff, m_rom.target());
|
||||||
m_slot->space().unmap_write(0xea0020,0xea1fff);
|
m_slot->space().unmap_write(0xea0020,0xea1fff);
|
||||||
m_slot->space().install_device(0xea0000, 0xea001f, *m_spc, &mb89352_device::map, 0x00ff00ff);
|
m_slot->space().install_device(0xea0000, 0xea001f, *m_spc, &mb89352_device::map, 0x00ff00ff);
|
||||||
|
|
||||||
|
// replace data register handlers with DMA-aware glue
|
||||||
|
m_slot->space().install_readwrite_handler(0xea0015, 0xea0015,
|
||||||
|
emu::rw_delegate(*this, FUNC(x68k_scsiext_device::data_r)),
|
||||||
|
emu::rw_delegate(*this, FUNC(x68k_scsiext_device::data_w)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void x68k_scsiext_device::device_reset()
|
void x68k_scsiext_device::device_reset()
|
||||||
@ -86,7 +94,8 @@ void x68k_scsiext_device::device_reset()
|
|||||||
|
|
||||||
void x68k_scsiext_device::irq_w(int state)
|
void x68k_scsiext_device::irq_w(int state)
|
||||||
{
|
{
|
||||||
m_slot->irq2_w(state); // correct? Or perhaps selectable?
|
// TODO: jumper-configurable IRQ2/IRQ4
|
||||||
|
m_slot->irq2_w(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t x68k_scsiext_device::iack2()
|
uint8_t x68k_scsiext_device::iack2()
|
||||||
@ -96,5 +105,36 @@ uint8_t x68k_scsiext_device::iack2()
|
|||||||
|
|
||||||
void x68k_scsiext_device::drq_w(int state)
|
void x68k_scsiext_device::drq_w(int state)
|
||||||
{
|
{
|
||||||
// TODO
|
m_drq = bool(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 x68k_scsiext_device::data_r()
|
||||||
|
{
|
||||||
|
// check for DMA cycle
|
||||||
|
if (m_slot->exown() && !machine().side_effects_disabled())
|
||||||
|
{
|
||||||
|
// negate #DTACK if not requesting a DMA transfer
|
||||||
|
if (!m_drq)
|
||||||
|
m_slot->dtack_w(1);
|
||||||
|
|
||||||
|
return m_spc->dma_r();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return m_spc->dreg_r();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void x68k_scsiext_device::data_w(u8 data)
|
||||||
|
{
|
||||||
|
// check for DMA cycle
|
||||||
|
if (m_slot->exown())
|
||||||
|
{
|
||||||
|
// negate #DTACK if not requesting a DMA transfer
|
||||||
|
if (!m_drq)
|
||||||
|
m_slot->dtack_w(1);
|
||||||
|
else
|
||||||
|
m_spc->dma_w(data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_spc->dreg_w(data);
|
||||||
}
|
}
|
||||||
|
@ -22,23 +22,28 @@ public:
|
|||||||
x68k_scsiext_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
x68k_scsiext_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// device-level overrides
|
// device_t implementation
|
||||||
virtual void device_start() override ATTR_COLD;
|
virtual void device_start() override ATTR_COLD;
|
||||||
virtual void device_reset() override ATTR_COLD;
|
virtual void device_reset() override ATTR_COLD;
|
||||||
virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
|
virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
|
||||||
virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD;
|
virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD;
|
||||||
|
|
||||||
// device_x68k_expansion_card_interface overrides
|
// device_x68k_expansion_card_interface implementation
|
||||||
virtual uint8_t iack2() override;
|
virtual uint8_t iack2() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void irq_w(int state);
|
void irq_w(int state);
|
||||||
void drq_w(int state);
|
void drq_w(int state);
|
||||||
|
|
||||||
|
u8 data_r();
|
||||||
|
void data_w(u8 data);
|
||||||
|
|
||||||
x68k_expansion_slot_device *m_slot;
|
x68k_expansion_slot_device *m_slot;
|
||||||
|
|
||||||
required_device<mb89352_device> m_spc;
|
required_device<mb89352_device> m_spc;
|
||||||
required_region_ptr<u8> m_rom;
|
required_region_ptr<u8> m_rom;
|
||||||
|
|
||||||
|
bool m_drq;
|
||||||
};
|
};
|
||||||
|
|
||||||
// device type definition
|
// device type definition
|
||||||
|
@ -53,6 +53,7 @@ x68k_expansion_slot_device::x68k_expansion_slot_device(const machine_config &mco
|
|||||||
m_out_irq4_cb(*this),
|
m_out_irq4_cb(*this),
|
||||||
m_out_nmi_cb(*this),
|
m_out_nmi_cb(*this),
|
||||||
m_out_reset_cb(*this),
|
m_out_reset_cb(*this),
|
||||||
|
m_out_dtack_cb(*this),
|
||||||
m_card(nullptr)
|
m_card(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -67,6 +68,8 @@ x68k_expansion_slot_device::~x68k_expansion_slot_device()
|
|||||||
|
|
||||||
void x68k_expansion_slot_device::device_start()
|
void x68k_expansion_slot_device::device_start()
|
||||||
{
|
{
|
||||||
|
save_item(NAME(m_exown));
|
||||||
|
|
||||||
m_card = get_card_device();
|
m_card = get_card_device();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,3 +78,4 @@ void x68k_expansion_slot_device::irq2_w(int state) { m_out_irq2_cb(state); }
|
|||||||
void x68k_expansion_slot_device::irq4_w(int state) { m_out_irq4_cb(state); }
|
void x68k_expansion_slot_device::irq4_w(int state) { m_out_irq4_cb(state); }
|
||||||
void x68k_expansion_slot_device::nmi_w(int state) { m_out_nmi_cb(state); }
|
void x68k_expansion_slot_device::nmi_w(int state) { m_out_nmi_cb(state); }
|
||||||
void x68k_expansion_slot_device::reset_w(int state) { m_out_reset_cb(state); }
|
void x68k_expansion_slot_device::reset_w(int state) { m_out_reset_cb(state); }
|
||||||
|
void x68k_expansion_slot_device::dtack_w(int state) { m_out_dtack_cb(state); }
|
||||||
|
@ -115,6 +115,7 @@ public:
|
|||||||
auto out_irq4_callback() { return m_out_irq4_cb.bind(); }
|
auto out_irq4_callback() { return m_out_irq4_cb.bind(); }
|
||||||
auto out_nmi_callback() { return m_out_nmi_cb.bind(); }
|
auto out_nmi_callback() { return m_out_nmi_cb.bind(); }
|
||||||
auto out_reset_callback() { return m_out_reset_cb.bind(); }
|
auto out_reset_callback() { return m_out_reset_cb.bind(); }
|
||||||
|
auto out_dtack_callback() { return m_out_dtack_cb.bind(); }
|
||||||
|
|
||||||
address_space &space() { return *m_space; }
|
address_space &space() { return *m_space; }
|
||||||
|
|
||||||
@ -122,22 +123,29 @@ public:
|
|||||||
void irq4_w(int state);
|
void irq4_w(int state);
|
||||||
void nmi_w(int state);
|
void nmi_w(int state);
|
||||||
void reset_w(int state);
|
void reset_w(int state);
|
||||||
|
void dtack_w(int state);
|
||||||
|
bool exown() const { return m_exown; }
|
||||||
|
|
||||||
uint8_t iack2() { return (m_card != nullptr) ? m_card->iack2() : 0x18; }
|
uint8_t iack2() { return (m_card != nullptr) ? m_card->iack2() : 0x18; }
|
||||||
uint8_t iack4() { return (m_card != nullptr) ? m_card->iack4() : 0x18; }
|
uint8_t iack4() { return (m_card != nullptr) ? m_card->iack4() : 0x18; }
|
||||||
|
void exown_w(int state) { m_exown = !state; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// device-level overrides
|
// device_t implementation
|
||||||
virtual void device_start() override ATTR_COLD;
|
virtual void device_start() override ATTR_COLD;
|
||||||
|
|
||||||
required_address_space m_space;
|
required_address_space m_space;
|
||||||
|
|
||||||
|
private:
|
||||||
devcb_write_line m_out_irq2_cb;
|
devcb_write_line m_out_irq2_cb;
|
||||||
devcb_write_line m_out_irq4_cb;
|
devcb_write_line m_out_irq4_cb;
|
||||||
devcb_write_line m_out_nmi_cb;
|
devcb_write_line m_out_nmi_cb;
|
||||||
devcb_write_line m_out_reset_cb;
|
devcb_write_line m_out_reset_cb;
|
||||||
|
devcb_write_line m_out_dtack_cb;
|
||||||
|
|
||||||
device_x68k_expansion_card_interface *m_card;
|
device_x68k_expansion_card_interface *m_card;
|
||||||
|
|
||||||
|
bool m_exown;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -742,24 +742,24 @@ void x68k_state::irq4_line(int state)
|
|||||||
|
|
||||||
uint8_t x68k_state::iack2()
|
uint8_t x68k_state::iack2()
|
||||||
{
|
{
|
||||||
// Relative priority of IACK2-1 and IACK2-2 is unknown
|
// IACK2-1 has higher priority than IACK2-2
|
||||||
if (m_exp_irq2[0])
|
if (m_exp_irq2[0])
|
||||||
return m_expansion[0]->iack2();
|
return m_expansion[0]->iack2();
|
||||||
else if (m_exp_irq2[1])
|
else if (m_exp_irq2[1])
|
||||||
return m_expansion[1]->iack2();
|
return m_expansion[1]->iack2();
|
||||||
else
|
else
|
||||||
return 0x18; // spurious interrupt
|
return m68000_base_device::autovector(0); // spurious interrupt
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t x68k_state::iack4()
|
uint8_t x68k_state::iack4()
|
||||||
{
|
{
|
||||||
// Relative priority of IACK4-1 and IACK4-2 is unknown
|
// IACK4-1 has higher priority than IACK4-2
|
||||||
if (m_exp_irq4[0])
|
if (m_exp_irq4[0])
|
||||||
return m_expansion[0]->iack4();
|
return m_expansion[0]->iack4();
|
||||||
else if (m_exp_irq4[1])
|
else if (m_exp_irq4[1])
|
||||||
return m_expansion[1]->iack4();
|
return m_expansion[1]->iack4();
|
||||||
else
|
else
|
||||||
return 0x18; // spurious interrupt
|
return m68000_base_device::autovector(0); // spurious interrupt
|
||||||
}
|
}
|
||||||
|
|
||||||
void x68k_state::cpu_space_map(address_map &map)
|
void x68k_state::cpu_space_map(address_map &map)
|
||||||
@ -1111,12 +1111,16 @@ void x68k_state::x68000_base(machine_config &config)
|
|||||||
m_expansion[0]->out_irq2_callback().set(FUNC(x68k_state::irq2_line<0>));
|
m_expansion[0]->out_irq2_callback().set(FUNC(x68k_state::irq2_line<0>));
|
||||||
m_expansion[0]->out_irq4_callback().set(FUNC(x68k_state::irq4_line<0>));
|
m_expansion[0]->out_irq4_callback().set(FUNC(x68k_state::irq4_line<0>));
|
||||||
m_expansion[0]->out_nmi_callback().set(nmi, FUNC(input_merger_any_high_device::in_w<0>));
|
m_expansion[0]->out_nmi_callback().set(nmi, FUNC(input_merger_any_high_device::in_w<0>));
|
||||||
|
m_expansion[0]->out_dtack_callback().set(m_hd63450, FUNC(hd63450_device::dtack_w));
|
||||||
|
m_hd63450->own().append(m_expansion[0], FUNC(x68k_expansion_slot_device::exown_w));
|
||||||
|
|
||||||
X68K_EXPANSION_SLOT(config, m_expansion[1], x68000_exp_cards, nullptr);
|
X68K_EXPANSION_SLOT(config, m_expansion[1], x68000_exp_cards, nullptr);
|
||||||
m_expansion[1]->set_space(m_maincpu, AS_PROGRAM);
|
m_expansion[1]->set_space(m_maincpu, AS_PROGRAM);
|
||||||
m_expansion[1]->out_irq2_callback().set(FUNC(x68k_state::irq2_line<1>));
|
m_expansion[1]->out_irq2_callback().set(FUNC(x68k_state::irq2_line<1>));
|
||||||
m_expansion[1]->out_irq4_callback().set(FUNC(x68k_state::irq4_line<1>));
|
m_expansion[1]->out_irq4_callback().set(FUNC(x68k_state::irq4_line<1>));
|
||||||
m_expansion[1]->out_nmi_callback().set(nmi, FUNC(input_merger_any_high_device::in_w<1>));
|
m_expansion[1]->out_nmi_callback().set(nmi, FUNC(input_merger_any_high_device::in_w<1>));
|
||||||
|
m_expansion[1]->out_dtack_callback().set(m_hd63450, FUNC(hd63450_device::dtack_w));
|
||||||
|
m_hd63450->own().append(m_expansion[1], FUNC(x68k_expansion_slot_device::exown_w));
|
||||||
|
|
||||||
/* internal ram */
|
/* internal ram */
|
||||||
RAM(config, m_ram).set_default_size("4M").set_extra_options("1M,2M,3M,5M,6M,7M,8M,9M,10M,11M,12M");
|
RAM(config, m_ram).set_default_size("4M").set_extra_options("1M,2M,3M,5M,6M,7M,8M,9M,10M,11M,12M");
|
||||||
@ -1169,12 +1173,9 @@ void x68ksupr_state::x68ksupr_base(machine_config &config)
|
|||||||
|
|
||||||
spc.set_clock(40_MHz_XTAL / 8);
|
spc.set_clock(40_MHz_XTAL / 8);
|
||||||
spc.out_irq_callback().set(*this, FUNC(x68ksupr_state::ioc_irq<IOC_HDD_INT>));
|
spc.out_irq_callback().set(*this, FUNC(x68ksupr_state::ioc_irq<IOC_HDD_INT>));
|
||||||
spc.out_dreq_callback().set(m_hd63450, FUNC(hd63450_device::drq1_w));
|
// TODO: duplicate DMA glue from CZ-6BS1
|
||||||
});
|
});
|
||||||
|
|
||||||
m_hd63450->dma_read<1>().set("scsi:7:spc", FUNC(mb89352_device::dma_r));
|
|
||||||
m_hd63450->dma_write<1>().set("scsi:7:spc", FUNC(mb89352_device::dma_w));
|
|
||||||
|
|
||||||
VICON(config, m_crtc, 38.86363_MHz_XTAL);
|
VICON(config, m_crtc, 38.86363_MHz_XTAL);
|
||||||
m_crtc->set_clock_69m(69.55199_MHz_XTAL);
|
m_crtc->set_clock_69m(69.55199_MHz_XTAL);
|
||||||
m_crtc->set_screen("screen");
|
m_crtc->set_screen("screen");
|
||||||
|
Loading…
Reference in New Issue
Block a user