trunk/src/emu/machine/upd765.c
| r19168 | r19169 | |
| 2153 | 2153 | cur_live.idbuf[3] == command[5]; |
| 2154 | 2154 | } |
| 2155 | 2155 | |
| 2156 | | void upd765_family_device::pll_t::set_clock(attotime _period) |
| 2157 | | { |
| 2158 | | period = _period; |
| 2159 | | period_adjust_base = period * 0.05; |
| 2160 | | min_period = period * 0.75; |
| 2161 | | max_period = period * 1.25; |
| 2162 | | } |
| 2163 | 2156 | |
| 2164 | | void upd765_family_device::pll_t::reset(attotime when) |
| 2165 | | { |
| 2166 | | ctime = when; |
| 2167 | | phase_adjust = attotime::zero; |
| 2168 | | freq_hist = 0; |
| 2169 | | write_position = 0; |
| 2170 | | write_start_time = attotime::never; |
| 2171 | | } |
| 2172 | | |
| 2173 | | void upd765_family_device::pll_t::start_writing(attotime tm) |
| 2174 | | { |
| 2175 | | write_start_time = tm; |
| 2176 | | write_position = 0; |
| 2177 | | } |
| 2178 | | |
| 2179 | | void upd765_family_device::pll_t::stop_writing(floppy_image_device *floppy, attotime tm) |
| 2180 | | { |
| 2181 | | commit(floppy, tm); |
| 2182 | | write_start_time = attotime::never; |
| 2183 | | } |
| 2184 | | |
| 2185 | | void upd765_family_device::pll_t::commit(floppy_image_device *floppy, attotime tm) |
| 2186 | | { |
| 2187 | | if(write_start_time.is_never() || tm == write_start_time) |
| 2188 | | return; |
| 2189 | | |
| 2190 | | if(floppy) |
| 2191 | | floppy->write_flux(write_start_time, tm, write_position, write_buffer); |
| 2192 | | write_start_time = tm; |
| 2193 | | write_position = 0; |
| 2194 | | } |
| 2195 | | |
| 2196 | | int upd765_family_device::pll_t::get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit) |
| 2197 | | { |
| 2198 | | attotime edge = floppy ? floppy->get_next_transition(ctime) : attotime::never; |
| 2199 | | |
| 2200 | | attotime next = ctime + period + phase_adjust; |
| 2201 | | |
| 2202 | | #if 0 |
| 2203 | | if(!edge.is_never()) |
| 2204 | | 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()); |
| 2205 | | #endif |
| 2206 | | |
| 2207 | | if(next > limit) |
| 2208 | | return -1; |
| 2209 | | |
| 2210 | | ctime = next; |
| 2211 | | tm = next; |
| 2212 | | |
| 2213 | | if(edge.is_never() || edge >= next) { |
| 2214 | | // No transition in the window means 0 and pll in free run mode |
| 2215 | | phase_adjust = attotime::zero; |
| 2216 | | return 0; |
| 2217 | | } |
| 2218 | | |
| 2219 | | // Transition in the window means 1, and the pll is adjusted |
| 2220 | | |
| 2221 | | attotime delta = edge - (next - period/2); |
| 2222 | | |
| 2223 | | if(delta.seconds < 0) |
| 2224 | | phase_adjust = attotime::zero - ((attotime::zero - delta)*65)/100; |
| 2225 | | else |
| 2226 | | phase_adjust = (delta*65)/100; |
| 2227 | | |
| 2228 | | if(delta < attotime::zero) { |
| 2229 | | if(freq_hist < 0) |
| 2230 | | freq_hist--; |
| 2231 | | else |
| 2232 | | freq_hist = -1; |
| 2233 | | } else if(delta > attotime::zero) { |
| 2234 | | if(freq_hist > 0) |
| 2235 | | freq_hist++; |
| 2236 | | else |
| 2237 | | freq_hist = 1; |
| 2238 | | } else |
| 2239 | | freq_hist = 0; |
| 2240 | | |
| 2241 | | if(freq_hist) { |
| 2242 | | int afh = freq_hist < 0 ? -freq_hist : freq_hist; |
| 2243 | | if(afh > 1) { |
| 2244 | | attotime aper = attotime::from_double(period_adjust_base.as_double()*delta.as_double()/period.as_double()); |
| 2245 | | period += aper; |
| 2246 | | |
| 2247 | | if(period < min_period) |
| 2248 | | period = min_period; |
| 2249 | | else if(period > max_period) |
| 2250 | | period = max_period; |
| 2251 | | } |
| 2252 | | } |
| 2253 | | |
| 2254 | | return 1; |
| 2255 | | } |
| 2256 | | |
| 2257 | | bool upd765_family_device::pll_t::write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit) |
| 2258 | | { |
| 2259 | | if(write_start_time.is_never()) { |
| 2260 | | write_start_time = ctime; |
| 2261 | | write_position = 0; |
| 2262 | | } |
| 2263 | | |
| 2264 | | attotime etime = ctime + period; |
| 2265 | | if(etime > limit) |
| 2266 | | return true; |
| 2267 | | |
| 2268 | | if(bit && write_position < ARRAY_LENGTH(write_buffer)) |
| 2269 | | write_buffer[write_position++] = ctime + period/2; |
| 2270 | | |
| 2271 | | tm = etime; |
| 2272 | | ctime = etime; |
| 2273 | | return false; |
| 2274 | | } |
| 2275 | | |
| 2276 | 2157 | 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) |
| 2277 | 2158 | { |
| 2278 | 2159 | m_shortname = "upd765a"; |
trunk/src/emu/machine/fdc_pll.c
| r19168 | r19169 | |
| 1 | #include "fdc_pll.h" |
| 2 | |
| 3 | void fdc_pll_t::set_clock(attotime _period) |
| 4 | { |
| 5 | period = _period; |
| 6 | period_adjust_base = period * 0.05; |
| 7 | min_period = period * 0.75; |
| 8 | max_period = period * 1.25; |
| 9 | } |
| 10 | |
| 11 | void fdc_pll_t::reset(attotime when) |
| 12 | { |
| 13 | ctime = when; |
| 14 | phase_adjust = attotime::zero; |
| 15 | freq_hist = 0; |
| 16 | write_position = 0; |
| 17 | write_start_time = attotime::never; |
| 18 | } |
| 19 | |
| 20 | void fdc_pll_t::start_writing(attotime tm) |
| 21 | { |
| 22 | write_start_time = tm; |
| 23 | write_position = 0; |
| 24 | } |
| 25 | |
| 26 | void fdc_pll_t::stop_writing(floppy_image_device *floppy, attotime tm) |
| 27 | { |
| 28 | commit(floppy, tm); |
| 29 | write_start_time = attotime::never; |
| 30 | } |
| 31 | |
| 32 | void fdc_pll_t::commit(floppy_image_device *floppy, attotime tm) |
| 33 | { |
| 34 | if(write_start_time.is_never() || tm == write_start_time) |
| 35 | return; |
| 36 | |
| 37 | if(floppy) |
| 38 | floppy->write_flux(write_start_time, tm, write_position, write_buffer); |
| 39 | write_start_time = tm; |
| 40 | write_position = 0; |
| 41 | } |
| 42 | |
| 43 | int fdc_pll_t::get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit) |
| 44 | { |
| 45 | attotime edge = floppy ? floppy->get_next_transition(ctime) : attotime::never; |
| 46 | |
| 47 | attotime next = ctime + period + phase_adjust; |
| 48 | |
| 49 | #if 0 |
| 50 | if(!edge.is_never()) |
| 51 | 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()); |
| 52 | #endif |
| 53 | |
| 54 | if(next > limit) |
| 55 | return -1; |
| 56 | |
| 57 | ctime = next; |
| 58 | tm = next; |
| 59 | |
| 60 | if(edge.is_never() || edge >= next) { |
| 61 | // No transition in the window means 0 and pll in free run mode |
| 62 | phase_adjust = attotime::zero; |
| 63 | return 0; |
| 64 | } |
| 65 | |
| 66 | // Transition in the window means 1, and the pll is adjusted |
| 67 | |
| 68 | attotime delta = edge - (next - period/2); |
| 69 | |
| 70 | if(delta.seconds < 0) |
| 71 | phase_adjust = attotime::zero - ((attotime::zero - delta)*65)/100; |
| 72 | else |
| 73 | phase_adjust = (delta*65)/100; |
| 74 | |
| 75 | if(delta < attotime::zero) { |
| 76 | if(freq_hist < 0) |
| 77 | freq_hist--; |
| 78 | else |
| 79 | freq_hist = -1; |
| 80 | } else if(delta > attotime::zero) { |
| 81 | if(freq_hist > 0) |
| 82 | freq_hist++; |
| 83 | else |
| 84 | freq_hist = 1; |
| 85 | } else |
| 86 | freq_hist = 0; |
| 87 | |
| 88 | if(freq_hist) { |
| 89 | int afh = freq_hist < 0 ? -freq_hist : freq_hist; |
| 90 | if(afh > 1) { |
| 91 | attotime aper = attotime::from_double(period_adjust_base.as_double()*delta.as_double()/period.as_double()); |
| 92 | period += aper; |
| 93 | |
| 94 | if(period < min_period) |
| 95 | period = min_period; |
| 96 | else if(period > max_period) |
| 97 | period = max_period; |
| 98 | } |
| 99 | } |
| 100 | |
| 101 | return 1; |
| 102 | } |
| 103 | |
| 104 | bool fdc_pll_t::write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit) |
| 105 | { |
| 106 | if(write_start_time.is_never()) { |
| 107 | write_start_time = ctime; |
| 108 | write_position = 0; |
| 109 | } |
| 110 | |
| 111 | attotime etime = ctime + period; |
| 112 | if(etime > limit) |
| 113 | return true; |
| 114 | |
| 115 | if(bit && write_position < ARRAY_LENGTH(write_buffer)) |
| 116 | write_buffer[write_position++] = ctime + period/2; |
| 117 | |
| 118 | tm = etime; |
| 119 | ctime = etime; |
| 120 | return false; |
| 121 | } |
trunk/src/emu/machine/fdc_pll.h
| r19168 | r19169 | |
| 1 | #ifndef __FDC_PLL_H__ |
| 2 | #define __FDC_PLL_H__ |
| 3 | |
| 4 | /* |
| 5 | * Generic pll class for floppy controllers with analog plls |
| 6 | */ |
| 7 | |
| 8 | #include "emu.h" |
| 9 | #include "imagedev/floppy.h" |
| 10 | |
| 11 | class fdc_pll_t { |
| 12 | public: |
| 13 | attotime ctime, period, min_period, max_period, period_adjust_base, phase_adjust; |
| 14 | |
| 15 | attotime write_start_time; |
| 16 | attotime write_buffer[32]; |
| 17 | int write_position; |
| 18 | int freq_hist; |
| 19 | |
| 20 | void set_clock(attotime period); |
| 21 | void reset(attotime when); |
| 22 | int get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit); |
| 23 | bool write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit); |
| 24 | void start_writing(attotime tm); |
| 25 | void commit(floppy_image_device *floppy, attotime tm); |
| 26 | void stop_writing(floppy_image_device *floppy, attotime tm); |
| 27 | }; |
| 28 | |
| 29 | #endif |