From 48edf48e1ae8787b8ec7dce969ec40b4b1eb05b6 Mon Sep 17 00:00:00 2001 From: Curt Coder Date: Mon, 3 Nov 2014 14:54:00 +0200 Subject: [PATCH] (MESS) victor9k: Floppy WIP. (nw) --- src/mess/machine/victor9k_fdc.c | 530 +++++++++++++++++++++++++++++--- src/mess/machine/victor9k_fdc.h | 115 ++++++- 2 files changed, 588 insertions(+), 57 deletions(-) diff --git a/src/mess/machine/victor9k_fdc.c b/src/mess/machine/victor9k_fdc.c index 9f920357918..be26841fb37 100644 --- a/src/mess/machine/victor9k_fdc.c +++ b/src/mess/machine/victor9k_fdc.c @@ -13,7 +13,12 @@ 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_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_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_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) : device_t(mconfig, VICTOR_9000_FDC, "Victor 9000 FDC", tag, owner, clock, "victor9k_fdc", __FILE__), m_irq_cb(*this), + m_syn_cb(*this), + m_lbrdy_cb(*this), m_maincpu(*this, I8048_TAG), m_via4(*this, M6522_4_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_ds0(1), m_ds1(1), - m_lms(0), + m_l0ms(0), + m_l1ms(0), m_st0(0), m_st1(0), m_stp0(0), m_stp1(0), m_drive(0), m_side(0), - m_brdy(1), - m_sync(1), - m_gcrerr(0), m_via4_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() { + // allocate timer + t_gen = timer_alloc(TM_GEN); + t_tach0 = timer_alloc(TM_TACH0); + t_tach1 = timer_alloc(TM_TACH1); + // state saving save_item(NAME(m_da)); 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_ds0)); 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_st1)); save_item(NAME(m_stp0)); save_item(NAME(m_stp1)); save_item(NAME(m_drive)); save_item(NAME(m_side)); - save_item(NAME(m_brdy)); - save_item(NAME(m_sync)); - save_item(NAME(m_gcrerr)); + save_item(NAME(m_drw)); + save_item(NAME(m_erase)); save_item(NAME(m_via4_irq)); save_item(NAME(m_via5_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() { + live_abort(); + // resolve callbacks m_irq_cb.resolve_safe(); + m_syn_cb.resolve_safe(); + m_lbrdy_cb.resolve_safe(); // reset devices 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) { + 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); - if (BIT(data, 1)) m_floppy0->mon_w(1); - if (BIT(data, 2)) m_floppy1->mon_w(0); - if (BIT(data, 3)) m_floppy1->mon_w(1); + bool sync = false; + + int mtr0 = m_mtr0; + 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); - - if (m_sel0 && !sel0) - { - m_da0 = m_da; - //m_floppy0->set_rpm(); - } - - m_sel0 = sel0; + if (m_sel0 != sel0) sync = true; int sel1 = BIT(data, 4); + if (m_sel1 != sel1) sync = true; - if (m_sel1 && !sel1) + if (sync) { - m_da1 = m_da; - //m_floppy1->set_rpm(); - } + live_sync(); - 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 - //------------------------------------------------- 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 ) @@ -443,8 +524,18 @@ WRITE8_MEMBER( victor_9000_fdc_t::via4_pa_w ) */ - m_lms = (m_lms & 0xf0) | (data & 0x0f); - m_st0 = data >> 4; + m_l0ms = data & 0x0f; + + 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 ) @@ -464,12 +555,30 @@ WRITE8_MEMBER( victor_9000_fdc_t::via4_pb_w ) */ - m_lms = (data << 4) | (m_lms & 0x0f); - m_st1 = data >> 4; + m_l1ms = data & 0x0f; + + 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 ) @@ -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); } - 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 ) @@ -516,6 +627,15 @@ WRITE8_MEMBER( victor_9000_fdc_t::via5_pb_w ) 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 ) @@ -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; // disk sync detect - data |= m_sync << 7; + data |= checkpoint_live.sync << 7; return data; } @@ -583,11 +703,31 @@ WRITE8_MEMBER( victor_9000_fdc_t::via6_pa_w ) // LED, drive B output_set_led_value(LED_B, BIT(data, 2)); + bool sync = false; + // dual side select - m_side = BIT(data, 4); + int side = BIT(data, 4); + if (m_side != side) sync = true; // 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 ) @@ -648,19 +788,58 @@ WRITE8_MEMBER( victor_9000_fdc_t::via6_pb_w ) if (!BIT(data, 2)) m_maincpu->reset(); + bool sync = false; + // stepper enable A - m_stp0 = BIT(data, 6); + int stp0 = BIT(data, 6); + if (m_stp0 != stp0) sync = true; // 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 ) { + 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 ) { + 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 ) @@ -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); } + +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 +} diff --git a/src/mess/machine/victor9k_fdc.h b/src/mess/machine/victor9k_fdc.h index 956f49f4b69..1918b30534b 100644 --- a/src/mess/machine/victor9k_fdc.h +++ b/src/mess/machine/victor9k_fdc.h @@ -29,6 +29,12 @@ #define MCFG_VICTOR_9000_FDC_IRQ_CB(_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); template static devcb_base &set_irq_wr_callback(device_t &device, _Object object) { return downcast(device).m_irq_cb.set_callback(object); } + template static devcb_base &set_syn_wr_callback(device_t &device, _Object object) { return downcast(device).m_syn_cb.set_callback(object); } + template static devcb_base &set_lbrdy_wr_callback(device_t &device, _Object object) { return downcast(device).m_lbrdy_cb.set_callback(object); } 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_WRITE8_MEMBER( cs6_w ) { return m_via6->write(space, offset, data); } - DECLARE_READ8_MEMBER( cs7_r ) { return m_via5->read(space, offset); } - DECLARE_WRITE8_MEMBER( cs7_w ) { return m_via5->write(space, offset, data); } + DECLARE_WRITE8_MEMBER( cs6_w ) { m_via6->write(space, offset, data); } + DECLARE_READ8_MEMBER( cs7_r ); + DECLARE_WRITE8_MEMBER( cs7_w ); DECLARE_FLOPPY_FORMATS( floppy_formats ); @@ -63,7 +71,7 @@ public: DECLARE_WRITE8_MEMBER( via4_pa_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_READ8_MEMBER( via5_pa_r ); @@ -89,13 +97,61 @@ protected: virtual machine_config_constructor device_mconfig_additions() const; private: + enum + { + TM_GEN, + TM_TACH0, + TM_TACH1 + }; + enum { LED_A = 0, 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_syn_cb; + devcb_write_line m_lbrdy_cb; required_device m_maincpu; required_device m_via4; @@ -105,6 +161,9 @@ private: required_device m_floppy1; 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); int load0_cb(floppy_image_device *device); void unload0_cb(floppy_image_device *device); @@ -116,6 +175,8 @@ private: UINT8 m_da; UINT8 m_da0; UINT8 m_da1; + int m_mtr0; + int m_mtr1; int m_sel0; int m_sel1; int m_tach0; @@ -124,20 +185,44 @@ private: int m_rdy1; int m_ds0; int m_ds1; - UINT8 m_lms; /* motor speed */ - int m_st0; /* stepper phase */ - int m_st1; /* stepper phase */ - int m_stp0; /* stepper enable */ - int m_stp1; /* stepper enable */ - int m_drive; /* selected drive */ - int m_side; /* selected side */ - int m_brdy; - int m_sync; - int m_gcrerr; + UINT8 m_l0ms; + UINT8 m_l1ms; + int m_st0; + int m_st1; + int m_stp0; + int m_stp1; + int m_drive; + int m_side; + int m_drw; + int m_erase; + UINT8 m_wd; + int m_wrsync; int m_via4_irq; int m_via5_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); };