1 // license:BSD-3-Clause
2 // copyright-holders:Olivier Galibert
3 #include "emu.h"
4 #include "wd_fdc.h"
5 
6 #include "imagedev/floppy.h"
7 
8 #include "debugger.h"
9 
10 //#define LOG_GENERAL   (1U << 0) //defined in logmacro.h already
11 #define LOG_SETUP   (1U << 1) // Shows register setup
12 #define LOG_SHIFT   (1U << 2) // Shows shift register contents
13 #define LOG_COMP    (1U << 3) // Shows operations on the CPU side
14 #define LOG_COMMAND (1U << 4) // Shows command invocation
15 #define LOG_SYNC    (1U << 5) // Shows sync actions
16 #define LOG_LINES   (1U << 6) // Show control lines
17 #define LOG_EVENT   (1U << 7) // Show events
18 #define LOG_MATCH   (1U << 8) // Show sector match operation
19 #define LOG_DESC    (1U << 9) // Show track description
20 #define LOG_WRITE   (1U << 10) // Show write operation on image
21 #define LOG_TRANSITION  (1U << 11) // Show transitions
22 #define LOG_STATE   (1U << 12) // Show state machine
23 #define LOG_LIVE    (1U << 13) // Live states
24 #define LOG_FUNC    (1U << 14) // Function calls
25 
26 #define VERBOSE (LOG_GENERAL)
27 //#define LOG_OUTPUT_STREAM std::cout
28 
29 #include "logmacro.h"
30 
31 #define LOGSETUP(...)   LOGMASKED(LOG_SETUP,  __VA_ARGS__)
32 #define LOGSHIFT(...)   LOGMASKED(LOG_SHIFT, __VA_ARGS__)
33 #define LOGCOMP(...)    LOGMASKED(LOG_COMP, __VA_ARGS__)
34 #define LOGCOMMAND(...) LOGMASKED(LOG_COMMAND, __VA_ARGS__)
35 #define LOGSYNC(...)    LOGMASKED(LOG_SYNC, __VA_ARGS__)
36 #define LOGLINES(...)   LOGMASKED(LOG_LINES, __VA_ARGS__)
37 #define LOGEVENT(...)   LOGMASKED(LOG_EVENT, __VA_ARGS__)
38 #define LOGMATCH(...)   LOGMASKED(LOG_MATCH, __VA_ARGS__)
39 #define LOGDESC(...)    LOGMASKED(LOG_DESC, __VA_ARGS__)
40 #define LOGWRITE(...)   LOGMASKED(LOG_WRITE, __VA_ARGS__)
41 #define LOGTRANSITION(...) LOGMASKED(LOG_TRANSITION, __VA_ARGS__)
42 #define LOGSTATE(...) LOGMASKED(LOG_STATE, __VA_ARGS__)
43 #define LOGLIVE(...) LOGMASKED(LOG_LIVE, __VA_ARGS__)
44 #define LOGFUNC(...) LOGMASKED(LOG_FUNC, __VA_ARGS__)
45 
46 #ifdef _MSC_VER
47 #define FUNCNAME __func__
48 #else
49 #define FUNCNAME __PRETTY_FUNCTION__
50 #endif
51 
52 DEFINE_DEVICE_TYPE(FD1771,     fd1771_device,     "fd1771",     "FD1771 FDC")
53 
54 DEFINE_DEVICE_TYPE(FD1781,     fd1781_device,     "fd1781",     "FD1781 FDC")
55 
56 DEFINE_DEVICE_TYPE(FD1791,     fd1791_device,     "fd1791",     "FD1791 FDC")
57 DEFINE_DEVICE_TYPE(FD1792,     fd1792_device,     "fd1792",     "FD1792 FDC")
58 DEFINE_DEVICE_TYPE(FD1793,     fd1793_device,     "fd1793",     "FD1793 FDC")
59 DEFINE_DEVICE_TYPE(KR1818VG93, kr1818vg93_device, "kr1818vg93", "KR1818VG93 FDC")
60 DEFINE_DEVICE_TYPE(FD1794,     fd1794_device,     "fd1794",     "FD1794 FDC")
61 DEFINE_DEVICE_TYPE(FD1795,     fd1795_device,     "fd1795",     "FD1795 FDC")
62 DEFINE_DEVICE_TYPE(FD1797,     fd1797_device,     "fd1797",     "FD1797 FDC")
63 
64 DEFINE_DEVICE_TYPE(MB8866,     mb8866_device,     "mb8866",     "Fujitsu MB8866 FDC")
65 DEFINE_DEVICE_TYPE(MB8876,     mb8876_device,     "mb8876",     "Fujitsu MB8876 FDC")
66 DEFINE_DEVICE_TYPE(MB8877,     mb8877_device,     "mb8877",     "Fujitsu MB8877 FDC")
67 
68 DEFINE_DEVICE_TYPE(FD1761,     fd1761_device,     "fd1761",     "FD1761 FDC")
69 DEFINE_DEVICE_TYPE(FD1763,     fd1763_device,     "fd1763",     "FD1763 FDC")
70 DEFINE_DEVICE_TYPE(FD1765,     fd1765_device,     "fd1765",     "FD1765 FDC")
71 DEFINE_DEVICE_TYPE(FD1767,     fd1767_device,     "fd1767",     "FD1767 FDC")
72 
73 DEFINE_DEVICE_TYPE(WD2791,     wd2791_device,     "wd2791",     "Western Digital WD2791 FDC")
74 DEFINE_DEVICE_TYPE(WD2793,     wd2793_device,     "wd2793",     "Western Digital WD2793 FDC")
75 DEFINE_DEVICE_TYPE(WD2795,     wd2795_device,     "wd2795",     "Western Digital WD2795 FDC")
76 DEFINE_DEVICE_TYPE(WD2797,     wd2797_device,     "wd2797",     "Western Digital WD2797 FDC")
77 
78 DEFINE_DEVICE_TYPE(WD1770,     wd1770_device,     "wd1770",     "Western Digital WD1770 FDC")
79 DEFINE_DEVICE_TYPE(WD1772,     wd1772_device,     "wd1772",     "Western Digital WD1772 FDC")
80 DEFINE_DEVICE_TYPE(WD1773,     wd1773_device,     "wd1773",     "Western Digital WD1773 FDC")
81 
wd_fdc_device_base(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock)82 wd_fdc_device_base::wd_fdc_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
83 	device_t(mconfig, type, tag, owner, clock),
84 	intrq_cb(*this),
85 	drq_cb(*this),
86 	hld_cb(*this),
87 	enp_cb(*this),
88 	sso_cb(*this),
89 	ready_cb(*this), // actually output by the drive, not by the FDC
90 	enmf_cb(*this),
91 	mon_cb(*this)
92 {
93 	force_ready = false;
94 	disable_motor_control = false;
95 	spinup_on_interrupt = false;
96 	hlt = true; // assume tied to VCC
97 }
98 
set_force_ready(bool _force_ready)99 void wd_fdc_device_base::set_force_ready(bool _force_ready)
100 {
101 	force_ready = _force_ready;
102 }
103 
set_disable_motor_control(bool _disable_motor_control)104 void wd_fdc_device_base::set_disable_motor_control(bool _disable_motor_control)
105 {
106 	disable_motor_control = _disable_motor_control;
107 }
108 
device_start()109 void wd_fdc_device_base::device_start()
110 {
111 	intrq_cb.resolve();
112 	drq_cb.resolve();
113 	hld_cb.resolve();
114 	enp_cb.resolve();
115 	sso_cb.resolve();
116 	ready_cb.resolve();
117 	enmf_cb.resolve();
118 	mon_cb.resolve_safe();
119 
120 	if (!has_enmf && !enmf_cb.isnull())
121 		logerror("Warning, this chip doesn't have an ENMF line.\n");
122 
123 	t_gen = timer_alloc(TM_GEN);
124 	t_cmd = timer_alloc(TM_CMD);
125 	t_track = timer_alloc(TM_TRACK);
126 	t_sector = timer_alloc(TM_SECTOR);
127 	dden = disable_mfm;
128 	enmf = false;
129 	floppy = nullptr;
130 	status = 0x00;
131 	data = 0x00;
132 	track = 0x00;
133 	mr = true;
134 
135 	save_item(NAME(status));
136 	save_item(NAME(command));
137 	save_item(NAME(main_state));
138 	save_item(NAME(sub_state));
139 	save_item(NAME(track));
140 	save_item(NAME(sector));
141 	save_item(NAME(intrq_cond));
142 	save_item(NAME(cmd_buffer));
143 	save_item(NAME(track_buffer));
144 	save_item(NAME(sector_buffer));
145 	save_item(NAME(counter));
146 	save_item(NAME(status_type_1));
147 	save_item(NAME(last_dir));
148 	if (!disable_mfm)
149 		save_item(NAME(dden));
150 	save_item(NAME(mr));
151 	save_item(NAME(intrq));
152 	save_item(NAME(drq));
153 	if (head_control)
154 		save_item(NAME(hld));
155 }
156 
device_reset()157 void wd_fdc_device_base::device_reset()
158 {
159 	soft_reset();
160 }
161 
soft_reset()162 void wd_fdc_device_base::soft_reset()
163 {
164 	if(mr) {
165 		mr_w(0);
166 		mr_w(1);
167 	}
168 }
169 
WRITE_LINE_MEMBER(wd_fdc_device_base::mr_w)170 WRITE_LINE_MEMBER(wd_fdc_device_base::mr_w)
171 {
172 	if(mr && !state) {
173 		command = 0x03;
174 		main_state = IDLE;
175 		sub_state = IDLE;
176 		cur_live.state = IDLE;
177 		sector = 0x01;
178 		status = 0x00;
179 		cmd_buffer = track_buffer = sector_buffer = -1;
180 		counter = 0;
181 		status_type_1 = true;
182 		last_dir = 1;
183 		mr = false;
184 
185 		// gnd == enmf enabled, otherwise disabled (default)
186 		if (!enmf_cb.isnull() && has_enmf)
187 			enmf = enmf_cb() ? false : true;
188 
189 		intrq = false;
190 		if (!intrq_cb.isnull())
191 			intrq_cb(intrq);
192 		drq = false;
193 		if (!drq_cb.isnull())
194 			drq_cb(drq);
195 		if(head_control) {
196 			hld = false;
197 			if(!hld_cb.isnull())
198 				hld_cb(hld);
199 		}
200 
201 		mon_cb(1); // Clear the MON* line
202 
203 		intrq_cond = 0;
204 		live_abort();
205 	} else if(state && !mr) {
206 		// WD1770/72 (supposedly) not perform RESTORE after reset
207 		if (!motor_control) {
208 			// trigger a restore after everything else is reset too, in particular the floppy device itself
209 			status |= S_BUSY;
210 			sub_state = INITIAL_RESTORE;
211 			t_gen->adjust(attotime::zero);
212 		}
213 		mr = true;
214 	}
215 }
216 
set_floppy(floppy_image_device * _floppy)217 void wd_fdc_device_base::set_floppy(floppy_image_device *_floppy)
218 {
219 	if(floppy == _floppy)
220 		return;
221 
222 	int prev_ready = floppy ? floppy->ready_r() : 1;
223 
224 	if(floppy) {
225 		// Warning: deselecting a drive does *not* stop its motor if it was running
226 		floppy->setup_index_pulse_cb(floppy_image_device::index_pulse_cb());
227 		floppy->setup_ready_cb(floppy_image_device::ready_cb());
228 	}
229 
230 	floppy = _floppy;
231 
232 	int next_ready = floppy ? floppy->ready_r() : 1;
233 
234 	if (motor_control)
235 		mon_cb(status & S_MON ? 0 : 1);
236 
237 	if(floppy) {
238 		if(motor_control && !disable_motor_control)
239 			floppy->mon_w(status & S_MON ? 0 : 1);
240 		floppy->setup_index_pulse_cb(floppy_image_device::index_pulse_cb(&wd_fdc_device_base::index_callback, this));
241 		floppy->setup_ready_cb(floppy_image_device::ready_cb(&wd_fdc_device_base::ready_callback, this));
242 	}
243 
244 	if(prev_ready != next_ready)
245 		ready_callback(floppy, next_ready);
246 }
247 
WRITE_LINE_MEMBER(wd_fdc_device_base::dden_w)248 WRITE_LINE_MEMBER(wd_fdc_device_base::dden_w)
249 {
250 	if(disable_mfm) {
251 		logerror("Error, this chip does not have a dden line\n");
252 		return;
253 	}
254 
255 	if(dden != bool(state)) {
256 		dden = bool(state);
257 		LOGLINES("select %s\n", dden ? "fm" : "mfm");
258 	}
259 }
260 
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)261 void wd_fdc_device_base::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
262 {
263 	LOGEVENT("Event fired for timer %s\n", (id==TM_GEN)? "TM_GEN" : (id==TM_CMD)? "TM_CMD" : (id==TM_TRACK)? "TM_TRACK" : "TM_SECTOR");
264 	live_sync();
265 
266 	switch(id) {
267 	case TM_GEN: do_generic(); break;
268 	case TM_CMD: do_cmd_w(); break;
269 	case TM_TRACK: do_track_w(); break;
270 	case TM_SECTOR: do_sector_w(); break;
271 	}
272 
273 	general_continue();
274 }
275 
command_end()276 void wd_fdc_device_base::command_end()
277 {
278 	LOGFUNC("%s\n", FUNCNAME);
279 	main_state = sub_state = IDLE;
280 	motor_timeout = 0;
281 
282 	if(!drq && (status & S_BUSY)) {
283 		status &= ~S_BUSY;
284 		intrq = true;
285 		if(!intrq_cb.isnull())
286 			intrq_cb(intrq);
287 	}
288 }
289 
seek_start(int state)290 void wd_fdc_device_base::seek_start(int state)
291 {
292 	LOGCOMMAND("cmd: seek %d %x (track=%u)\n", state, data, track);
293 	main_state = state;
294 	status &= ~(S_CRC|S_RNF|S_SPIN);
295 	sub_state = motor_control ? SPINUP : SPINUP_DONE;
296 	status_type_1 = true;
297 	if(head_control) {
298 		if(BIT(command, 3))
299 			set_hld();
300 		else
301 			drop_hld();
302 	}
303 	seek_continue();
304 }
305 
seek_continue()306 void wd_fdc_device_base::seek_continue()
307 {
308 	for(;;) {
309 		switch(sub_state) {
310 		case SPINUP:
311 			LOGSTATE("SPINUP\n");
312 			if(!(status & S_MON)) {
313 				spinup();
314 				return;
315 			}
316 			if(!(command & 0x08))
317 				status |= S_SPIN;
318 			sub_state = SPINUP_DONE;
319 			break;
320 
321 		case SPINUP_WAIT:
322 			LOGSTATE("SPINUP_WAIT\n");
323 			return;
324 
325 		case SPINUP_DONE:
326 			LOGSTATE("SPINUP_DONE\n");
327 			if(main_state == RESTORE && floppy && !floppy->trk00_r()) {
328 				sub_state = SEEK_WAIT_STEP_TIME;
329 				delay_cycles(t_gen, step_times[command & 3]);
330 			}
331 
332 			if(main_state == SEEK && track == data) {
333 				if (command & 0x04) {
334 					set_hld();
335 					sub_state = SEEK_WAIT_STABILIZATION_TIME;
336 					delay_cycles(t_gen, 30000);
337 					return;
338 				}
339 				else
340 					sub_state = SEEK_DONE;
341 			}
342 
343 			if(sub_state == SPINUP_DONE) {
344 				counter = 0;
345 				sub_state = SEEK_MOVE;
346 			}
347 			break;
348 
349 		case SEEK_MOVE:
350 			LOGSTATE("SEEK_MOVE\n");
351 			if(floppy) {
352 				floppy->dir_w(last_dir);
353 				floppy->stp_w(0);
354 				floppy->stp_w(1);
355 			}
356 			// When stepping with update, the track register is updated before seeking.
357 			// Important for the sam coupe format code.
358 			if(main_state == STEP && (command & 0x10))
359 				track += last_dir ? -1 : 1;
360 			counter++;
361 			sub_state = SEEK_WAIT_STEP_TIME;
362 			delay_cycles(t_gen, step_times[command & 3]);
363 			return;
364 
365 		case SEEK_WAIT_STEP_TIME:
366 			LOGSTATE("SEEK_WAIT_STEP_TIME\n");
367 			return;
368 
369 		case SEEK_WAIT_STEP_TIME_DONE: {
370 			LOGSTATE("SEEK_WAIT_STEP_TIME_DONE\n");
371 			bool done = false;
372 			switch(main_state) {
373 			case RESTORE:
374 				done = floppy && !floppy->trk00_r();
375 				break;
376 			case SEEK:
377 				track += last_dir ? -1 : 1;
378 				done = track == data;
379 				break;
380 			case STEP:
381 				done = true;
382 				break;
383 			}
384 
385 			if(done || counter == 255) {
386 				if(main_state == RESTORE)
387 					track = 0;
388 
389 				if(command & 0x04) {
390 					set_hld();
391 					sub_state = SEEK_WAIT_STABILIZATION_TIME;
392 					delay_cycles(t_gen, 30000);
393 					return;
394 				} else
395 					sub_state = SEEK_DONE;
396 
397 			} else
398 				sub_state = SEEK_MOVE;
399 
400 			break;
401 		}
402 
403 		case SEEK_WAIT_STABILIZATION_TIME:
404 			LOGSTATE("SEEK_WAIT_STABILIZATION_TIME\n");
405 			return;
406 
407 		case SEEK_WAIT_STABILIZATION_TIME_DONE:
408 			LOGSTATE("SEEK_WAIT_STABILIZATION_TIME_DONE\n");
409 			// TODO: here should be HLT wait
410 			sub_state = SEEK_DONE;
411 			break;
412 
413 		case SEEK_DONE:
414 			LOGSTATE("SEEK_DONE\n");
415 			if(command & 0x04) {
416 				if(!is_ready()) {
417 					status |= S_RNF;
418 					command_end();
419 					return;
420 				}
421 				sub_state = SCAN_ID;
422 				counter = 0;
423 				live_start(SEARCH_ADDRESS_MARK_HEADER);
424 				return;
425 			}
426 			command_end();
427 			return;
428 
429 		case SCAN_ID:
430 			LOGSTATE("SCAN_ID\n");
431 			if(cur_live.idbuf[0] != track) {
432 				live_start(SEARCH_ADDRESS_MARK_HEADER);
433 				return;
434 			}
435 			if(cur_live.crc) {
436 				status |= S_CRC;
437 				live_start(SEARCH_ADDRESS_MARK_HEADER);
438 				return;
439 			}
440 			command_end();
441 			return;
442 
443 		case SCAN_ID_FAILED:
444 			LOGSTATE("SCAN_ID_FAILED\n");
445 			status |= S_RNF;
446 			command_end();
447 			return;
448 
449 		default:
450 			logerror("%s: seek unknown sub-state %d\n", machine().time().to_string(), sub_state);
451 			return;
452 		}
453 	}
454 }
455 
sector_matches() const456 bool wd_fdc_device_base::sector_matches() const
457 {
458 	   LOGMATCH("matching read T=%02x H=%02x S=%02x L=%02x - searched T=%02x S=%02x\n",
459 					cur_live.idbuf[0], cur_live.idbuf[1], cur_live.idbuf[2], cur_live.idbuf[3],
460 					track, sector);
461 
462 	if(cur_live.idbuf[0] != track || cur_live.idbuf[2] != sector)
463 		return false;
464 	if(!side_compare || ((command & 2)==0))
465 		return true;
466 	if(command & 8)
467 		return cur_live.idbuf[1] & 1;
468 	else
469 		return !(cur_live.idbuf[1] & 1);
470 }
471 
is_ready()472 bool wd_fdc_device_base::is_ready()
473 {
474 	return !ready_hooked || force_ready || (floppy && !floppy->ready_r());
475 }
476 
read_sector_start()477 void wd_fdc_device_base::read_sector_start()
478 {
479 	LOGCOMMAND("cmd: read sector%s (c=%02x) t=%d, s=%d\n", command & 0x10 ? " multiple" : "", command, track, sector);
480 	if(!is_ready()) {
481 		command_end();
482 		return;
483 	}
484 
485 	main_state = READ_SECTOR;
486 	status &= ~(S_CRC|S_LOST|S_RNF|S_WP|S_DDM);
487 	drop_drq();
488 	update_sso();
489 	set_hld();
490 	sub_state = motor_control ? SPINUP : SPINUP_DONE;
491 	status_type_1 = false;
492 	read_sector_continue();
493 }
494 
read_sector_continue()495 void wd_fdc_device_base::read_sector_continue()
496 {
497 	for(;;) {
498 		switch(sub_state) {
499 		case SPINUP:
500 			LOGSTATE("SPINUP\n");
501 			if(!(status & S_MON)) {
502 				spinup();
503 				return;
504 			}
505 			sub_state = SPINUP_DONE;
506 			break;
507 
508 		case SPINUP_WAIT:
509 			LOGSTATE("SPINUP_WAIT\n");
510 			return;
511 
512 		case SPINUP_DONE:
513 			LOGSTATE("SPINUP_DONE\n");
514 			if(command & 4) {
515 				sub_state = SETTLE_WAIT;
516 				delay_cycles(t_gen, settle_time());
517 				return;
518 			} else {
519 				sub_state = SETTLE_DONE;
520 				break;
521 			}
522 
523 		case SETTLE_WAIT:
524 			LOGSTATE("SETTLE_WAIT\n");
525 			return;
526 
527 		case SETTLE_DONE:
528 			LOGSTATE("SETTLE_DONE\n");
529 			sub_state = SCAN_ID;
530 			counter = 0;
531 			live_start(SEARCH_ADDRESS_MARK_HEADER);
532 			return;
533 
534 		case SCAN_ID:
535 			LOGSTATE("SCAN_ID\n");
536 			if(!sector_matches()) {
537 				live_start(SEARCH_ADDRESS_MARK_HEADER);
538 				return;
539 			}
540 			if(cur_live.crc) {
541 				status |= S_CRC;
542 				live_start(SEARCH_ADDRESS_MARK_HEADER);
543 				return;
544 			}
545 			sector_size = calc_sector_size(cur_live.idbuf[3], command);
546 			sub_state = SECTOR_READ;
547 			live_start(SEARCH_ADDRESS_MARK_DATA);
548 			return;
549 
550 		case SCAN_ID_FAILED:
551 			LOGSTATE("SCAN_ID_FAILED\n");
552 			status |= S_RNF;
553 			command_end();
554 			return;
555 
556 		case SECTOR_READ:
557 			LOGSTATE("SECTOR_READ\n");
558 			if(cur_live.crc)
559 				status |= S_CRC;
560 
561 			if(command & 0x10 && !(status & S_RNF)) {
562 				sector++;
563 				sub_state = SETTLE_DONE;
564 			} else {
565 				command_end();
566 				return;
567 			}
568 			break;
569 
570 		default:
571 			logerror("%s: read sector unknown sub-state %d\n", machine().time().to_string(), sub_state);
572 			return;
573 		}
574 	}
575 }
576 
read_track_start()577 void wd_fdc_device_base::read_track_start()
578 {
579 	LOGCOMMAND("cmd: read track (c=%02x) t=%d\n", command, track);
580 
581 	if(!is_ready()) {
582 		command_end();
583 		return;
584 	}
585 
586 	main_state = READ_TRACK;
587 	status &= ~(S_LOST|S_RNF);
588 	drop_drq();
589 	update_sso();
590 	set_hld();
591 	sub_state = motor_control ? SPINUP : SPINUP_DONE;
592 	status_type_1 = false;
593 	read_track_continue();
594 }
595 
read_track_continue()596 void wd_fdc_device_base::read_track_continue()
597 {
598 	for(;;) {
599 		switch(sub_state) {
600 		case SPINUP:
601 			LOGSTATE("SPINUP\n");
602 			if(!(status & S_MON)) {
603 				spinup();
604 				return;
605 			}
606 			sub_state = SPINUP_DONE;
607 			break;
608 
609 		case SPINUP_WAIT:
610 			LOGSTATE("SPINUP_WAIT\n");
611 			return;
612 
613 		case SPINUP_DONE:
614 			LOGSTATE("SPINUP_DONE\n");
615 			if(command & 4) {
616 				sub_state = SETTLE_WAIT;
617 				delay_cycles(t_gen, settle_time());
618 				return;
619 
620 			} else {
621 				sub_state = SETTLE_DONE;
622 				break;
623 			}
624 
625 		case SETTLE_WAIT:
626 			LOGSTATE("SETTLE_WAIT\n");
627 			return;
628 
629 		case SETTLE_DONE:
630 			LOGSTATE("SETTLE_DONE\n");
631 			sub_state = WAIT_INDEX;
632 			return;
633 
634 		case WAIT_INDEX:
635 			LOGSTATE("WAIT_INDEX\n");
636 			return;
637 
638 		case WAIT_INDEX_DONE:
639 			LOGSTATE("WAIT_INDEX_DONE\n");
640 			sub_state = TRACK_DONE;
641 			live_start(READ_TRACK_DATA);
642 			return;
643 
644 		case TRACK_DONE:
645 			LOGSTATE("TRACK_DONE\n");
646 			command_end();
647 			return;
648 
649 		default:
650 			logerror("%s: read track unknown sub-state %d\n", machine().time().to_string(), sub_state);
651 			return;
652 		}
653 	}
654 }
655 
read_id_start()656 void wd_fdc_device_base::read_id_start()
657 {
658 	LOGCOMMAND("cmd: read id (c=%02x)\n", command);
659 	if(!is_ready()) {
660 		LOGCOMMAND("cmd: - not ready!");
661 		command_end();
662 		return;
663 	}
664 
665 	main_state = READ_ID;
666 	status &= ~(S_WP|S_DDM|S_LOST|S_RNF);
667 	drop_drq();
668 	update_sso();
669 	set_hld();
670 	sub_state = motor_control ? SPINUP : SPINUP_DONE;
671 	status_type_1 = false;
672 	read_id_continue();
673 }
674 
read_id_continue()675 void wd_fdc_device_base::read_id_continue()
676 {
677 	LOGFUNC("%s\n", FUNCNAME);
678 	for(;;) {
679 		switch(sub_state) {
680 		case SPINUP:
681 			LOGSTATE("SPINUP\n");
682 			if(!(status & S_MON)) {
683 				spinup();
684 				return;
685 			}
686 			sub_state = SPINUP_DONE;
687 			break;
688 
689 		case SPINUP_WAIT:
690 			LOGSTATE("SPINUP_WAIT\n");
691 			return;
692 
693 		case SPINUP_DONE:
694 			LOGSTATE("SPINUP_DONE\n");
695 			if(command & 4) {
696 				sub_state = SETTLE_WAIT;
697 				delay_cycles(t_gen, settle_time());
698 				return;
699 			} else {
700 				sub_state = SETTLE_DONE;
701 				break;
702 			}
703 
704 		case SETTLE_WAIT:
705 			LOGSTATE("SETTLE_WAIT\n");
706 			return;
707 
708 		case SETTLE_DONE:
709 			LOGSTATE("SETTLE_DONE\n");
710 			sub_state = SCAN_ID;
711 			counter = 0;
712 			live_start(SEARCH_ADDRESS_MARK_HEADER);
713 			return;
714 
715 		case SCAN_ID:
716 			LOGSTATE("SCAN_ID\n");
717 			command_end();
718 			return;
719 
720 		case SCAN_ID_FAILED:
721 			LOGSTATE("SCAN_ID_FAILED\n");
722 			status |= S_RNF;
723 			command_end();
724 			return;
725 
726 		default:
727 			logerror("%s: read id unknown sub-state %d\n", machine().time().to_string(), sub_state);
728 			return;
729 		}
730 	}
731 }
732 
write_track_start()733 void wd_fdc_device_base::write_track_start()
734 {
735 	LOGCOMMAND("cmd: write track (c=%02x) t=%d\n", command, track);
736 
737 	if(!is_ready()) {
738 		command_end();
739 		return;
740 	}
741 
742 	main_state = WRITE_TRACK;
743 	status &= ~(S_WP|S_DDM|S_LOST|S_RNF);
744 	drop_drq();
745 	update_sso();
746 	set_hld();
747 	sub_state = motor_control ? SPINUP : SPINUP_DONE;
748 	status_type_1 = false;
749 
750 	format_last_byte = 0;
751 	format_last_byte_count = 0;
752 	format_description_string = "";
753 
754 	write_track_continue();
755 }
756 
write_track_continue()757 void wd_fdc_device_base::write_track_continue()
758 {
759 	for(;;) {
760 		switch(sub_state) {
761 		case SPINUP:
762 			LOGSTATE("SPINUP\n");
763 			if(!(status & S_MON)) {
764 				spinup();
765 				return;
766 			}
767 			sub_state = SPINUP_DONE;
768 			break;
769 
770 		case SPINUP_WAIT:
771 			LOGSTATE("SPINUP_WAIT\n");
772 			return;
773 
774 		case SPINUP_DONE:
775 			LOGSTATE("SPINUP_DONE\n");
776 			if(command & 4) {
777 				sub_state = SETTLE_WAIT;
778 				delay_cycles(t_gen, settle_time());
779 				return;
780 			} else {
781 				sub_state = SETTLE_DONE;
782 				break;
783 			}
784 
785 		case SETTLE_WAIT:
786 			LOGSTATE("SETTLE_WAIT\n");
787 			return;
788 
789 		case SETTLE_DONE:
790 			LOGSTATE("SETTLE_DONE\n");
791 			if (floppy && floppy->wpt_r()) {
792 				LOGSTATE("WRITE_PROT\n");
793 				status |= S_WP;
794 				command_end();
795 				return;
796 			}
797 			set_drq();
798 			sub_state = DATA_LOAD_WAIT;
799 			delay_cycles(t_gen, 192);
800 			return;
801 
802 		case DATA_LOAD_WAIT:
803 			LOGSTATE("DATA_LOAD_WAIT\n");
804 			return;
805 
806 		case DATA_LOAD_WAIT_DONE:
807 			LOGSTATE("DATA_LOAD_WAIT_DONE\n");
808 			if(drq) {
809 				status |= S_LOST;
810 				drop_drq();
811 				command_end();
812 				return;
813 			}
814 			sub_state = WAIT_INDEX;
815 			break;
816 
817 		case WAIT_INDEX:
818 			LOGSTATE("WAIT_INDEX\n");
819 			return;
820 
821 		case WAIT_INDEX_DONE:
822 			LOGSTATE("WAIT_INDEX_DONE\n");
823 			sub_state = TRACK_DONE;
824 			live_start(WRITE_TRACK_DATA);
825 			pll_start_writing(machine().time());
826 			return;
827 
828 		case TRACK_DONE:
829 			LOGSTATE("TRACK_DONE\n");
830 			if(format_last_byte_count) {
831 				char buf[32];
832 				if(format_last_byte_count > 1)
833 					sprintf(buf, "%dx%02x", format_last_byte_count, format_last_byte);
834 				else
835 					sprintf(buf, "%02x", format_last_byte);
836 				format_description_string += buf;
837 			}
838 			LOGDESC("track description %s\n", format_description_string.c_str());
839 			command_end();
840 			return;
841 
842 		default:
843 			logerror("%s: write track unknown sub-state %d\n", machine().time().to_string(), sub_state);
844 			return;
845 		}
846 	}
847 }
848 
849 
write_sector_start()850 void wd_fdc_device_base::write_sector_start()
851 {
852 	LOGCOMMAND("cmd: write sector%s (c=%02x) t=%d, s=%d\n", command & 0x10 ? " multiple" : "", command, track, sector);
853 
854 	if(!is_ready()) {
855 		command_end();
856 		return;
857 	}
858 
859 	main_state = WRITE_SECTOR;
860 	status &= ~(S_CRC|S_LOST|S_RNF|S_WP|S_DDM);
861 	drop_drq();
862 	update_sso();
863 	set_hld();
864 	sub_state = motor_control  ? SPINUP : SPINUP_DONE;
865 	status_type_1 = false;
866 	write_sector_continue();
867 }
868 
write_sector_continue()869 void wd_fdc_device_base::write_sector_continue()
870 {
871 	for(;;) {
872 		switch(sub_state) {
873 		case SPINUP:
874 			LOGSTATE("SPINUP\n");
875 			if(!(status & S_MON)) {
876 				spinup();
877 				return;
878 			}
879 			sub_state = SPINUP_DONE;
880 			break;
881 
882 		case SPINUP_WAIT:
883 			LOGSTATE("SPINUP_WAIT\n");
884 			return;
885 
886 		case SPINUP_DONE:
887 			LOGSTATE("SPINUP_DONE\n");
888 			if(command & 4) {
889 				sub_state = SETTLE_WAIT;
890 				delay_cycles(t_gen, settle_time());
891 				return;
892 			} else {
893 				sub_state = SETTLE_DONE;
894 				break;
895 			}
896 
897 		case SETTLE_WAIT:
898 			LOGSTATE("SETTLE_WAIT\n");
899 			return;
900 
901 		case SETTLE_DONE:
902 			LOGSTATE("SETTLE_DONE\n");
903 			if (floppy && floppy->wpt_r()) {
904 				LOGSTATE("WRITE_PROT\n");
905 				status |= S_WP;
906 				command_end();
907 				return;
908 			}
909 			sub_state = SCAN_ID;
910 			counter = 0;
911 			live_start(SEARCH_ADDRESS_MARK_HEADER);
912 			return;
913 
914 		case SCAN_ID:
915 			LOGSTATE("SCAN_ID\n");
916 			if(!sector_matches()) {
917 				live_start(SEARCH_ADDRESS_MARK_HEADER);
918 				return;
919 			}
920 			if(cur_live.crc) {
921 				status |= S_CRC;
922 				live_start(SEARCH_ADDRESS_MARK_HEADER);
923 				return;
924 			}
925 			sector_size = calc_sector_size(cur_live.idbuf[3], command);
926 			sub_state = SECTOR_WRITE;
927 			live_start(WRITE_SECTOR_PRE);
928 			return;
929 
930 		case SCAN_ID_FAILED:
931 			LOGSTATE("SCAN_ID_FAILED\n");
932 			status |= S_RNF;
933 			command_end();
934 			return;
935 
936 		case SECTOR_WRITE:
937 			LOGSTATE("SECTOR_WRITE\n");
938 			if(command & 0x10) {
939 				sector++;
940 				sub_state = SPINUP_DONE;
941 			} else {
942 				command_end();
943 				return;
944 			}
945 			break;
946 
947 		default:
948 			logerror("%s: write sector unknown sub-state %d\n", machine().time().to_string(), sub_state);
949 			return;
950 		}
951 	}
952 }
953 
interrupt_start()954 void wd_fdc_device_base::interrupt_start()
955 {
956 	// technically we should re-execute this (at chip-specific rate) all the time while interrupt command code is in command register
957 
958 	LOGCOMMAND("cmd: forced interrupt (c=%02x)\n", command);
959 
960 	if(status & S_BUSY) {
961 		main_state = sub_state = cur_live.state = IDLE;
962 		cur_live.tm = attotime::never;
963 		status &= ~S_BUSY;
964 		drop_drq();
965 		motor_timeout = 0;
966 	}
967 	else
968 	{
969 		// when a force interrupt command is issued and there is no
970 		// currently running command, return the status type 1 bits
971 		status_type_1 = true;
972 	}
973 
974 	intrq_cond = command & 0x0f;
975 
976 	if(!intrq && (command & I_IMM)) {
977 		intrq = true;
978 		if(!intrq_cb.isnull())
979 			intrq_cb(intrq);
980 	}
981 
982 	if (spinup_on_interrupt)  // see notes in FD1771 and WD1772 constructors, might be true for other FDC types as well.
983 	{
984 		motor_timeout = 0;
985 
986 		if (head_control)
987 			set_hld();
988 
989 		if (motor_control) {
990 			status |= S_MON | S_SPIN;
991 
992 			mon_cb(0);
993 			if (floppy && !disable_motor_control)
994 				floppy->mon_w(0);
995 		}
996 	}
997 
998 	if(command & 0x03) {
999 		logerror("%s: unhandled interrupt generation (%02x)\n", machine().time().to_string(), command);
1000 	}
1001 }
1002 
general_continue()1003 void wd_fdc_device_base::general_continue()
1004 {
1005 	LOGFUNC("%s\n", FUNCNAME);
1006 	if(cur_live.state != IDLE) {
1007 		live_run();
1008 		if(cur_live.state != IDLE)
1009 			return;
1010 	}
1011 
1012 	switch(main_state) {
1013 	case IDLE:
1014 		break;
1015 	case RESTORE: case SEEK: case STEP:
1016 		seek_continue();
1017 		break;
1018 	case READ_SECTOR:
1019 		read_sector_continue();
1020 		break;
1021 	case READ_TRACK:
1022 		read_track_continue();
1023 		break;
1024 	case READ_ID:
1025 		read_id_continue();
1026 		break;
1027 	case WRITE_TRACK:
1028 		write_track_continue();
1029 		break;
1030 	case WRITE_SECTOR:
1031 		write_sector_continue();
1032 		break;
1033 	default:
1034 		logerror("%s: general_continue on unknown main-state %d\n", machine().time().to_string(), main_state);
1035 		break;
1036 	}
1037 }
1038 
do_generic()1039 void wd_fdc_device_base::do_generic()
1040 {
1041 	switch(sub_state) {
1042 	case IDLE:
1043 	case SCAN_ID:
1044 	case SECTOR_READ:
1045 		break;
1046 
1047 	case SETTLE_WAIT:
1048 		sub_state = SETTLE_DONE;
1049 		break;
1050 
1051 	case SEEK_WAIT_STEP_TIME:
1052 		sub_state = SEEK_WAIT_STEP_TIME_DONE;
1053 		break;
1054 
1055 	case SEEK_WAIT_STABILIZATION_TIME:
1056 		sub_state = SEEK_WAIT_STABILIZATION_TIME_DONE;
1057 		break;
1058 
1059 	case DATA_LOAD_WAIT:
1060 		sub_state = DATA_LOAD_WAIT_DONE;
1061 		break;
1062 
1063 	case INITIAL_RESTORE:
1064 		last_dir = 1;
1065 		seek_start(RESTORE);
1066 		break;
1067 
1068 	default:
1069 		if(cur_live.tm.is_never())
1070 			logerror("%s: do_generic on unknown sub-state %d\n", machine().time().to_string(), sub_state);
1071 		break;
1072 	}
1073 }
1074 
do_cmd_w()1075 void wd_fdc_device_base::do_cmd_w()
1076 {
1077 	// it is actually possible to send another command even while in busy state.
1078 	// currently we simply accept any commands, but chip logic probably more complex (presumable it is possible change command of the same type only).
1079 #if 0
1080 	// Only available command when busy is interrupt
1081 	if(main_state != IDLE && (cmd_buffer & 0xf0) != 0xd0) {
1082 		cmd_buffer = -1;
1083 		return;
1084 	}
1085 #endif
1086 	command = cmd_buffer;
1087 	cmd_buffer = -1;
1088 
1089 	LOGCOMMAND("%s %02x: %s\n", FUNCNAME, command, std::array<char const *, 16>
1090 		   {{"RESTORE", "SEEK", "STEP", "STEP", "STEP in", "STEP in", "STEP out", "STEP out",
1091 			 "READ sector start", "READ sector start", "WRITE sector start", "WRITE sector start",
1092 			 "READ ID start",     "INTERRUPT start",   "READ track start",   "WRITE track start"}}[(command >> 4) & 0x0f]);
1093 	switch(command & 0xf0) {
1094 	case 0x00:
1095 		last_dir = 1;
1096 		seek_start(RESTORE);
1097 		break;
1098 	case 0x10:
1099 		last_dir = data > track ? 0 : 1;
1100 		seek_start(SEEK);
1101 		break;
1102 	case 0x20:
1103 	case 0x30:
1104 		seek_start(STEP);
1105 		break;
1106 	case 0x40:
1107 	case 0x50:
1108 		last_dir = 0;
1109 		seek_start(STEP);
1110 		break;
1111 	case 0x60:
1112 	case 0x70:
1113 		last_dir = 1;
1114 		seek_start(STEP);
1115 		break;
1116 	case 0x80:
1117 	case 0x90:
1118 		read_sector_start();
1119 		break;
1120 	case 0xa0:
1121 	case 0xb0:
1122 		write_sector_start();
1123 		break;
1124 	case 0xc0:
1125 		read_id_start();
1126 		break;
1127 	case 0xd0:
1128 		interrupt_start();
1129 		break;
1130 	case 0xe0:
1131 		read_track_start();
1132 		break;
1133 	case 0xf0:
1134 		write_track_start();
1135 		break;
1136 	}
1137 }
1138 
cmd_w(uint8_t val)1139 void wd_fdc_device_base::cmd_w(uint8_t val)
1140 {
1141 	if (inverted_bus) val ^= 0xff;
1142 	if (!mr) {
1143 		logerror("Not initiating command %02x during master reset\n", val);
1144 		return;
1145 	}
1146 
1147 	LOGCOMP("Initiating command %02x\n", val);
1148 
1149 	if (intrq) {
1150 		intrq = false;
1151 		if(!intrq_cb.isnull())
1152 			intrq_cb(intrq);
1153 	}
1154 
1155 	// No more than one write in flight, but interrupts take priority
1156 	if(cmd_buffer != -1 && ((val & 0xf0) != 0xd0))
1157 		return;
1158 
1159 	cmd_buffer = val;
1160 
1161 	if ((val & 0xf0) == 0xd0)
1162 	{
1163 		// checkme timings
1164 		delay_cycles(t_cmd, dden ? delay_register_commit * 2 : delay_register_commit);
1165 	}
1166 	else
1167 	{
1168 		intrq_cond = 0;
1169 		// set busy, then set a timer to process the command
1170 		status |= S_BUSY;
1171 		delay_cycles(t_cmd, dden ? delay_command_commit*2 : delay_command_commit);
1172 	}
1173 }
1174 
status_r()1175 uint8_t wd_fdc_device_base::status_r()
1176 {
1177 	if(intrq && !(intrq_cond & I_IMM) && !machine().side_effects_disabled()) {
1178 		intrq = false;
1179 		if(!intrq_cb.isnull())
1180 			intrq_cb(intrq);
1181 	}
1182 
1183 	if(status_type_1) {
1184 		if(floppy && floppy->idx_r())
1185 			status |= S_IP;
1186 		else
1187 			status &= ~S_IP;
1188 	} else {
1189 		if(drq)
1190 			status |= S_DRQ;
1191 		else
1192 			status &= ~S_DRQ;
1193 	}
1194 
1195 	if (status_type_1 && head_control)
1196 	{ // note: this status bit is AND of HLD latch and HLT input line
1197 		if (hld && hlt)
1198 			status |= S_HLD;
1199 		else
1200 			status &= ~S_HLD;
1201 	}
1202 
1203 	if(status_type_1) {
1204 		status &= ~(S_TR00|S_WP);
1205 		if(floppy) {
1206 			if(floppy->wpt_r())
1207 				status |= S_WP;
1208 			if(!floppy->trk00_r())
1209 				status |= S_TR00;
1210 		}
1211 	}
1212 
1213 	if(ready_hooked) {
1214 		if(!is_ready())
1215 			status |= S_NRDY;
1216 		else
1217 			status &= ~S_NRDY;
1218 	}
1219 
1220 	uint8_t val = status;
1221 	if (inverted_bus) val ^= 0xff;
1222 
1223 	return val;
1224 }
1225 
do_track_w()1226 void wd_fdc_device_base::do_track_w()
1227 {
1228 	track = track_buffer;
1229 	track_buffer = -1;
1230 }
1231 
track_w(uint8_t val)1232 void wd_fdc_device_base::track_w(uint8_t val)
1233 {
1234 	if (inverted_bus) val ^= 0xff;
1235 
1236 	// No more than one write in flight
1237 	if(track_buffer != -1 || !mr)
1238 		return;
1239 
1240 	track_buffer = val;
1241 	delay_cycles(t_track, dden ? delay_register_commit*2 : delay_register_commit);
1242 }
1243 
track_r()1244 uint8_t wd_fdc_device_base::track_r()
1245 {
1246 	uint8_t val = track;
1247 	if (inverted_bus) val ^= 0xff;
1248 
1249 	return val;
1250 }
1251 
do_sector_w()1252 void wd_fdc_device_base::do_sector_w()
1253 {
1254 	sector = sector_buffer;
1255 	sector_buffer = -1;
1256 }
1257 
sector_w(uint8_t val)1258 void wd_fdc_device_base::sector_w(uint8_t val)
1259 {
1260 	if (!mr) return;
1261 
1262 	if (inverted_bus) val ^= 0xff;
1263 
1264 	// No more than one write in flight
1265 	// C1581 accesses this register with an INC opcode,
1266 	// i.e. write old value, write new value, and the new value gets ignored by this
1267 	//if(sector_buffer != -1)
1268 	//  return;
1269 
1270 	sector_buffer = val;
1271 
1272 	// set a timer to write the new value to the register, but only if we aren't in
1273 	// the middle of an already occurring update
1274 	if (!t_sector->enabled())
1275 		delay_cycles(t_sector, dden ? delay_register_commit*2 : delay_register_commit);
1276 }
1277 
sector_r()1278 uint8_t wd_fdc_device_base::sector_r()
1279 {
1280 	uint8_t val = sector;
1281 	if (inverted_bus) val ^= 0xff;
1282 
1283 	return val;
1284 }
1285 
data_w(uint8_t val)1286 void wd_fdc_device_base::data_w(uint8_t val)
1287 {
1288 	if (!mr) return;
1289 
1290 	if (inverted_bus) val ^= 0xff;
1291 
1292 	data = val;
1293 	drop_drq();
1294 }
1295 
data_r()1296 uint8_t wd_fdc_device_base::data_r()
1297 {
1298 	if (!machine().side_effects_disabled())
1299 		drop_drq();
1300 
1301 	uint8_t val = data;
1302 	if (inverted_bus) val ^= 0xff;
1303 
1304 	return val;
1305 }
1306 
write(offs_t reg,uint8_t val)1307 void wd_fdc_device_base::write(offs_t reg, uint8_t val)
1308 {
1309 	LOGFUNC("%s %02x: %02x\n", FUNCNAME, reg, val);
1310 	switch(reg) {
1311 	case 0: cmd_w(val); break;
1312 	case 1: track_w(val); break;
1313 	case 2: sector_w(val); break;
1314 	case 3: data_w(val); break;
1315 	}
1316 }
1317 
read(offs_t reg)1318 uint8_t wd_fdc_device_base::read(offs_t reg)
1319 {
1320 	switch(reg) {
1321 	case 0: return status_r();
1322 	case 1: return track_r();
1323 	case 2: return sector_r();
1324 	case 3: return data_r();
1325 	}
1326 	return 0xff;
1327 }
1328 
delay_cycles(emu_timer * tm,int cycles)1329 void wd_fdc_device_base::delay_cycles(emu_timer *tm, int cycles)
1330 {
1331 	tm->adjust(clocks_to_attotime(cycles*clock_ratio));
1332 }
1333 
spinup()1334 void wd_fdc_device_base::spinup()
1335 {
1336 	if(command & 0x08)
1337 		sub_state = SPINUP_DONE;
1338 	else {
1339 		sub_state = SPINUP_WAIT;
1340 		counter = 0;
1341 	}
1342 
1343 	status |= S_MON|S_SPIN;
1344 
1345 	mon_cb(0);
1346 	if(floppy && !disable_motor_control)
1347 		floppy->mon_w(0);
1348 }
1349 
ready_callback(floppy_image_device * floppy,int state)1350 void wd_fdc_device_base::ready_callback(floppy_image_device *floppy, int state)
1351 {
1352 	if(!ready_cb.isnull())
1353 		ready_cb(state);
1354 
1355 	// why is this even possible?
1356 	if (!floppy)
1357 		return;
1358 
1359 	live_sync();
1360 	if(!ready_hooked)
1361 		return;
1362 
1363 	if(!intrq && (((intrq_cond & I_RDY) && !state) || ((intrq_cond & I_NRDY) && state))) {
1364 		intrq = true;
1365 		if(!intrq_cb.isnull())
1366 			intrq_cb(intrq);
1367 	}
1368 }
1369 
index_callback(floppy_image_device * floppy,int state)1370 void wd_fdc_device_base::index_callback(floppy_image_device *floppy, int state)
1371 {
1372 	live_sync();
1373 
1374 	if(!state) {
1375 		//general_continue();
1376 		return;
1377 	}
1378 
1379 	switch(sub_state) {
1380 	case IDLE:
1381 		if(motor_control || head_control) {
1382 			motor_timeout ++;
1383 			// Spindown delay is 9 revs according to spec
1384 			if(motor_control && motor_timeout >= 8) {
1385 				status &= ~S_MON;
1386 				mon_cb(1);
1387 				if(floppy && !disable_motor_control)
1388 					floppy->mon_w(1);
1389 			}
1390 
1391 			if(head_control && motor_timeout >= hld_timeout)
1392 				drop_hld();
1393 		}
1394 
1395 		if(!intrq && (intrq_cond & I_IDX)) {
1396 			intrq = true;
1397 			if(!intrq_cb.isnull())
1398 				intrq_cb(intrq);
1399 		}
1400 		break;
1401 
1402 	case SPINUP:
1403 		break;
1404 
1405 	case SPINUP_WAIT:
1406 		counter++;
1407 		if(counter == 6) {
1408 			sub_state = SPINUP_DONE;
1409 			if(status_type_1)
1410 				status |= S_SPIN;
1411 		}
1412 		break;
1413 
1414 	case SPINUP_DONE:
1415 	case SETTLE_WAIT:
1416 	case SETTLE_DONE:
1417 	case DATA_LOAD_WAIT:
1418 	case DATA_LOAD_WAIT_DONE:
1419 	case SEEK_MOVE:
1420 	case SEEK_WAIT_STEP_TIME:
1421 	case SEEK_WAIT_STEP_TIME_DONE:
1422 	case SEEK_WAIT_STABILIZATION_TIME:
1423 	case SEEK_WAIT_STABILIZATION_TIME_DONE:
1424 	case SEEK_DONE:
1425 	case WAIT_INDEX_DONE:
1426 	case SCAN_ID_FAILED:
1427 	case SECTOR_READ:
1428 	case SECTOR_WRITE:
1429 		break;
1430 
1431 	case SCAN_ID:
1432 		counter++;
1433 		if(counter == 5) {
1434 			sub_state = SCAN_ID_FAILED;
1435 			live_abort();
1436 		}
1437 		break;
1438 
1439 	case WAIT_INDEX:
1440 		sub_state = WAIT_INDEX_DONE;
1441 		break;
1442 
1443 	case TRACK_DONE:
1444 		live_abort();
1445 		break;
1446 
1447 	case DUMMY:
1448 		return;
1449 
1450 	default:
1451 		logerror("%s: Index pulse on unknown sub-state %d\n", machine().time().to_string(), sub_state);
1452 		break;
1453 	}
1454 
1455 	general_continue();
1456 }
1457 
READ_LINE_MEMBER(wd_fdc_device_base::intrq_r)1458 READ_LINE_MEMBER(wd_fdc_device_base::intrq_r)
1459 {
1460 	return intrq;
1461 }
1462 
READ_LINE_MEMBER(wd_fdc_device_base::drq_r)1463 READ_LINE_MEMBER(wd_fdc_device_base::drq_r)
1464 {
1465 	return drq;
1466 }
1467 
READ_LINE_MEMBER(wd_fdc_device_base::hld_r)1468 READ_LINE_MEMBER(wd_fdc_device_base::hld_r)
1469 {
1470 	return hld;
1471 }
1472 
WRITE_LINE_MEMBER(wd_fdc_device_base::hlt_w)1473 WRITE_LINE_MEMBER(wd_fdc_device_base::hlt_w)
1474 {
1475 	hlt = bool(state);
1476 }
1477 
READ_LINE_MEMBER(wd_fdc_device_base::enp_r)1478 READ_LINE_MEMBER(wd_fdc_device_base::enp_r)
1479 {
1480 	return enp;
1481 }
1482 
live_start(int state)1483 void wd_fdc_device_base::live_start(int state)
1484 {
1485 	LOGFUNC("%s\n", FUNCNAME);
1486 	cur_live.tm = machine().time();
1487 	cur_live.state = state;
1488 	cur_live.next_state = -1;
1489 	cur_live.shift_reg = 0;
1490 	cur_live.crc = 0xffff;
1491 	cur_live.bit_counter = 0;
1492 	cur_live.data_separator_phase = false;
1493 	cur_live.data_reg = 0;
1494 	cur_live.previous_type = live_info::PT_NONE;
1495 	cur_live.data_bit_context = false;
1496 	cur_live.byte_counter = 0;
1497 
1498 	if (!enmf_cb.isnull() && has_enmf)
1499 		enmf = enmf_cb() ? false : true;
1500 
1501 	pll_reset(dden, enmf, cur_live.tm);
1502 	checkpoint_live = cur_live;
1503 	pll_save_checkpoint();
1504 
1505 	live_run();
1506 }
1507 
checkpoint()1508 void wd_fdc_device_base::checkpoint()
1509 {
1510 	LOGFUNC("%s\n", FUNCNAME);
1511 	pll_commit(floppy, cur_live.tm);
1512 	checkpoint_live = cur_live;
1513 	pll_save_checkpoint();
1514 }
1515 
rollback()1516 void wd_fdc_device_base::rollback()
1517 {
1518 	cur_live = checkpoint_live;
1519 	pll_retrieve_checkpoint();
1520 }
1521 
live_delay(int state)1522 void wd_fdc_device_base::live_delay(int state)
1523 {
1524 	cur_live.next_state = state;
1525 	t_gen->adjust(cur_live.tm - machine().time());
1526 }
1527 
live_sync()1528 void wd_fdc_device_base::live_sync()
1529 {
1530 	if(!cur_live.tm.is_never()) {
1531 		if(cur_live.tm > machine().time()) {
1532 			LOGSYNC("%s: Rolling back and replaying (%s)\n", machine().time().to_string(), cur_live.tm.to_string());
1533 			rollback();
1534 			live_run(machine().time());
1535 			pll_commit(floppy, cur_live.tm);
1536 		} else {
1537 			LOGSYNC("%s: Committing (%s)\n", machine().time().to_string(), cur_live.tm.to_string());
1538 			pll_commit(floppy, cur_live.tm);
1539 			if(cur_live.next_state != -1) {
1540 				cur_live.state = cur_live.next_state;
1541 				cur_live.next_state = -1;
1542 			}
1543 			if(cur_live.state == IDLE) {
1544 				pll_stop_writing(floppy, cur_live.tm);
1545 				cur_live.tm = attotime::never;
1546 			}
1547 		}
1548 		cur_live.next_state = -1;
1549 		checkpoint();
1550 	}
1551 }
1552 
live_abort()1553 void wd_fdc_device_base::live_abort()
1554 {
1555 	if(!cur_live.tm.is_never() && cur_live.tm > machine().time()) {
1556 		rollback();
1557 		live_run(machine().time());
1558 	}
1559 
1560 	pll_stop_writing(floppy, cur_live.tm);
1561 	cur_live.tm = attotime::never;
1562 	cur_live.state = IDLE;
1563 	cur_live.next_state = -1;
1564 }
1565 
read_one_bit(const attotime & limit)1566 bool wd_fdc_device_base::read_one_bit(const attotime &limit)
1567 {
1568 	int bit = pll_get_next_bit(cur_live.tm, floppy, limit);
1569 	if(bit < 0)
1570 		return true;
1571 	cur_live.shift_reg = (cur_live.shift_reg << 1) | bit;
1572 	cur_live.bit_counter++;
1573 	if(cur_live.data_separator_phase) {
1574 		cur_live.data_reg = (cur_live.data_reg << 1) | bit;
1575 		if((cur_live.crc ^ (bit ? 0x8000 : 0x0000)) & 0x8000)
1576 			cur_live.crc = (cur_live.crc << 1) ^ 0x1021;
1577 		else
1578 			cur_live.crc = cur_live.crc << 1;
1579 	}
1580 	cur_live.data_separator_phase = !cur_live.data_separator_phase;
1581 	return false;
1582 }
1583 
write_one_bit(const attotime & limit)1584 bool wd_fdc_device_base::write_one_bit(const attotime &limit)
1585 {
1586 	bool bit = cur_live.shift_reg & 0x8000;
1587 	if(pll_write_next_bit(bit, cur_live.tm, floppy, limit))
1588 		return true;
1589 	if(cur_live.bit_counter & 1) {
1590 		if((cur_live.crc ^ (bit ? 0x8000 : 0x0000)) & 0x8000)
1591 			cur_live.crc = (cur_live.crc << 1) ^ 0x1021;
1592 		else
1593 			cur_live.crc = cur_live.crc << 1;
1594 	}
1595 	cur_live.shift_reg = cur_live.shift_reg << 1;
1596 	cur_live.bit_counter--;
1597 	return false;
1598 }
1599 
live_write_raw(uint16_t raw)1600 void wd_fdc_device_base::live_write_raw(uint16_t raw)
1601 {
1602 	LOGWRITE("write raw %04x, CRC=%04x\n", raw, cur_live.crc);
1603 	cur_live.shift_reg = raw;
1604 	cur_live.data_bit_context = raw & 1;
1605 }
1606 
live_write_mfm(uint8_t mfm)1607 void wd_fdc_device_base::live_write_mfm(uint8_t mfm)
1608 {
1609 	bool context = cur_live.data_bit_context;
1610 	uint16_t raw = 0;
1611 	for(int i=0; i<8; i++) {
1612 		bool bit = mfm & (0x80 >> i);
1613 		if(!(bit || context))
1614 			raw |= 0x8000 >> (2*i);
1615 		if(bit)
1616 			raw |= 0x4000 >> (2*i);
1617 		context = bit;
1618 	}
1619 	cur_live.shift_reg = raw;
1620 	cur_live.data_bit_context = context;
1621 	LOGWRITE("live_write_mfm byte=%02x, raw=%04x, CRC=%04x\n", mfm, raw, cur_live.crc);
1622 }
1623 
1624 
live_write_fm(uint8_t fm)1625 void wd_fdc_device_base::live_write_fm(uint8_t fm)
1626 {
1627 	uint16_t raw = 0xaaaa;
1628 	for(int i=0; i<8; i++)
1629 		if(fm & (0x80 >> i))
1630 			raw |= 0x4000 >> (2*i);
1631 	cur_live.data_reg = fm;
1632 	cur_live.shift_reg = raw;
1633 	cur_live.data_bit_context = fm & 1;
1634 	LOGWRITE("live_write_fm byte=%02x, raw=%04x, CRC=%04x\n", fm, raw, cur_live.crc);
1635 }
1636 
live_run(attotime limit)1637 void wd_fdc_device_base::live_run(attotime limit)
1638 {
1639   //    LOG("%s\n", FUNCNAME);
1640 	if(cur_live.state == IDLE || cur_live.next_state != -1)
1641 		return;
1642 
1643 	if(limit == attotime::never) {
1644 		if(floppy)
1645 			limit = floppy->time_next_index();
1646 		if(limit == attotime::never) {
1647 			// Happens when there's no disk or if the wd is not
1648 			// connected to a drive, hence no index pulse. Force a
1649 			// sync from time to time in that case, so that the main
1650 			// cpu timeout isn't too painful.  Avoids looping into
1651 			// infinity looking for data too.
1652 
1653 			limit = machine().time() + attotime::from_msec(1);
1654 			t_gen->adjust(attotime::from_msec(1));
1655 		}
1656 	}
1657 
1658 	//  logerror("%s: live_run(%s)\n", machine().time().to_string(), limit.to_string());
1659 
1660 	for(;;) {
1661 		switch(cur_live.state) {
1662 		case SEARCH_ADDRESS_MARK_HEADER:
1663 			LOGLIVE("%s - SEARCH_ADDRESS_MARK_HEADER\n", FUNCNAME);
1664 			if(read_one_bit(limit))
1665 				return;
1666 
1667 			LOGSHIFT("%s: shift = %04x data=%02x c=%d\n", cur_live.tm.to_string(), cur_live.shift_reg,
1668 					(cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) |
1669 					(cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) |
1670 					(cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) |
1671 					(cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) |
1672 					(cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) |
1673 					(cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) |
1674 					(cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) |
1675 					(cur_live.shift_reg & 0x0001 ? 0x01 : 0x00),
1676 					cur_live.bit_counter);
1677 
1678 			if(!dden && cur_live.shift_reg == 0x4489) {
1679 				cur_live.crc = 0x443b;
1680 				cur_live.data_separator_phase = false;
1681 				cur_live.bit_counter = 0;
1682 				cur_live.state = READ_HEADER_BLOCK_HEADER;
1683 			}
1684 
1685 			if(dden && cur_live.shift_reg == 0xf57e) {
1686 				cur_live.crc = 0xef21;
1687 				cur_live.data_separator_phase = false;
1688 				cur_live.bit_counter = 0;
1689 				if(main_state == READ_ID)
1690 					cur_live.state = READ_ID_BLOCK_TO_DMA;
1691 				else
1692 					cur_live.state = READ_ID_BLOCK_TO_LOCAL;
1693 			}
1694 			break;
1695 
1696 		case READ_HEADER_BLOCK_HEADER: {
1697 			LOGLIVE("%s - READ_HEADER_BLOCK_HEADER\n", FUNCNAME);
1698 			if(read_one_bit(limit))
1699 				return;
1700 
1701 			LOGSHIFT("%s: shift = %04x data=%02x counter=%d\n", cur_live.tm.to_string(), cur_live.shift_reg,
1702 					(cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) |
1703 					(cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) |
1704 					(cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) |
1705 					(cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) |
1706 					(cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) |
1707 					(cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) |
1708 					(cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) |
1709 					(cur_live.shift_reg & 0x0001 ? 0x01 : 0x00),
1710 					cur_live.bit_counter);
1711 
1712 			if(cur_live.bit_counter & 15)
1713 				break;
1714 
1715 			int slot = cur_live.bit_counter >> 4;
1716 
1717 			if(slot < 3) {
1718 				if(cur_live.shift_reg != 0x4489)
1719 					cur_live.state = SEARCH_ADDRESS_MARK_HEADER;
1720 				break;
1721 			}
1722 			if(cur_live.data_reg != 0xfe && cur_live.data_reg != 0xff) {
1723 				cur_live.state = SEARCH_ADDRESS_MARK_HEADER;
1724 				break;
1725 			}
1726 
1727 			cur_live.bit_counter = 0;
1728 
1729 			if(main_state == READ_ID)
1730 				cur_live.state = READ_ID_BLOCK_TO_DMA;
1731 			else
1732 				cur_live.state = READ_ID_BLOCK_TO_LOCAL;
1733 
1734 			break;
1735 		}
1736 
1737 		case READ_ID_BLOCK_TO_LOCAL: {
1738 			LOGLIVE("%s - READ_ID_BLOCK_TO_LOCAL\n", FUNCNAME);
1739 			if(read_one_bit(limit))
1740 				return;
1741 			if(cur_live.bit_counter & 15)
1742 				break;
1743 			int slot = (cur_live.bit_counter >> 4)-1;
1744 			//          logerror("%s: slot[%d] = %02x  crc = %04x\n", cur_live.tm.to_string(), slot, cur_live.data_reg, cur_live.crc);
1745 			cur_live.idbuf[slot] = cur_live.data_reg;
1746 			if(slot == 5) {
1747 				live_delay(IDLE);
1748 				return;
1749 			}
1750 			break;
1751 		}
1752 
1753 		case READ_ID_BLOCK_TO_DMA:
1754 			LOGLIVE("%s - READ_ID_BLOCK_TO_DMA\n", FUNCNAME);
1755 			if(read_one_bit(limit))
1756 				return;
1757 			if(cur_live.bit_counter & 15)
1758 				break;
1759 			live_delay(READ_ID_BLOCK_TO_DMA_BYTE);
1760 			return;
1761 
1762 		case READ_ID_BLOCK_TO_DMA_BYTE:
1763 			LOGLIVE("%s - READ_ID_BLOCK_TO_DMA_BYTE\n", FUNCNAME);
1764 			data = cur_live.data_reg;
1765 			if(cur_live.bit_counter == 16)
1766 				sector = data;
1767 			set_drq();
1768 
1769 			if(cur_live.bit_counter == 16*6) {
1770 				if(cur_live.crc) {
1771 					status |= S_CRC;
1772 				}
1773 
1774 				// Already synchronous
1775 				cur_live.state = IDLE;
1776 				return;
1777 			}
1778 
1779 			cur_live.state = READ_ID_BLOCK_TO_DMA;
1780 			checkpoint();
1781 			break;
1782 
1783 		case SEARCH_ADDRESS_MARK_DATA:
1784 			LOGLIVE("%s - SEARCH_ADDRESS_MARK_DATA\n", FUNCNAME);
1785 			if(read_one_bit(limit))
1786 				return;
1787 
1788 			LOGSHIFT("%s: shift = %04x data=%02x c=%d.%x\n", cur_live.tm.to_string(), cur_live.shift_reg,
1789 					(cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) |
1790 					(cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) |
1791 					(cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) |
1792 					(cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) |
1793 					(cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) |
1794 					(cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) |
1795 					(cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) |
1796 					(cur_live.shift_reg & 0x0001 ? 0x01 : 0x00),
1797 					cur_live.bit_counter >> 4, cur_live.bit_counter & 15);
1798 
1799 			if(!dden) {
1800 				if(cur_live.bit_counter > 43*16) {
1801 					live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED);
1802 					return;
1803 				}
1804 
1805 				if(cur_live.bit_counter >= 28*16 && cur_live.shift_reg == 0x4489) {
1806 					cur_live.crc = 0x443b;
1807 					cur_live.data_separator_phase = false;
1808 					cur_live.bit_counter = 0;
1809 					cur_live.state = READ_DATA_BLOCK_HEADER;
1810 				}
1811 			} else {
1812 				if(cur_live.bit_counter > 23*16) {
1813 					live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED);
1814 					return;
1815 				}
1816 
1817 				if(cur_live.bit_counter >= 11*16 && (cur_live.shift_reg == 0xf56a || cur_live.shift_reg == 0xf56b ||
1818 														cur_live.shift_reg == 0xf56e || cur_live.shift_reg == 0xf56f)) {
1819 					cur_live.crc =
1820 						cur_live.shift_reg == 0xf56a ? 0x8fe7 :
1821 						cur_live.shift_reg == 0xf56b ? 0x9fc6 :
1822 						cur_live.shift_reg == 0xf56e ? 0xafa5 :
1823 						0xbf84;
1824 
1825 					if((cur_live.data_reg & 0xfe) == 0xf8)
1826 						status |= S_DDM;
1827 
1828 					cur_live.data_separator_phase = false;
1829 					cur_live.bit_counter = 0;
1830 					cur_live.state = READ_SECTOR_DATA;
1831 				}
1832 			}
1833 			break;
1834 
1835 		case READ_DATA_BLOCK_HEADER: {
1836 			LOGLIVE("%s - READ_DATA_BLOCK_HEADER\n", FUNCNAME);
1837 			if(read_one_bit(limit))
1838 				return;
1839 
1840 			LOGSHIFT("%s: shift = %04x data=%02x counter=%d\n", cur_live.tm.to_string(), cur_live.shift_reg,
1841 					(cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) |
1842 					(cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) |
1843 					(cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) |
1844 					(cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) |
1845 					(cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) |
1846 					(cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) |
1847 					(cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) |
1848 					(cur_live.shift_reg & 0x0001 ? 0x01 : 0x00),
1849 					cur_live.bit_counter);
1850 
1851 			if(cur_live.bit_counter & 15)
1852 				break;
1853 
1854 			int slot = cur_live.bit_counter >> 4;
1855 
1856 			if(slot < 3) {
1857 				if(cur_live.shift_reg != 0x4489) {
1858 					live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED);
1859 					return;
1860 				}
1861 				break;
1862 			}
1863 			if((cur_live.data_reg & 0xfe) != 0xfa && (cur_live.data_reg & 0xfe) != 0xf8) {
1864 				live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED);
1865 				return;
1866 			}
1867 
1868 			cur_live.bit_counter = 0;
1869 			if((cur_live.data_reg & 0xfe) == 0xf8)
1870 				status |= S_DDM;
1871 			live_delay(READ_SECTOR_DATA);
1872 			return;
1873 		}
1874 
1875 		case SEARCH_ADDRESS_MARK_DATA_FAILED:
1876 			LOGLIVE("%s - SEARCH_ADDRESS_MARK_DATA_FAILED\n", FUNCNAME);
1877 			status |= S_RNF;
1878 			cur_live.state = IDLE;
1879 			return;
1880 
1881 		case READ_SECTOR_DATA: {
1882 			LOGLIVE("%s - READ_SECTOR_DATA\n", FUNCNAME);
1883 			if(read_one_bit(limit))
1884 				return;
1885 			if(cur_live.bit_counter & 15)
1886 				break;
1887 			int slot = (cur_live.bit_counter >> 4)-1;
1888 			if(slot < sector_size) {
1889 				// Sector data
1890 				live_delay(READ_SECTOR_DATA_BYTE);
1891 				return;
1892 
1893 			} else if(slot < sector_size+2) {
1894 				// CRC
1895 				if(slot == sector_size+1) {
1896 					live_delay(IDLE);
1897 					return;
1898 				}
1899 			}
1900 			break;
1901 		}
1902 
1903 		case READ_SECTOR_DATA_BYTE:
1904 			LOGLIVE("%s - READ_SECTOR_DATA_BYTE\n", FUNCNAME);
1905 			data = cur_live.data_reg;
1906 			set_drq();
1907 			cur_live.state = READ_SECTOR_DATA;
1908 			checkpoint();
1909 			break;
1910 
1911 		case READ_TRACK_DATA: {
1912 			LOGLIVE("%s - READ_TRACK_DATA\n", FUNCNAME);
1913 			if(read_one_bit(limit))
1914 				return;
1915 
1916 			if(cur_live.bit_counter != 16
1917 				// MFM resyncs
1918 				&& !(!dden && (cur_live.shift_reg == 0x4489
1919 							|| cur_live.shift_reg == 0x5224))
1920 				// FM resyncs
1921 				&& !(dden && (cur_live.shift_reg == 0xf57e      // FM IDAM
1922 							|| cur_live.shift_reg == 0xf56f     // FM DAM
1923 							|| cur_live.shift_reg == 0xf56a))   // FM DDAM
1924 				)
1925 				break;
1926 
1927 
1928 			// Incorrect, hmmm
1929 			// Probably >2 + not just after a sync if <16
1930 
1931 			// Transitions 00..00 -> 4489.4489.4489 at varied syncs:
1932 			//  0: 00.00.14.a1   1: ff.fe.c2.a1   2: 00.01.14.a1   3: ff.fc.c2.a1
1933 			//  4: 00.02.14.a1   5: ff.f8.c2.a1   6: 00.05.14.a1   7: ff.f0.c2.a1
1934 			//  8: 00.00.0a.a1   9: ff.ff.e1.a1  10: 00.00.14.a1  11: ff.ff.ce.a1
1935 			// 12: 00.00.14.a1  13: ff.ff.c2.a1  14: 00.00.14.a1  15: ff.ff.c2.a1
1936 
1937 			// MZ: TI99 "DISkASSEMBLER" copy protection requires a threshold of 8
1938 			bool output_byte = cur_live.bit_counter > 8;
1939 
1940 			cur_live.data_separator_phase = false;
1941 			cur_live.bit_counter = 0;
1942 
1943 			if(output_byte) {
1944 				live_delay(READ_TRACK_DATA_BYTE);
1945 				return;
1946 			}
1947 			break;
1948 		}
1949 
1950 		case READ_TRACK_DATA_BYTE:
1951 			LOGLIVE("%s - READ_TRACK_DATA_BYTE\n", FUNCNAME);
1952 			data = cur_live.data_reg;
1953 			set_drq();
1954 			cur_live.state = READ_TRACK_DATA;
1955 			checkpoint();
1956 			break;
1957 
1958 		case WRITE_TRACK_DATA:
1959 			if(drq) {
1960 				status |= S_LOST;
1961 				data = 0;
1962 			}
1963 			if(data != format_last_byte) {
1964 				if(format_last_byte_count) {
1965 					char buf[32];
1966 					if(format_last_byte_count > 1)
1967 						sprintf(buf, "%dx%02x ", format_last_byte_count, format_last_byte);
1968 					else
1969 						sprintf(buf, "%02x ", format_last_byte);
1970 					format_description_string += buf;
1971 				}
1972 				format_last_byte = data;
1973 				format_last_byte_count = 1;
1974 			} else
1975 				format_last_byte_count++;
1976 
1977 			if(dden) {
1978 				switch(data) {
1979 				case 0xf7:
1980 					if(cur_live.previous_type == live_info::PT_CRC_2) {
1981 						cur_live.previous_type = live_info::PT_NONE;
1982 						live_write_fm(0xf7);
1983 					} else {
1984 						cur_live.previous_type = live_info::PT_CRC_1;
1985 						live_write_fm(cur_live.crc >> 8);
1986 					}
1987 					break;
1988 				case 0xf8:
1989 					live_write_raw(0xf56a);
1990 					cur_live.crc = 0xffff;
1991 					cur_live.previous_type = live_info::PT_NONE;
1992 					break;
1993 				case 0xf9:
1994 					live_write_raw(0xf56b);
1995 					cur_live.crc = 0xffff;
1996 					cur_live.previous_type = live_info::PT_NONE;
1997 					break;
1998 				case 0xfa:
1999 					live_write_raw(0xf56e);
2000 					cur_live.crc = 0xffff;
2001 					cur_live.previous_type = live_info::PT_NONE;
2002 					break;
2003 				case 0xfb:
2004 					live_write_raw(0xf56f);
2005 					cur_live.crc = 0xffff;
2006 					cur_live.previous_type = live_info::PT_NONE;
2007 					break;
2008 				case 0xfc:
2009 					live_write_raw(0xf77a);
2010 					cur_live.previous_type = live_info::PT_NONE;
2011 					break;
2012 				case 0xfe:
2013 					live_write_raw(0xf57e);
2014 					cur_live.crc = 0xffff;
2015 					cur_live.previous_type = live_info::PT_NONE;
2016 					break;
2017 				default:
2018 					cur_live.previous_type = live_info::PT_NONE;
2019 					live_write_fm(data);
2020 					break;
2021 				}
2022 
2023 			} else {
2024 				switch(data) {
2025 				case 0xf5:
2026 					live_write_raw(0x4489);
2027 					cur_live.crc = 0x968b; // Ensures that the crc is cdb4 after writing the byte
2028 					cur_live.previous_type = live_info::PT_NONE;
2029 					break;
2030 				case 0xf6:
2031 					cur_live.previous_type = live_info::PT_NONE;
2032 					live_write_raw(0x5224);
2033 					break;
2034 				case 0xf7:
2035 					if(cur_live.previous_type == live_info::PT_CRC_2) {
2036 						cur_live.previous_type = live_info::PT_NONE;
2037 						live_write_mfm(0xf7);
2038 					} else {
2039 						cur_live.previous_type = live_info::PT_CRC_1;
2040 						live_write_mfm(cur_live.crc >> 8);
2041 					}
2042 					break;
2043 				default:
2044 					cur_live.previous_type = live_info::PT_NONE;
2045 					live_write_mfm(data);
2046 					break;
2047 				}
2048 			}
2049 			set_drq();
2050 			cur_live.state = WRITE_BYTE;
2051 			cur_live.bit_counter = 16;
2052 			checkpoint();
2053 			break;
2054 
2055 		case WRITE_BYTE:
2056 			if(write_one_bit(limit))
2057 				return;
2058 			if(cur_live.bit_counter == 0) {
2059 				live_delay(WRITE_BYTE_DONE);
2060 				return;
2061 			}
2062 			break;
2063 
2064 		case WRITE_BYTE_DONE:
2065 			switch(sub_state) {
2066 			case TRACK_DONE:
2067 				if(cur_live.previous_type == live_info::PT_CRC_1) {
2068 					cur_live.previous_type = live_info::PT_CRC_2;
2069 					if(dden)
2070 						live_write_fm(cur_live.crc >> 8);
2071 					else
2072 						live_write_mfm(cur_live.crc >> 8);
2073 					cur_live.state = WRITE_BYTE;
2074 					cur_live.bit_counter = 16;
2075 					checkpoint();
2076 				} else
2077 					cur_live.state = WRITE_TRACK_DATA;
2078 				break;
2079 
2080 			case SECTOR_WRITE:
2081 				cur_live.state = WRITE_BYTE;
2082 				cur_live.bit_counter = 16;
2083 				cur_live.byte_counter++;
2084 
2085 				if(dden) {
2086 					if(cur_live.byte_counter < 6)
2087 						live_write_fm(0x00);
2088 					else if(cur_live.byte_counter < 7) {
2089 						cur_live.crc = 0xffff;
2090 						live_write_raw(command & 1 ? 0xf56a : 0xf56f);
2091 					} else if(cur_live.byte_counter < sector_size + 7-1) {
2092 						if(drq) {
2093 							status |= S_LOST;
2094 							data = 0;
2095 						}
2096 						live_write_fm(data);
2097 						set_drq();
2098 					} else if(cur_live.byte_counter < sector_size + 7) {
2099 						if(drq) {
2100 							status |= S_LOST;
2101 							data = 0;
2102 						}
2103 						live_write_fm(data);
2104 					} else if(cur_live.byte_counter < sector_size + 7+2)
2105 						live_write_fm(cur_live.crc >> 8);
2106 					else if(cur_live.byte_counter < sector_size + 7+3)
2107 						live_write_fm(0xff);
2108 					else {
2109 						pll_stop_writing(floppy, cur_live.tm);
2110 						cur_live.state = IDLE;
2111 						return;
2112 					}
2113 
2114 				} else {
2115 					if(cur_live.byte_counter < 12)
2116 						live_write_mfm(0x00);
2117 					else if(cur_live.byte_counter < 15)
2118 						live_write_raw(0x4489);
2119 					else if(cur_live.byte_counter < 16) {
2120 						cur_live.crc = 0xcdb4;
2121 						live_write_mfm(command & 1 ? 0xf8 : 0xfb);
2122 
2123 					} else if(cur_live.byte_counter < sector_size + 16-1) {
2124 						if(drq) {
2125 							status |= S_LOST;
2126 							data = 0;
2127 						}
2128 						live_write_mfm(data);
2129 						set_drq();
2130 					} else if(cur_live.byte_counter < sector_size + 16) {
2131 						if(drq) {
2132 							status |= S_LOST;
2133 							data = 0;
2134 						}
2135 						live_write_mfm(data);
2136 					} else if(cur_live.byte_counter < sector_size + 16+2)
2137 						live_write_mfm(cur_live.crc >> 8);
2138 					else if(cur_live.byte_counter < sector_size + 16+3)
2139 						live_write_mfm(0xff);
2140 					else {
2141 						pll_stop_writing(floppy, cur_live.tm);
2142 						cur_live.state = IDLE;
2143 						return;
2144 					}
2145 				}
2146 
2147 
2148 				checkpoint();
2149 				break;
2150 
2151 			default:
2152 				logerror("%s: Unknown sub state %d in WRITE_BYTE_DONE\n", cur_live.tm.to_string(), sub_state);
2153 				live_abort();
2154 				return;
2155 			}
2156 			break;
2157 
2158 		case WRITE_SECTOR_PRE:
2159 			if(read_one_bit(limit))
2160 				return;
2161 			if(cur_live.bit_counter != 16)
2162 				break;
2163 			live_delay(WRITE_SECTOR_PRE_BYTE);
2164 			return;
2165 
2166 		case WRITE_SECTOR_PRE_BYTE:
2167 			cur_live.state = WRITE_SECTOR_PRE;
2168 			cur_live.byte_counter++;
2169 			cur_live.bit_counter = 0;
2170 			switch(cur_live.byte_counter) {
2171 			case 2:
2172 				set_drq();
2173 				checkpoint();
2174 				break;
2175 
2176 			// MZ: There is an inconsistency in the wd177x specs; compare
2177 			// the flow chart and the text of the section "Write sector" (1-9) and
2178 			// pages 1-17 and 1-18.
2179 			//
2180 			// I suppose the sum of the delays in the flow chart should be
2181 			// 11 and 22, so we shorten the 9-byte delay to 8 bytes.
2182 
2183 			// case 11:
2184 			case 10:
2185 				if(drq) {
2186 					status |= S_LOST;
2187 					cur_live.state = IDLE;
2188 					return;
2189 				}
2190 				break;
2191 			// case 12:
2192 			case 11:
2193 				if(dden) {
2194 					cur_live.state = WRITE_BYTE;
2195 					cur_live.bit_counter = 16;
2196 					cur_live.byte_counter = 0;
2197 					cur_live.data_bit_context = cur_live.data_reg & 1;
2198 					pll_start_writing(cur_live.tm);
2199 					live_write_fm(0x00);
2200 				}
2201 				break;
2202 
2203 			case 22:
2204 				cur_live.state = WRITE_BYTE;
2205 				cur_live.bit_counter = 16;
2206 				cur_live.byte_counter = 0;
2207 				cur_live.data_bit_context = cur_live.data_reg & 1;
2208 				pll_start_writing(cur_live.tm);
2209 				live_write_mfm(0x00);
2210 				break;
2211 			}
2212 			break;
2213 
2214 		default:
2215 			logerror("%s: Unknown live state %d\n", cur_live.tm.to_string(), cur_live.state);
2216 			return;
2217 		}
2218 	}
2219 }
2220 
set_drq()2221 void wd_fdc_device_base::set_drq()
2222 {
2223 	if(drq) {
2224 		status |= S_LOST;
2225 		drq = false;
2226 		if(!drq_cb.isnull())
2227 			drq_cb(false);
2228 	} else if(!(status & S_LOST)) {
2229 		drq = true;
2230 		if(!drq_cb.isnull())
2231 			drq_cb(true);
2232 	}
2233 }
2234 
drop_drq()2235 void wd_fdc_device_base::drop_drq()
2236 {
2237 	if(drq) {
2238 		drq = false;
2239 		if(!drq_cb.isnull())
2240 			drq_cb(false);
2241 		if(main_state == IDLE && (status & S_BUSY)) {
2242 			status &= ~S_BUSY;
2243 			intrq = true;
2244 			if(!intrq_cb.isnull())
2245 				intrq_cb(intrq);
2246 		}
2247 	}
2248 }
2249 
set_hld()2250 void wd_fdc_device_base::set_hld()
2251 {
2252 	if(head_control && !hld) {
2253 		hld = true;
2254 		int temp = sub_state;
2255 		sub_state = DUMMY;
2256 		if(!hld_cb.isnull())
2257 			hld_cb(hld);
2258 		sub_state = temp;
2259 	}
2260 }
2261 
drop_hld()2262 void wd_fdc_device_base::drop_hld()
2263 {
2264 	if(head_control && hld) {
2265 		hld = false;
2266 		int temp = sub_state;
2267 		sub_state = DUMMY;
2268 		if(!hld_cb.isnull())
2269 			hld_cb(hld);
2270 		sub_state = temp;
2271 	}
2272 }
2273 
update_sso()2274 void wd_fdc_device_base::update_sso()
2275 {
2276 	// The 'side_control' flag is interpreted as meaning that the FDC has
2277 	// a SSO output feature, not that it necessarily controls the floppy.
2278 	if(!side_control)
2279 		return;
2280 
2281 	uint8_t side = (command & 0x02) ? 1 : 0;
2282 
2283 	// If a SSO callback is defined then it is assumed that this callback
2284 	// will update the floppy side if that is the connection. There are
2285 	// some machines that use the SSO output for other purposes.
2286 	if(!sso_cb.isnull()) {
2287 		sso_cb(side);
2288 		return;
2289 	}
2290 
2291 	// If a SSO callback is not defined then assume that the machine
2292 	// intended the driver to update the floppy side which appears to be
2293 	// the case in most cases.
2294 	if(floppy) {
2295 		floppy->ss_w((command & 0x02) ? 1 : 0);
2296 	}
2297 }
2298 
calc_sector_size(uint8_t size,uint8_t command) const2299 int wd_fdc_device_base::calc_sector_size(uint8_t size, uint8_t command) const
2300 {
2301 	return 128 << (size & 3);
2302 }
2303 
settle_time() const2304 int wd_fdc_device_base::settle_time() const
2305 {
2306 	return 60000;
2307 }
2308 
wd_fdc_analog_device_base(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock)2309 wd_fdc_analog_device_base::wd_fdc_analog_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
2310 	wd_fdc_device_base(mconfig, type, tag, owner, clock)
2311 {
2312 	clock_ratio = 1;
2313 }
2314 
pll_reset(bool fm,bool enmf,const attotime & when)2315 void wd_fdc_analog_device_base::pll_reset(bool fm, bool enmf, const attotime &when)
2316 {
2317 	int clocks = 2;
2318 
2319 	if (fm)   clocks *= 2;
2320 	if (enmf) clocks *= 2;
2321 
2322 	cur_pll.reset(when);
2323 	cur_pll.set_clock(clocks_to_attotime(clocks));
2324 }
2325 
pll_start_writing(const attotime & tm)2326 void wd_fdc_analog_device_base::pll_start_writing(const attotime &tm)
2327 {
2328 	cur_pll.start_writing(tm);
2329 }
2330 
pll_commit(floppy_image_device * floppy,const attotime & tm)2331 void wd_fdc_analog_device_base::pll_commit(floppy_image_device *floppy, const attotime &tm)
2332 {
2333 	cur_pll.commit(floppy, tm);
2334 }
2335 
pll_stop_writing(floppy_image_device * floppy,const attotime & tm)2336 void wd_fdc_analog_device_base::pll_stop_writing(floppy_image_device *floppy, const attotime &tm)
2337 {
2338 	cur_pll.stop_writing(floppy, tm);
2339 }
2340 
pll_save_checkpoint()2341 void wd_fdc_analog_device_base::pll_save_checkpoint()
2342 {
2343 	checkpoint_pll = cur_pll;
2344 }
2345 
pll_retrieve_checkpoint()2346 void wd_fdc_analog_device_base::pll_retrieve_checkpoint()
2347 {
2348 	cur_pll = checkpoint_pll;
2349 }
2350 
pll_get_next_bit(attotime & tm,floppy_image_device * floppy,const attotime & limit)2351 int wd_fdc_analog_device_base::pll_get_next_bit(attotime &tm, floppy_image_device *floppy, const attotime &limit)
2352 {
2353 	return cur_pll.get_next_bit(tm, floppy, limit);
2354 }
2355 
pll_write_next_bit(bool bit,attotime & tm,floppy_image_device * floppy,const attotime & limit)2356 bool wd_fdc_analog_device_base::pll_write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, const attotime &limit)
2357 {
2358 	return cur_pll.write_next_bit(bit, tm, floppy, limit);
2359 }
2360 
wd_fdc_digital_device_base(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock)2361 wd_fdc_digital_device_base::wd_fdc_digital_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
2362 	wd_fdc_device_base(mconfig, type, tag, owner, clock)
2363 {
2364 	clock_ratio = 4;
2365 }
2366 
2367 constexpr int wd_fdc_digital_device_base::wd_digital_step_times[4];
2368 
pll_reset(bool fm,bool enmf,const attotime & when)2369 void wd_fdc_digital_device_base::pll_reset(bool fm, bool enmf, const attotime &when)
2370 {
2371 	int clocks = 1;
2372 
2373 	if (fm)   clocks *= 2;
2374 	if (enmf) clocks *= 2;
2375 
2376 	cur_pll.reset(when);
2377 	cur_pll.set_clock(clocks_to_attotime(clocks));
2378 }
2379 
pll_start_writing(const attotime & tm)2380 void wd_fdc_digital_device_base::pll_start_writing(const attotime &tm)
2381 {
2382 	cur_pll.start_writing(tm);
2383 }
2384 
pll_commit(floppy_image_device * floppy,const attotime & tm)2385 void wd_fdc_digital_device_base::pll_commit(floppy_image_device *floppy, const attotime &tm)
2386 {
2387 	cur_pll.commit(floppy, tm);
2388 }
2389 
pll_stop_writing(floppy_image_device * floppy,const attotime & tm)2390 void wd_fdc_digital_device_base::pll_stop_writing(floppy_image_device *floppy, const attotime &tm)
2391 {
2392 	cur_pll.stop_writing(floppy, tm);
2393 }
2394 
pll_get_next_bit(attotime & tm,floppy_image_device * floppy,const attotime & limit)2395 int wd_fdc_digital_device_base::pll_get_next_bit(attotime &tm, floppy_image_device *floppy, const attotime &limit)
2396 {
2397 	return cur_pll.get_next_bit(tm, floppy, limit);
2398 }
2399 
pll_write_next_bit(bool bit,attotime & tm,floppy_image_device * floppy,const attotime & limit)2400 bool wd_fdc_digital_device_base::pll_write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, const attotime &limit)
2401 {
2402 	return cur_pll.write_next_bit(bit, tm, floppy, limit);
2403 }
2404 
pll_save_checkpoint()2405 void wd_fdc_digital_device_base::pll_save_checkpoint()
2406 {
2407 	checkpoint_pll = cur_pll;
2408 }
2409 
pll_retrieve_checkpoint()2410 void wd_fdc_digital_device_base::pll_retrieve_checkpoint()
2411 {
2412 	cur_pll = checkpoint_pll;
2413 }
2414 
set_clock(const attotime & period)2415 void wd_fdc_digital_device_base::digital_pll_t::set_clock(const attotime &period)
2416 {
2417 	for(int i=0; i<42; i++)
2418 		delays[i] = period*(i+1);
2419 }
2420 
reset(const attotime & when)2421 void wd_fdc_digital_device_base::digital_pll_t::reset(const attotime &when)
2422 {
2423 	counter = 0;
2424 	increment = 128;
2425 	transition_time = 0xffff;
2426 	history = 0x80;
2427 	slot = 0;
2428 	ctime = when;
2429 	phase_add = 0x00;
2430 	phase_sub = 0x00;
2431 	freq_add  = 0x00;
2432 	freq_sub  = 0x00;
2433 	write_position = 0;
2434 	write_start_time = attotime::never;
2435 }
2436 
get_next_bit(attotime & tm,floppy_image_device * floppy,const attotime & limit)2437 int wd_fdc_digital_device_base::digital_pll_t::get_next_bit(attotime &tm, floppy_image_device *floppy, const attotime &limit)
2438 {
2439 	attotime when = floppy ? floppy->get_next_transition(ctime) : attotime::never;
2440 
2441 	/*
2442 	    if(!when.is_never())
2443 	        LOGTRANSITION("transition_time=%s\n", when.to_string());
2444 	*/
2445 	for(;;) {
2446 		// LOGTRANSITION("slot=%2d, counter=%03x\n", slot, counter);
2447 		attotime etime = ctime+delays[slot];
2448 		// LOGTRANSITION("etime=%s\n", etime.to_string());
2449 		if(etime > limit)
2450 			return -1;
2451 		if(transition_time == 0xffff && !when.is_never() && etime >= when)
2452 			transition_time = counter;
2453 		if(slot < 8) {
2454 			uint8_t mask = 1 << slot;
2455 			if(phase_add & mask)
2456 				counter += 226;
2457 			else if(phase_sub & mask)
2458 				counter += 30;
2459 			else
2460 				counter += increment;
2461 
2462 			if((freq_add & mask) && increment < 140)
2463 				increment++;
2464 			else if((freq_sub & mask) && increment > 117)
2465 				increment--;
2466 		} else
2467 			counter += increment;
2468 
2469 		slot++;
2470 		tm = etime;
2471 		if(counter & 0x800)
2472 			break;
2473 	}
2474 	//LOGTRANSITION("first transition, time=%03x, inc=%3d\n", transition_time, increment);
2475 	int bit = transition_time != 0xffff;
2476 
2477 	if(transition_time != 0xffff) {
2478 		static const uint8_t pha[8] = { 0xf, 0x7, 0x3, 0x1, 0, 0, 0, 0 };
2479 		static const uint8_t phs[8] = { 0, 0, 0, 0, 0x1, 0x3, 0x7, 0xf };
2480 		static const uint8_t freqa[4][8] = {
2481 			{ 0xf, 0x7, 0x3, 0x1, 0, 0, 0, 0 },
2482 			{ 0x7, 0x3, 0x1, 0, 0, 0, 0, 0 },
2483 			{ 0x7, 0x3, 0x1, 0, 0, 0, 0, 0 },
2484 			{ 0, 0, 0, 0, 0, 0, 0, 0 }
2485 		};
2486 		static const uint8_t freqs[4][8] = {
2487 			{ 0, 0, 0, 0, 0, 0, 0, 0 },
2488 			{ 0, 0, 0, 0, 0, 0x1, 0x3, 0x7 },
2489 			{ 0, 0, 0, 0, 0, 0x1, 0x3, 0x7 },
2490 			{ 0, 0, 0, 0, 0x1, 0x3, 0x7, 0xf },
2491 		};
2492 
2493 		int cslot = transition_time >> 8;
2494 		phase_add = pha[cslot];
2495 		phase_sub = phs[cslot];
2496 		int way = transition_time & 0x400 ? 1 : 0;
2497 		if(history & 0x80)
2498 			history = way ? 0x80 : 0x83;
2499 		else if(history & 0x40)
2500 			history = way ? history & 2 : (history & 2) | 1;
2501 		freq_add = freqa[history & 3][cslot];
2502 		freq_sub = freqs[history & 3][cslot];
2503 		history = way ? (history >> 1) | 2 : history >> 1;
2504 
2505 	} else
2506 		phase_add = phase_sub = freq_add = freq_sub = 0;
2507 
2508 	counter &= 0x7ff;
2509 
2510 	ctime = tm;
2511 	transition_time = 0xffff;
2512 	slot = 0;
2513 
2514 	return bit;
2515 }
2516 
start_writing(const attotime & tm)2517 void wd_fdc_digital_device_base::digital_pll_t::start_writing(const attotime &tm)
2518 {
2519 	write_start_time = tm;
2520 	write_position = 0;
2521 }
2522 
stop_writing(floppy_image_device * floppy,const attotime & tm)2523 void wd_fdc_digital_device_base::digital_pll_t::stop_writing(floppy_image_device *floppy, const attotime &tm)
2524 {
2525 	commit(floppy, tm);
2526 	write_start_time = attotime::never;
2527 }
2528 
write_next_bit(bool bit,attotime & tm,floppy_image_device * floppy,const attotime & limit)2529 bool wd_fdc_digital_device_base::digital_pll_t::write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, const attotime &limit)
2530 {
2531 	if(write_start_time.is_never()) {
2532 		write_start_time = ctime;
2533 		write_position = 0;
2534 	}
2535 
2536 	for(;;) {
2537 		attotime etime = ctime+delays[slot];
2538 		if(etime > limit)
2539 			return true;
2540 		uint16_t pre_counter = counter;
2541 		counter += increment;
2542 		if(bit && !(pre_counter & 0x400) && (counter & 0x400))
2543 			if(write_position < ARRAY_LENGTH(write_buffer))
2544 				write_buffer[write_position++] = etime;
2545 		slot++;
2546 		tm = etime;
2547 		if(counter & 0x800)
2548 			break;
2549 	}
2550 
2551 	counter &= 0x7ff;
2552 
2553 	ctime = tm;
2554 	slot = 0;
2555 
2556 	return false;
2557 }
2558 
commit(floppy_image_device * floppy,const attotime & tm)2559 void wd_fdc_digital_device_base::digital_pll_t::commit(floppy_image_device *floppy, const attotime &tm)
2560 {
2561 	if(write_start_time.is_never() || tm == write_start_time)
2562 		return;
2563 
2564 	if(floppy)
2565 		floppy->write_flux(write_start_time, tm, write_position, write_buffer);
2566 	write_start_time = tm;
2567 	write_position = 0;
2568 }
2569 
fd1771_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2570 fd1771_device::fd1771_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : wd_fdc_analog_device_base(mconfig, FD1771, tag, owner, clock)
2571 {
2572 	constexpr static int fd1771_step_times[4] = { 12000, 12000, 20000, 40000 };
2573 
2574 	step_times = fd1771_step_times;
2575 	delay_register_commit = 16/2; // will became x2 later due to FM
2576 	delay_command_commit = 20/2;  // same as above
2577 	disable_mfm = true;
2578 	inverted_bus = true;
2579 	side_control = false;
2580 	side_compare = false;
2581 	head_control = true;
2582 	hld_timeout = 3;
2583 	motor_control = false;
2584 	ready_hooked = true;
2585 	spinup_on_interrupt = true; // ZX-Spectrum Beta-disk V2 require this, or ReadSector command should set HLD before RDY check
2586 }
2587 
calc_sector_size(uint8_t size,uint8_t command) const2588 int fd1771_device::calc_sector_size(uint8_t size, uint8_t command) const
2589 {
2590 	if(command & 0x08)
2591 		return 128 << (size & 3);
2592 	else
2593 		return size ? size << 4 : 4096;
2594 }
2595 
fd1781_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2596 fd1781_device::fd1781_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : wd_fdc_analog_device_base(mconfig, FD1781, tag, owner, clock)
2597 {
2598 	constexpr static int fd1781_step_times[4] = { 6000, 12000, 20000, 40000 };
2599 
2600 	step_times = fd1781_step_times;
2601 	delay_register_commit = 16;
2602 	delay_command_commit = 12;
2603 	disable_mfm = false;
2604 	inverted_bus = true;
2605 	side_control = false;
2606 	side_compare = false;
2607 	head_control = true;
2608 	hld_timeout = 3;
2609 	motor_control = false;
2610 	ready_hooked = true;
2611 }
2612 
calc_sector_size(uint8_t size,uint8_t command) const2613 int fd1781_device::calc_sector_size(uint8_t size, uint8_t command) const
2614 {
2615 	if(command & 0x08)
2616 		return 128 << (size & 3);
2617 	else
2618 		return size ? size << 4 : 4096;
2619 }
2620 
2621 constexpr int wd_fdc_device_base::fd179x_step_times[4];
2622 constexpr int wd_fdc_device_base::fd176x_step_times[4];
2623 
fd1791_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2624 fd1791_device::fd1791_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : wd_fdc_analog_device_base(mconfig, FD1791, tag, owner, clock)
2625 {
2626 	step_times = fd179x_step_times;
2627 	delay_register_commit = 4;
2628 	delay_command_commit = 12;
2629 	disable_mfm = false;
2630 	has_enmf = false;
2631 	inverted_bus = true;
2632 	side_control = false;
2633 	side_compare = true;
2634 	head_control = true;
2635 	hld_timeout = 15;
2636 	motor_control = false;
2637 	ready_hooked = true;
2638 }
2639 
fd1792_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2640 fd1792_device::fd1792_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : wd_fdc_analog_device_base(mconfig, FD1792, tag, owner, clock)
2641 {
2642 	step_times = fd179x_step_times;
2643 	delay_register_commit = 4;
2644 	delay_command_commit = 12;
2645 	disable_mfm = true;
2646 	has_enmf = false;
2647 	inverted_bus = true;
2648 	side_control = false;
2649 	side_compare = true;
2650 	head_control = true;
2651 	hld_timeout = 15;
2652 	motor_control = false;
2653 	ready_hooked = true;
2654 }
2655 
fd1793_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2656 fd1793_device::fd1793_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : wd_fdc_analog_device_base(mconfig, FD1793, tag, owner, clock)
2657 {
2658 	step_times = fd179x_step_times;
2659 	delay_register_commit = 4;
2660 	delay_command_commit = 12;
2661 	disable_mfm = false;
2662 	has_enmf = false;
2663 	inverted_bus = false;
2664 	side_control = false;
2665 	side_compare = true;
2666 	head_control = true;
2667 	hld_timeout = 15;
2668 	motor_control = false;
2669 	ready_hooked = true;
2670 }
2671 
kr1818vg93_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2672 kr1818vg93_device::kr1818vg93_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : wd_fdc_analog_device_base(mconfig, KR1818VG93, tag, owner, clock)
2673 {
2674 	step_times = fd179x_step_times;
2675 	delay_register_commit = 4;
2676 	delay_command_commit = 12;
2677 	disable_mfm = false;
2678 	has_enmf = false;
2679 	inverted_bus = false;
2680 	side_control = false;
2681 	side_compare = true;
2682 	head_control = true;
2683 	hld_timeout = 15;
2684 	motor_control = false;
2685 	ready_hooked = true;
2686 }
2687 
fd1794_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2688 fd1794_device::fd1794_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : wd_fdc_analog_device_base(mconfig, FD1794, tag, owner, clock)
2689 {
2690 	step_times = fd179x_step_times;
2691 	delay_register_commit = 4;
2692 	delay_command_commit = 12;
2693 	disable_mfm = true;
2694 	has_enmf = false;
2695 	inverted_bus = false;
2696 	side_control = false;
2697 	side_compare = true;
2698 	head_control = true;
2699 	hld_timeout = 15;
2700 	motor_control = false;
2701 	ready_hooked = true;
2702 }
2703 
fd1795_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2704 fd1795_device::fd1795_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : wd_fdc_analog_device_base(mconfig, FD1795, tag, owner, clock)
2705 {
2706 	step_times = fd179x_step_times;
2707 	delay_register_commit = 4;
2708 	delay_command_commit = 12;
2709 	disable_mfm = false;
2710 	has_enmf = false;
2711 	inverted_bus = true;
2712 	side_control = true;
2713 	side_compare = false;
2714 	head_control = true;
2715 	hld_timeout = 15;
2716 	motor_control = false;
2717 	ready_hooked = true;
2718 }
2719 
calc_sector_size(uint8_t size,uint8_t command) const2720 int fd1795_device::calc_sector_size(uint8_t size, uint8_t command) const
2721 {
2722 	if(command & 0x08)
2723 		return 128 << (size & 3);
2724 	else
2725 		return 128 << ((size + 1) & 3);
2726 }
2727 
fd1797_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2728 fd1797_device::fd1797_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : wd_fdc_analog_device_base(mconfig, FD1797, tag, owner, clock)
2729 {
2730 	step_times = fd179x_step_times;
2731 	delay_register_commit = 4;
2732 	delay_command_commit = 12;
2733 	disable_mfm = false;
2734 	has_enmf = false;
2735 	inverted_bus = false;
2736 	side_control = true;
2737 	side_compare = false;
2738 	head_control = true;
2739 	hld_timeout = 15;
2740 	motor_control = false;
2741 	ready_hooked = true;
2742 }
2743 
calc_sector_size(uint8_t size,uint8_t command) const2744 int fd1797_device::calc_sector_size(uint8_t size, uint8_t command) const
2745 {
2746 	if(command & 0x08)
2747 		return 128 << (size & 3);
2748 	else
2749 		return 128 << ((size + 1) & 3);
2750 }
2751 
mb8866_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2752 mb8866_device::mb8866_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : wd_fdc_analog_device_base(mconfig, MB8866, tag, owner, clock)
2753 {
2754 	step_times = fd179x_step_times;
2755 	delay_register_commit = 4;
2756 	delay_command_commit = 12;
2757 	disable_mfm = false;
2758 	has_enmf = false;
2759 	inverted_bus = true;
2760 	side_control = false;
2761 	side_compare = true;
2762 	head_control = true;
2763 	hld_timeout = 15;
2764 	motor_control = false;
2765 	ready_hooked = true;
2766 }
2767 
mb8876_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2768 mb8876_device::mb8876_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : wd_fdc_analog_device_base(mconfig, MB8876, tag, owner, clock)
2769 {
2770 	step_times = fd179x_step_times;
2771 	delay_register_commit = 4;
2772 	delay_command_commit = 12;
2773 	disable_mfm = false;
2774 	has_enmf = false;
2775 	inverted_bus = true;
2776 	side_control = false;
2777 	side_compare = true;
2778 	head_control = true;
2779 	hld_timeout = 15;
2780 	motor_control = false;
2781 	ready_hooked = true;
2782 }
2783 
mb8877_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2784 mb8877_device::mb8877_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : wd_fdc_analog_device_base(mconfig, MB8877, tag, owner, clock)
2785 {
2786 	step_times = fd179x_step_times;
2787 	delay_register_commit = 4;
2788 	delay_command_commit = 12;
2789 	disable_mfm = false;
2790 	has_enmf = false;
2791 	inverted_bus = false;
2792 	side_control = false;
2793 	side_compare = true;
2794 	head_control = true;
2795 	hld_timeout = 15;
2796 	motor_control = false;
2797 	ready_hooked = true;
2798 }
2799 
fd1761_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2800 fd1761_device::fd1761_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : wd_fdc_analog_device_base(mconfig, FD1761, tag, owner, clock)
2801 {
2802 	step_times = fd176x_step_times;
2803 	delay_register_commit = 16;
2804 	delay_command_commit = 12;
2805 	disable_mfm = false;
2806 	has_enmf = false;
2807 	inverted_bus = true;
2808 	side_control = false;
2809 	side_compare = true;
2810 	head_control = true;
2811 	hld_timeout = 15;
2812 	motor_control = false;
2813 	ready_hooked = true;
2814 }
2815 
fd1763_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2816 fd1763_device::fd1763_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : wd_fdc_analog_device_base(mconfig, FD1763, tag, owner, clock)
2817 {
2818 	step_times = fd176x_step_times;
2819 	delay_register_commit = 16;
2820 	delay_command_commit = 12;
2821 	disable_mfm = false;
2822 	has_enmf = false;
2823 	inverted_bus = false;
2824 	side_control = false;
2825 	side_compare = true;
2826 	head_control = true;
2827 	hld_timeout = 15;
2828 	motor_control = false;
2829 	ready_hooked = true;
2830 }
2831 
fd1765_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2832 fd1765_device::fd1765_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : wd_fdc_analog_device_base(mconfig, FD1765, tag, owner, clock)
2833 {
2834 	step_times = fd176x_step_times;
2835 	delay_register_commit = 16;
2836 	delay_command_commit = 12;
2837 	disable_mfm = false;
2838 	has_enmf = false;
2839 	inverted_bus = true;
2840 	side_control = true;
2841 	side_compare = false;
2842 	head_control = true;
2843 	hld_timeout = 15;
2844 	motor_control = false;
2845 	ready_hooked = true;
2846 }
2847 
calc_sector_size(uint8_t size,uint8_t command) const2848 int fd1765_device::calc_sector_size(uint8_t size, uint8_t command) const
2849 {
2850 	if(command & 0x08)
2851 		return 128 << (size & 3);
2852 	else
2853 		return 128 << ((size + 1) & 3);
2854 }
2855 
fd1767_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2856 fd1767_device::fd1767_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : wd_fdc_analog_device_base(mconfig, FD1767, tag, owner, clock)
2857 {
2858 	step_times = fd179x_step_times;
2859 	delay_register_commit = 16;
2860 	delay_command_commit = 12;
2861 	disable_mfm = false;
2862 	has_enmf = false;
2863 	inverted_bus = false;
2864 	side_control = true;
2865 	side_compare = false;
2866 	head_control = true;
2867 	hld_timeout = 15;
2868 	motor_control = false;
2869 	ready_hooked = true;
2870 }
2871 
calc_sector_size(uint8_t size,uint8_t command) const2872 int fd1767_device::calc_sector_size(uint8_t size, uint8_t command) const
2873 {
2874 	if(command & 0x08)
2875 		return 128 << (size & 3);
2876 	else
2877 		return 128 << ((size + 1) & 3);
2878 }
2879 
wd2791_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2880 wd2791_device::wd2791_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : wd_fdc_analog_device_base(mconfig, WD2791, tag, owner, clock)
2881 {
2882 	step_times = fd179x_step_times;
2883 	delay_register_commit = 16;
2884 	delay_command_commit = 12;
2885 	disable_mfm = false;
2886 	has_enmf = true;
2887 	inverted_bus = true;
2888 	side_control = false;
2889 	side_compare = true;
2890 	head_control = true;
2891 	hld_timeout = 15;
2892 	motor_control = false;
2893 	ready_hooked = true;
2894 }
2895 
wd2793_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2896 wd2793_device::wd2793_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : wd_fdc_analog_device_base(mconfig, WD2793, tag, owner, clock)
2897 {
2898 	step_times = fd179x_step_times;
2899 	delay_register_commit = 16;
2900 	delay_command_commit = 12;
2901 	disable_mfm = false;
2902 	has_enmf = true;
2903 	inverted_bus = false;
2904 	side_control = false;
2905 	side_compare = true;
2906 	head_control = true;
2907 	hld_timeout = 15;
2908 	motor_control = false;
2909 	ready_hooked = true;
2910 }
2911 
wd2795_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2912 wd2795_device::wd2795_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : wd_fdc_analog_device_base(mconfig, WD2795, tag, owner, clock)
2913 {
2914 	step_times = fd179x_step_times;
2915 	delay_register_commit = 16;
2916 	delay_command_commit = 12;
2917 	disable_mfm = false;
2918 	has_enmf = false;
2919 	inverted_bus = true;
2920 	side_control = true;
2921 	side_compare = false;
2922 	head_control = true;
2923 	hld_timeout = 15;
2924 	motor_control = false;
2925 	ready_hooked = true;
2926 }
2927 
calc_sector_size(uint8_t size,uint8_t command) const2928 int wd2795_device::calc_sector_size(uint8_t size, uint8_t command) const
2929 {
2930 	if(command & 0x08)
2931 		return 128 << (size & 3);
2932 	else
2933 		return 128 << ((size + 1) & 3);
2934 }
2935 
wd2797_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2936 wd2797_device::wd2797_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : wd_fdc_analog_device_base(mconfig, WD2797, tag, owner, clock)
2937 {
2938 	step_times = fd179x_step_times;
2939 	delay_register_commit = 16;
2940 	delay_command_commit = 12;
2941 	disable_mfm = false;
2942 	has_enmf = false;
2943 	inverted_bus = false;
2944 	side_control = true;
2945 	side_compare = false;
2946 	head_control = true;
2947 	hld_timeout = 15;
2948 	motor_control = false;
2949 	ready_hooked = true;
2950 }
2951 
calc_sector_size(uint8_t size,uint8_t command) const2952 int wd2797_device::calc_sector_size(uint8_t size, uint8_t command) const
2953 {
2954 	if(command & 0x08)
2955 		return 128 << (size & 3);
2956 	else
2957 		return 128 << ((size + 1) & 3);
2958 }
2959 
wd1770_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2960 wd1770_device::wd1770_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : wd_fdc_digital_device_base(mconfig, WD1770, tag, owner, clock)
2961 {
2962 	step_times = wd_digital_step_times;
2963 	delay_register_commit = 16;
2964 	delay_command_commit = 36; // official 48 is too high for oric jasmin boot
2965 	disable_mfm = false;
2966 	has_enmf = false;
2967 	inverted_bus = false;
2968 	side_control = false;
2969 	side_compare = false;
2970 	head_control = false;
2971 	hld_timeout = 0;
2972 	motor_control = true;
2973 	ready_hooked = false;
2974 }
2975 
wd1772_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2976 wd1772_device::wd1772_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : wd_fdc_digital_device_base(mconfig, WD1772, tag, owner, clock)
2977 {
2978 	const static int wd1772_step_times[4] = { 12000, 24000, 4000, 6000 };
2979 
2980 	step_times = wd1772_step_times;
2981 	delay_register_commit = 16;
2982 	delay_command_commit = 48;
2983 	disable_mfm = false;
2984 	has_enmf = false;
2985 	inverted_bus = false;
2986 	side_control = false;
2987 	side_compare = false;
2988 	head_control = false;
2989 	hld_timeout = 0;
2990 	motor_control = true;
2991 	ready_hooked = false;
2992 
2993 	/* Sam Coupe/+D/Disciple expect a 0xd0 force interrupt command to cause a spin-up.
2994 	   eg. +D issues 2x 0xd0, then waits for index pulses to start, bails out with no disk error if that doesn't happen.
2995 	   Not sure if other chips should do this too? */
2996 	spinup_on_interrupt = true;
2997 }
2998 
settle_time() const2999 int wd1772_device::settle_time() const
3000 {
3001 	return 30000;
3002 }
3003 
wd1773_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)3004 wd1773_device::wd1773_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : wd_fdc_digital_device_base(mconfig, WD1773, tag, owner, clock)
3005 {
3006 	step_times = wd_digital_step_times;
3007 	delay_register_commit = 16;
3008 	delay_command_commit = 48;
3009 	disable_mfm = false;
3010 	has_enmf = false;
3011 	inverted_bus = false;
3012 	side_control = false;
3013 	side_compare = true;
3014 	head_control = false;
3015 	hld_timeout = 0;
3016 	motor_control = false;
3017 	ready_hooked = true;
3018 }
3019