summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Olivier Galibert <galibert@pobox.com>2021-01-17 23:15:10 +0100
committer Olivier Galibert <galibert@pobox.com>2021-01-17 23:15:57 +0100
commit07318ffb9d267935c4af399a565b34f69949322b (patch)
tree01534f6c3b1a3af6cf3140ff3e4ee99c69c82be5
parentc3e15affc352f05dcf2ea46dba595869071fb544 (diff)
swim2: Add mfm read, fix mfm write and mfm detection. SWIM2 seems done at that point.
-rw-r--r--src/devices/imagedev/floppy.cpp14
-rw-r--r--src/devices/imagedev/floppy.h1
-rw-r--r--src/devices/machine/swim2.cpp141
-rw-r--r--src/devices/machine/swim2.h5
4 files changed, 107 insertions, 54 deletions
diff --git a/src/devices/imagedev/floppy.cpp b/src/devices/imagedev/floppy.cpp
index ba41355a74e..af79d45af97 100644
--- a/src/devices/imagedev/floppy.cpp
+++ b/src/devices/imagedev/floppy.cpp
@@ -2422,7 +2422,7 @@ bool mac_floppy_device::wpt_r()
// actual_ss may have changed after the phases were set
m_reg = (m_reg & 7) | (actual_ss ? 8 : 0);
- if(m_reg != 4 && m_reg != 12)
+ if(m_reg != 4 && m_reg != 12 && m_reg != 5 && m_reg != 13)
logerror("fdc disk sense reg %x %s %p\n", m_reg, regnames[m_reg], image.get());
switch(m_reg) {
@@ -2433,8 +2433,9 @@ bool mac_floppy_device::wpt_r()
case 0x2: // Is the motor on?
return mon;
- case 0x4: // Used when reading data, result ignored
- return false;
+ case 0x4:
+ case 0xc: // Index pulse, probably only on the superdrive though
+ return !m_has_mfm ? false : !image || mon ? true : idx;
case 0x5: // Is it a superdrive (supports 1.4M MFM) ?
return m_has_mfm;
@@ -2454,9 +2455,6 @@ bool mac_floppy_device::wpt_r()
case 0xa: // Not on track 0?
return cyl != 0;
- case 0xc: // Another identification bit
- return m_rd1;
-
case 0xd: // Is the current mode GCR or MFM?
return m_mfm;
@@ -2588,9 +2586,7 @@ bool oa_d34v_device::is_2m() const
mfd51w_device::mfd51w_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : mac_floppy_device(mconfig, MFD51W, tag, owner, clock)
{
- m_has_mfm = true;
}
-
void mfd51w_device::setup_characteristics()
{
form_factor = floppy_image::FF_35;
@@ -2626,5 +2622,5 @@ void mfd75w_device::setup_characteristics()
bool mfd75w_device::is_2m() const
{
- return true;
+ return false;
}
diff --git a/src/devices/imagedev/floppy.h b/src/devices/imagedev/floppy.h
index 6f3f1e9d7f3..ce83d7b4839 100644
--- a/src/devices/imagedev/floppy.h
+++ b/src/devices/imagedev/floppy.h
@@ -287,7 +287,6 @@ protected:
u8 m_reg;
bool m_strb;
bool m_mfm, m_has_mfm;
- bool m_rd1;
mac_floppy_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
diff --git a/src/devices/machine/swim2.cpp b/src/devices/machine/swim2.cpp
index a7ea6d8162a..e45a4edd624 100644
--- a/src/devices/machine/swim2.cpp
+++ b/src/devices/machine/swim2.cpp
@@ -33,6 +33,11 @@ void swim2_device::device_start()
save_item(NAME(m_current_bit));
save_item(NAME(m_tss_sr));
save_item(NAME(m_tss_output));
+ save_item(NAME(m_sr));
+ save_item(NAME(m_mfm_sync_counter));
+ save_item(NAME(m_flux_write_start));
+ save_item(NAME(m_flux_write));
+ save_item(NAME(m_flux_write_count));
}
void swim2_device::device_reset()
@@ -52,11 +57,14 @@ void swim2_device::device_reset()
m_current_bit = 0;
m_tss_sr = 0;
m_tss_output = 0;
+ m_sr = 0;
+ m_mfm_sync_counter = 0;
m_devsel_cb(0);
m_sel35_cb(true);
m_hdsel_cb(false);
m_flux_write_start = 0;
m_flux_write_count = 0;
+ std::fill(m_flux_write.begin(), m_flux_write.end(), 0);
m_last_sync = machine().time().as_ticks(clock());
}
@@ -93,13 +101,9 @@ void swim2_device::flush_write(u64 when)
m_flux_write_count--;
attotime start = cycles_to_time(m_flux_write_start);
attotime end = cycles_to_time(when);
- logerror("wbuf start %s\n", start.to_string());
std::vector<attotime> fluxes(m_flux_write_count);
- for(u32 i=0; i != m_flux_write_count; i++) {
+ for(u32 i=0; i != m_flux_write_count; i++)
fluxes[i] = cycles_to_time(m_flux_write[i]);
- logerror("wbuf flux %s\n", fluxes[i].to_string());
- }
- logerror("wbuf end %s\n", end.to_string());
m_floppy->write_flux(start, end, m_flux_write_count, m_flux_write_count ? &fluxes[0] : nullptr);
}
m_flux_write_count = 0;
@@ -172,10 +176,10 @@ u8 swim2_device::read(offs_t offset)
if(m_fifo_pos > 0) {
if(m_fifo[m_fifo_pos - 1] & M_MARK)
h |= 0x01;
- if(m_fifo[m_fifo_pos - 1] & M_CRC0)
+ if(!(m_fifo[m_fifo_pos - 1] & M_CRC0))
h |= 0x02;
}
- // addata on 4
+ // rddata on 4
if(!m_floppy || m_floppy->wpt_r())
h |= 0x08;
if(m_error)
@@ -193,7 +197,6 @@ u8 swim2_device::read(offs_t offset)
else if(m_fifo_pos == 1)
h |= 0x80;
}
- // logerror("handshake %02x\n", h);
return h;
}
@@ -304,6 +307,7 @@ void swim2_device::write(offs_t offset, u8 data)
// Entering read mode
m_current_bit = 0;
m_sr = 0;
+ m_mfm_sync_counter = 0;
logerror("%s read start %s %s floppy=%p\n", machine().time().to_string(), m_setup & 0x04 ? "gcr" : "mfm", m_setup & 0x08 ? "fclk/2" : "fclk", m_floppy);
m_pll.reset(machine().time());
@@ -326,6 +330,20 @@ u64 swim2_device::time_to_cycles(const attotime &tm) const
return tm.as_ticks(clock());
}
+void swim2_device::crc_clear()
+{
+ m_crc = 0xcdb4;
+}
+
+void swim2_device::crc_update(int bit)
+{
+ if((m_crc ^ (bit ? 0x8000 : 0x0000)) & 0x8000)
+ m_crc = (m_crc << 1) ^ 0x1021;
+ else
+ m_crc = m_crc << 1;
+
+}
+
attotime swim2_device::cycles_to_time(u64 cycles) const
{
return attotime::from_ticks(cycles, clock());
@@ -334,13 +352,11 @@ attotime swim2_device::cycles_to_time(u64 cycles) const
void swim2_device::fifo_clear()
{
m_fifo_pos = 0;
- // must clear the crc to the appropriate r/w-dependant value. No idea yet which it is, but I have my suspicions.
- m_crc = 0x1234;
+ crc_clear();
}
bool swim2_device::fifo_push(u16 data)
{
- logerror("fifo push %03x\n", data);
if(m_fifo_pos == 2)
return true;
m_fifo[m_fifo_pos ++] = data;
@@ -380,15 +396,12 @@ void swim2_device::sync()
return;
}
- logerror("ACTIVE %s %d-%d\n", m_mode & 0x10 ? "write" : "read", m_last_sync, next_sync);
-
if(m_mode & 0x10) {
// We count in half-cycles but only toggle write on full cycles
u32 cycles = (next_sync - m_last_sync) << 1;
// Write mode
while(cycles) {
- // logerror("half cycles avail %d needed %d\n", cycles, m_half_cycles_before_change);
if(m_half_cycles_before_change) {
if(cycles >= m_half_cycles_before_change) {
cycles -= m_half_cycles_before_change;
@@ -402,7 +415,6 @@ void swim2_device::sync()
if(m_tss_output & 0xc) {
- logerror("SR %03x.%d TSS %c%c\n", m_sr, m_current_bit, m_tss_output & 8 ? m_tss_output & 2 ? '1' : '0' : '.', m_tss_output & 4 ? m_tss_output & 1 ? '1' : '0' : '.');
bool bit;
if(m_tss_output & 8) {
bit = (m_tss_output >> 1) & 1;
@@ -420,40 +432,44 @@ void swim2_device::sync()
m_half_cycles_before_change = m_setup & 0x40 ? 63 : 31;
if(m_setup & 8)
m_half_cycles_before_change <<= 1;
- logerror("T%d, %d half cycles\n", bit, m_half_cycles_before_change);
continue;
}
if(m_current_bit == 0xff)
fatalerror("Sequence break on write\n");
if(m_current_bit == 0) {
- u16 r = fifo_pop();
- if(m_setup & 0x40)
- logerror("DATAW %02x\n", r);
- logerror("fifo pop %03x\n", r);
- if(r == 0xffff && !m_error) {
- m_error |= 0x01;
- flush_write();
- m_current_bit = 0xff;
- m_half_cycles_before_change = 0;
- m_mode &= ~8;
- logerror("write end on underrun\n");
- break;
- }
- if(r & M_CRC) {
- fatalerror("crc alpha\n");
+ if(m_sr & M_CRC)
+ m_sr = m_crc >> 8;
+ else {
+ u16 r = fifo_pop();
+ if(r == 0xffff && !m_error) {
+ m_error |= 0x01;
+ flush_write();
+ m_current_bit = 0xff;
+ m_half_cycles_before_change = 0;
+ m_mode &= ~8;
+ logerror("write end on underrun\n");
+ break;
+ }
+ if(r & M_CRC)
+ m_sr = M_CRC | (m_crc >> 8);
+ else
+ m_sr = r & (M_MARK | M_CRC | 0xff);
}
- m_sr = r & (M_MARK | M_CRC | 0xff);
m_current_bit = 8;
+ if(m_sr & M_MARK)
+ crc_clear();
}
m_current_bit --;
bool bit = (m_sr >> m_current_bit) & 1;
+ if(!(m_sr & M_MARK))
+ crc_update(bit);
m_tss_sr = (m_tss_sr << 1) | bit;
if(m_setup & 0x40)
m_tss_output = 4 | bit;
else {
static const u8 tss[4] = { 5, 0xd, 4, 5 };
- if((m_sr & M_MARK) && (m_tss_sr == 8))
+ if((m_sr & M_MARK) && ((m_tss_sr & 0xf) == 8))
m_tss_output = 0xc;
else
m_tss_output = tss[m_tss_sr & 3];
@@ -471,16 +487,7 @@ void swim2_device::sync()
if(bit == -1)
break;
m_sr = ((m_sr << 1) | bit) & 0xff;
- logerror("%s: bit %d, sr=%02x\n", when.to_string(), bit, m_sr);
if(m_sr & 0x80) {
- static u8 m1, m2, m3;
- m1 = m2;
- m2 = m3;
- m3 = m_sr;
- logerror("DATAR %02x\n", m_sr);
- if(m1 == 0xd5 && m2 == 0xaa && m3 == 0xad)
- machine().debug_break();
- logerror("read byte %02x\n", m_sr);
if(fifo_push(m_sr) && !m_error)
m_error |= 0x01;
m_sr = 0;
@@ -488,8 +495,56 @@ void swim2_device::sync()
}
} else {
// MFM mode
+ for(;;) {
+ static u16 xinf = 0xffff;
+ attotime when;
+ int bit = m_pll.get_next_bit(when, m_floppy, limit);
+ if(bit == -1)
+ break;
+ xinf = (xinf << 1) | bit;
+ if(m_mfm_sync_counter < 64) {
+ if(bit != (m_mfm_sync_counter & 1))
+ m_mfm_sync_counter ++;
+ else
+ m_mfm_sync_counter = 0;
+ } else {
+ if(m_mfm_sync_counter == 64 && bit)
+ m_mfm_sync_counter --;
+ else {
+ if(m_mfm_sync_counter == 65 || m_mfm_sync_counter == 81) {
+ m_tss_sr = 0xff;
+ m_sr = 0;
+ }
+ if(m_mfm_sync_counter & 1) {
+ m_sr |= bit << (((96 - m_mfm_sync_counter) >> 1) & 7);
+ crc_update(bit);
+ }
+ m_tss_sr = (m_tss_sr << 1) | bit;
+ if((m_tss_sr & 0xf) == 1 && !(m_mfm_sync_counter & 1))
+ m_sr |= M_MARK;
+
+ m_mfm_sync_counter ++;
+ if(m_mfm_sync_counter == 80) {
+ if(!(m_sr & M_MARK))
+ m_mfm_sync_counter = 0;
+ else {
+ crc_clear();
+ if(fifo_push(m_sr) && !m_error)
+ m_error |= 0x01;
+ }
+ } else if(m_mfm_sync_counter == 96) {
+ m_mfm_sync_counter -= 16;
+ if(m_sr & M_MARK)
+ crc_clear();
+ else if(!m_crc)
+ m_sr |= M_CRC0;
+ if(fifo_push(m_sr) && !m_error)
+ m_error |= 0x01;
+ }
+ }
+ }
+ }
}
-
}
m_last_sync = next_sync;
diff --git a/src/devices/machine/swim2.h b/src/devices/machine/swim2.h
index 3045cd710ed..bddcd7b49d1 100644
--- a/src/devices/machine/swim2.h
+++ b/src/devices/machine/swim2.h
@@ -49,7 +49,7 @@ private:
u8 m_param[4];
u8 m_mode, m_setup, m_error, m_param_idx, m_fifo_pos, m_tss_sr, m_tss_output, m_current_bit;
u16 m_fifo[2], m_sr;
- u16 m_crc;
+ u16 m_crc, m_mfm_sync_counter;
u32 m_half_cycles_before_change;
u64 m_last_sync;
@@ -67,6 +67,9 @@ private:
u16 fifo_pop();
void flush_write(u64 when = 0);
void show_mode() const;
+
+ void crc_update(int bit);
+ void crc_clear();
};
DECLARE_DEVICE_TYPE(SWIM2, swim2_device)