mirror of
https://github.com/holub/mame
synced 2025-04-20 15:32:45 +03:00
swim1: Add mfm read, write needs a little more work
This commit is contained in:
parent
7d64b7cf36
commit
fc8d69e743
@ -280,7 +280,6 @@ void iwm_device::data_w(u8 data)
|
||||
m_wsh = data;
|
||||
if(m_mode & 0x01)
|
||||
m_whd &= 0x7f;
|
||||
logerror("data load %02x, m_mode %02x whd %02x\n", m_data, m_mode, m_whd);
|
||||
}
|
||||
|
||||
u64 iwm_device::time_to_cycles(const attotime &tm) const
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include "emu.h"
|
||||
#include "swim1.h"
|
||||
|
||||
#include "cpu/m68000/m68000.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(SWIM1, swim1_device, "swim1", "Apple SWIM1 (Sander/Wozniak Integrated Machine) version 1 floppy controller")
|
||||
|
||||
swim1_device::swim1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
@ -129,12 +131,38 @@ void swim1_device::write(offs_t offset, u8 data)
|
||||
|
||||
u8 swim1_device::ism_read(offs_t offset)
|
||||
{
|
||||
static const char *const names[] = {
|
||||
"data", "mark", "crc", "param", "phases", "setup", "status", "handshake"
|
||||
};
|
||||
ism_sync();
|
||||
|
||||
logerror("read ism %s\n", names[offset & 7]);
|
||||
// static const char *const names[] = {
|
||||
// "data", "mark", "crc", "param", "phases", "setup", "status", "handshake"
|
||||
// };
|
||||
|
||||
// logerror("read ism %s\n", names[offset & 7]);
|
||||
switch(offset & 7) {
|
||||
case 0x0: { // data
|
||||
u16 r = ism_fifo_pop();
|
||||
if(!m_ism_error) {
|
||||
if(r == 0xffff)
|
||||
m_ism_error |= 4;
|
||||
else if(r & M_MARK)
|
||||
m_ism_error |= 2;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
case 0x1: { // mark
|
||||
u16 r = ism_fifo_pop();
|
||||
if(!m_ism_error && r == 0xffff)
|
||||
m_ism_error |= 4;
|
||||
return r;
|
||||
}
|
||||
|
||||
case 0x2: { // error
|
||||
u8 err = m_ism_error;
|
||||
m_ism_error = 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
case 0x3: {
|
||||
u8 r = m_ism_param[m_ism_param_idx];
|
||||
m_ism_param_idx = (m_ism_param_idx + 1) & 15;
|
||||
@ -150,6 +178,35 @@ u8 swim1_device::ism_read(offs_t offset)
|
||||
case 0x6: // mode
|
||||
return m_ism_mode;
|
||||
|
||||
case 0x7: { // handshake
|
||||
u8 h = 0;
|
||||
if(m_ism_fifo_pos > 0) {
|
||||
if(m_ism_fifo[m_ism_fifo_pos - 1] & M_MARK)
|
||||
h |= 0x01;
|
||||
if(!(m_ism_fifo[m_ism_fifo_pos - 1] & M_CRC0))
|
||||
h |= 0x02;
|
||||
}
|
||||
// rddata on 4
|
||||
if(!m_floppy || m_floppy->wpt_r())
|
||||
h |= 0x08;
|
||||
if(m_ism_error)
|
||||
h |= 0x20;
|
||||
if(m_ism_mode & 0x10) {
|
||||
// write
|
||||
if(m_ism_fifo_pos == 0)
|
||||
h |= 0xc0;
|
||||
else if(m_ism_fifo_pos == 1)
|
||||
h |= 0x80;
|
||||
} else {
|
||||
// read
|
||||
if(m_ism_fifo_pos == 2)
|
||||
h |= 0xc0;
|
||||
else if(m_ism_fifo_pos == 1)
|
||||
h |= 0x80;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
default:
|
||||
// logerror("read %s\n", names[offset & 7]);
|
||||
break;
|
||||
@ -159,10 +216,29 @@ u8 swim1_device::ism_read(offs_t offset)
|
||||
|
||||
void swim1_device::ism_write(offs_t offset, u8 data)
|
||||
{
|
||||
ism_sync();
|
||||
|
||||
u8 prev_mode = m_ism_mode;
|
||||
|
||||
static const char *const names[] = {
|
||||
"data", "mark", "crc", "param", "phases", "setup", "mode0", "mode1",
|
||||
};
|
||||
switch(offset) {
|
||||
case 0:
|
||||
if(ism_fifo_push(data) && !m_ism_error)
|
||||
m_ism_error |= 0x04;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if(ism_fifo_push(M_MARK | data) && !m_ism_error)
|
||||
m_ism_error |= 0x04;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if(ism_fifo_push(M_CRC) && !m_ism_error)
|
||||
m_ism_error |= 0x04;
|
||||
break;
|
||||
|
||||
case 0x3: {
|
||||
static const char *const pname[16] = {
|
||||
"minct", "mult", "ssl", "sss", "sll", "sls", "rpt", "csls",
|
||||
@ -173,6 +249,7 @@ void swim1_device::ism_write(offs_t offset, u8 data)
|
||||
m_ism_param_idx = (m_ism_param_idx + 1) & 15;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x4: {
|
||||
logerror("ism phases %02x\n", data);
|
||||
m_phases = data;
|
||||
@ -210,6 +287,54 @@ void swim1_device::ism_write(offs_t offset, u8 data)
|
||||
logerror("write %s, %02x\n", names[offset & 7], data);
|
||||
break;
|
||||
}
|
||||
|
||||
if(m_ism_mode & 0x01)
|
||||
ism_fifo_clear();
|
||||
|
||||
if((m_ism_mode ^ prev_mode) & 0x06)
|
||||
m_devsel_cb(m_ism_mode & 0x80 ? (m_ism_mode >> 1) & 3 : 0);
|
||||
if((m_ism_mode ^ prev_mode) & 0x20)
|
||||
m_hdsel_cb((m_ism_mode >> 5) & 1);
|
||||
|
||||
if((m_ism_mode & 0x18) == 0x18 && ((prev_mode & 0x18) != 0x18)) {
|
||||
// Entering write mode
|
||||
m_ism_current_bit = 0;
|
||||
logerror("%s write start %s %s floppy=%p\n", machine().time().to_string(), m_ism_setup & 0x40 ? "gcr" : "mfm", m_ism_setup & 0x08 ? "fclk/2" : "fclk", m_floppy);
|
||||
m_flux_write_start = m_last_sync;
|
||||
m_flux_write_count = 0;
|
||||
|
||||
} else if((prev_mode & 0x18) == 0x18 && (m_ism_mode & 0x18) != 0x18) {
|
||||
// Exiting write mode
|
||||
flush_write();
|
||||
m_flux_write_start = 0;
|
||||
m_ism_current_bit = 0xff;
|
||||
m_ism_half_cycles_before_change = 0;
|
||||
logerror("%s write end\n", machine().time().to_string());
|
||||
}
|
||||
|
||||
if((m_ism_mode & 0x18) == 0x08 && ((prev_mode & 0x18) != 0x08)) {
|
||||
// Entering read mode
|
||||
m_ism_current_bit = 0;
|
||||
m_ism_sr = 0;
|
||||
m_ism_mfm_sync_counter = 0;
|
||||
m_ism_latest_edge = m_last_sync;
|
||||
m_ism_first_edge = true;
|
||||
m_ism_prev_ls = (1<<2) | 1;
|
||||
m_ism_csm_state = m_ism_setup & 0x04 ? CSM_SYNCHRONIZED : CSM_INIT;
|
||||
m_ism_csm_error_counter[0] = m_ism_csm_error_counter[1] = 0;
|
||||
m_ism_correction_factor[0] = m_ism_correction_factor[1] = 0;
|
||||
m_ism_csm_pair_side = 0;
|
||||
m_ism_csm_min_count = 0;
|
||||
|
||||
logerror("%s read start %s %s floppy=%p\n", machine().time().to_string(), m_ism_setup & 0x04 ? "gcr" : "mfm", m_ism_setup & 0x08 ? "fclk/2" : "fclk", m_floppy);
|
||||
|
||||
} else if((prev_mode & 0x18) == 0x08 && (m_ism_mode & 0x18) != 0x08) {
|
||||
// Exiting read mode
|
||||
flush_write();
|
||||
m_ism_current_bit = 0xff;
|
||||
m_ism_half_cycles_before_change = 0;
|
||||
logerror("%s read end\n", machine().time().to_string());
|
||||
}
|
||||
}
|
||||
|
||||
void swim1_device::device_timer(emu_timer &, device_timer_id, int, void *)
|
||||
@ -247,7 +372,8 @@ void swim1_device::flush_write(u64 when)
|
||||
|
||||
u8 swim1_device::iwm_control(int offset, u8 data)
|
||||
{
|
||||
sync();
|
||||
iwm_sync();
|
||||
|
||||
u8 prev_iwm_to_ism_counter = m_iwm_to_ism_counter;
|
||||
|
||||
if(0)
|
||||
@ -399,14 +525,15 @@ void swim1_device::ism_crc_update(int bit)
|
||||
|
||||
}
|
||||
|
||||
// The ism part of the swim1 works in half-clocks
|
||||
u64 swim1_device::time_to_cycles(const attotime &tm) const
|
||||
{
|
||||
return tm.as_ticks(clock());
|
||||
return tm.as_ticks(2*clock());
|
||||
}
|
||||
|
||||
attotime swim1_device::cycles_to_time(u64 cycles) const
|
||||
{
|
||||
return attotime::from_ticks(cycles, clock());
|
||||
return attotime::from_ticks(cycles, 2*clock());
|
||||
}
|
||||
|
||||
void swim1_device::ism_fifo_clear()
|
||||
@ -465,10 +592,10 @@ bool swim1_device::iwm_is_sync() const
|
||||
u64 swim1_device::iwm_half_window_size() const
|
||||
{
|
||||
switch(m_iwm_mode & 0x18) {
|
||||
case 0x00: return 14;
|
||||
case 0x08: return 7;
|
||||
case 0x10: return 16;
|
||||
case 0x18: return 8;
|
||||
case 0x00: return 2*14;
|
||||
case 0x08: return 2* 7;
|
||||
case 0x10: return 2*16;
|
||||
case 0x18: return 2* 8;
|
||||
}
|
||||
abort();
|
||||
}
|
||||
@ -476,10 +603,10 @@ u64 swim1_device::iwm_half_window_size() const
|
||||
u64 swim1_device::iwm_window_size() const
|
||||
{
|
||||
switch(m_iwm_mode & 0x18) {
|
||||
case 0x00: return 28;
|
||||
case 0x08: return 14;
|
||||
case 0x10: return 36;
|
||||
case 0x18: return 16;
|
||||
case 0x00: return 2*28;
|
||||
case 0x08: return 2*14;
|
||||
case 0x10: return 2*36;
|
||||
case 0x18: return 2*16;
|
||||
}
|
||||
abort();
|
||||
}
|
||||
@ -642,6 +769,349 @@ void swim1_device::iwm_sync()
|
||||
|
||||
void swim1_device::ism_sync()
|
||||
{
|
||||
u64 next_sync = time_to_cycles(machine().time());
|
||||
if(!(m_ism_mode & 0x08)) {
|
||||
m_last_sync = next_sync;
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_ism_mode & 0x10) {
|
||||
u32 cycles = next_sync - m_last_sync;
|
||||
|
||||
// Write mode
|
||||
while(cycles) {
|
||||
if(m_ism_half_cycles_before_change) {
|
||||
if(cycles >= m_ism_half_cycles_before_change) {
|
||||
cycles -= m_ism_half_cycles_before_change;
|
||||
m_ism_half_cycles_before_change = 0;
|
||||
} else {
|
||||
m_ism_half_cycles_before_change -= cycles;
|
||||
cycles = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(m_ism_tss_output & 0xc) {
|
||||
bool bit;
|
||||
if(m_ism_tss_output & 8) {
|
||||
bit = (m_ism_tss_output >> 1) & 1;
|
||||
m_ism_tss_output &= ~0xa;
|
||||
} else {
|
||||
bit = m_ism_tss_output & 1;
|
||||
m_ism_tss_output = 0;
|
||||
}
|
||||
if(bit) {
|
||||
if(m_flux_write_count == m_flux_write.size())
|
||||
flush_write(next_sync - cycles);
|
||||
m_flux_write[m_flux_write_count ++] = next_sync - cycles;
|
||||
m_ism_half_cycles_before_change = 63;
|
||||
} else
|
||||
m_ism_half_cycles_before_change = m_ism_setup & 0x40 ? 63 : 31;
|
||||
if(m_ism_setup & 8)
|
||||
m_ism_half_cycles_before_change <<= 1;
|
||||
continue;
|
||||
}
|
||||
if(m_ism_current_bit == 0xff)
|
||||
fatalerror("Sequence break on write\n");
|
||||
|
||||
if(m_ism_current_bit == 0) {
|
||||
if(m_ism_sr & M_CRC)
|
||||
m_ism_sr = m_ism_crc >> 8;
|
||||
else {
|
||||
u16 r = ism_fifo_pop();
|
||||
if(r == 0xffff && !m_ism_error) {
|
||||
m_ism_error |= 0x01;
|
||||
flush_write();
|
||||
m_ism_current_bit = 0xff;
|
||||
m_ism_half_cycles_before_change = 0;
|
||||
m_ism_mode &= ~8;
|
||||
logerror("write end on underrun\n");
|
||||
break;
|
||||
}
|
||||
if(r & M_CRC)
|
||||
m_ism_sr = M_CRC | (m_ism_crc >> 8);
|
||||
else
|
||||
m_ism_sr = r & (M_MARK | M_CRC | 0xff);
|
||||
}
|
||||
m_ism_current_bit = 8;
|
||||
if(m_ism_sr & M_MARK)
|
||||
ism_crc_clear();
|
||||
}
|
||||
m_ism_current_bit --;
|
||||
bool bit = (m_ism_sr >> m_ism_current_bit) & 1;
|
||||
if(!(m_ism_sr & M_MARK))
|
||||
ism_crc_update(bit);
|
||||
m_ism_tss_sr = (m_ism_tss_sr << 1) | bit;
|
||||
if(m_ism_setup & 0x40)
|
||||
m_ism_tss_output = 4 | bit;
|
||||
else {
|
||||
static const u8 tss[4] = { 5, 0xd, 4, 5 };
|
||||
if((m_ism_sr & M_MARK) && ((m_ism_tss_sr & 0xf) == 8))
|
||||
m_ism_tss_output = 0xc;
|
||||
else
|
||||
m_ism_tss_output = tss[m_ism_tss_sr & 3];
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
while(m_last_sync < next_sync) {
|
||||
// Find when in the future the next edge happens
|
||||
u64 cycles_to_next;
|
||||
bool will_hit_edge;
|
||||
if(!m_floppy) {
|
||||
cycles_to_next = next_sync - m_ism_latest_edge;
|
||||
will_hit_edge = false;
|
||||
} else {
|
||||
auto when = m_floppy->get_next_transition(cycles_to_time(m_ism_latest_edge+2));
|
||||
if(when == attotime::never || when > cycles_to_time(next_sync)) {
|
||||
cycles_to_next = next_sync - m_ism_latest_edge;
|
||||
will_hit_edge = false;
|
||||
} else {
|
||||
cycles_to_next = time_to_cycles(when) - m_ism_latest_edge;
|
||||
will_hit_edge = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Pick up the current rescaling factor
|
||||
int scale = m_ism_correction_factor[m_ism_csm_pair_side];
|
||||
if(scale < 192)
|
||||
scale |= 256;
|
||||
|
||||
// Count the number of cells in the L and the S hypothesis
|
||||
u32 sct, lct;
|
||||
if(m_ism_prev_ls == 0x5) {
|
||||
// Previous was a short
|
||||
if(cycles_to_next <= (scale * (m_ism_param[P_MINCT] + 3*2)) >> 8)
|
||||
sct = 0;
|
||||
else if(cycles_to_next <= (scale * (m_ism_param[P_MINCT] + 3*2 + m_ism_param[P_SSS] + 2*2)) >> 8)
|
||||
sct = 1;
|
||||
else if(cycles_to_next <= (scale * (m_ism_param[P_MINCT] + 3*2 + m_ism_param[P_SSS] + 2*2 + m_ism_param[P_SLS] + 2*2)) >> 8)
|
||||
sct = 2;
|
||||
else if(cycles_to_next <= (scale * (m_ism_param[P_MINCT] + 3*2 + m_ism_param[P_SSS] + 2*2 + m_ism_param[P_SLS] + 2*2 + m_ism_param[P_RPT] + 2*2)) >> 8)
|
||||
sct = 3;
|
||||
else
|
||||
sct = 4;
|
||||
if(cycles_to_next <= (scale * (m_ism_param[P_MINCT] + 3*2)) >> 8)
|
||||
lct = 0;
|
||||
else if(cycles_to_next <= (scale * (m_ism_param[P_MINCT] + 3*2 + m_ism_param[P_SSL] + 2*2)) >> 8)
|
||||
lct = 1;
|
||||
else if(cycles_to_next <= (scale * (m_ism_param[P_MINCT] + 3*2 + m_ism_param[P_SSL] + 2*2 + m_ism_param[P_SLL] + 2*2)) >> 8)
|
||||
lct = 2;
|
||||
else if(cycles_to_next <= (scale * (m_ism_param[P_MINCT] + 3*2 + m_ism_param[P_SSL] + 2*2 + m_ism_param[P_SLL] + 2*2 + m_ism_param[P_RPT] + 2*2)) >> 8)
|
||||
lct = 3;
|
||||
else
|
||||
lct = 4;
|
||||
|
||||
} else if(m_ism_prev_ls == 0x6 || m_ism_prev_ls == 0x7 || m_ism_prev_ls == 0x9 || m_ism_prev_ls == 0xd) {
|
||||
// Previous was marginal
|
||||
if(cycles_to_next <= (scale * (m_ism_param[P_MINCT] + 3*2)) >> 8)
|
||||
sct = 0;
|
||||
else if(cycles_to_next <= (scale * (m_ism_param[P_MINCT] + 3*2 + m_ism_param[P_LSS] + 2*2)) >> 8)
|
||||
sct = 1;
|
||||
else if(cycles_to_next <= (scale * (m_ism_param[P_MINCT] + 3*2 + m_ism_param[P_LSS] + 2*2 + m_ism_param[P_CSLS] + 2*2)) >> 8)
|
||||
sct = 2;
|
||||
else if(cycles_to_next <= (scale * (m_ism_param[P_MINCT] + 3*2 + m_ism_param[P_LSS] + 2*2 + m_ism_param[P_CSLS] + 2*2 + m_ism_param[P_RPT] + 2*2)) >> 8)
|
||||
sct = 3;
|
||||
else
|
||||
sct = 4;
|
||||
if(cycles_to_next <= (scale * (m_ism_param[P_MINCT] + 3*2)) >> 8)
|
||||
lct = 0;
|
||||
else if(cycles_to_next <= (scale * (m_ism_param[P_MINCT] + 3*2 + m_ism_param[P_LSL] + 2*2)) >> 8)
|
||||
lct = 1;
|
||||
else if(cycles_to_next <= (scale * (m_ism_param[P_MINCT] + 3*2 + m_ism_param[P_LSL] + 2*2 + m_ism_param[P_CSLS] + 2*2)) >> 8)
|
||||
lct = 2;
|
||||
else if(cycles_to_next <= (scale * (m_ism_param[P_MINCT] + 3*2 + m_ism_param[P_LSL] + 2*2 + m_ism_param[P_CSLS] + 2*2 + m_ism_param[P_RPT] + 2*2)) >> 8)
|
||||
lct = 3;
|
||||
else
|
||||
lct = 4;
|
||||
|
||||
} else {
|
||||
// Previous was long
|
||||
if(cycles_to_next <= (scale * (m_ism_param[P_MINCT] + 3*2)) >> 8)
|
||||
sct = 0;
|
||||
else if(cycles_to_next <= (scale * (m_ism_param[P_MINCT] + 3*2 + m_ism_param[P_LSS] + 2*2)) >> 8)
|
||||
sct = 1;
|
||||
else if(cycles_to_next <= (scale * (m_ism_param[P_MINCT] + 3*2 + m_ism_param[P_LSS] + 2*2 + m_ism_param[P_LLS] + 2*2)) >> 8)
|
||||
sct = 2;
|
||||
else if(cycles_to_next <= (scale * (m_ism_param[P_MINCT] + 3*2 + m_ism_param[P_LSS] + 2*2 + m_ism_param[P_LLS] + 2*2 + m_ism_param[P_RPT] + 2*2)) >> 8)
|
||||
sct = 3;
|
||||
else
|
||||
sct = 4;
|
||||
if(cycles_to_next <= (scale * (m_ism_param[P_MINCT] + 3*2)) >> 8)
|
||||
lct = 0;
|
||||
else if(cycles_to_next <= (scale * (m_ism_param[P_MINCT] + 3*2 + m_ism_param[P_LSL] + 2*2)) >> 8)
|
||||
lct = 1;
|
||||
else if(cycles_to_next <= (scale * (m_ism_param[P_MINCT] + 3*2 + m_ism_param[P_LSL] + 2*2 + m_ism_param[P_LLL] + 2*2)) >> 8)
|
||||
lct = 2;
|
||||
else if(cycles_to_next <= (scale * (m_ism_param[P_MINCT] + 3*2 + m_ism_param[P_LSL] + 2*2 + m_ism_param[P_LLL] + 2*2 + m_ism_param[P_RPT] + 2*2)) >> 8)
|
||||
lct = 3;
|
||||
else
|
||||
lct = 4;
|
||||
}
|
||||
|
||||
// Actually resolve the cell lengths according to the counts
|
||||
int resolved_ls_count = 0;
|
||||
int resolved_ls_type[2] = { 0, 0 };
|
||||
if((sct == 4 || lct == 4) && !m_ism_error)
|
||||
m_ism_error |= 0x20;
|
||||
|
||||
if(will_hit_edge) {
|
||||
if(sct == 0) {
|
||||
if(!m_ism_error && !m_ism_first_edge) {
|
||||
// Don't do the short cell error, write splices often trigger it and the physical media
|
||||
// probably doesn't actually allow for it.
|
||||
// m_ism_error |= 0x10;
|
||||
}
|
||||
sct = lct = 1;
|
||||
}
|
||||
if(sct == 4)
|
||||
sct = 3;
|
||||
if(lct == 4)
|
||||
lct = 3;
|
||||
|
||||
bool previous_marginal = m_ism_prev_ls == 0x6 || m_ism_prev_ls == 0x7 || m_ism_prev_ls == 0x9 || m_ism_prev_ls == 0xd;
|
||||
bool current_marginal = (sct == 1 && lct > 1) || (lct == 1 && sct > 1);
|
||||
|
||||
if(previous_marginal && current_marginal) {
|
||||
if(!m_ism_error)
|
||||
m_ism_error |= 0x40;
|
||||
resolved_ls_count = 2;
|
||||
resolved_ls_type[0] = (m_ism_prev_ls >> 2) & 3;
|
||||
resolved_ls_type[1] = lct;
|
||||
} else {
|
||||
if(previous_marginal) {
|
||||
if(sct == 1)
|
||||
resolved_ls_type[resolved_ls_count++] = m_ism_prev_ls & 3;
|
||||
else
|
||||
resolved_ls_type[resolved_ls_count++] = (m_ism_prev_ls >> 2) & 3;
|
||||
}
|
||||
if(!current_marginal) {
|
||||
if(sct == 1)
|
||||
resolved_ls_type[resolved_ls_count++] = sct;
|
||||
else
|
||||
resolved_ls_type[resolved_ls_count++] = lct;
|
||||
}
|
||||
}
|
||||
|
||||
m_ism_prev_ls = (lct << 2) | sct;
|
||||
}
|
||||
|
||||
// If we have cell lengths, run the Correction State Machine and the Trans-Space Machine appropriately
|
||||
for(int i=0; i != resolved_ls_count; i++) {
|
||||
int type = resolved_ls_type[i];
|
||||
bool drop_one_bit = false;
|
||||
switch(m_ism_csm_state) {
|
||||
case CSM_INIT:
|
||||
m_ism_csm_error_counter[0] = m_ism_csm_error_counter[1] = 0;
|
||||
m_ism_csm_pair_side = 0;
|
||||
m_ism_csm_min_count = 0;
|
||||
m_ism_csm_state = CSM_COUNT_MIN;
|
||||
break;
|
||||
|
||||
case CSM_COUNT_MIN:
|
||||
if(type != 1) {
|
||||
m_ism_csm_state = CSM_INIT;
|
||||
break;
|
||||
}
|
||||
m_ism_csm_error_counter[m_ism_csm_pair_side] += m_ism_param[P_MULT] * (cycles_to_next >> 1);
|
||||
m_ism_csm_min_count ++;
|
||||
if(m_ism_csm_min_count == 64) {
|
||||
for(int i=0; i != 2; i++) {
|
||||
m_ism_correction_factor[i] = m_ism_csm_error_counter[i] >> 8;
|
||||
if(!m_ism_error && (m_ism_csm_error_counter[i] < 0xc000 || m_ism_csm_error_counter[i] >= 0x1c000))
|
||||
m_ism_error |= 0x08;
|
||||
}
|
||||
m_ism_csm_state = CSM_WAIT_NON_MIN;
|
||||
}
|
||||
break;
|
||||
|
||||
case CSM_WAIT_NON_MIN:
|
||||
if(type == 1) {
|
||||
break;
|
||||
}
|
||||
m_ism_csm_state = CSM_CHECK_MARK;
|
||||
m_ism_tsm_out = 0;
|
||||
m_ism_tsm_mark = false;
|
||||
m_ism_tsm_bits = 0;
|
||||
ism_crc_clear();
|
||||
drop_one_bit = true;
|
||||
[[fallthrough]];
|
||||
|
||||
// 2 1 3 1 3 2 2 2 1
|
||||
// 2 3 2 3 2
|
||||
|
||||
case CSM_CHECK_MARK:
|
||||
case CSM_SYNCHRONIZED:
|
||||
if(m_ism_setup & 0x04) {
|
||||
for(int i=0; i != type; i++) {
|
||||
int bit = (i+1 == type) ? 1 : 0;
|
||||
m_ism_tsm_out = (m_ism_tsm_out << 1) | bit;
|
||||
if(m_ism_tsm_out & 0x80) {
|
||||
if(ism_fifo_push(m_ism_tsm_out) && !m_ism_error)
|
||||
m_ism_error |= 0x01;
|
||||
m_ism_tsm_out = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
static u32 nb[6] = { 1, 1, 2, 1, 2, 2 };
|
||||
static u32 bb[6] = { 1, 0, 1, 0, 1, 0 };
|
||||
int idx = (m_ism_tsm_out & 1 ? 0 : 3) + type - 1;
|
||||
int nbc = nb[idx];
|
||||
int bbc = bb[idx];
|
||||
if(drop_one_bit) {
|
||||
nbc--;
|
||||
drop_one_bit = false;
|
||||
}
|
||||
if(idx == 5)
|
||||
m_ism_tsm_mark = true;
|
||||
for(int i=0; i != nbc; i++) {
|
||||
int bit = (bbc >> (nbc-1-i)) & 1;
|
||||
m_ism_tsm_out = (m_ism_tsm_out << 1) | bit;
|
||||
m_ism_tsm_bits ++;
|
||||
ism_crc_update(bit);
|
||||
|
||||
if(m_ism_tsm_bits == 8) {
|
||||
if(m_ism_csm_state == CSM_CHECK_MARK) {
|
||||
if(!m_ism_tsm_mark) {
|
||||
m_ism_csm_state = CSM_INIT;
|
||||
break;
|
||||
}
|
||||
m_ism_csm_state = CSM_SYNCHRONIZED;
|
||||
}
|
||||
u16 val = m_ism_tsm_out & 0xff;
|
||||
if(m_ism_tsm_mark) {
|
||||
m_ism_tsm_mark = false;
|
||||
val |= M_MARK;
|
||||
ism_crc_clear();
|
||||
}
|
||||
if(!m_ism_crc)
|
||||
val |= M_CRC0;
|
||||
if(ism_fifo_push(val) && !m_ism_error)
|
||||
m_ism_error |= 0x01;
|
||||
machine().debug_break();
|
||||
m_ism_tsm_bits = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
m_ism_csm_pair_side = !m_ism_csm_pair_side;
|
||||
}
|
||||
|
||||
|
||||
// Go to the next sync point
|
||||
if(will_hit_edge) {
|
||||
m_ism_latest_edge += cycles_to_next;
|
||||
m_last_sync = m_ism_latest_edge;
|
||||
m_ism_first_edge = false;
|
||||
} else
|
||||
m_last_sync = next_sync;
|
||||
}
|
||||
}
|
||||
|
||||
m_last_sync = next_sync;
|
||||
}
|
||||
|
||||
void swim1_device::sync()
|
||||
|
@ -44,7 +44,7 @@ private:
|
||||
MODE_READ, MODE_WRITE // m_iwm_rw modes
|
||||
};
|
||||
|
||||
// state machine states
|
||||
// iwm state machine states
|
||||
enum {
|
||||
S_IDLE,
|
||||
SR_WINDOW_EDGE_0,
|
||||
@ -54,6 +54,28 @@ private:
|
||||
SW_WINDOW_END
|
||||
};
|
||||
|
||||
// ism buffered byte marks
|
||||
enum {
|
||||
M_MARK = 0x100,
|
||||
M_CRC = 0x200,
|
||||
M_CRC0 = 0x400
|
||||
};
|
||||
|
||||
// parameter ram addresses
|
||||
enum {
|
||||
P_MINCT, P_MULT, P_SSL, P_SSS, P_SLL, P_SLS, P_RPT, P_CSLS,
|
||||
P_LSL, P_LSS, P_LLL, P_LLS, P_LATE, P_TIME0, P_EARLY, P_TIME1
|
||||
};
|
||||
|
||||
// CSM states
|
||||
enum {
|
||||
CSM_INIT,
|
||||
CSM_COUNT_MIN,
|
||||
CSM_WAIT_NON_MIN,
|
||||
CSM_CHECK_MARK,
|
||||
CSM_SYNCHRONIZED
|
||||
};
|
||||
|
||||
floppy_image_device *m_floppy;
|
||||
emu_timer *m_timer;
|
||||
|
||||
@ -64,14 +86,24 @@ private:
|
||||
|
||||
u8 m_ism_param[16];
|
||||
u8 m_ism_mode, m_ism_setup;
|
||||
//u8 m_ism_error;
|
||||
u8 m_ism_error;
|
||||
u8 m_ism_param_idx, m_ism_fifo_pos;
|
||||
//u8 m_ism_tss_sr, m_ism_tss_output, m_ism_current_bit;
|
||||
u8 m_ism_tss_sr, m_ism_tss_output, m_ism_current_bit;
|
||||
u16 m_ism_fifo[2];
|
||||
//u16 m_ism_sr;
|
||||
u16 m_ism_sr;
|
||||
u16 m_ism_crc;
|
||||
//u16 m_ism_mfm_sync_counter;
|
||||
//u32 m_ism_half_cycles_before_change;
|
||||
u16 m_ism_mfm_sync_counter;
|
||||
u32 m_ism_half_cycles_before_change;
|
||||
u8 m_ism_correction_factor[2];
|
||||
|
||||
u64 m_ism_latest_edge;
|
||||
bool m_ism_first_edge;
|
||||
u8 m_ism_prev_ls;
|
||||
u8 m_ism_csm_state;
|
||||
u32 m_ism_csm_error_counter[2];
|
||||
u8 m_ism_csm_pair_side, m_ism_csm_min_count;
|
||||
u8 m_ism_tsm_out, m_ism_tsm_bits;
|
||||
bool m_ism_tsm_mark;
|
||||
|
||||
u64 m_iwm_next_state_change, m_iwm_sync_update, m_iwm_async_update;
|
||||
int m_iwm_active, m_iwm_rw, m_iwm_rw_state;
|
||||
|
@ -149,7 +149,7 @@ u8 swim2_device::read(offs_t offset)
|
||||
return r;
|
||||
}
|
||||
|
||||
case 0x2: { // errpr
|
||||
case 0x2: { // error
|
||||
u8 err = m_error;
|
||||
m_error = 0;
|
||||
return err;
|
||||
@ -157,7 +157,7 @@ u8 swim2_device::read(offs_t offset)
|
||||
|
||||
case 0x3: { // param
|
||||
u8 r = m_param[m_param_idx];
|
||||
m_param_idx = (m_param_idx + 1) & 15;
|
||||
m_param_idx = (m_param_idx + 1) & 3;
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -520,6 +520,7 @@ void swim2_device::sync()
|
||||
crc_clear();
|
||||
else if(!m_crc)
|
||||
m_sr |= M_CRC0;
|
||||
logerror("DATAR %03x %04x\n", m_sr, m_crc);
|
||||
if(fifo_push(m_sr) && !m_error)
|
||||
m_error |= 0x01;
|
||||
}
|
||||
|
@ -656,6 +656,9 @@ uint16_t mac_state::mac_iwm_r(offs_t offset, uint16_t mem_mask)
|
||||
|
||||
uint16_t result = m_fdc->read(offset >> 8);
|
||||
|
||||
if (!machine().side_effects_disabled())
|
||||
m_maincpu->adjust_icount(-5);
|
||||
|
||||
if (LOG_MAC_IWM)
|
||||
printf("%s mac_iwm_r: offset=0x%08x mem_mask %04x = %02x\n", machine().describe_context().c_str(), offset, mem_mask, result);
|
||||
|
||||
@ -671,6 +674,9 @@ void mac_state::mac_iwm_w(offs_t offset, uint16_t data, uint16_t mem_mask)
|
||||
m_fdc->write((offset >> 8), data & 0xff);
|
||||
else
|
||||
m_fdc->write((offset >> 8), data>>8);
|
||||
|
||||
if (!machine().side_effects_disabled())
|
||||
m_maincpu->adjust_icount(-5);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(mac_state::mac_adb_via_out_cb2)
|
||||
@ -853,7 +859,7 @@ void mac_state::mac_via_out_a(uint8_t data)
|
||||
set_scc_waitrequest((data & 0x80) >> 7);
|
||||
m_screen_buffer = (data & 0x40) >> 6;
|
||||
#if NEW_SWIM
|
||||
if (m_cur_floppy && (m_fdc->type() == IWM || m_fdc->type() == SWIM1))
|
||||
if (m_cur_floppy)
|
||||
m_cur_floppy->ss_w((data & 0x20) >> 5);
|
||||
#else
|
||||
sony_set_sel_line(m_fdc.target(), (data & 0x20) >> 5);
|
||||
@ -2509,14 +2515,12 @@ void mac_state::devsel_w(uint8_t devsel)
|
||||
else
|
||||
m_cur_floppy = nullptr;
|
||||
m_fdc->set_floppy(m_cur_floppy);
|
||||
if(m_cur_floppy && (m_fdc->type() == IWM || m_fdc->type() == SWIM1))
|
||||
if(m_cur_floppy)
|
||||
m_cur_floppy->ss_w((m_via1->read_pa() & 0x20) >> 5);
|
||||
}
|
||||
|
||||
void mac_state::hdsel_w(int hdsel)
|
||||
{
|
||||
if(m_cur_floppy)
|
||||
m_cur_floppy->ss_w(hdsel);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user