mirror of
https://github.com/holub/mame
synced 2025-04-09 18:17:44 +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);
|
||||
|
||||
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_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_spc(*this, "scsi:7:spc")
|
||||
, m_rom(*this, "scsiexrom")
|
||||
, m_drq(false)
|
||||
{
|
||||
}
|
||||
|
||||
void x68k_scsiext_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_drq));
|
||||
|
||||
m_slot = dynamic_cast<x68k_expansion_slot_device *>(owner());
|
||||
|
||||
m_slot->space().install_rom(0xea0020,0xea1fff, m_rom.target());
|
||||
m_slot->space().unmap_write(0xea0020,0xea1fff);
|
||||
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()
|
||||
@ -86,7 +94,8 @@ void x68k_scsiext_device::device_reset()
|
||||
|
||||
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()
|
||||
@ -96,5 +105,36 @@ uint8_t x68k_scsiext_device::iack2()
|
||||
|
||||
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);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
// device_t implementation
|
||||
virtual void device_start() override ATTR_COLD;
|
||||
virtual void device_reset() 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;
|
||||
|
||||
// device_x68k_expansion_card_interface overrides
|
||||
// device_x68k_expansion_card_interface implementation
|
||||
virtual uint8_t iack2() override;
|
||||
|
||||
private:
|
||||
void irq_w(int state);
|
||||
void drq_w(int state);
|
||||
|
||||
u8 data_r();
|
||||
void data_w(u8 data);
|
||||
|
||||
x68k_expansion_slot_device *m_slot;
|
||||
|
||||
required_device<mb89352_device> m_spc;
|
||||
required_region_ptr<u8> m_rom;
|
||||
|
||||
bool m_drq;
|
||||
};
|
||||
|
||||
// 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_nmi_cb(*this),
|
||||
m_out_reset_cb(*this),
|
||||
m_out_dtack_cb(*this),
|
||||
m_card(nullptr)
|
||||
{
|
||||
}
|
||||
@ -67,6 +68,8 @@ x68k_expansion_slot_device::~x68k_expansion_slot_device()
|
||||
|
||||
void x68k_expansion_slot_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_exown));
|
||||
|
||||
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::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::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_nmi_callback() { return m_out_nmi_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; }
|
||||
|
||||
@ -122,22 +123,29 @@ public:
|
||||
void irq4_w(int state);
|
||||
void nmi_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 iack4() { return (m_card != nullptr) ? m_card->iack4() : 0x18; }
|
||||
void exown_w(int state) { m_exown = !state; }
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
// device_t implementation
|
||||
virtual void device_start() override ATTR_COLD;
|
||||
|
||||
required_address_space m_space;
|
||||
|
||||
private:
|
||||
devcb_write_line m_out_irq2_cb;
|
||||
devcb_write_line m_out_irq4_cb;
|
||||
devcb_write_line m_out_nmi_cb;
|
||||
devcb_write_line m_out_reset_cb;
|
||||
devcb_write_line m_out_dtack_cb;
|
||||
|
||||
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()
|
||||
{
|
||||
// Relative priority of IACK2-1 and IACK2-2 is unknown
|
||||
// IACK2-1 has higher priority than IACK2-2
|
||||
if (m_exp_irq2[0])
|
||||
return m_expansion[0]->iack2();
|
||||
else if (m_exp_irq2[1])
|
||||
return m_expansion[1]->iack2();
|
||||
else
|
||||
return 0x18; // spurious interrupt
|
||||
return m68000_base_device::autovector(0); // spurious interrupt
|
||||
}
|
||||
|
||||
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])
|
||||
return m_expansion[0]->iack4();
|
||||
else if (m_exp_irq4[1])
|
||||
return m_expansion[1]->iack4();
|
||||
else
|
||||
return 0x18; // spurious interrupt
|
||||
return m68000_base_device::autovector(0); // spurious interrupt
|
||||
}
|
||||
|
||||
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_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_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);
|
||||
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_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_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 */
|
||||
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.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);
|
||||
m_crtc->set_clock_69m(69.55199_MHz_XTAL);
|
||||
m_crtc->set_screen("screen");
|
||||
|
Loading…
Reference in New Issue
Block a user