mirror of
https://github.com/holub/mame
synced 2025-05-08 23:31:54 +03:00
upd765: Externalize the fdc [O. Galibert]
This commit is contained in:
parent
958c5307e1
commit
a219677251
@ -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 \
|
||||
|
@ -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;
|
||||
}
|
@ -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
|
@ -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)
|
||||
{
|
||||
|
@ -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];
|
||||
|
Loading…
Reference in New Issue
Block a user