From 19bbe2ac4dbe3fe5801bb262d685220121f3c408 Mon Sep 17 00:00:00 2001 From: Curt Coder Date: Thu, 16 Apr 2015 00:16:05 +0300 Subject: [PATCH] (MESS) pet: Implemented write mode on the Commodore 8050/8250/SFD-1001 floppy drives. [Curt Coder] (MESS) victor9k: Separated read/write modes in the floppy controller. (nw) fdc_pll: Removed write_next_bit_prev_cell hack. (nw) --- src/emu/bus/ieee488/c8050fdc.c | 104 ++++++++++++++++++-------------- src/emu/bus/ieee488/c8050fdc.h | 2 +- src/emu/machine/fdc_pll.c | 19 ------ src/emu/machine/fdc_pll.h | 2 - src/mess/machine/victor9k_fdc.c | 40 ++++++++---- src/mess/machine/victor9k_fdc.h | 2 +- 6 files changed, 88 insertions(+), 81 deletions(-) diff --git a/src/emu/bus/ieee488/c8050fdc.c b/src/emu/bus/ieee488/c8050fdc.c index 986d6de9126..cb0a077548f 100644 --- a/src/emu/bus/ieee488/c8050fdc.c +++ b/src/emu/bus/ieee488/c8050fdc.c @@ -13,9 +13,7 @@ TODO: - - write mode - write protect - - separate read/write methods */ @@ -28,6 +26,8 @@ //************************************************************************** #define LOG 0 +#define LOG_MORE 0 +#define LOG_BITS 0 #define GCR_DECODE(_e, _i) \ ((BIT(_e, 6) << 7) | (BIT(_i, 7) << 6) | (_e & 0x33) | (BIT(_e, 2) << 3) | (_i & 0x04)) @@ -74,7 +74,7 @@ const rom_entry *c8050_fdc_t::device_rom_region() const //------------------------------------------------- c8050_fdc_t::c8050_fdc_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : - device_t(mconfig, C8050_FDC, "C8050 FDC", tag, owner, clock, "c8050fdc", __FILE__), + device_t(mconfig, C8050_FDC, "Commodore 8050 FDC", tag, owner, clock, "c8050fdc", __FILE__), m_write_sync(*this), m_write_ready(*this), m_write_brdy(*this), @@ -89,7 +89,7 @@ c8050_fdc_t::c8050_fdc_t(const machine_config &mconfig, const char *tag, device_ m_ds(0), m_drv_sel(0), m_mode_sel(0), - m_rw_sel(0) + m_rw_sel(1) { cur_live.tm = attotime::never; cur_live.state = IDLE; @@ -210,7 +210,8 @@ void c8050_fdc_t::ds_w(int ds) { live_sync(); m_ds = cur_live.ds = ds; - pll_reset(cur_live.tm, attotime::from_hz(clock() / (16 - m_ds))); + pll_reset(cur_live.tm); + if (LOG) logerror("%s %s DS %u\n", machine().time().as_string(), machine().describe_context(), ds); checkpoint(); live_run(); } @@ -240,22 +241,23 @@ void c8050_fdc_t::live_start() cur_live.rw_sel = m_rw_sel; cur_live.pi = m_pi; - pll_reset(cur_live.tm, attotime::from_hz(clock() / (16 - m_ds))); + pll_reset(cur_live.tm); checkpoint_live = cur_live; pll_save_checkpoint(); live_run(); } -void c8050_fdc_t::pll_reset(const attotime &when, const attotime &clock) +void c8050_fdc_t::pll_reset(const attotime &when) { cur_pll.reset(when); - cur_pll.set_clock(clock); + cur_pll.set_clock(attotime::from_hz(clock() / (16 - m_ds))); } void c8050_fdc_t::pll_start_writing(const attotime &tm) { cur_pll.start_writing(tm); + pll_reset(cur_live.tm); } void c8050_fdc_t::pll_commit(floppy_image_device *floppy, const attotime &tm) @@ -266,6 +268,7 @@ void c8050_fdc_t::pll_commit(floppy_image_device *floppy, const attotime &tm) void c8050_fdc_t::pll_stop_writing(floppy_image_device *floppy, const attotime &tm) { cur_pll.stop_writing(floppy, tm); + pll_reset(cur_live.tm); } void c8050_fdc_t::pll_save_checkpoint() @@ -285,7 +288,7 @@ int c8050_fdc_t::pll_get_next_bit(attotime &tm, floppy_image_device *floppy, con bool c8050_fdc_t::pll_write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, const attotime &limit) { - return cur_pll.write_next_bit_prev_cell(bit, tm, floppy, limit); + return cur_pll.write_next_bit(bit, tm, floppy, limit); } void c8050_fdc_t::checkpoint() @@ -366,10 +369,33 @@ void c8050_fdc_t::live_run(const attotime &limit) return; // read bit - int bit = pll_get_next_bit(cur_live.tm, get_floppy(), limit); - if(bit < 0) - return; + int bit = 0; + if (cur_live.rw_sel) { + bit = pll_get_next_bit(cur_live.tm, get_floppy(), limit); + if(bit < 0) + return; + } + // write bit + int write_bit = BIT(cur_live.shift_reg_write, 9); + if (!cur_live.rw_sel) { // TODO WPS + /* + write precompensation + + UA5.A = UM6.Qc + UA5.B = !(!(!BRDY && UM6.Qa) && !(BRDY && E7)) + UA5.C0 = UA4.Qb = bit clock delayed 333ns + UA5.C1 = UA4.Qa = bit clock delayed 166ns + UA5.C2 = UA4.Qc = bit clock delayed 499ns + UA5.C3 = UA5.Qb = bit clock delayed 333ns + + DATA OUT = !(!BITCLK || !(UA5.Y && !(WRITE_ENABLE && !UM6.Qb))) + */ + if (pll_write_next_bit(write_bit, cur_live.tm, get_floppy(), limit)) + return; + } + + // clock read shift register cur_live.shift_reg <<= 1; cur_live.shift_reg |= bit; cur_live.shift_reg &= 0x3ff; @@ -378,16 +404,9 @@ void c8050_fdc_t::live_run(const attotime &limit) int sync = !((cur_live.shift_reg == 0x3ff) && cur_live.rw_sel); // bit counter - if (cur_live.rw_sel) { - 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; - } - } - } else { + 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; @@ -403,8 +422,6 @@ void c8050_fdc_t::live_run(const attotime &limit) cur_live.e = m_gcr_rom->base()[cur_live.i]; - if (LOG) logerror("%s cyl %u bit %u sync %u bc %u sr %03x i %03x e %02x\n",cur_live.tm.as_string(),get_floppy()->get_cyl(),bit,sync,cur_live.bit_counter,cur_live.shift_reg,cur_live.i,cur_live.e); - // byte ready int ready = !(cur_live.bit_counter == 9); // 74190 _RC, should be triggered on the falling edge of the clock int brdy = ready; // 74190 TC @@ -412,18 +429,19 @@ void c8050_fdc_t::live_run(const attotime &limit) // GCR error int error = !(ready || BIT(cur_live.e, 3)); - // write bit - if (!cur_live.rw_sel) { // TODO WPS - int write_bit = BIT(cur_live.shift_reg_write, 9); - if (LOG) logerror("%s writing bit %u sr %03x\n",cur_live.tm.as_string(),write_bit,cur_live.shift_reg_write); - pll_write_next_bit(write_bit, cur_live.tm, get_floppy(), limit); + if (LOG_BITS) { + if (cur_live.rw_sel) { + logerror("%s cyl %u bit %u sync %u bc %u sr %03x i %03x e %02x\n",cur_live.tm.as_string(),get_floppy()->get_cyl(),bit,sync,cur_live.bit_counter,cur_live.shift_reg,cur_live.i,cur_live.e); + } else { + logerror("%s cyl %u writing bit %u bc %u sr %03x i %03x e %02x\n",cur_live.tm.as_string(),get_floppy()->get_cyl(),write_bit,cur_live.bit_counter,cur_live.shift_reg_write,cur_live.i,cur_live.e); + } } if (!ready) { // load write shift register cur_live.shift_reg_write = GCR_ENCODE(cur_live.e, cur_live.i); - if (LOG) logerror("%s load write shift register %03x\n",cur_live.tm.as_string(),cur_live.shift_reg_write); + if (LOG_BITS) logerror("%s load write shift register %03x\n",cur_live.tm.as_string(),cur_live.shift_reg_write); } else { // clock write shift register cur_live.shift_reg_write <<= 1; @@ -431,13 +449,14 @@ void c8050_fdc_t::live_run(const attotime &limit) } if (ready != cur_live.ready) { - if (LOG) logerror("%s READY %u : %02x\n", cur_live.tm.as_string(),ready,GCR_DECODE(cur_live.e, cur_live.i)); + if (cur_live.rw_sel && !ready) + if (LOG) logerror("%s READY %u : %02x\n", cur_live.tm.as_string(),ready,GCR_DECODE(cur_live.e, cur_live.i)); cur_live.ready = ready; syncpoint = true; } if (brdy != cur_live.brdy) { - if (LOG) logerror("%s BRDY %u\n", cur_live.tm.as_string(), brdy); + if (LOG_MORE) logerror("%s BRDY %u\n", cur_live.tm.as_string(), brdy); cur_live.brdy = brdy; syncpoint = true; } @@ -449,7 +468,7 @@ void c8050_fdc_t::live_run(const attotime &limit) } if (error != cur_live.error) { - if (LOG) logerror("%s ERROR %u\n", cur_live.tm.as_string(), error); + if (LOG_MORE) logerror("%s ERROR %u\n", cur_live.tm.as_string(), error); cur_live.error = error; syncpoint = true; } @@ -462,10 +481,6 @@ void c8050_fdc_t::live_run(const attotime &limit) } case RUNNING_SYNCPOINT: { - if (LOG) { - if (!cur_live.sync) logerror("%s SYNC\n",cur_live.tm.as_string()); - if (!cur_live.ready && cur_live.bit_counter == 9) logerror("%s DATA %02x\n",cur_live.tm.as_string(),GCR_DECODE(cur_live.e,cur_live.i)); - } m_write_ready(cur_live.ready); m_write_brdy(cur_live.brdy); m_write_sync(cur_live.sync); @@ -484,21 +499,18 @@ READ8_MEMBER( c8050_fdc_t::read ) UINT8 e = checkpoint_live.e; offs_t i = checkpoint_live.i; - UINT8 data = GCR_DECODE(e, i); - - if (LOG)logerror("%s %s VIA reads data %02x (%03x)\n", machine().time().as_string(), machine().describe_context(), data, checkpoint_live.shift_reg); - - return data; + return GCR_DECODE(e, i); } WRITE8_MEMBER( c8050_fdc_t::write ) { + if (LOG) logerror("%s %s PI %02x\n", machine().time().as_string(), machine().describe_context(), data); + if (m_pi != data) { live_sync(); m_pi = cur_live.pi = data; checkpoint(); - if (LOG) logerror("%s %s PI %02x\n", machine().time().as_string(), machine().describe_context(), data); live_run(); } } @@ -548,9 +560,9 @@ WRITE_LINE_MEMBER( c8050_fdc_t::rw_sel_w ) checkpoint(); if (LOG) logerror("%s %s RW SEL %u\n", machine().time().as_string(), machine().describe_context(), state); if (m_rw_sel) { - pll_stop_writing(get_floppy(), machine().time()); + pll_stop_writing(get_floppy(), cur_live.tm); } else { - pll_start_writing(machine().time()); + pll_start_writing(cur_live.tm); } live_run(); } @@ -616,5 +628,5 @@ WRITE_LINE_MEMBER( c8050_fdc_t::odd_hd_w ) WRITE_LINE_MEMBER( c8050_fdc_t::pull_sync_w ) { - if (LOG) logerror("%s %s PULL SYNC %u\n", machine().time().as_string(), machine().describe_context(), state); + if (LOG_MORE) logerror("%s %s PULL SYNC %u\n", machine().time().as_string(), machine().describe_context(), state); } diff --git a/src/emu/bus/ieee488/c8050fdc.h b/src/emu/bus/ieee488/c8050fdc.h index fe41e7c73bc..9c4f9d665f1 100644 --- a/src/emu/bus/ieee488/c8050fdc.h +++ b/src/emu/bus/ieee488/c8050fdc.h @@ -150,7 +150,7 @@ protected: void live_start(); void checkpoint(); void rollback(); - void pll_reset(const attotime &when, const attotime &clock); + void pll_reset(const attotime &when); void pll_start_writing(const attotime &tm); void pll_commit(floppy_image_device *floppy, const attotime &tm); void pll_stop_writing(floppy_image_device *floppy, const attotime &tm); diff --git a/src/emu/machine/fdc_pll.c b/src/emu/machine/fdc_pll.c index a035a9c868b..0efb48b813e 100644 --- a/src/emu/machine/fdc_pll.c +++ b/src/emu/machine/fdc_pll.c @@ -22,7 +22,6 @@ void fdc_pll_t::set_clock(const attotime &_period) void fdc_pll_t::reset(const attotime &when) { ctime = when; - write_ctime = when; phase_adjust = attotime::zero; freq_hist = 0; write_position = 0; @@ -66,7 +65,6 @@ int fdc_pll_t::get_next_bit(attotime &tm, floppy_image_device *floppy, const att if(next > limit) return -1; - write_ctime = ctime; ctime = next; tm = next; @@ -132,20 +130,3 @@ bool fdc_pll_t::write_next_bit(bool bit, attotime &tm, floppy_image_device *flop ctime = etime; return false; } - -bool fdc_pll_t::write_next_bit_prev_cell(bool bit, attotime &tm, floppy_image_device *floppy, const attotime &limit) -{ - if(write_start_time.is_never()) { - write_start_time = write_ctime; - write_position = 0; - } - - attotime etime = write_ctime + period; - if(etime > limit) - return true; - - if(bit && write_position < ARRAY_LENGTH(write_buffer)) - write_buffer[write_position++] = write_ctime + period/2; - - return false; -} diff --git a/src/emu/machine/fdc_pll.h b/src/emu/machine/fdc_pll.h index 0cb08bba8cf..4a356616126 100644 --- a/src/emu/machine/fdc_pll.h +++ b/src/emu/machine/fdc_pll.h @@ -12,7 +12,6 @@ class fdc_pll_t { public: attotime ctime, period, min_period, max_period, period_adjust_base, phase_adjust; - attotime write_ctime; attotime write_start_time; attotime write_buffer[32]; int write_position; @@ -22,7 +21,6 @@ public: void reset(const attotime &when); int get_next_bit(attotime &tm, floppy_image_device *floppy, const attotime &limit); bool write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, const attotime &limit); - bool write_next_bit_prev_cell(bool bit, attotime &tm, floppy_image_device *floppy, const attotime &limit); void start_writing(const attotime &tm); void commit(floppy_image_device *floppy, const attotime &tm); void stop_writing(floppy_image_device *floppy, const attotime &tm); diff --git a/src/mess/machine/victor9k_fdc.c b/src/mess/machine/victor9k_fdc.c index 5d4b39b7c4f..1ae238401ed 100644 --- a/src/mess/machine/victor9k_fdc.c +++ b/src/mess/machine/victor9k_fdc.c @@ -54,6 +54,7 @@ #define LOG 0 #define LOG_VIA 0 #define LOG_SCP 0 +#define LOG_BITS 0 #define I8048_TAG "5d" #define M6522_4_TAG "1f" @@ -1069,22 +1070,23 @@ void victor_9000_fdc_t::live_start() cur_live.wrsync = m_wrsync; cur_live.erase = m_erase; - pll_reset(cur_live.tm, attotime::from_nsec(2130)); + pll_reset(cur_live.tm); checkpoint_live = cur_live; pll_save_checkpoint(); live_run(); } -void victor_9000_fdc_t::pll_reset(const attotime &when, const attotime &clock) +void victor_9000_fdc_t::pll_reset(const attotime &when) { cur_pll.reset(when); - cur_pll.set_clock(clock); + cur_pll.set_clock(attotime::from_nsec(2130)); } void victor_9000_fdc_t::pll_start_writing(const attotime &tm) { cur_pll.start_writing(tm); + pll_reset(cur_live.tm); } void victor_9000_fdc_t::pll_commit(floppy_image_device *floppy, const attotime &tm) @@ -1095,6 +1097,7 @@ void victor_9000_fdc_t::pll_commit(floppy_image_device *floppy, const attotime & void victor_9000_fdc_t::pll_stop_writing(floppy_image_device *floppy, const attotime &tm) { cur_pll.stop_writing(floppy, tm); + pll_reset(cur_live.tm); } void victor_9000_fdc_t::pll_save_checkpoint() @@ -1114,7 +1117,7 @@ int victor_9000_fdc_t::pll_get_next_bit(attotime &tm, floppy_image_device *flopp bool victor_9000_fdc_t::pll_write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, const attotime &limit) { - return cur_pll.write_next_bit_prev_cell(bit, tm, floppy, limit); + return cur_pll.write_next_bit(bit, tm, floppy, limit); } void victor_9000_fdc_t::checkpoint() @@ -1197,10 +1200,22 @@ void victor_9000_fdc_t::live_run(const attotime &limit) return; // read bit - int bit = pll_get_next_bit(cur_live.tm, get_floppy(), limit); - if(bit < 0) - return; + int bit = 0; + if (cur_live.drw) { + bit = pll_get_next_bit(cur_live.tm, get_floppy(), limit); + if(bit < 0) + return; + } + // write bit + int write_bit = 0; + if (!cur_live.drw) { // TODO WPS + write_bit = BIT(cur_live.shift_reg_write, 9); + if (pll_write_next_bit(write_bit, cur_live.tm, get_floppy(), limit)) + return; + } + + // clock read shift register cur_live.shift_reg <<= 1; cur_live.shift_reg |= bit; cur_live.shift_reg &= 0x3ff; @@ -1261,11 +1276,12 @@ void victor_9000_fdc_t::live_run(const attotime &limit) // GCR error int gcr_err = !(brdy || BIT(cur_live.e, 3)); - // write bit - if (!cur_live.drw) { // TODO WPS - int write_bit = BIT(cur_live.shift_reg_write, 9); - if (LOG) logerror("%s writing bit %u sr %03x\n",cur_live.tm.as_string(),write_bit,cur_live.shift_reg_write); - pll_write_next_bit(write_bit, cur_live.tm, get_floppy(), limit); + if (LOG_BITS) { + if (cur_live.drw) { + logerror("%s cyl %u bit %u sync %u bc %u sr %03x i %03x e %02x\n",cur_live.tm.as_string(),get_floppy()->get_cyl(),bit,sync,cur_live.bit_counter,cur_live.shift_reg,cur_live.i,cur_live.e); + } else { + logerror("%s cyl %u writing bit %u bc %u sr %03x i %03x e %02x\n",cur_live.tm.as_string(),get_floppy()->get_cyl(),write_bit,cur_live.bit_counter,cur_live.shift_reg_write,cur_live.i,cur_live.e); + } } if (!brdy) { diff --git a/src/mess/machine/victor9k_fdc.h b/src/mess/machine/victor9k_fdc.h index f107e718452..f9005c4af16 100644 --- a/src/mess/machine/victor9k_fdc.h +++ b/src/mess/machine/victor9k_fdc.h @@ -218,7 +218,7 @@ private: floppy_image_device* get_floppy(); void live_start(); - void pll_reset(const attotime &when, const attotime &clock); + void pll_reset(const attotime &when); void pll_start_writing(const attotime &tm); void pll_commit(floppy_image_device *floppy, const attotime &tm); void pll_stop_writing(floppy_image_device *floppy, const attotime &tm);