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