mirror of
https://github.com/holub/mame
synced 2025-04-22 00:11:58 +03:00
(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)
This commit is contained in:
parent
d4c67891c4
commit
19bbe2ac4d
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user