void c8050_fdc_t::live_run(const attotime &limit) { if(cur_live.state == IDLE || cur_live.next_state != -1) return; for(;;) { switch(cur_live.state) { case RUNNING: { bool syncpoint = false; if (cur_live.tm > limit) return; // read bit 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; // sync int sync = !((cur_live.shift_reg == 0x3ff) && cur_live.rw_sel); // bit counter 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; } } // GCR decoder if (cur_live.rw_sel) { cur_live.i = (cur_live.rw_sel << 10) | cur_live.shift_reg; } else { cur_live.i = (cur_live.rw_sel << 10) | ((cur_live.pi & 0xf0) << 1) | (cur_live.mode_sel << 4) | (cur_live.pi & 0x0f); } cur_live.e = m_gcr_rom->base()[cur_live.i]; // 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 // GCR error int error = !(ready || BIT(cur_live.e, 3)); 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_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; cur_live.shift_reg_write &= 0x3ff; } if (ready != cur_live.ready) { 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_MORE) logerror("%s BRDY %u\n", cur_live.tm.as_string(), brdy); cur_live.brdy = brdy; syncpoint = true; } if (sync != cur_live.sync) { if (LOG) logerror("%s SYNC %u\n", cur_live.tm.as_string(), sync); cur_live.sync = sync; syncpoint = true; } if (error != cur_live.error) { if (LOG_MORE) logerror("%s ERROR %u\n", cur_live.tm.as_string(), error); cur_live.error = error; syncpoint = true; } if (syncpoint) { live_delay(RUNNING_SYNCPOINT); return; } break; } case RUNNING_SYNCPOINT: { m_write_ready(cur_live.ready); m_write_brdy(cur_live.brdy); m_write_sync(cur_live.sync); m_write_error(cur_live.error); cur_live.state = RUNNING; checkpoint(); break; } } } }
void victor_9000_fdc_t::live_run(const attotime &limit) { if(cur_live.state == IDLE || cur_live.next_state != -1) return; for(;;) { switch(cur_live.state) { case RUNNING: { bool syncpoint = false; if (cur_live.tm > limit) return; // read bit int bit = pll_get_next_bit(cur_live.tm, get_floppy(), limit); if(bit < 0) return; cur_live.shift_reg <<= 1; cur_live.shift_reg |= bit; cur_live.shift_reg &= 0x3ff; // sync int sync = !(cur_live.shift_reg == 0x3ff); // bit counter if (cur_live.drw) { 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 { cur_live.bit_counter++; if (cur_live.bit_counter == 10) { cur_live.bit_counter = 0; } } // sync counter if (sync) { cur_live.sync_bit_counter = 0; cur_live.sync_byte_counter = 10; // TODO 9 in schematics } else if (!cur_live.sync) { cur_live.sync_bit_counter++; if (cur_live.sync_bit_counter == 10) { cur_live.sync_bit_counter = 0; cur_live.sync_byte_counter++; if (cur_live.sync_byte_counter == 16) { cur_live.sync_byte_counter = 0; } } } // syn int syn = !(cur_live.sync_byte_counter == 15); // GCR decoder if (cur_live.drw) { cur_live.i = cur_live.shift_reg; } else { cur_live.i = 0x200 | ((cur_live.wd & 0xf0) << 1) | cur_live.wrsync << 4 | (cur_live.wd & 0x0f); } cur_live.e = m_gcr_rom->base()[cur_live.drw << 10 | cur_live.i]; attotime next = cur_live.tm + m_period; if (LOG) logerror("%s:%s cyl %u bit %u sync %u bc %u sr %03x sbc %u sBC %u syn %u i %03x e %02x\n",cur_live.tm.as_string(),next.as_string(),get_floppy()->get_cyl(),bit,sync,cur_live.bit_counter,cur_live.shift_reg,cur_live.sync_bit_counter,cur_live.sync_byte_counter,syn,cur_live.i,cur_live.e); // byte ready int brdy = !(cur_live.bit_counter == 9); // 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 (!brdy) { // 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); } else { // clock write shift register cur_live.shift_reg_write <<= 1; cur_live.shift_reg_write &= 0x3ff; } if (brdy != cur_live.brdy) { if (LOG) logerror("%s BRDY %u\n", cur_live.tm.as_string(),brdy); if (!brdy) { cur_live.lbrdy_changed = true; if (LOG_VIA) logerror("%s LBRDY 0 : %02x\n", cur_live.tm.as_string(), GCR_DECODE(cur_live.e, cur_live.i)); } cur_live.brdy = brdy; syncpoint = true; } if (sync != cur_live.sync) { if (LOG) logerror("%s SYNC %u\n", cur_live.tm.as_string(),sync); cur_live.sync = sync; syncpoint = true; } if (syn != cur_live.syn) { if (LOG) logerror("%s SYN %u\n", cur_live.tm.as_string(),syn); cur_live.syn = syn; cur_live.syn_changed = true; syncpoint = true; } if (gcr_err != cur_live.gcr_err) { if (LOG) logerror("%s GCR ERR %u\n", cur_live.tm.as_string(),gcr_err); cur_live.gcr_err = gcr_err; syncpoint = true; } if (syncpoint) { live_delay(RUNNING_SYNCPOINT); return; } break; } case RUNNING_SYNCPOINT: { if (cur_live.lbrdy_changed) { m_lbrdy_cb(0); cur_live.lbrdy_changed = false; } if (cur_live.syn_changed) { m_syn_cb(cur_live.syn); cur_live.syn_changed = false; } m_via5->write_ca1(cur_live.brdy); cur_live.state = RUNNING; checkpoint(); break; } } } }