void c2040_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; int bit = get_next_bit(cur_live.tm, limit); if(bit < 0) return; int cell_counter = cur_live.cell_counter; if (bit) { cur_live.cycle_counter = cur_live.ds; cur_live.cell_counter = 0; } else { cur_live.cycle_counter++; } if (cur_live.cycle_counter == 16) { cur_live.cycle_counter = cur_live.ds; cur_live.cell_counter++; cur_live.cell_counter &= 0xf; } if (!BIT(cell_counter, 1) && BIT(cur_live.cell_counter, 1)) { // read bit cur_live.shift_reg <<= 1; cur_live.shift_reg |= !(BIT(cur_live.cell_counter, 3) || BIT(cur_live.cell_counter, 2)); cur_live.shift_reg &= 0x3ff; if (LOG) logerror("%s read bit %u (%u) >> %03x, rw=%u mode=%u\n", cur_live.tm.as_string(), cur_live.bit_counter, !(BIT(cur_live.cell_counter, 3) || BIT(cur_live.cell_counter, 2)), cur_live.shift_reg, cur_live.rw_sel, cur_live.mode_sel); // write bit if (!cur_live.rw_sel) { // TODO WPS write_next_bit(BIT(cur_live.shift_reg_write, 9), limit); } syncpoint = true; } int sync = !((cur_live.shift_reg == 0x3ff) && cur_live.rw_sel); if (!sync) { cur_live.bit_counter = 0; } else if (!BIT(cell_counter, 1) && BIT(cur_live.cell_counter, 1) && cur_live.sync) { cur_live.bit_counter++; if (cur_live.bit_counter == 10) { cur_live.bit_counter = 0; } } // update GCR 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]; int ready = !(BIT(cell_counter, 1) && !BIT(cur_live.cell_counter, 1) && (cur_live.bit_counter == 9)); 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); } else if (BIT(cell_counter, 1) && !BIT(cur_live.cell_counter, 1)) { // clock write shift register cur_live.shift_reg_write <<= 1; cur_live.shift_reg_write &= 0x3ff; if (LOG) logerror("%s write shift << %03x\n",cur_live.tm.as_string(),cur_live.shift_reg_write); } int error = !(BIT(cur_live.e, 3) || ready); if (ready != cur_live.ready) { if (LOG) logerror("%s READY %u\n", cur_live.tm.as_string(),ready); cur_live.ready = ready; 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) { cur_live.error = error; syncpoint = true; } if (syncpoint) { commit(cur_live.tm); cur_live.tm += m_period; live_delay(RUNNING_SYNCPOINT); return; } cur_live.tm += m_period; break; } case RUNNING_SYNCPOINT: { m_write_ready(cur_live.ready); m_write_sync(cur_live.sync); m_write_error(cur_live.error); cur_live.state = RUNNING; checkpoint(); break; } } } }
void c64h156_device::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; int bit = get_next_bit(cur_live.tm, limit); if(bit < 0) return; int cell_counter = cur_live.cell_counter; if (bit) { cur_live.cycle_counter = cur_live.ds; cur_live.cell_counter = 0; } else { cur_live.cycle_counter++; } if (cur_live.cycle_counter == 16) { cur_live.cycle_counter = cur_live.ds; cur_live.cell_counter++; cur_live.cell_counter &= 0xf; } if (!BIT(cell_counter, 1) && BIT(cur_live.cell_counter, 1)) { // read bit cur_live.shift_reg <<= 1; cur_live.shift_reg |= !(BIT(cur_live.cell_counter, 3) || BIT(cur_live.cell_counter, 2)); cur_live.shift_reg &= 0x3ff; if (LOG) logerror("%s read bit %u (%u) >> %03x, oe=%u soe=%u sync=%u byte=%u\n", cur_live.tm.as_string(), cur_live.bit_counter, !(BIT(cur_live.cell_counter, 3) || BIT(cur_live.cell_counter, 2)), cur_live.shift_reg, cur_live.oe, cur_live.soe, cur_live.sync, cur_live.byte); syncpoint = true; } if (BIT(cell_counter, 1) && !BIT(cur_live.cell_counter, 1) && !cur_live.oe) { write_next_bit(BIT(cur_live.shift_reg_write, 7), limit); } int sync = !((cur_live.shift_reg == 0x3ff) && cur_live.oe); if (!sync) { cur_live.bit_counter = 8; } else if (!BIT(cell_counter, 1) && BIT(cur_live.cell_counter, 1) && cur_live.sync) { cur_live.bit_counter++; cur_live.bit_counter &= 0xf; } int byte = !(((cur_live.bit_counter & 7) == 7) && cur_live.soe && !(cur_live.cell_counter & 2)); int load = !(((cur_live.bit_counter & 7) == 7) && ((cur_live.cell_counter & 3) == 3)); if (!load) { if (cur_live.oe) { cur_live.shift_reg_write = cur_live.shift_reg; if (LOG) logerror("%s load write shift register from read shift register %02x\n",cur_live.tm.as_string(),cur_live.shift_reg_write); } else { cur_live.shift_reg_write = cur_live.yb; if (LOG) logerror("%s load write shift register from YB %02x\n",cur_live.tm.as_string(),cur_live.shift_reg_write); } } else if (!BIT(cell_counter, 1) && BIT(cur_live.cell_counter, 1)) { cur_live.shift_reg_write <<= 1; cur_live.shift_reg_write &= 0xff; if (LOG) logerror("%s shift write register << %02x\n", cur_live.tm.as_string(), cur_live.shift_reg_write); } // update signals if (byte != cur_live.byte) { if (!byte || !cur_live.accl) { if (LOG) logerror("%s BYTE %u\n", cur_live.tm.as_string(),byte); cur_live.byte = byte; syncpoint = true; } if (!byte) { cur_live.accl_yb = cur_live.shift_reg & 0xff; } } 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 (syncpoint) { commit(cur_live.tm); cur_live.tm += m_period; live_delay(RUNNING_SYNCPOINT); return; } cur_live.tm += m_period; break; } case RUNNING_SYNCPOINT: { m_write_sync(cur_live.sync); m_write_byte(cur_live.byte); cur_live.state = RUNNING; checkpoint(); break; } } } }