From a2196772510022fe97b608fca2b6cf3000c65e5c Mon Sep 17 00:00:00 2001 From: Olivier Galibert Date: Tue, 27 Nov 2012 16:55:25 +0000 Subject: [PATCH] upd765: Externalize the fdc [O. Galibert] --- src/emu/emu.mak | 1 + src/emu/machine/fdc_pll.c | 121 ++++++++++++++++++++++++++++++++++++++ src/emu/machine/fdc_pll.h | 29 +++++++++ src/emu/machine/upd765.c | 119 ------------------------------------- src/emu/machine/upd765.h | 3 +- 5 files changed, 153 insertions(+), 120 deletions(-) diff --git a/src/emu/emu.mak b/src/emu/emu.mak index fa3b949f475..e6dbf0268c9 100644 --- a/src/emu/emu.mak +++ b/src/emu/emu.mak @@ -181,6 +181,7 @@ EMUMACHINEOBJS = \ $(EMUMACHINE)/eeprom.o \ $(EMUMACHINE)/er2055.o \ $(EMUMACHINE)/f3853.o \ + $(EMUMACHINE)/fdc_pll.o \ $(EMUMACHINE)/generic.o \ $(EMUMACHINE)/i2cmem.o \ $(EMUMACHINE)/i8155.o \ diff --git a/src/emu/machine/fdc_pll.c b/src/emu/machine/fdc_pll.c index e69de29bb2d..3451ee984ee 100644 --- a/src/emu/machine/fdc_pll.c +++ b/src/emu/machine/fdc_pll.c @@ -0,0 +1,121 @@ +#include "fdc_pll.h" + +void fdc_pll_t::set_clock(attotime _period) +{ + period = _period; + period_adjust_base = period * 0.05; + min_period = period * 0.75; + max_period = period * 1.25; +} + +void fdc_pll_t::reset(attotime when) +{ + ctime = when; + phase_adjust = attotime::zero; + freq_hist = 0; + write_position = 0; + write_start_time = attotime::never; +} + +void fdc_pll_t::start_writing(attotime tm) +{ + write_start_time = tm; + write_position = 0; +} + +void fdc_pll_t::stop_writing(floppy_image_device *floppy, attotime tm) +{ + commit(floppy, tm); + write_start_time = attotime::never; +} + +void fdc_pll_t::commit(floppy_image_device *floppy, attotime tm) +{ + if(write_start_time.is_never() || tm == write_start_time) + return; + + if(floppy) + floppy->write_flux(write_start_time, tm, write_position, write_buffer); + write_start_time = tm; + write_position = 0; +} + +int fdc_pll_t::get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit) +{ + attotime edge = floppy ? floppy->get_next_transition(ctime) : attotime::never; + + attotime next = ctime + period + phase_adjust; + +#if 0 + if(!edge.is_never()) + fprintf(stderr, "ctime=%s, transition_time=%s, next=%s, pha=%s\n", tts(ctime).cstr(), tts(edge).cstr(), tts(next).cstr(), tts(phase_adjust).cstr()); +#endif + + if(next > limit) + return -1; + + ctime = next; + tm = next; + + if(edge.is_never() || edge >= next) { + // No transition in the window means 0 and pll in free run mode + phase_adjust = attotime::zero; + return 0; + } + + // Transition in the window means 1, and the pll is adjusted + + attotime delta = edge - (next - period/2); + + if(delta.seconds < 0) + phase_adjust = attotime::zero - ((attotime::zero - delta)*65)/100; + else + phase_adjust = (delta*65)/100; + + if(delta < attotime::zero) { + if(freq_hist < 0) + freq_hist--; + else + freq_hist = -1; + } else if(delta > attotime::zero) { + if(freq_hist > 0) + freq_hist++; + else + freq_hist = 1; + } else + freq_hist = 0; + + if(freq_hist) { + int afh = freq_hist < 0 ? -freq_hist : freq_hist; + if(afh > 1) { + attotime aper = attotime::from_double(period_adjust_base.as_double()*delta.as_double()/period.as_double()); + period += aper; + + if(period < min_period) + period = min_period; + else if(period > max_period) + period = max_period; + } + } + + return 1; +} + +bool fdc_pll_t::write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit) +{ + if(write_start_time.is_never()) { + write_start_time = ctime; + write_position = 0; + } + + attotime etime = ctime + period; + if(etime > limit) + return true; + + if(bit && write_position < ARRAY_LENGTH(write_buffer)) + write_buffer[write_position++] = ctime + period/2; + + tm = etime; + ctime = etime; + return false; +} diff --git a/src/emu/machine/fdc_pll.h b/src/emu/machine/fdc_pll.h index e69de29bb2d..49cf2c33b6a 100644 --- a/src/emu/machine/fdc_pll.h +++ b/src/emu/machine/fdc_pll.h @@ -0,0 +1,29 @@ +#ifndef __FDC_PLL_H__ +#define __FDC_PLL_H__ + +/* + * Generic pll class for floppy controllers with analog plls + */ + +#include "emu.h" +#include "imagedev/floppy.h" + +class fdc_pll_t { +public: + attotime ctime, period, min_period, max_period, period_adjust_base, phase_adjust; + + attotime write_start_time; + attotime write_buffer[32]; + int write_position; + int freq_hist; + + void set_clock(attotime period); + void reset(attotime when); + int get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit); + bool write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit); + void start_writing(attotime tm); + void commit(floppy_image_device *floppy, attotime tm); + void stop_writing(floppy_image_device *floppy, attotime tm); +}; + +#endif diff --git a/src/emu/machine/upd765.c b/src/emu/machine/upd765.c index d994406a9d2..f6e1a12ba8b 100644 --- a/src/emu/machine/upd765.c +++ b/src/emu/machine/upd765.c @@ -2153,125 +2153,6 @@ bool upd765_family_device::sector_matches() const cur_live.idbuf[3] == command[5]; } -void upd765_family_device::pll_t::set_clock(attotime _period) -{ - period = _period; - period_adjust_base = period * 0.05; - min_period = period * 0.75; - max_period = period * 1.25; -} - -void upd765_family_device::pll_t::reset(attotime when) -{ - ctime = when; - phase_adjust = attotime::zero; - freq_hist = 0; - write_position = 0; - write_start_time = attotime::never; -} - -void upd765_family_device::pll_t::start_writing(attotime tm) -{ - write_start_time = tm; - write_position = 0; -} - -void upd765_family_device::pll_t::stop_writing(floppy_image_device *floppy, attotime tm) -{ - commit(floppy, tm); - write_start_time = attotime::never; -} - -void upd765_family_device::pll_t::commit(floppy_image_device *floppy, attotime tm) -{ - if(write_start_time.is_never() || tm == write_start_time) - return; - - if(floppy) - floppy->write_flux(write_start_time, tm, write_position, write_buffer); - write_start_time = tm; - write_position = 0; -} - -int upd765_family_device::pll_t::get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit) -{ - attotime edge = floppy ? floppy->get_next_transition(ctime) : attotime::never; - - attotime next = ctime + period + phase_adjust; - -#if 0 - if(!edge.is_never()) - fprintf(stderr, "ctime=%s, transition_time=%s, next=%s, pha=%s\n", tts(ctime).cstr(), tts(edge).cstr(), tts(next).cstr(), tts(phase_adjust).cstr()); -#endif - - if(next > limit) - return -1; - - ctime = next; - tm = next; - - if(edge.is_never() || edge >= next) { - // No transition in the window means 0 and pll in free run mode - phase_adjust = attotime::zero; - return 0; - } - - // Transition in the window means 1, and the pll is adjusted - - attotime delta = edge - (next - period/2); - - if(delta.seconds < 0) - phase_adjust = attotime::zero - ((attotime::zero - delta)*65)/100; - else - phase_adjust = (delta*65)/100; - - if(delta < attotime::zero) { - if(freq_hist < 0) - freq_hist--; - else - freq_hist = -1; - } else if(delta > attotime::zero) { - if(freq_hist > 0) - freq_hist++; - else - freq_hist = 1; - } else - freq_hist = 0; - - if(freq_hist) { - int afh = freq_hist < 0 ? -freq_hist : freq_hist; - if(afh > 1) { - attotime aper = attotime::from_double(period_adjust_base.as_double()*delta.as_double()/period.as_double()); - period += aper; - - if(period < min_period) - period = min_period; - else if(period > max_period) - period = max_period; - } - } - - return 1; -} - -bool upd765_family_device::pll_t::write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit) -{ - if(write_start_time.is_never()) { - write_start_time = ctime; - write_position = 0; - } - - attotime etime = ctime + period; - if(etime > limit) - return true; - - if(bit && write_position < ARRAY_LENGTH(write_buffer)) - write_buffer[write_position++] = ctime + period/2; - - tm = etime; - ctime = etime; - return false; -} upd765a_device::upd765a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : upd765_family_device(mconfig, UPD765A, "UPD765A", tag, owner, clock) { diff --git a/src/emu/machine/upd765.h b/src/emu/machine/upd765.h index 22f00f18394..ff23b84d69a 100644 --- a/src/emu/machine/upd765.h +++ b/src/emu/machine/upd765.h @@ -3,6 +3,7 @@ #include "emu.h" #include "imagedev/floppy.h" +#include "fdc_pll.h" /* * ready = true if the ready line is physically connected to the floppy drive @@ -272,7 +273,7 @@ protected: bool data_separator_phase, data_bit_context; UINT8 data_reg; UINT8 idbuf[6]; - pll_t pll; + fdc_pll_t pll; }; static int rates[4];