fs3216: Start fleshing out the FDC interface (nw)

upd765: Kludge in an output callback for the index pulse, which doesn't deserve to be attached to this device but is done this way because of MAME's FDC model. (nw)
This commit is contained in:
AJR 2019-01-12 22:14:55 -05:00
parent 0a677239d7
commit bf10f9ce47
3 changed files with 171 additions and 29 deletions

View File

@ -167,6 +167,7 @@ upd765_family_device::upd765_family_device(const machine_config &mconfig, device
intrq_cb(*this),
drq_cb(*this),
hdl_cb(*this),
idx_cb(*this),
us_cb(*this)
{
ready_polled = true;
@ -192,16 +193,20 @@ void upd765_family_device::set_mode(int _mode)
mode = _mode;
}
void upd765_family_device::device_resolve_objects()
{
intrq_cb.resolve_safe();
drq_cb.resolve_safe();
hdl_cb.resolve_safe();
idx_cb.resolve_safe();
us_cb.resolve_safe();
}
void upd765_family_device::device_start()
{
save_item(NAME(motorcfg));
save_item(NAME(selected_drive));
intrq_cb.resolve_safe();
drq_cb.resolve_safe();
hdl_cb.resolve_safe();
us_cb.resolve_safe();
for(int i=0; i != 4; i++) {
char name[2];
flopi[i].tm = timer_alloc(i);
@ -344,6 +349,8 @@ void upd765_family_device::set_floppy(floppy_image_device *flop)
}
if(flop)
flop->setup_index_pulse_cb(floppy_image_device::index_pulse_cb(&upd765_family_device::index_callback, this));
else
idx_cb(0);
}
READ8_MEMBER(upd765_family_device::sra_r)
@ -2446,6 +2453,7 @@ void upd765_family_device::index_callback(floppy_image_device *floppy, int state
if(fi.live)
live_sync();
fi.index = state;
idx_cb(state);
if(!state) {
general_continue(fi);

View File

@ -46,6 +46,7 @@ public:
auto drq_wr_callback() { return drq_cb.bind(); }
auto hdl_wr_callback() { return hdl_cb.bind(); }
auto us_wr_callback() { return us_cb.bind(); }
auto idx_wr_callback() { return idx_cb.bind(); }
virtual void map(address_map &map) override = 0;
@ -92,6 +93,7 @@ public:
protected:
upd765_family_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
virtual void device_resolve_objects() override;
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
@ -270,7 +272,7 @@ protected:
int main_phase;
live_info cur_live, checkpoint_live;
devcb_write_line intrq_cb, drq_cb, hdl_cb;
devcb_write_line intrq_cb, drq_cb, hdl_cb, idx_cb;
devcb_write8 us_cb;
bool cur_irq, other_irq, data_irq, drq, internal_drq, tc, tc_done, locked, mfm, scan_done;
floppy_info flopi[4];

View File

@ -12,7 +12,7 @@
//#include "bus/rs232/rs232.h"
#include "cpu/m68000/m68000.h"
#include "cpu/8x300/8x300.h"
//#include "imagedev/floppy.h"
#include "imagedev/floppy.h"
#include "machine/bankdev.h"
//#include "machine/com8116.h"
#include "machine/upd765.h"
@ -32,6 +32,7 @@ public:
, m_clb(*this, "clb")
, m_ctc(*this, "ctc")
, m_fdc(*this, "fdc")
, m_floppy(*this, "fdc:%u", 0U)
, m_earom(*this, "earom")
, m_vecprom(*this, "vecprom")
, m_videoram(*this, "videoram")
@ -59,14 +60,21 @@ private:
DECLARE_READ8_MEMBER(ctc_r);
DECLARE_WRITE8_MEMBER(ctc_w);
void floppy_select_w(u8 data);
u8 floppy_status_r();
void fdc_reset_w(u16 data);
u8 fdc_ram_r(offs_t offset);
void fdc_ram_w(offs_t offset, u8 data);
u16 earom_recall_r();
u16 earom_store_r();
DECLARE_WRITE_LINE_MEMBER(fdc_int_w);
DECLARE_WRITE_LINE_MEMBER(fdc_drq_w);
DECLARE_WRITE_LINE_MEMBER(fdc_hdl_w);
DECLARE_WRITE_LINE_MEMBER(floppy_idx_w);
void fdc_us_w(u8 data);
u16 floppy_select_r(offs_t offset);
void floppy_select_w(offs_t offset, u16 data);
void floppy_control_w(u8 data);
u8 floppy_status_r();
u8 fdc_ram_r(offs_t offset);
void fdc_ram_w(offs_t offset, u8 data);
void main_map(address_map &map);
void clb_map(address_map &map);
void wdcpu_prog_map(address_map &map);
@ -76,6 +84,7 @@ private:
required_device<address_map_bank_device> m_clb;
required_device<z80ctc_device> m_ctc;
required_device<upd765a_device> m_fdc;
required_device_array<floppy_connector, 4> m_floppy;
required_device<x2212_device> m_earom;
required_region_ptr<u8> m_vecprom;
@ -83,21 +92,37 @@ private:
required_region_ptr<u8> m_chargen;
u32 m_mmu_reg[4];
std::unique_ptr<u8[]> m_fdc_ram;
bool m_from_reset;
u8 m_floppy_status;
u8 m_floppy_control;
u8 m_floppy_select;
u8 m_fdc_select;
u16 m_fdc_dma_count;
std::unique_ptr<u8[]> m_fdc_ram;
};
void fs3216_state::machine_start()
{
m_fdc_ram = make_unique_clear<u8[]>(0x400);
save_pointer(NAME(m_fdc_ram), 0x400);
m_fdc_ram = make_unique_clear<u8[]>(0x800);
save_pointer(NAME(m_fdc_ram), 0x800);
std::fill(std::begin(m_mmu_reg), std::end(m_mmu_reg), 0);
m_floppy_status = 0;
m_floppy_control = 0;
m_floppy_select = 0;
m_fdc_select = 0;
m_fdc_dma_count = 0;
save_item(NAME(m_mmu_reg));
save_item(NAME(m_from_reset));
save_item(NAME(m_floppy_status));
save_item(NAME(m_floppy_control));
save_item(NAME(m_floppy_select));
save_item(NAME(m_fdc_select));
save_item(NAME(m_fdc_dma_count));
}
void fs3216_state::machine_reset()
@ -106,6 +131,9 @@ void fs3216_state::machine_reset()
// FIXME: fix the 68000 so that it doesn't read vectors during device_reset
m_maincpu->reset();
floppy_control_w(0);
floppy_select_w(0, 0);
}
@ -224,28 +252,118 @@ u16 fs3216_state::earom_store_r()
return 0xffff;
}
void fs3216_state::floppy_select_w(u8 data)
WRITE_LINE_MEMBER(fs3216_state::fdc_int_w)
{
if (state)
m_floppy_status |= 0x02;
else
m_floppy_status &= 0xfd;
}
WRITE_LINE_MEMBER(fs3216_state::fdc_drq_w)
{
if (state)
m_floppy_status |= 0x01;
else
m_floppy_status &= 0xfe;
}
WRITE_LINE_MEMBER(fs3216_state::fdc_hdl_w)
{
if (state)
m_floppy_status |= 0x40;
else
m_floppy_status &= 0xbf;
}
WRITE_LINE_MEMBER(fs3216_state::floppy_idx_w)
{
if (state)
m_floppy_status |= 0x20;
else
m_floppy_status &= 0xdf;
if (BIT(m_floppy_select, 2))
m_fdc->ready_w(state);
}
void fs3216_state::fdc_us_w(u8 data)
{
m_fdc_select = data;
if (!BIT(m_floppy_select, 2))
m_fdc->set_floppy(m_floppy[m_fdc_select]->get_device());
}
u16 fs3216_state::floppy_select_r(offs_t offset)
{
if (!machine().side_effects_disabled())
floppy_select_w(offset, 0);
return 0xffff;
}
void fs3216_state::floppy_select_w(offs_t offset, u16 data)
{
if (m_floppy_select == offset)
return;
m_floppy_select = offset;
if (BIT(offset, 2))
m_fdc->set_floppy(m_floppy[offset & 3]->get_device());
else
m_fdc->set_floppy(m_floppy[m_fdc_select]->get_device());
}
void fs3216_state::floppy_control_w(u8 data)
{
m_floppy_control = data;
floppy_image_device *fd = m_floppy[BIT(m_floppy_select, 2) ? (m_floppy_select & 3) : m_fdc_select]->get_device();
if (BIT(data, 5))
{
if (fd != nullptr)
fd->mon_w(0);
m_floppy_status |= 0x10;
}
else
{
if (fd != nullptr)
fd->mon_w(1);
m_floppy_status &= 0xef;
}
if (!BIT(data, 1))
{
m_fdc->soft_reset();
m_fdc_dma_count = 0;
m_fdc->tc_w(0);
}
m_fdc->set_unscaled_clock(16_MHz_XTAL / (BIT(data, 0) ? 4 : 2));
}
u8 fs3216_state::floppy_status_r()
{
return 0xff;
}
void fs3216_state::fdc_reset_w(u16 data)
{
m_fdc->soft_reset();
return m_floppy_status;
}
u8 fs3216_state::fdc_ram_r(offs_t offset)
{
return m_fdc_ram[offset];
if (!machine().side_effects_disabled())
{
m_fdc_dma_count = offset;
m_fdc->tc_w(BIT(offset, 11));
}
return m_fdc_ram[offset & 0x7ff];
}
void fs3216_state::fdc_ram_w(offs_t offset, u8 data)
{
m_fdc_ram[offset] = data;
if (!machine().side_effects_disabled())
{
m_fdc_dma_count = offset;
m_fdc->tc_w(BIT(offset, 11));
}
m_fdc_ram[offset & 0x7ff] = data;
}
@ -259,13 +377,15 @@ void fs3216_state::clb_map(address_map &map)
map(0x000000, 0x017fff).ram();
map(0x780000, 0x783fff).rom().region("momrom", 0);
map(0x792000, 0x792003).m(m_fdc, FUNC(upd765a_device::map)).umask16(0x00ff);
map(0x792041, 0x792041).w(FUNC(fs3216_state::floppy_select_w));
map(0x792010, 0x79201f).rw(FUNC(fs3216_state::floppy_select_r), FUNC(fs3216_state::floppy_select_w));
map(0x792041, 0x792041).w(FUNC(fs3216_state::floppy_control_w));
map(0x792051, 0x792051).r(FUNC(fs3216_state::floppy_status_r));
map(0x794680, 0x79468f).rw(FUNC(fs3216_state::ctc_r), FUNC(fs3216_state::ctc_w)).umask16(0x00ff);
map(0x794701, 0x794701).rw("dart", FUNC(z80dart_device::da_r), FUNC(z80dart_device::da_w));
map(0x794709, 0x794709).rw("dart", FUNC(z80dart_device::ca_r), FUNC(z80dart_device::ca_w));
map(0x794711, 0x794711).rw("dart", FUNC(z80dart_device::db_r), FUNC(z80dart_device::db_w));
map(0x794719, 0x794719).rw("dart", FUNC(z80dart_device::cb_r), FUNC(z80dart_device::cb_w));
map(0x796000, 0x797fff).rw(FUNC(fs3216_state::fdc_ram_r), FUNC(fs3216_state::fdc_ram_w)).umask16(0x00ff);
map(0x7a0000, 0x7a1fff).rom().region("video", 0);
map(0x7a4001, 0x7a4001).w("crtc", FUNC(mc6845_device::address_w));
map(0x7a4003, 0x7a4003).rw("crtc", FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w));
@ -276,8 +396,7 @@ void fs3216_state::clb_map(address_map &map)
map(0x7f1000, 0x7f1001).r(FUNC(fs3216_state::irq_r));
map(0x7f3000, 0x7f300f).w(FUNC(fs3216_state::mmu_reg_w));
map(0x7f5000, 0x7f5001).w(FUNC(fs3216_state::mmu_init_w));
map(0x7f6000, 0x7f6001).w(FUNC(fs3216_state::fdc_reset_w));
map(0x7f6800, 0x7f6fff).rw(FUNC(fs3216_state::fdc_ram_r), FUNC(fs3216_state::fdc_ram_w)).umask16(0x00ff);
map(0x7f6000, 0x7f6001).nopw();
map(0x7f7000, 0x7f7001).r(FUNC(fs3216_state::earom_store_r));
map(0x7f7200, 0x7f7201).r(FUNC(fs3216_state::earom_recall_r));
map(0x7f7400, 0x7f75ff).rw(m_earom, FUNC(x2212_device::read), FUNC(x2212_device::write)).umask16(0x00ff);
@ -294,6 +413,11 @@ void fs3216_state::wdcpu_bank_map(address_map &map)
}
static void fs3216_floppies(device_slot_interface &device)
{
device.option_add("525dd", FLOPPY_525_DD);
}
void fs3216_state::fs3216(machine_config &config)
{
M68000(config, m_maincpu, 44.2368_MHz_XTAL / 8); // 5.5 MHz
@ -318,7 +442,15 @@ void fs3216_state::fs3216(machine_config &config)
Z80DART(config, "dart", 44.2368_MHz_XTAL / 8); // Z8470BPS
UPD765A(config, m_fdc, 16_MHz_XTAL / 2, true, false);
UPD765A(config, m_fdc, 16_MHz_XTAL / 2, false, false);
m_fdc->intrq_wr_callback().set(FUNC(fs3216_state::fdc_int_w));
m_fdc->drq_wr_callback().set(FUNC(fs3216_state::fdc_drq_w));
m_fdc->hdl_wr_callback().set(FUNC(fs3216_state::fdc_hdl_w));
m_fdc->idx_wr_callback().set(FUNC(fs3216_state::floppy_idx_w));
m_fdc->us_wr_callback().set(FUNC(fs3216_state::fdc_us_w));
for (int i = 0; i < 4; i++)
FLOPPY_CONNECTOR(config, m_floppy[i], fs3216_floppies, i < 1 ? "525dd" : nullptr, floppy_image_device::default_floppy_formats);
X2212(config, m_earom);