Beispiel #1
0
void c2040_fdc_t::commit(const attotime &tm)
{
	if(cur_live.write_start_time.is_never() || tm == cur_live.write_start_time || !cur_live.write_position)
		return;

	if (LOG) logerror("%s committing %u transitions since %s\n", tm.as_string(), cur_live.write_position, cur_live.write_start_time.as_string());

	if(get_floppy())
		get_floppy()->write_flux(cur_live.write_start_time, tm, cur_live.write_position, cur_live.write_buffer);

	cur_live.write_start_time = tm;
	cur_live.write_position = 0;
}
imgtoolerr_t imgtool_floppy_write_sector(imgtool_image *image, UINT32 track, UINT32 head, UINT32 sector, const void *buffer, size_t len)
{
	floperr_t ferr;

	ferr = floppy_write_sector(get_floppy(image), head, track, sector, 0, buffer, len);
	if (ferr)
		return imgtool_floppy_error(ferr);

	return IMGTOOLERR_SUCCESS;
}
imgtoolerr_t imgtool_floppy_get_sector_size(imgtool_image *image, UINT32 track, UINT32 head, UINT32 sector, UINT32 *sector_size)
{
	floperr_t ferr;

	ferr = floppy_get_sector_length(get_floppy(image), head, track, sector, sector_size);
	if (ferr)
		return imgtool_floppy_error(ferr);

	return IMGTOOLERR_SUCCESS;
}
Beispiel #4
0
void c8050_fdc_t::live_sync()
{
	if(!cur_live.tm.is_never()) {
		if(cur_live.tm > machine().time()) {
			rollback();
			live_run(machine().time());
			pll_commit(get_floppy(), cur_live.tm);
		} else {
			pll_commit(get_floppy(), cur_live.tm);
			if(cur_live.next_state != -1) {
				cur_live.state = cur_live.next_state;
				cur_live.next_state = -1;
			}
			if(cur_live.state == IDLE) {
				pll_stop_writing(get_floppy(), cur_live.tm);
				cur_live.tm = attotime::never;
			}
		}
		cur_live.next_state = -1;
		checkpoint();
	}
}
Beispiel #5
0
void c8050_fdc_t::live_abort()
{
	if(!cur_live.tm.is_never() && cur_live.tm > machine().time()) {
		rollback();
		live_run(machine().time());
	}

	pll_stop_writing(get_floppy(), cur_live.tm);

	cur_live.tm = attotime::never;
	cur_live.state = IDLE;
	cur_live.next_state = -1;

	cur_live.ready = 1;
	cur_live.brdy = 1;
	cur_live.sync = 1;
	cur_live.error = 1;
}
Beispiel #6
0
void victor_9000_fdc_t::live_abort()
{
	if(!cur_live.tm.is_never() && cur_live.tm > machine().time()) {
		rollback();
		live_run(machine().time());
	}

	pll_stop_writing(get_floppy(), cur_live.tm);

	cur_live.tm = attotime::never;
	cur_live.state = IDLE;
	cur_live.next_state = -1;

	cur_live.brdy = 1;
	cur_live.lbrdy_changed = true;
	cur_live.sync = 1;
	cur_live.syn = 1;
	cur_live.syn_changed = true;
	cur_live.gcr_err = 1;
}
Beispiel #7
0
void c2040_fdc_t::get_next_edge(const attotime &when)
{
	floppy_image_device *floppy = get_floppy();

	cur_live.edge = floppy ? floppy->get_next_transition(when) : attotime::never;
}
Beispiel #8
0
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;
		}
		}
	}
}
Beispiel #9
0
void c8050_fdc_t::checkpoint()
{
	pll_commit(get_floppy(), cur_live.tm);
	checkpoint_live = cur_live;
	pll_save_checkpoint();
}
Beispiel #10
0
static void imgtool_floppy_close(imgtool_image *img)
{
	floppy_close(get_floppy(img));
}
Beispiel #11
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;
		}
		}
	}
}