mirror of
https://github.com/holub/mame
synced 2025-05-29 00:53:09 +03:00
(MESS) victor9k: Floppy WIP. (nw)
This commit is contained in:
parent
ce28862753
commit
48edf48e1a
@ -13,7 +13,12 @@
|
|||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
|
|
||||||
- everything
|
- floppy format
|
||||||
|
- spindle speed
|
||||||
|
- stepper
|
||||||
|
- read PLL
|
||||||
|
- TACH0/1
|
||||||
|
- write logic
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -147,7 +152,7 @@ static MACHINE_CONFIG_FRAGMENT( victor_9000_fdc )
|
|||||||
MCFG_DEVICE_ADD(M6522_4_TAG, VIA6522, XTAL_30MHz/30)
|
MCFG_DEVICE_ADD(M6522_4_TAG, VIA6522, XTAL_30MHz/30)
|
||||||
MCFG_VIA6522_WRITEPA_HANDLER(WRITE8(victor_9000_fdc_t, via4_pa_w))
|
MCFG_VIA6522_WRITEPA_HANDLER(WRITE8(victor_9000_fdc_t, via4_pa_w))
|
||||||
MCFG_VIA6522_WRITEPB_HANDLER(WRITE8(victor_9000_fdc_t, via4_pb_w))
|
MCFG_VIA6522_WRITEPB_HANDLER(WRITE8(victor_9000_fdc_t, via4_pb_w))
|
||||||
MCFG_VIA6522_CA2_HANDLER(WRITELINE(victor_9000_fdc_t, mode_w))
|
MCFG_VIA6522_CA2_HANDLER(WRITELINE(victor_9000_fdc_t, wrsync_w))
|
||||||
MCFG_VIA6522_IRQ_HANDLER(WRITELINE(victor_9000_fdc_t, via4_irq_w))
|
MCFG_VIA6522_IRQ_HANDLER(WRITELINE(victor_9000_fdc_t, via4_irq_w))
|
||||||
|
|
||||||
MCFG_DEVICE_ADD(M6522_5_TAG, VIA6522, XTAL_30MHz/30)
|
MCFG_DEVICE_ADD(M6522_5_TAG, VIA6522, XTAL_30MHz/30)
|
||||||
@ -192,6 +197,8 @@ machine_config_constructor victor_9000_fdc_t::device_mconfig_additions() const
|
|||||||
victor_9000_fdc_t::victor_9000_fdc_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
victor_9000_fdc_t::victor_9000_fdc_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
||||||
device_t(mconfig, VICTOR_9000_FDC, "Victor 9000 FDC", tag, owner, clock, "victor9k_fdc", __FILE__),
|
device_t(mconfig, VICTOR_9000_FDC, "Victor 9000 FDC", tag, owner, clock, "victor9k_fdc", __FILE__),
|
||||||
m_irq_cb(*this),
|
m_irq_cb(*this),
|
||||||
|
m_syn_cb(*this),
|
||||||
|
m_lbrdy_cb(*this),
|
||||||
m_maincpu(*this, I8048_TAG),
|
m_maincpu(*this, I8048_TAG),
|
||||||
m_via4(*this, M6522_4_TAG),
|
m_via4(*this, M6522_4_TAG),
|
||||||
m_via5(*this, M6522_5_TAG),
|
m_via5(*this, M6522_5_TAG),
|
||||||
@ -210,20 +217,25 @@ victor_9000_fdc_t::victor_9000_fdc_t(const machine_config &mconfig, const char *
|
|||||||
m_rdy1(0),
|
m_rdy1(0),
|
||||||
m_ds0(1),
|
m_ds0(1),
|
||||||
m_ds1(1),
|
m_ds1(1),
|
||||||
m_lms(0),
|
m_l0ms(0),
|
||||||
|
m_l1ms(0),
|
||||||
m_st0(0),
|
m_st0(0),
|
||||||
m_st1(0),
|
m_st1(0),
|
||||||
m_stp0(0),
|
m_stp0(0),
|
||||||
m_stp1(0),
|
m_stp1(0),
|
||||||
m_drive(0),
|
m_drive(0),
|
||||||
m_side(0),
|
m_side(0),
|
||||||
m_brdy(1),
|
|
||||||
m_sync(1),
|
|
||||||
m_gcrerr(0),
|
|
||||||
m_via4_irq(CLEAR_LINE),
|
m_via4_irq(CLEAR_LINE),
|
||||||
m_via5_irq(CLEAR_LINE),
|
m_via5_irq(CLEAR_LINE),
|
||||||
m_via6_irq(CLEAR_LINE)
|
m_via6_irq(CLEAR_LINE),
|
||||||
|
m_syn(0),
|
||||||
|
m_lbrdy(1)
|
||||||
{
|
{
|
||||||
|
cur_live.tm = attotime::never;
|
||||||
|
cur_live.state = IDLE;
|
||||||
|
cur_live.next_state = -1;
|
||||||
|
cur_live.write_position = 0;
|
||||||
|
cur_live.write_start_time = attotime::never;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -233,6 +245,11 @@ victor_9000_fdc_t::victor_9000_fdc_t(const machine_config &mconfig, const char *
|
|||||||
|
|
||||||
void victor_9000_fdc_t::device_start()
|
void victor_9000_fdc_t::device_start()
|
||||||
{
|
{
|
||||||
|
// allocate timer
|
||||||
|
t_gen = timer_alloc(TM_GEN);
|
||||||
|
t_tach0 = timer_alloc(TM_TACH0);
|
||||||
|
t_tach1 = timer_alloc(TM_TACH1);
|
||||||
|
|
||||||
// state saving
|
// state saving
|
||||||
save_item(NAME(m_da));
|
save_item(NAME(m_da));
|
||||||
save_item(NAME(m_da0));
|
save_item(NAME(m_da0));
|
||||||
@ -245,19 +262,21 @@ void victor_9000_fdc_t::device_start()
|
|||||||
save_item(NAME(m_rdy1));
|
save_item(NAME(m_rdy1));
|
||||||
save_item(NAME(m_ds0));
|
save_item(NAME(m_ds0));
|
||||||
save_item(NAME(m_ds1));
|
save_item(NAME(m_ds1));
|
||||||
save_item(NAME(m_lms));
|
save_item(NAME(m_l0ms));
|
||||||
|
save_item(NAME(m_l1ms));
|
||||||
save_item(NAME(m_st0));
|
save_item(NAME(m_st0));
|
||||||
save_item(NAME(m_st1));
|
save_item(NAME(m_st1));
|
||||||
save_item(NAME(m_stp0));
|
save_item(NAME(m_stp0));
|
||||||
save_item(NAME(m_stp1));
|
save_item(NAME(m_stp1));
|
||||||
save_item(NAME(m_drive));
|
save_item(NAME(m_drive));
|
||||||
save_item(NAME(m_side));
|
save_item(NAME(m_side));
|
||||||
save_item(NAME(m_brdy));
|
save_item(NAME(m_drw));
|
||||||
save_item(NAME(m_sync));
|
save_item(NAME(m_erase));
|
||||||
save_item(NAME(m_gcrerr));
|
|
||||||
save_item(NAME(m_via4_irq));
|
save_item(NAME(m_via4_irq));
|
||||||
save_item(NAME(m_via5_irq));
|
save_item(NAME(m_via5_irq));
|
||||||
save_item(NAME(m_via6_irq));
|
save_item(NAME(m_via6_irq));
|
||||||
|
save_item(NAME(m_syn));
|
||||||
|
save_item(NAME(m_lbrdy));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -267,8 +286,12 @@ void victor_9000_fdc_t::device_start()
|
|||||||
|
|
||||||
void victor_9000_fdc_t::device_reset()
|
void victor_9000_fdc_t::device_reset()
|
||||||
{
|
{
|
||||||
|
live_abort();
|
||||||
|
|
||||||
// resolve callbacks
|
// resolve callbacks
|
||||||
m_irq_cb.resolve_safe();
|
m_irq_cb.resolve_safe();
|
||||||
|
m_syn_cb.resolve_safe();
|
||||||
|
m_lbrdy_cb.resolve_safe();
|
||||||
|
|
||||||
// reset devices
|
// reset devices
|
||||||
m_via4->reset();
|
m_via4->reset();
|
||||||
@ -291,6 +314,20 @@ void victor_9000_fdc_t::device_reset()
|
|||||||
|
|
||||||
void victor_9000_fdc_t::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
void victor_9000_fdc_t::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||||
{
|
{
|
||||||
|
switch (id)
|
||||||
|
{
|
||||||
|
case TM_GEN:
|
||||||
|
live_sync();
|
||||||
|
live_run();
|
||||||
|
|
||||||
|
case TM_TACH0:
|
||||||
|
// TODO
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TM_TACH1:
|
||||||
|
// TODO
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -315,7 +352,7 @@ READ8_MEMBER( victor_9000_fdc_t::floppy_p1_r )
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return m_lms;
|
return (m_l1ms << 4) | m_l0ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -370,30 +407,48 @@ WRITE8_MEMBER( victor_9000_fdc_t::floppy_p2_w )
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (BIT(data, 0)) m_floppy0->mon_w(0);
|
bool sync = false;
|
||||||
if (BIT(data, 1)) m_floppy0->mon_w(1);
|
|
||||||
if (BIT(data, 2)) m_floppy1->mon_w(0);
|
int mtr0 = m_mtr0;
|
||||||
if (BIT(data, 3)) m_floppy1->mon_w(1);
|
if ((data & 0x03) == 0x01) mtr0 = 0;
|
||||||
|
if ((data & 0x03) == 0x02) mtr0 = 1;
|
||||||
|
if (m_mtr0 != mtr0) sync = true;
|
||||||
|
|
||||||
|
int mtr1 = m_mtr1;
|
||||||
|
if ((data & 0x0c) == 0x04) mtr1 = 0;
|
||||||
|
if ((data & 0x0c) == 0x08) mtr1 = 1;
|
||||||
|
if (m_mtr1 != mtr1) sync = true;
|
||||||
|
|
||||||
int sel0 = BIT(data, 5);
|
int sel0 = BIT(data, 5);
|
||||||
|
if (m_sel0 != sel0) sync = true;
|
||||||
if (m_sel0 && !sel0)
|
|
||||||
{
|
|
||||||
m_da0 = m_da;
|
|
||||||
//m_floppy0->set_rpm();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_sel0 = sel0;
|
|
||||||
|
|
||||||
int sel1 = BIT(data, 4);
|
int sel1 = BIT(data, 4);
|
||||||
|
if (m_sel1 != sel1) sync = true;
|
||||||
|
|
||||||
if (m_sel1 && !sel1)
|
if (sync)
|
||||||
{
|
{
|
||||||
m_da1 = m_da;
|
live_sync();
|
||||||
//m_floppy1->set_rpm();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_sel1 = sel1;
|
m_mtr0 = mtr0;
|
||||||
|
m_mtr1 = mtr1;
|
||||||
|
m_sel0 = sel0;
|
||||||
|
m_sel1 = sel1;
|
||||||
|
|
||||||
|
if (LOG) logerror("%s MTR0 %u MTR1 %u SEL0 %u SEL1 %u\n", machine().time().as_string(), m_mtr0, m_mtr1, m_sel0, m_sel1);
|
||||||
|
|
||||||
|
update_spindle_motor();
|
||||||
|
checkpoint();
|
||||||
|
|
||||||
|
if (!m_mtr0 || !m_mtr1) {
|
||||||
|
if(cur_live.state == IDLE) {
|
||||||
|
live_start();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
live_abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
live_run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -417,13 +472,39 @@ READ8_MEMBER( victor_9000_fdc_t::tach1_r )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void victor_9000_fdc_t::update_stepper_motor(floppy_image_device *floppy, int stp, int old_st, int st)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void victor_9000_fdc_t::update_spindle_motor()
|
||||||
|
{
|
||||||
|
if (m_sel0) m_da0 = m_da;
|
||||||
|
m_floppy0->mon_w(m_mtr0);
|
||||||
|
m_floppy0->set_rpm(300); // TODO
|
||||||
|
t_tach0->adjust(attotime::never); // TODO
|
||||||
|
|
||||||
|
if (m_sel1) m_da1 = m_da;
|
||||||
|
m_floppy1->mon_w(m_mtr1);
|
||||||
|
m_floppy1->set_rpm(300); // TODO
|
||||||
|
t_tach1->adjust(attotime::never); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// da_w -
|
// da_w -
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
WRITE8_MEMBER( victor_9000_fdc_t::da_w )
|
WRITE8_MEMBER( victor_9000_fdc_t::da_w )
|
||||||
{
|
{
|
||||||
m_da = data;
|
if (m_da != data)
|
||||||
|
{
|
||||||
|
live_sync();
|
||||||
|
m_da = data;
|
||||||
|
update_spindle_motor();
|
||||||
|
checkpoint();
|
||||||
|
live_run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE8_MEMBER( victor_9000_fdc_t::via4_pa_w )
|
WRITE8_MEMBER( victor_9000_fdc_t::via4_pa_w )
|
||||||
@ -443,8 +524,18 @@ WRITE8_MEMBER( victor_9000_fdc_t::via4_pa_w )
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
m_lms = (m_lms & 0xf0) | (data & 0x0f);
|
m_l0ms = data & 0x0f;
|
||||||
m_st0 = data >> 4;
|
|
||||||
|
UINT8 st0 = data >> 4;
|
||||||
|
|
||||||
|
if (m_st0 != st0)
|
||||||
|
{
|
||||||
|
live_sync();
|
||||||
|
update_stepper_motor(m_floppy0, m_stp0, st0, m_st0);
|
||||||
|
m_st0 = st0;
|
||||||
|
checkpoint();
|
||||||
|
live_run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE8_MEMBER( victor_9000_fdc_t::via4_pb_w )
|
WRITE8_MEMBER( victor_9000_fdc_t::via4_pb_w )
|
||||||
@ -464,12 +555,30 @@ WRITE8_MEMBER( victor_9000_fdc_t::via4_pb_w )
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
m_lms = (data << 4) | (m_lms & 0x0f);
|
m_l1ms = data & 0x0f;
|
||||||
m_st1 = data >> 4;
|
|
||||||
|
UINT8 st1 = data >> 4;
|
||||||
|
|
||||||
|
if (m_st1 != st1)
|
||||||
|
{
|
||||||
|
live_sync();
|
||||||
|
update_stepper_motor(m_floppy1, m_stp1, st1, m_st1);
|
||||||
|
m_st1 = st1;
|
||||||
|
checkpoint();
|
||||||
|
live_run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE_LINE_MEMBER( victor_9000_fdc_t::mode_w )
|
WRITE_LINE_MEMBER( victor_9000_fdc_t::wrsync_w )
|
||||||
{
|
{
|
||||||
|
if (m_wrsync != state)
|
||||||
|
{
|
||||||
|
live_sync();
|
||||||
|
m_wrsync = state;
|
||||||
|
cur_live.wrsync = state;
|
||||||
|
checkpoint();
|
||||||
|
live_run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE_LINE_MEMBER( victor_9000_fdc_t::via4_irq_w )
|
WRITE_LINE_MEMBER( victor_9000_fdc_t::via4_irq_w )
|
||||||
@ -479,7 +588,6 @@ WRITE_LINE_MEMBER( victor_9000_fdc_t::via4_irq_w )
|
|||||||
m_irq_cb(m_via4_irq || m_via5_irq || m_via6_irq);
|
m_irq_cb(m_via4_irq || m_via5_irq || m_via6_irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
READ8_MEMBER( victor_9000_fdc_t::via5_pa_r )
|
READ8_MEMBER( victor_9000_fdc_t::via5_pa_r )
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -497,7 +605,10 @@ READ8_MEMBER( victor_9000_fdc_t::via5_pa_r )
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return 0;
|
UINT8 e = checkpoint_live.e;
|
||||||
|
UINT8 i = checkpoint_live.i;
|
||||||
|
|
||||||
|
return BIT(e, 6) << 7 | BIT(i, 7) << 6 | BIT(e, 5) << 5 | BIT(e, 4) << 4 | BIT(e, 2) << 3 | BIT(i, 1) << 2 | (e & 0x03);
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE8_MEMBER( victor_9000_fdc_t::via5_pb_w )
|
WRITE8_MEMBER( victor_9000_fdc_t::via5_pb_w )
|
||||||
@ -516,6 +627,15 @@ WRITE8_MEMBER( victor_9000_fdc_t::via5_pb_w )
|
|||||||
PB7 WD7
|
PB7 WD7
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (m_wd != data)
|
||||||
|
{
|
||||||
|
live_sync();
|
||||||
|
m_wd = data;
|
||||||
|
cur_live.wd = data;
|
||||||
|
checkpoint();
|
||||||
|
live_run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE_LINE_MEMBER( victor_9000_fdc_t::via5_irq_w )
|
WRITE_LINE_MEMBER( victor_9000_fdc_t::via5_irq_w )
|
||||||
@ -555,7 +675,7 @@ READ8_MEMBER( victor_9000_fdc_t::via6_pa_r )
|
|||||||
data |= (m_drive ? m_floppy1->wpt_r() : m_floppy0->wpt_r()) << 6;
|
data |= (m_drive ? m_floppy1->wpt_r() : m_floppy0->wpt_r()) << 6;
|
||||||
|
|
||||||
// disk sync detect
|
// disk sync detect
|
||||||
data |= m_sync << 7;
|
data |= checkpoint_live.sync << 7;
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
@ -583,11 +703,31 @@ WRITE8_MEMBER( victor_9000_fdc_t::via6_pa_w )
|
|||||||
// LED, drive B
|
// LED, drive B
|
||||||
output_set_led_value(LED_B, BIT(data, 2));
|
output_set_led_value(LED_B, BIT(data, 2));
|
||||||
|
|
||||||
|
bool sync = false;
|
||||||
|
|
||||||
// dual side select
|
// dual side select
|
||||||
m_side = BIT(data, 4);
|
int side = BIT(data, 4);
|
||||||
|
if (m_side != side) sync = true;
|
||||||
|
|
||||||
// select drive A/B
|
// select drive A/B
|
||||||
m_drive = BIT(data, 5);
|
int drive = BIT(data, 5);
|
||||||
|
if (m_drive != drive) sync = true;
|
||||||
|
|
||||||
|
if (sync)
|
||||||
|
{
|
||||||
|
live_sync();
|
||||||
|
|
||||||
|
m_side = side;
|
||||||
|
cur_live.side = side;
|
||||||
|
m_floppy0->ss_w(side);
|
||||||
|
m_floppy1->ss_w(side);
|
||||||
|
|
||||||
|
m_drive = drive;
|
||||||
|
cur_live.drive = drive;
|
||||||
|
|
||||||
|
checkpoint();
|
||||||
|
live_run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
READ8_MEMBER( victor_9000_fdc_t::via6_pb_r )
|
READ8_MEMBER( victor_9000_fdc_t::via6_pb_r )
|
||||||
@ -648,19 +788,58 @@ WRITE8_MEMBER( victor_9000_fdc_t::via6_pb_w )
|
|||||||
if (!BIT(data, 2))
|
if (!BIT(data, 2))
|
||||||
m_maincpu->reset();
|
m_maincpu->reset();
|
||||||
|
|
||||||
|
bool sync = false;
|
||||||
|
|
||||||
// stepper enable A
|
// stepper enable A
|
||||||
m_stp0 = BIT(data, 6);
|
int stp0 = BIT(data, 6);
|
||||||
|
if (m_stp0 != stp0) sync = true;
|
||||||
|
|
||||||
// stepper enable B
|
// stepper enable B
|
||||||
m_stp1 = BIT(data, 7);
|
int stp1 = BIT(data, 7);
|
||||||
|
if (m_stp1 != stp1) sync = true;
|
||||||
|
|
||||||
|
if (sync)
|
||||||
|
{
|
||||||
|
live_sync();
|
||||||
|
|
||||||
|
m_stp0 = stp0;
|
||||||
|
update_stepper_motor(m_floppy0, m_stp0, m_st0, m_st0);
|
||||||
|
|
||||||
|
m_stp1 = stp1;
|
||||||
|
update_stepper_motor(m_floppy1, m_stp1, m_st1, m_st1);
|
||||||
|
|
||||||
|
checkpoint();
|
||||||
|
live_run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE_LINE_MEMBER( victor_9000_fdc_t::drw_w )
|
WRITE_LINE_MEMBER( victor_9000_fdc_t::drw_w )
|
||||||
{
|
{
|
||||||
|
if (m_drw != state)
|
||||||
|
{
|
||||||
|
live_sync();
|
||||||
|
m_drw = cur_live.drw = state;
|
||||||
|
checkpoint();
|
||||||
|
if (LOG) logerror("%s DRW %u\n", machine().time().as_string(), state);
|
||||||
|
if (state) {
|
||||||
|
stop_writing(machine().time());
|
||||||
|
} else {
|
||||||
|
start_writing(machine().time());
|
||||||
|
}
|
||||||
|
live_run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE_LINE_MEMBER( victor_9000_fdc_t::erase_w )
|
WRITE_LINE_MEMBER( victor_9000_fdc_t::erase_w )
|
||||||
{
|
{
|
||||||
|
if (m_erase != state)
|
||||||
|
{
|
||||||
|
live_sync();
|
||||||
|
m_erase = cur_live.erase = state;
|
||||||
|
checkpoint();
|
||||||
|
if (LOG) logerror("%s ERASE %u\n", machine().time().as_string(), state);
|
||||||
|
live_run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE_LINE_MEMBER( victor_9000_fdc_t::via6_irq_w )
|
WRITE_LINE_MEMBER( victor_9000_fdc_t::via6_irq_w )
|
||||||
@ -669,3 +848,270 @@ WRITE_LINE_MEMBER( victor_9000_fdc_t::via6_irq_w )
|
|||||||
|
|
||||||
m_irq_cb(m_via4_irq || m_via5_irq || m_via6_irq);
|
m_irq_cb(m_via4_irq || m_via5_irq || m_via6_irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
READ8_MEMBER( victor_9000_fdc_t::cs7_r )
|
||||||
|
{
|
||||||
|
if (!checkpoint_live.lbrdy)
|
||||||
|
{
|
||||||
|
live_sync();
|
||||||
|
cur_live.lbrdy = 1;
|
||||||
|
m_lbrdy_cb(1);
|
||||||
|
checkpoint();
|
||||||
|
live_run();
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_via5->read(space, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE8_MEMBER( victor_9000_fdc_t::cs7_w )
|
||||||
|
{
|
||||||
|
if (!checkpoint_live.lbrdy)
|
||||||
|
{
|
||||||
|
live_sync();
|
||||||
|
cur_live.lbrdy = 1;
|
||||||
|
m_lbrdy_cb(1);
|
||||||
|
checkpoint();
|
||||||
|
live_run();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_via5->write(space, offset, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
floppy_image_device* victor_9000_fdc_t::get_floppy()
|
||||||
|
{
|
||||||
|
return m_drive ? m_floppy1 : m_floppy0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void victor_9000_fdc_t::live_start()
|
||||||
|
{
|
||||||
|
cur_live.tm = machine().time();
|
||||||
|
cur_live.state = RUNNING;
|
||||||
|
cur_live.next_state = -1;
|
||||||
|
|
||||||
|
cur_live.shift_reg = 0;
|
||||||
|
cur_live.shift_reg_write = 0;
|
||||||
|
cur_live.bit_counter = 0;
|
||||||
|
|
||||||
|
cur_live.drive = m_drive;
|
||||||
|
cur_live.side = m_side;
|
||||||
|
cur_live.drw = m_drw;
|
||||||
|
cur_live.wd = m_wd;
|
||||||
|
cur_live.wrsync = m_wrsync;
|
||||||
|
cur_live.erase = m_erase;
|
||||||
|
|
||||||
|
checkpoint_live = cur_live;
|
||||||
|
|
||||||
|
live_run();
|
||||||
|
}
|
||||||
|
|
||||||
|
void victor_9000_fdc_t::checkpoint()
|
||||||
|
{
|
||||||
|
get_next_edge(machine().time());
|
||||||
|
checkpoint_live = cur_live;
|
||||||
|
}
|
||||||
|
|
||||||
|
void victor_9000_fdc_t::rollback()
|
||||||
|
{
|
||||||
|
cur_live = checkpoint_live;
|
||||||
|
get_next_edge(cur_live.tm);
|
||||||
|
}
|
||||||
|
|
||||||
|
void victor_9000_fdc_t::start_writing(const attotime &tm)
|
||||||
|
{
|
||||||
|
cur_live.write_start_time = tm;
|
||||||
|
cur_live.write_position = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void victor_9000_fdc_t::stop_writing(const attotime &tm)
|
||||||
|
{
|
||||||
|
commit(tm);
|
||||||
|
cur_live.write_start_time = attotime::never;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool victor_9000_fdc_t::write_next_bit(bool bit, const attotime &limit)
|
||||||
|
{
|
||||||
|
if(cur_live.write_start_time.is_never()) {
|
||||||
|
cur_live.write_start_time = cur_live.tm;
|
||||||
|
cur_live.write_position = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
attotime etime = cur_live.tm + m_period;
|
||||||
|
if(etime > limit)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if(bit && cur_live.write_position < ARRAY_LENGTH(cur_live.write_buffer))
|
||||||
|
cur_live.write_buffer[cur_live.write_position++] = cur_live.tm;
|
||||||
|
|
||||||
|
if (LOG) logerror("%s write bit %u (%u)\n", cur_live.tm.as_string(), cur_live.bit_counter, bit);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void victor_9000_fdc_t::commit(const attotime &tm)
|
||||||
|
{
|
||||||
|
if(cur_live.write_start_time.is_never() || tm == cur_live.write_start_time || !cur_live.write_position)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (LOG) logerror("%s committing %u transitions since %s\n", tm.as_string(), cur_live.write_position, cur_live.write_start_time.as_string());
|
||||||
|
|
||||||
|
if(get_floppy())
|
||||||
|
get_floppy()->write_flux(cur_live.write_start_time, tm, cur_live.write_position, cur_live.write_buffer);
|
||||||
|
|
||||||
|
cur_live.write_start_time = tm;
|
||||||
|
cur_live.write_position = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void victor_9000_fdc_t::live_delay(int state)
|
||||||
|
{
|
||||||
|
cur_live.next_state = state;
|
||||||
|
if(cur_live.tm != machine().time())
|
||||||
|
t_gen->adjust(cur_live.tm - machine().time());
|
||||||
|
else
|
||||||
|
live_sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void victor_9000_fdc_t::live_sync()
|
||||||
|
{
|
||||||
|
if(!cur_live.tm.is_never()) {
|
||||||
|
if(cur_live.tm > machine().time()) {
|
||||||
|
rollback();
|
||||||
|
live_run(machine().time());
|
||||||
|
commit(cur_live.tm);
|
||||||
|
} else {
|
||||||
|
commit(cur_live.tm);
|
||||||
|
if(cur_live.next_state != -1) {
|
||||||
|
cur_live.state = cur_live.next_state;
|
||||||
|
cur_live.next_state = -1;
|
||||||
|
}
|
||||||
|
if(cur_live.state == IDLE) {
|
||||||
|
stop_writing(cur_live.tm);
|
||||||
|
cur_live.tm = attotime::never;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cur_live.next_state = -1;
|
||||||
|
checkpoint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void victor_9000_fdc_t::live_abort()
|
||||||
|
{
|
||||||
|
if(!cur_live.tm.is_never() && cur_live.tm > machine().time()) {
|
||||||
|
rollback();
|
||||||
|
live_run(machine().time());
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_writing(cur_live.tm);
|
||||||
|
|
||||||
|
cur_live.tm = attotime::never;
|
||||||
|
cur_live.state = IDLE;
|
||||||
|
cur_live.next_state = -1;
|
||||||
|
cur_live.write_position = 0;
|
||||||
|
cur_live.write_start_time = attotime::never;
|
||||||
|
|
||||||
|
cur_live.brdy = 1;
|
||||||
|
cur_live.lbrdy = 1;
|
||||||
|
cur_live.sync = 1;
|
||||||
|
cur_live.gcr_err = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void victor_9000_fdc_t::live_run(const attotime &limit)
|
||||||
|
{
|
||||||
|
if(cur_live.state == IDLE || cur_live.next_state != -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
switch(cur_live.state) {
|
||||||
|
case RUNNING: {
|
||||||
|
bool syncpoint = false;
|
||||||
|
|
||||||
|
if (cur_live.tm > limit)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// read bit
|
||||||
|
int bit = get_next_bit(cur_live.tm, limit);
|
||||||
|
if(bit < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cur_live.shift_reg <<= 1;
|
||||||
|
cur_live.shift_reg |= bit;
|
||||||
|
cur_live.shift_reg &= 0x3ff;
|
||||||
|
|
||||||
|
// sync
|
||||||
|
int sync = !(cur_live.shift_reg == 0x3ff);
|
||||||
|
|
||||||
|
// bit counter
|
||||||
|
if (!sync) {
|
||||||
|
cur_live.bit_counter = 0;
|
||||||
|
} else if (cur_live.sync) {
|
||||||
|
cur_live.bit_counter++;
|
||||||
|
if (cur_live.bit_counter == 10) {
|
||||||
|
cur_live.bit_counter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GCR decoder
|
||||||
|
if (cur_live.drw) {
|
||||||
|
cur_live.i = cur_live.drw << 10 | cur_live.shift_reg;
|
||||||
|
} else {
|
||||||
|
cur_live.i = 0x300 | ((cur_live.wd & 0xf0) << 1) | cur_live.wrsync << 4 | (cur_live.wd & 0x0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_live.e = m_gcr_rom->base()[cur_live.i];
|
||||||
|
|
||||||
|
// byte ready
|
||||||
|
int brdy = cur_live.bit_counter == 9;
|
||||||
|
|
||||||
|
// GCR error
|
||||||
|
int gcr_err = !(brdy || BIT(cur_live.e, 3));
|
||||||
|
|
||||||
|
if (brdy != cur_live.brdy) {
|
||||||
|
if (LOG) logerror("%s BRDY %u\n", cur_live.tm.as_string(),brdy);
|
||||||
|
cur_live.brdy = brdy;
|
||||||
|
if (!brdy) cur_live.lbrdy = 0;
|
||||||
|
syncpoint = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sync != cur_live.sync) {
|
||||||
|
if (LOG) logerror("%s SYNC %u\n", cur_live.tm.as_string(),sync);
|
||||||
|
cur_live.sync = sync;
|
||||||
|
syncpoint = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gcr_err != cur_live.gcr_err) {
|
||||||
|
if (LOG) logerror("%s GCR ERR %u\n", cur_live.tm.as_string(),gcr_err);
|
||||||
|
cur_live.gcr_err = gcr_err;
|
||||||
|
syncpoint = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (syncpoint) {
|
||||||
|
commit(cur_live.tm);
|
||||||
|
|
||||||
|
cur_live.tm += m_period;
|
||||||
|
live_delay(RUNNING_SYNCPOINT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_live.tm += m_period;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case RUNNING_SYNCPOINT: {
|
||||||
|
m_lbrdy_cb(cur_live.lbrdy);
|
||||||
|
|
||||||
|
cur_live.state = RUNNING;
|
||||||
|
checkpoint();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void victor_9000_fdc_t::get_next_edge(const attotime &when)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
int victor_9000_fdc_t::get_next_bit(attotime &tm, const attotime &limit)
|
||||||
|
{
|
||||||
|
return -1; // TODO
|
||||||
|
}
|
||||||
|
@ -29,6 +29,12 @@
|
|||||||
#define MCFG_VICTOR_9000_FDC_IRQ_CB(_write) \
|
#define MCFG_VICTOR_9000_FDC_IRQ_CB(_write) \
|
||||||
devcb = &victor_9000_fdc_t::set_irq_wr_callback(*device, DEVCB_##_write);
|
devcb = &victor_9000_fdc_t::set_irq_wr_callback(*device, DEVCB_##_write);
|
||||||
|
|
||||||
|
#define MCFG_VICTOR_9000_FDC_SYN_CB(_write) \
|
||||||
|
devcb = &victor_9000_fdc_t::set_syn_wr_callback(*device, DEVCB_##_write);
|
||||||
|
|
||||||
|
#define MCFG_VICTOR_9000_FDC_LBRDY_CB(_write) \
|
||||||
|
devcb = &victor_9000_fdc_t::set_lbrdy_wr_callback(*device, DEVCB_##_write);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
@ -44,13 +50,15 @@ public:
|
|||||||
victor_9000_fdc_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
victor_9000_fdc_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
template<class _Object> static devcb_base &set_irq_wr_callback(device_t &device, _Object object) { return downcast<victor_9000_fdc_t &>(device).m_irq_cb.set_callback(object); }
|
template<class _Object> static devcb_base &set_irq_wr_callback(device_t &device, _Object object) { return downcast<victor_9000_fdc_t &>(device).m_irq_cb.set_callback(object); }
|
||||||
|
template<class _Object> static devcb_base &set_syn_wr_callback(device_t &device, _Object object) { return downcast<victor_9000_fdc_t &>(device).m_syn_cb.set_callback(object); }
|
||||||
|
template<class _Object> static devcb_base &set_lbrdy_wr_callback(device_t &device, _Object object) { return downcast<victor_9000_fdc_t &>(device).m_lbrdy_cb.set_callback(object); }
|
||||||
|
|
||||||
DECLARE_READ8_MEMBER( cs5_r ) { return m_via4->read(space, offset); }
|
DECLARE_READ8_MEMBER( cs5_r ) { return m_via4->read(space, offset); }
|
||||||
DECLARE_WRITE8_MEMBER( cs5_w ) { return m_via4->write(space, offset, data); }
|
DECLARE_WRITE8_MEMBER( cs5_w ) { m_via4->write(space, offset, data); }
|
||||||
DECLARE_READ8_MEMBER( cs6_r ) { return m_via6->read(space, offset); }
|
DECLARE_READ8_MEMBER( cs6_r ) { return m_via6->read(space, offset); }
|
||||||
DECLARE_WRITE8_MEMBER( cs6_w ) { return m_via6->write(space, offset, data); }
|
DECLARE_WRITE8_MEMBER( cs6_w ) { m_via6->write(space, offset, data); }
|
||||||
DECLARE_READ8_MEMBER( cs7_r ) { return m_via5->read(space, offset); }
|
DECLARE_READ8_MEMBER( cs7_r );
|
||||||
DECLARE_WRITE8_MEMBER( cs7_w ) { return m_via5->write(space, offset, data); }
|
DECLARE_WRITE8_MEMBER( cs7_w );
|
||||||
|
|
||||||
DECLARE_FLOPPY_FORMATS( floppy_formats );
|
DECLARE_FLOPPY_FORMATS( floppy_formats );
|
||||||
|
|
||||||
@ -63,7 +71,7 @@ public:
|
|||||||
|
|
||||||
DECLARE_WRITE8_MEMBER( via4_pa_w );
|
DECLARE_WRITE8_MEMBER( via4_pa_w );
|
||||||
DECLARE_WRITE8_MEMBER( via4_pb_w );
|
DECLARE_WRITE8_MEMBER( via4_pb_w );
|
||||||
DECLARE_WRITE_LINE_MEMBER( mode_w );
|
DECLARE_WRITE_LINE_MEMBER( wrsync_w );
|
||||||
DECLARE_WRITE_LINE_MEMBER( via4_irq_w );
|
DECLARE_WRITE_LINE_MEMBER( via4_irq_w );
|
||||||
|
|
||||||
DECLARE_READ8_MEMBER( via5_pa_r );
|
DECLARE_READ8_MEMBER( via5_pa_r );
|
||||||
@ -89,13 +97,61 @@ protected:
|
|||||||
virtual machine_config_constructor device_mconfig_additions() const;
|
virtual machine_config_constructor device_mconfig_additions() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TM_GEN,
|
||||||
|
TM_TACH0,
|
||||||
|
TM_TACH1
|
||||||
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
LED_A = 0,
|
LED_A = 0,
|
||||||
LED_B
|
LED_B
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
IDLE,
|
||||||
|
RUNNING,
|
||||||
|
RUNNING_SYNCPOINT
|
||||||
|
};
|
||||||
|
|
||||||
|
struct live_info {
|
||||||
|
attotime tm;
|
||||||
|
int state, next_state;
|
||||||
|
|
||||||
|
int drive;
|
||||||
|
int side;
|
||||||
|
int drw;
|
||||||
|
|
||||||
|
// common
|
||||||
|
offs_t i;
|
||||||
|
UINT8 e;
|
||||||
|
|
||||||
|
// read
|
||||||
|
attotime edge;
|
||||||
|
UINT16 shift_reg;
|
||||||
|
int bit_counter;
|
||||||
|
int brdy;
|
||||||
|
int lbrdy;
|
||||||
|
int sync;
|
||||||
|
int gcr_err;
|
||||||
|
|
||||||
|
// write
|
||||||
|
UINT16 shift_reg_write;
|
||||||
|
attotime write_start_time;
|
||||||
|
attotime write_buffer[32];
|
||||||
|
int write_position;
|
||||||
|
UINT8 wd;
|
||||||
|
int wrsync;
|
||||||
|
int syn;
|
||||||
|
int gcr_data;
|
||||||
|
int erase;
|
||||||
|
};
|
||||||
|
|
||||||
devcb_write_line m_irq_cb;
|
devcb_write_line m_irq_cb;
|
||||||
|
devcb_write_line m_syn_cb;
|
||||||
|
devcb_write_line m_lbrdy_cb;
|
||||||
|
|
||||||
required_device<cpu_device> m_maincpu;
|
required_device<cpu_device> m_maincpu;
|
||||||
required_device<via6522_device> m_via4;
|
required_device<via6522_device> m_via4;
|
||||||
@ -105,6 +161,9 @@ private:
|
|||||||
required_device<floppy_image_device> m_floppy1;
|
required_device<floppy_image_device> m_floppy1;
|
||||||
required_memory_region m_gcr_rom;
|
required_memory_region m_gcr_rom;
|
||||||
|
|
||||||
|
void update_stepper_motor(floppy_image_device *floppy, int stp, int old_st, int st);
|
||||||
|
void update_spindle_motor();
|
||||||
|
|
||||||
void ready0_cb(floppy_image_device *, int device);
|
void ready0_cb(floppy_image_device *, int device);
|
||||||
int load0_cb(floppy_image_device *device);
|
int load0_cb(floppy_image_device *device);
|
||||||
void unload0_cb(floppy_image_device *device);
|
void unload0_cb(floppy_image_device *device);
|
||||||
@ -116,6 +175,8 @@ private:
|
|||||||
UINT8 m_da;
|
UINT8 m_da;
|
||||||
UINT8 m_da0;
|
UINT8 m_da0;
|
||||||
UINT8 m_da1;
|
UINT8 m_da1;
|
||||||
|
int m_mtr0;
|
||||||
|
int m_mtr1;
|
||||||
int m_sel0;
|
int m_sel0;
|
||||||
int m_sel1;
|
int m_sel1;
|
||||||
int m_tach0;
|
int m_tach0;
|
||||||
@ -124,20 +185,44 @@ private:
|
|||||||
int m_rdy1;
|
int m_rdy1;
|
||||||
int m_ds0;
|
int m_ds0;
|
||||||
int m_ds1;
|
int m_ds1;
|
||||||
UINT8 m_lms; /* motor speed */
|
UINT8 m_l0ms;
|
||||||
int m_st0; /* stepper phase */
|
UINT8 m_l1ms;
|
||||||
int m_st1; /* stepper phase */
|
int m_st0;
|
||||||
int m_stp0; /* stepper enable */
|
int m_st1;
|
||||||
int m_stp1; /* stepper enable */
|
int m_stp0;
|
||||||
int m_drive; /* selected drive */
|
int m_stp1;
|
||||||
int m_side; /* selected side */
|
int m_drive;
|
||||||
int m_brdy;
|
int m_side;
|
||||||
int m_sync;
|
int m_drw;
|
||||||
int m_gcrerr;
|
int m_erase;
|
||||||
|
UINT8 m_wd;
|
||||||
|
int m_wrsync;
|
||||||
|
|
||||||
int m_via4_irq;
|
int m_via4_irq;
|
||||||
int m_via5_irq;
|
int m_via5_irq;
|
||||||
int m_via6_irq;
|
int m_via6_irq;
|
||||||
|
int m_syn;
|
||||||
|
int m_lbrdy;
|
||||||
|
|
||||||
|
attotime m_period;
|
||||||
|
|
||||||
|
live_info cur_live, checkpoint_live;
|
||||||
|
emu_timer *t_gen, *t_tach0, *t_tach1;
|
||||||
|
|
||||||
|
floppy_image_device* get_floppy();
|
||||||
|
void live_start();
|
||||||
|
void checkpoint();
|
||||||
|
void rollback();
|
||||||
|
bool write_next_bit(bool bit, const attotime &limit);
|
||||||
|
void start_writing(const attotime &tm);
|
||||||
|
void commit(const attotime &tm);
|
||||||
|
void stop_writing(const attotime &tm);
|
||||||
|
void live_delay(int state);
|
||||||
|
void live_sync();
|
||||||
|
void live_abort();
|
||||||
|
void live_run(const attotime &limit = attotime::never);
|
||||||
|
void get_next_edge(const attotime &when);
|
||||||
|
int get_next_bit(attotime &tm, const attotime &limit);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user