diff options
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 |
commit | 07318ffb9d267935c4af399a565b34f69949322b (patch) | |
tree | 01534f6c3b1a3af6cf3140ff3e4ee99c69c82be5 | |
parent | c3e15affc352f05dcf2ea46dba595869071fb544 (diff) |
swim2: Add mfm read, fix mfm write and mfm detection. SWIM2 seems done at that point.
-rw-r--r-- | src/devices/imagedev/floppy.cpp | 14 | ||||
-rw-r--r-- | src/devices/imagedev/floppy.h | 1 | ||||
-rw-r--r-- | src/devices/machine/swim2.cpp | 141 | ||||
-rw-r--r-- | src/devices/machine/swim2.h | 5 |
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) |