예제 #1
0
파일: c8050fdc.cpp 프로젝트: Ashura-X/mame
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;
		}
		}
	}
}
예제 #2
0
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;
		}
		}
	}
}