Previous 199869 Revisions Next

r19166 Tuesday 27th November, 2012 at 16:53:24 UTC by O. Galibert
upd765, wd1772: Move to emu [O. Galibert]
[src/emu]emu.mak
[src/emu/machine]upd765.c upd765.h wd1772.c wd1772.h
[src/mess]mess.mak
[src/mess/machine]pc_fdc.h upd765.c upd765.h wd1772.c wd1772.h

trunk/src/emu/emu.mak
r19165r19166
269269   $(EMUMACHINE)/upd1990a.o   \
270270   $(EMUMACHINE)/upd4701.o      \
271271   $(EMUMACHINE)/upd7201.o      \
272   $(EMUMACHINE)/upd765.o      \
272273   $(EMUMACHINE)/v3021.o      \
274   $(EMUMACHINE)/wd1772.o      \
273275   $(EMUMACHINE)/wd17xx.o      \
274276   $(EMUMACHINE)/wd33c93.o      \
275277   $(EMUMACHINE)/x2212.o      \
trunk/src/emu/machine/wd1772.c
r19165r19166
1/***************************************************************************
2
3    Copyright Olivier Galibert
4    All rights reserved.
5
6    Redistribution and use in source and binary forms, with or without
7    modification, are permitted provided that the following conditions are
8    met:
9
10        * Redistributions of source code must retain the above copyright
11          notice, this list of conditions and the following disclaimer.
12        * Redistributions in binary form must reproduce the above copyright
13          notice, this list of conditions and the following disclaimer in
14          the documentation and/or other materials provided with the
15          distribution.
16        * Neither the name 'MAME' nor the names of its contributors may be
17          used to endorse or promote products derived from this software
18          without specific prior written permission.
19
20    THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
21    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23    DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
24    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
29    IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30    POSSIBILITY OF SUCH DAMAGE.
31
32****************************************************************************/
33
34#include "wd1772.h"
35
36#include "debugger.h"
37
38const device_type FD1771x = &device_creator<fd1771_t>;
39const device_type FD1793x = &device_creator<fd1793_t>;
40const device_type FD1797x = &device_creator<fd1797_t>;
41const device_type WD2793x = &device_creator<wd2793_t>;
42const device_type WD2797x = &device_creator<wd2797_t>;
43const device_type WD1770x = &device_creator<wd1770_t>;
44const device_type WD1772x = &device_creator<wd1772_t>;
45const device_type WD1773x = &device_creator<wd1773_t>;
46
47wd177x_t::wd177x_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) :
48   device_t(mconfig, type, name, tag, owner, clock)
49{
50}
51
52void wd177x_t::device_start()
53{
54   t_gen = timer_alloc(TM_GEN);
55   t_cmd = timer_alloc(TM_CMD);
56   t_track = timer_alloc(TM_TRACK);
57   t_sector = timer_alloc(TM_SECTOR);
58   dden = false;
59   floppy = 0;
60
61   save_item(NAME(status));
62   save_item(NAME(command));
63   save_item(NAME(main_state));
64   save_item(NAME(sub_state));
65   save_item(NAME(track));
66   save_item(NAME(sector));
67   save_item(NAME(intrq_cond));
68   save_item(NAME(cmd_buffer));
69   save_item(NAME(track_buffer));
70   save_item(NAME(sector_buffer));
71   save_item(NAME(counter));
72   save_item(NAME(status_type_1));
73   save_item(NAME(last_dir));
74}
75
76void wd177x_t::device_reset()
77{
78   command = 0x00;
79   main_state = IDLE;
80   sub_state = IDLE;
81   cur_live.state = IDLE;
82   track = 0x00;
83   sector = 0x00;
84   status = 0x00;
85   data = 0x00;
86   cmd_buffer = track_buffer = sector_buffer = -1;
87   counter = 0;
88   status_type_1 = true;
89   last_dir = 1;
90   intrq = false;
91   drq = false;
92   hld = false;
93   live_abort();
94}
95
96void wd177x_t::set_floppy(floppy_image_device *_floppy)
97{
98   if(floppy == _floppy)
99      return;
100
101   if(floppy) {
102      floppy->mon_w(1);
103      floppy->setup_index_pulse_cb(floppy_image_device::index_pulse_cb());
104   }
105
106   floppy = _floppy;
107
108   if(floppy) {
109      if(has_motor())
110         floppy->mon_w(status & S_MON ? 0 : 1);
111      floppy->setup_index_pulse_cb(floppy_image_device::index_pulse_cb(FUNC(wd177x_t::index_callback), this));
112   }
113}
114
115void wd177x_t::setup_intrq_cb(line_cb cb)
116{
117   intrq_cb = cb;
118}
119
120void wd177x_t::setup_drq_cb(line_cb cb)
121{
122   drq_cb = cb;
123}
124
125void wd177x_t::setup_hld_cb(line_cb cb)
126{
127   hld_cb = cb;
128}
129
130void wd177x_t::setup_enp_cb(line_cb cb)
131{
132   enp_cb = cb;
133}
134
135void wd177x_t::dden_w(bool _dden)
136{
137   dden = _dden;
138}
139
140astring wd177x_t::tts(attotime t)
141{
142   char buf[256];
143   int nsec = t.attoseconds / ATTOSECONDS_PER_NANOSECOND;
144   sprintf(buf, "%4d.%03d,%03d,%03d", int(t.seconds), nsec/1000000, (nsec/1000)%1000, nsec % 1000);
145   return buf;
146}
147
148astring wd177x_t::ttsn()
149{
150   return tts(machine().time());
151}
152
153void wd177x_t::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
154{
155   live_sync();
156
157   switch(id) {
158   case TM_GEN: do_generic(); break;
159   case TM_CMD: do_cmd_w(); break;
160   case TM_TRACK: do_track_w(); break;
161   case TM_SECTOR: do_sector_w(); break;
162   }
163
164   general_continue();
165}
166
167void wd177x_t::command_end()
168{
169   main_state = sub_state = IDLE;
170   status &= ~S_BUSY;
171   intrq = true;
172   motor_timeout = 0;
173   if(!intrq_cb.isnull())
174      intrq_cb(intrq);
175}
176
177void wd177x_t::seek_start(int state)
178{
179   main_state = state;
180   status = (status & ~(S_CRC|S_RNF|S_SPIN)) | S_BUSY;
181   if(has_head_load()) {
182      // TODO get value from HLT callback
183      if (command & 8)
184         status |= S_HLD;
185      else
186         status &= ~S_HLD;
187   }
188   sub_state = has_motor() && !has_head_load() ? SPINUP : SPINUP_DONE;
189   status_type_1 = true;
190   seek_continue();
191}
192
193void wd177x_t::seek_continue()
194{
195   for(;;) {
196      switch(sub_state) {
197      case SPINUP:
198         if(!(status & S_MON)) {
199            spinup();
200            return;
201         }
202         if(!(command & 0x08))
203            status |= S_SPIN;
204         sub_state = SPINUP_DONE;
205         break;
206
207      case SPINUP_WAIT:
208         return;
209
210      case SPINUP_DONE:
211         if(main_state == RESTORE && floppy && !floppy->trk00_r())
212            sub_state = SEEK_DONE;
213
214         if(main_state == SEEK && track == data)
215            sub_state = SEEK_DONE;
216
217         if(sub_state == SPINUP_DONE) {
218            counter = 0;
219            sub_state = SEEK_MOVE;
220         }
221         break;
222
223      case SEEK_MOVE:
224         if(floppy) {
225            floppy->dir_w(last_dir);
226            floppy->stp_w(0);
227            floppy->stp_w(1);
228         }
229         // When stepping with update, the track register is updated before seeking.
230         // Important for the sam coupe format code.
231         if(main_state == STEP && (command & 0x10))
232            track += last_dir ? -1 : 1;
233         counter++;
234         sub_state = SEEK_WAIT_STEP_TIME;
235         delay_cycles(t_gen, step_time(command & 3));
236         return;
237
238      case SEEK_WAIT_STEP_TIME:
239         return;
240
241      case SEEK_WAIT_STEP_TIME_DONE: {
242         bool done = false;
243         switch(main_state) {
244         case RESTORE:
245            done = !floppy || !floppy->trk00_r();
246            break;
247         case SEEK:
248            track += last_dir ? -1 : 1;
249            done = track == data;
250            break;
251         case STEP:
252            done = true;
253            break;
254         }
255
256         if(done || counter == 255) {
257            if(main_state == RESTORE)
258               track = 0;
259
260            if(command & 0x04) {
261               sub_state = SEEK_WAIT_STABILIZATION_TIME;
262               delay_cycles(t_gen, 120000);
263               return;
264            } else
265               sub_state = SEEK_DONE;
266
267         } else
268            sub_state = SEEK_MOVE;
269
270         break;
271      }
272
273      case SEEK_WAIT_STABILIZATION_TIME:
274         return;
275
276      case SEEK_WAIT_STABILIZATION_TIME_DONE:
277         sub_state = SEEK_DONE;
278         break;
279
280      case SEEK_DONE:
281         if(command & 0x04) {
282            if(has_ready() && !is_ready()) {
283               status |= S_RNF;
284               command_end();
285               return;
286            }
287            sub_state = SCAN_ID;
288            counter = 0;
289            live_start(SEARCH_ADDRESS_MARK_HEADER);
290            return;
291         }
292         command_end();
293         return;
294
295      case SCAN_ID:
296         if(cur_live.idbuf[0] != track) {
297            live_start(SEARCH_ADDRESS_MARK_HEADER);
298            return;
299         }
300         if(cur_live.crc) {
301            status |= S_CRC;
302            live_start(SEARCH_ADDRESS_MARK_HEADER);
303            return;
304         }
305         command_end();
306         return;
307
308      case SCAN_ID_FAILED:
309         status |= S_RNF;
310         command_end();
311         return;
312
313      default:
314         logerror("%s: seek unknown sub-state %d\n", ttsn().cstr(), sub_state);
315         return;
316      }
317   }
318}
319
320bool wd177x_t::sector_matches() const
321{
322   if(cur_live.idbuf[0] != track || cur_live.idbuf[2] != sector)
323      return false;
324   if(!has_side_check() || (command & 2))
325      return true;
326   if(command & 8)
327      return cur_live.idbuf[1] & 1;
328   else
329      return !(cur_live.idbuf[1] & 1);
330}
331
332bool wd177x_t::is_ready()
333{
334   return (floppy && !floppy->ready_r());
335}
336
337void wd177x_t::read_sector_start()
338{
339   if(has_ready() && !is_ready())
340      command_end();
341
342   main_state = READ_SECTOR;
343   status = (status & ~(S_CRC|S_LOST|S_RNF|S_WP|S_DDM)) | S_BUSY;
344   drop_drq();
345   if (has_side_select() && floppy)
346      floppy->ss_w(BIT(command, 1));
347   sub_state = has_motor() && !has_head_load() ? SPINUP : SPINUP_DONE;
348   status_type_1 = false;
349   read_sector_continue();
350}
351
352void wd177x_t::read_sector_continue()
353{
354   for(;;) {
355      switch(sub_state) {
356      case SPINUP:
357         if(!(status & S_MON)) {
358            spinup();
359            return;
360         }
361         sub_state = SPINUP_DONE;
362         break;
363
364      case SPINUP_WAIT:
365         return;
366
367      case SPINUP_DONE:
368         if(command & 4) {
369            sub_state = SETTLE_WAIT;
370            delay_cycles(t_gen, settle_time());
371            return;
372         } else {
373            sub_state = SETTLE_DONE;
374            break;
375         }
376
377      case SETTLE_WAIT:
378         return;
379
380      case SETTLE_DONE:
381         sub_state = SCAN_ID;
382         counter = 0;
383         live_start(SEARCH_ADDRESS_MARK_HEADER);
384         return;
385
386      case SCAN_ID:
387         if(!sector_matches()) {
388            live_start(SEARCH_ADDRESS_MARK_HEADER);
389            return;
390         }
391         if(cur_live.crc) {
392            status |= S_CRC;
393            live_start(SEARCH_ADDRESS_MARK_HEADER);
394            return;
395         }
396         // TODO WD2795/7 alternate sector size
397         sector_size = 128 << (cur_live.idbuf[3] & 3);
398         sub_state = SECTOR_READ;
399         live_start(SEARCH_ADDRESS_MARK_DATA);
400         return;
401
402      case SCAN_ID_FAILED:
403         status |= S_RNF;
404         command_end();
405         return;
406
407      case SECTOR_READ:
408         if(cur_live.crc)
409            status |= S_CRC;
410
411         if(command & 0x10 && !(status & S_RNF)) {
412            sector++;
413            sub_state = SETTLE_DONE;
414         } else {
415            command_end();
416            return;
417         }
418         break;
419
420      default:
421         logerror("%s: read sector unknown sub-state %d\n", ttsn().cstr(), sub_state);
422         return;
423      }
424   }
425}
426
427void wd177x_t::read_track_start()
428{
429   if(has_ready() && !is_ready())
430      command_end();
431   
432   main_state = READ_TRACK;
433   status = (status & ~(S_LOST|S_RNF)) | S_BUSY;
434   drop_drq();
435   if (has_side_select() && floppy)
436      floppy->ss_w(BIT(command, 1));
437   sub_state = has_motor() && !has_head_load()  ? SPINUP : SPINUP_DONE;
438   status_type_1 = false;
439   read_track_continue();
440}
441
442void wd177x_t::read_track_continue()
443{
444   for(;;) {
445      switch(sub_state) {
446      case SPINUP:
447         if(!(status & S_MON)) {
448            spinup();
449            return;
450         }
451         sub_state = SPINUP_DONE;
452         break;
453
454      case SPINUP_WAIT:
455         return;
456
457      case SPINUP_DONE:
458         if(command & 4) {
459            sub_state = SETTLE_WAIT;
460            delay_cycles(t_gen, settle_time());
461            return;
462
463         } else {
464            sub_state = SETTLE_DONE;
465            break;
466         }
467
468      case SETTLE_WAIT:
469         return;
470
471      case SETTLE_DONE:
472         sub_state = WAIT_INDEX;
473         return;
474
475      case WAIT_INDEX:
476         return;
477
478      case WAIT_INDEX_DONE:
479         sub_state = TRACK_DONE;
480         live_start(READ_TRACK_DATA);
481         return;
482
483      case TRACK_DONE:
484         command_end();
485         return;
486
487      default:
488         logerror("%s: read track unknown sub-state %d\n", ttsn().cstr(), sub_state);
489         return;
490      }
491   }
492}
493
494void wd177x_t::read_id_start()
495{
496   if(has_ready() && !is_ready())
497      command_end();
498   
499   main_state = READ_ID;
500   status = (status & ~(S_WP|S_DDM|S_LOST|S_RNF)) | S_BUSY;
501   drop_drq();
502   if (has_side_select() && floppy)
503      floppy->ss_w(BIT(command, 1));
504   sub_state = has_motor() && !has_head_load()  ? SPINUP : SPINUP_DONE;
505   status_type_1 = false;
506   read_id_continue();
507}
508
509void wd177x_t::read_id_continue()
510{
511   for(;;) {
512      switch(sub_state) {
513      case SPINUP:
514         if(!(status & S_MON)) {
515            spinup();
516            return;
517         }
518         sub_state = SPINUP_DONE;
519         break;
520
521      case SPINUP_WAIT:
522         return;
523
524      case SPINUP_DONE:
525         if(command & 4) {
526            sub_state = SETTLE_WAIT;
527            delay_cycles(t_gen, settle_time());
528            return;
529         } else {
530            sub_state = SETTLE_DONE;
531            break;
532         }
533
534      case SETTLE_WAIT:
535         return;
536
537      case SETTLE_DONE:
538         sub_state = SCAN_ID;
539         counter = 0;
540         live_start(SEARCH_ADDRESS_MARK_HEADER);
541         return;
542
543      case SCAN_ID:
544         command_end();
545         return;
546
547      case SCAN_ID_FAILED:
548         status |= S_RNF;
549         command_end();
550         return;
551
552      default:
553         logerror("%s: read id unknown sub-state %d\n", ttsn().cstr(), sub_state);
554         return;
555      }
556   }
557}
558
559void wd177x_t::write_track_start()
560{
561   if(has_ready() && !is_ready())
562      command_end();
563   
564   main_state = WRITE_TRACK;
565   status = (status & ~(S_WP|S_DDM|S_LOST|S_RNF)) | S_BUSY;
566   drop_drq();
567   if (has_side_select() && floppy)
568      floppy->ss_w(BIT(command, 1));
569   sub_state = has_motor()  && !has_head_load() ? SPINUP : SPINUP_DONE;
570   status_type_1 = false;
571   write_track_continue();
572}
573
574void wd177x_t::write_track_continue()
575{
576   for(;;) {
577      switch(sub_state) {
578      case SPINUP:
579         if(!(status & S_MON)) {
580            spinup();
581            return;
582         }
583         sub_state = SPINUP_DONE;
584         break;
585
586      case SPINUP_WAIT:
587         return;
588
589      case SPINUP_DONE:
590         if(command & 4) {
591            sub_state = SETTLE_WAIT;
592            delay_cycles(t_gen, settle_time());
593            return;
594         } else {
595            sub_state = SETTLE_DONE;
596            break;
597         }
598
599      case SETTLE_WAIT:
600         return;
601
602      case SETTLE_DONE:
603         set_drq();
604         sub_state = DATA_LOAD_WAIT;
605         delay_cycles(t_gen, 768);
606         return;
607
608      case DATA_LOAD_WAIT:
609         return;
610
611      case DATA_LOAD_WAIT_DONE:
612         if(drq) {
613            status |= S_LOST;
614            command_end();
615            return;
616         }
617         sub_state = WAIT_INDEX;
618         break;
619
620      case WAIT_INDEX:
621         return;
622
623      case WAIT_INDEX_DONE:
624         sub_state = TRACK_DONE;
625         live_start(WRITE_TRACK_DATA);
626         cur_live.pll.start_writing(machine().time());
627         return;
628
629      case TRACK_DONE:
630         command_end();
631         return;
632
633      default:
634         logerror("%s: write track unknown sub-state %d\n", ttsn().cstr(), sub_state);
635         return;
636      }
637   }
638}
639
640
641void wd177x_t::write_sector_start()
642{
643   if(has_ready() && !is_ready())
644      command_end();
645   
646   main_state = WRITE_SECTOR;
647   status = (status & ~(S_CRC|S_LOST|S_RNF|S_WP|S_DDM)) | S_BUSY;
648   drop_drq();
649   if (has_side_select() && floppy)
650      floppy->ss_w(BIT(command, 1));
651   sub_state = has_motor() && !has_head_load()  ? SPINUP : SPINUP_DONE;
652   status_type_1 = false;
653   write_sector_continue();
654}
655
656void wd177x_t::write_sector_continue()
657{
658   for(;;) {
659      switch(sub_state) {
660      case SPINUP:
661         if(!(status & S_MON)) {
662            spinup();
663            return;
664         }
665         sub_state = SPINUP_DONE;
666         break;
667
668      case SPINUP_WAIT:
669         return;
670
671      case SPINUP_DONE:
672         if(command & 4) {
673            sub_state = SETTLE_WAIT;
674            delay_cycles(t_gen, settle_time());
675            return;
676         } else {
677            sub_state = SETTLE_DONE;
678            break;
679         }
680
681      case SETTLE_WAIT:
682         return;
683
684      case SETTLE_DONE:
685         sub_state = SCAN_ID;
686         counter = 0;
687         live_start(SEARCH_ADDRESS_MARK_HEADER);
688         return;
689
690      case SCAN_ID:
691         if(!sector_matches()) {
692            live_start(SEARCH_ADDRESS_MARK_HEADER);
693            return;
694         }
695         if(cur_live.crc) {
696            status |= S_CRC;
697            live_start(SEARCH_ADDRESS_MARK_HEADER);
698            return;
699         }
700         // TODO WD2795/7 alternate sector size
701         sector_size = 128 << (cur_live.idbuf[3] & 3);
702         sub_state = SECTOR_WRITE;
703         live_start(WRITE_SECTOR_PRE);
704         return;
705
706      case SCAN_ID_FAILED:
707         status |= S_RNF;
708         command_end();
709         return;
710
711      case SECTOR_WRITE:
712         if(command & 0x10) {
713            sector++;
714            sub_state = SPINUP_DONE;
715         } else {
716            command_end();
717            return;
718         }
719         break;
720
721      default:
722         logerror("%s: write sector unknown sub-state %d\n", ttsn().cstr(), sub_state);
723         return;
724      }
725   }
726}
727
728void wd177x_t::interrupt_start()
729{
730   if(status & S_BUSY) {
731      main_state = sub_state = cur_live.state = IDLE;
732      cur_live.tm = attotime::never;
733      status &= ~S_BUSY;
734      drop_drq();
735      motor_timeout = 0;
736   }
737   
738   if(!(command & 0x0f)) {
739      intrq_cond = 0;
740   } else {
741      intrq_cond = (intrq_cond & I_IMM) | (command & 0x07);
742   }
743
744   if(intrq_cond & I_IMM) {
745      intrq = true;
746      if(!intrq_cb.isnull())
747         intrq_cb(intrq);
748   }
749
750   if(command & 0x03) {
751      logerror("%s: unhandled interrupt generation (%02x)\n", ttsn().cstr(), command);
752   }
753}
754
755void wd177x_t::general_continue()
756{
757   if(cur_live.state != IDLE) {
758      live_run();
759      if(cur_live.state != IDLE)
760         return;
761   }
762
763   switch(main_state) {
764   case IDLE:
765      break;
766   case RESTORE: case SEEK: case STEP:
767      seek_continue();
768      break;
769   case READ_SECTOR:
770      read_sector_continue();
771      break;
772   case READ_TRACK:
773      read_track_continue();
774      break;
775   case READ_ID:
776      read_id_continue();
777      break;
778   case WRITE_TRACK:
779      write_track_continue();
780      break;
781   case WRITE_SECTOR:
782      write_sector_continue();
783      break;
784   default:
785      logerror("%s: general_continue on unknown main-state %d\n", ttsn().cstr(), main_state);
786      break;
787   }
788}
789
790void wd177x_t::do_generic()
791{
792   switch(sub_state) {
793   case IDLE:
794   case SCAN_ID:
795   case SECTOR_READ:
796      break;
797
798   case SETTLE_WAIT:
799      sub_state = SETTLE_DONE;
800      break;
801
802   case SEEK_WAIT_STEP_TIME:
803      sub_state = SEEK_WAIT_STEP_TIME_DONE;
804      break;
805
806   case SEEK_WAIT_STABILIZATION_TIME:
807      sub_state = SEEK_WAIT_STABILIZATION_TIME_DONE;
808      break;
809
810   case DATA_LOAD_WAIT:
811      sub_state = DATA_LOAD_WAIT_DONE;
812      break;
813
814   default:
815      if(cur_live.tm.is_never())
816         logerror("%s: do_generic on unknown sub-state %d\n", ttsn().cstr(), sub_state);
817      break;
818   }
819}
820
821void wd177x_t::do_cmd_w()
822{
823   //  fprintf(stderr, "%s: command %02x\n", ttsn().cstr(), cmd_buffer);
824
825   // Only available command when busy is interrupt
826   if(main_state != IDLE && (cmd_buffer & 0xf0) != 0xd0) {
827      cmd_buffer = -1;
828      return;
829   }
830   command = cmd_buffer;
831   cmd_buffer = -1;
832
833   switch(command & 0xf0) {
834   case 0x00: logerror("wd1772: restore\n"); last_dir = 1; seek_start(RESTORE); break;
835   case 0x10: logerror("wd1772: seek %d\n", data); last_dir = data > track ? 0 : 1; seek_start(SEEK); break;
836   case 0x20: case 0x30: logerror("wd1772: step\n"); seek_start(STEP); break;
837   case 0x40: case 0x50: logerror("wd1772: step +\n"); last_dir = 0; seek_start(STEP); break;
838   case 0x60: case 0x70: logerror("wd1772: step -\n"); last_dir = 1; seek_start(STEP); break;
839   case 0x80: case 0x90: logerror("wd1772: read sector%s %d, %d\n", command & 0x10 ? " multiple" : "", track, sector); read_sector_start(); break;
840   case 0xa0: case 0xb0: logerror("wd1772: write sector%s %d, %d\n", command & 0x10 ? " multiple" : "", track, sector); write_sector_start(); break;
841   case 0xc0: logerror("wd1772: read id\n"); read_id_start(); break;
842   case 0xd0: logerror("wd1772: interrupt\n"); interrupt_start(); break;
843   case 0xe0: logerror("wd1772: read track %d\n", track); read_track_start(); break;
844   case 0xf0: logerror("wd1772: write track %d\n", track); write_track_start(); break;
845   }
846}
847
848void wd177x_t::cmd_w(UINT8 val)
849{
850   logerror("wd1772 cmd: %02x\n", val);
851   
852   if(intrq && !(intrq_cond & I_IMM)) {
853      intrq = false;
854      if(!intrq_cb.isnull())
855         intrq_cb(intrq);
856   }
857
858   // No more than one write in flight
859   if(cmd_buffer != -1)
860      return;
861
862   cmd_buffer = val;
863
864   delay_cycles(t_cmd, dden ? 384 : 184);
865}
866
867UINT8 wd177x_t::status_r()
868{
869   if(intrq && !(intrq_cond & I_IMM)) {
870      intrq = false;
871      if(!intrq_cb.isnull())
872         intrq_cb(intrq);
873   }
874
875   if(main_state == IDLE || status_type_1) {
876      if(floppy && floppy->idx_r())
877         status |= S_IP;
878      else
879         status &= ~S_IP;
880   } else {
881      if(drq)
882         status |= S_DRQ;
883      else
884         status &= ~S_DRQ;
885   }
886
887   if(status_type_1) {
888      status &= ~(S_TR00|S_WP);
889      if(floppy) {
890         if(floppy->wpt_r())
891            status |= S_WP;
892         if(!floppy->trk00_r())
893            status |= S_TR00;
894      }
895   }
896
897   if(has_ready()) {
898      if(!is_ready())
899         status |= S_NRDY;
900      else
901         status &= ~S_NRDY;
902   }
903
904   return status;
905}
906
907void wd177x_t::do_track_w()
908{
909   track = track_buffer;
910   track_buffer = -1;
911}
912
913void wd177x_t::track_w(UINT8 val)
914{
915   // No more than one write in flight
916   if(track_buffer != -1)
917      return;
918
919   track_buffer = val;
920   delay_cycles(t_track, dden ? 256 : 128);
921}
922
923UINT8 wd177x_t::track_r()
924{
925   return track;
926}
927
928void wd177x_t::do_sector_w()
929{
930   sector = sector_buffer;
931   sector_buffer = -1;
932}
933
934void wd177x_t::sector_w(UINT8 val)
935{
936   // No more than one write in flight
937   if(sector_buffer != -1)
938      return;
939
940   sector_buffer = val;
941   delay_cycles(t_sector, dden ? 256 : 128);
942}
943
944UINT8 wd177x_t::sector_r()
945{
946   return sector;
947}
948
949void wd177x_t::data_w(UINT8 val)
950{
951   data = val;
952   drop_drq();
953}
954
955UINT8 wd177x_t::data_r()
956{
957   drop_drq();
958   return data;
959}
960
961void wd177x_t::gen_w(int reg, UINT8 val)
962{
963   switch(reg) {
964   case 0: cmd_w(val); break;
965   case 1: track_w(val); break;
966   case 2: sector_w(val); break;
967   case 3: data_w(val); break;
968   }
969}
970
971UINT8 wd177x_t::gen_r(int reg)
972{
973   switch(reg) {
974   case 0: return status_r(); break;
975   case 1: return track_r(); break;
976   case 2: return sector_r(); break;
977   case 3: return data_r(); break;
978   }
979   return 0xff;
980}
981
982void wd177x_t::delay_cycles(emu_timer *tm, int cycles)
983{
984   tm->adjust(clocks_to_attotime(cycles));
985}
986
987void wd177x_t::spinup()
988{
989   if(command & 0x08)
990      sub_state = SPINUP_DONE;
991   else {
992      sub_state = SPINUP_WAIT;
993      counter = 0;
994   }
995
996   status |= S_MON;
997   if(floppy)
998      floppy->mon_w(0);
999
1000}
1001
1002void wd177x_t::index_callback(floppy_image_device *floppy, int state)
1003{
1004   live_sync();
1005
1006   if(!state) {
1007      general_continue();
1008      return;
1009   }
1010
1011   if(intrq_cond & I_IDX) {
1012      intrq = true;
1013      if(!intrq_cb.isnull())
1014         intrq_cb(intrq);
1015   }
1016
1017   switch(sub_state) {
1018   case IDLE:
1019      if(has_motor()) {
1020         motor_timeout ++;
1021         if(motor_timeout >= 5) {
1022            status &= ~S_MON;
1023            if(floppy)
1024               floppy->mon_w(1);
1025         }
1026      }
1027      break;
1028
1029   case SPINUP:
1030      break;
1031
1032   case SPINUP_WAIT:
1033      counter++;
1034      if(counter == 6) {
1035         sub_state = SPINUP_DONE;
1036         if(status_type_1)
1037            status |= S_SPIN;
1038      }
1039      break;
1040
1041   case SPINUP_DONE:
1042   case SETTLE_WAIT:
1043   case SETTLE_DONE:
1044   case DATA_LOAD_WAIT:
1045   case DATA_LOAD_WAIT_DONE:
1046   case SEEK_MOVE:
1047   case SEEK_WAIT_STEP_TIME:
1048   case SEEK_WAIT_STEP_TIME_DONE:
1049   case SEEK_WAIT_STABILIZATION_TIME:
1050   case SEEK_WAIT_STABILIZATION_TIME_DONE:
1051   case SEEK_DONE:
1052   case WAIT_INDEX_DONE:
1053   case SCAN_ID_FAILED:
1054   case SECTOR_READ:
1055   case SECTOR_WRITE:
1056      break;
1057
1058   case SCAN_ID:
1059      counter++;
1060      if(counter == 5) {
1061         sub_state = SCAN_ID_FAILED;
1062         live_abort();
1063      }
1064      break;
1065
1066   case WAIT_INDEX:
1067      sub_state = WAIT_INDEX_DONE;
1068      break;
1069
1070   case TRACK_DONE:
1071      live_abort();
1072      break;
1073
1074   default:
1075      logerror("%s: Index pulse on unknown sub-state %d\n", ttsn().cstr(), sub_state);
1076      break;
1077   }
1078
1079   general_continue();
1080}
1081
1082bool wd177x_t::intrq_r()
1083{
1084   return intrq;
1085}
1086
1087bool wd177x_t::drq_r()
1088{
1089   return drq;
1090}
1091
1092bool wd177x_t::hld_r()
1093{
1094   return hld;
1095}
1096
1097void wd177x_t::hlt_w(bool state)
1098{
1099   hlt = state;
1100}
1101
1102bool wd177x_t::enp_r()
1103{
1104   return enp;
1105}
1106
1107void wd177x_t::live_start(int state)
1108{
1109   cur_live.tm = machine().time();
1110   cur_live.state = state;
1111   cur_live.next_state = -1;
1112   cur_live.shift_reg = 0;
1113   cur_live.crc = 0xffff;
1114   cur_live.bit_counter = 0;
1115   cur_live.data_separator_phase = false;
1116   cur_live.data_reg = 0;
1117   cur_live.previous_type = live_info::PT_NONE;
1118   cur_live.data_bit_context = false;
1119   cur_live.byte_counter = 0;
1120   cur_live.pll.reset(cur_live.tm);
1121   cur_live.pll.set_clock(clocks_to_attotime(1));
1122   checkpoint_live = cur_live;
1123
1124   live_run();
1125}
1126
1127void wd177x_t::checkpoint()
1128{
1129   cur_live.pll.commit(floppy, cur_live.tm);
1130   checkpoint_live = cur_live;
1131}
1132
1133void wd177x_t::rollback()
1134{
1135   cur_live = checkpoint_live;
1136}
1137
1138void wd177x_t::live_delay(int state)
1139{
1140   cur_live.next_state = state;
1141   t_gen->adjust(cur_live.tm - machine().time());
1142}
1143
1144void wd177x_t::live_sync()
1145{
1146   if(!cur_live.tm.is_never()) {
1147      if(cur_live.tm > machine().time()) {
1148         //          fprintf(stderr, "%s: Rolling back and replaying (%s)\n", ttsn().cstr(), tts(cur_live.tm).cstr());
1149         rollback();
1150         live_run(machine().time());
1151         cur_live.pll.commit(floppy, cur_live.tm);
1152      } else {
1153         //          fprintf(stderr, "%s: Committing (%s)\n", ttsn().cstr(), tts(cur_live.tm).cstr());
1154         cur_live.pll.commit(floppy, cur_live.tm);
1155         if(cur_live.next_state != -1) {
1156            cur_live.state = cur_live.next_state;
1157            cur_live.next_state = -1;
1158         }
1159         if(cur_live.state == IDLE) {
1160            cur_live.pll.stop_writing(floppy, cur_live.tm);
1161            cur_live.tm = attotime::never;
1162         }
1163      }
1164      cur_live.next_state = -1;
1165      checkpoint();
1166   }
1167}
1168
1169void wd177x_t::live_abort()
1170{
1171   if(!cur_live.tm.is_never() && cur_live.tm > machine().time()) {
1172      rollback();
1173      live_run(machine().time());
1174   }
1175
1176   cur_live.pll.stop_writing(floppy, cur_live.tm);
1177   cur_live.tm = attotime::never;
1178   cur_live.state = IDLE;
1179   cur_live.next_state = -1;
1180}
1181
1182bool wd177x_t::read_one_bit(attotime limit)
1183{
1184   int bit = cur_live.pll.get_next_bit(cur_live.tm, floppy, limit);
1185   if(bit < 0)
1186      return true;
1187   cur_live.shift_reg = (cur_live.shift_reg << 1) | bit;
1188   cur_live.bit_counter++;
1189   if(cur_live.data_separator_phase) {
1190      cur_live.data_reg = (cur_live.data_reg << 1) | bit;
1191      if((cur_live.crc ^ (bit ? 0x8000 : 0x0000)) & 0x8000)
1192         cur_live.crc = (cur_live.crc << 1) ^ 0x1021;
1193      else
1194         cur_live.crc = cur_live.crc << 1;
1195   }
1196   cur_live.data_separator_phase = !cur_live.data_separator_phase;
1197   return false;
1198}
1199
1200bool wd177x_t::write_one_bit(attotime limit)
1201{
1202   bool bit = cur_live.shift_reg & 0x8000;
1203   if(cur_live.pll.write_next_bit(bit, cur_live.tm, floppy, limit))
1204      return true;
1205   if(cur_live.bit_counter & 1) {
1206      if((cur_live.crc ^ (bit ? 0x8000 : 0x0000)) & 0x8000)
1207         cur_live.crc = (cur_live.crc << 1) ^ 0x1021;
1208      else
1209         cur_live.crc = cur_live.crc << 1;
1210   }
1211   cur_live.shift_reg = cur_live.shift_reg << 1;
1212   cur_live.bit_counter--;
1213   return false;
1214}
1215
1216void wd177x_t::live_write_raw(UINT16 raw)
1217{
1218   //  logerror("write %04x %04x\n", raw, cur_live.crc);
1219   cur_live.shift_reg = raw;
1220   cur_live.data_bit_context = raw & 1;
1221}
1222
1223void wd177x_t::live_write_mfm(UINT8 mfm)
1224{
1225   bool context = cur_live.data_bit_context;
1226   UINT16 raw = 0;
1227   for(int i=0; i<8; i++) {
1228      bool bit = mfm & (0x80 >> i);
1229      if(!(bit || context))
1230         raw |= 0x8000 >> (2*i);
1231      if(bit)
1232         raw |= 0x4000 >> (2*i);
1233      context = bit;
1234   }
1235   cur_live.shift_reg = raw;
1236   cur_live.data_bit_context = context;
1237   //  logerror("write %02x   %04x %04x\n", mfm, cur_live.crc, raw);
1238}
1239
1240void wd177x_t::live_run(attotime limit)
1241{
1242   if(cur_live.state == IDLE || cur_live.next_state != -1)
1243      return;
1244
1245   if(limit == attotime::never) {
1246      if(floppy)
1247         limit = floppy->time_next_index();
1248      if(limit == attotime::never) {
1249         // Happens when there's no disk or if the wd is not
1250         // connected to a drive, hence no index pulse. Force a
1251         // sync from time to time in that case, so that the main
1252         // cpu timeout isn't too painful.  Avoids looping into
1253         // infinity looking for data too.
1254
1255         limit = machine().time() + attotime::from_msec(1);
1256         t_gen->adjust(attotime::from_msec(1));
1257      }
1258   }
1259
1260   //  fprintf(stderr, "%s: live_run(%s)\n", ttsn().cstr(), tts(limit).cstr());
1261
1262   for(;;) {
1263      switch(cur_live.state) {
1264      case SEARCH_ADDRESS_MARK_HEADER:
1265         if(read_one_bit(limit))
1266            return;
1267#if 0
1268         fprintf(stderr, "%s: shift = %04x data=%02x c=%d\n", tts(cur_live.tm).cstr(), cur_live.shift_reg,
1269               (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) |
1270               (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) |
1271               (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) |
1272               (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) |
1273               (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) |
1274               (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) |
1275               (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) |
1276               (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00),
1277               cur_live.bit_counter);
1278#endif
1279
1280         if(cur_live.shift_reg == 0x4489) {
1281            cur_live.crc = 0x443b;
1282            cur_live.data_separator_phase = false;
1283            cur_live.bit_counter = 0;
1284            cur_live.state = READ_HEADER_BLOCK_HEADER;
1285         }
1286         break;
1287
1288      case READ_HEADER_BLOCK_HEADER: {
1289         if(read_one_bit(limit))
1290            return;
1291#if 0
1292         fprintf(stderr, "%s: shift = %04x data=%02x counter=%d\n", tts(cur_live.tm).cstr(), cur_live.shift_reg,
1293               (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) |
1294               (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) |
1295               (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) |
1296               (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) |
1297               (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) |
1298               (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) |
1299               (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) |
1300               (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00),
1301               cur_live.bit_counter);
1302#endif
1303         if(cur_live.bit_counter & 15)
1304            break;
1305
1306         int slot = cur_live.bit_counter >> 4;
1307
1308         if(slot < 3) {
1309            if(cur_live.shift_reg != 0x4489)
1310               cur_live.state = SEARCH_ADDRESS_MARK_HEADER;
1311            break;
1312         }
1313         if(cur_live.data_reg != 0xfe && cur_live.data_reg != 0xff) {
1314            cur_live.state = SEARCH_ADDRESS_MARK_HEADER;
1315            break;
1316         }
1317
1318         cur_live.bit_counter = 0;
1319
1320         if(main_state == READ_ID)
1321            cur_live.state = READ_ID_BLOCK_TO_DMA;
1322         else
1323            cur_live.state = READ_ID_BLOCK_TO_LOCAL;
1324
1325         break;
1326      }
1327
1328      case READ_ID_BLOCK_TO_LOCAL: {
1329         if(read_one_bit(limit))
1330            return;
1331         if(cur_live.bit_counter & 15)
1332            break;
1333         int slot = (cur_live.bit_counter >> 4)-1;
1334         cur_live.idbuf[slot] = cur_live.data_reg;
1335         if(slot == 5) {
1336            live_delay(IDLE);
1337            return;
1338         }
1339         break;
1340      }
1341
1342      case READ_ID_BLOCK_TO_DMA: {
1343         if(read_one_bit(limit))
1344            return;
1345         if(cur_live.bit_counter & 15)
1346            break;
1347         live_delay(READ_ID_BLOCK_TO_DMA_BYTE);
1348         return;
1349      }
1350
1351      case READ_ID_BLOCK_TO_DMA_BYTE:
1352         data = cur_live.data_reg;
1353         if(cur_live.bit_counter == 16)
1354            sector = data;
1355         set_drq();
1356
1357         if(cur_live.bit_counter == 16*6) {
1358            // Already synchronous
1359            cur_live.state = IDLE;
1360            return;
1361         }
1362
1363         cur_live.state = READ_ID_BLOCK_TO_DMA;
1364         checkpoint();
1365         break;
1366
1367      case SEARCH_ADDRESS_MARK_DATA:
1368         if(read_one_bit(limit))
1369            return;
1370#if 0
1371         fprintf(stderr, "%s: shift = %04x data=%02x c=%d.%x\n", tts(cur_live.tm).cstr(), cur_live.shift_reg,
1372               (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) |
1373               (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) |
1374               (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) |
1375               (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) |
1376               (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) |
1377               (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) |
1378               (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) |
1379               (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00),
1380               cur_live.bit_counter >> 4, cur_live.bit_counter & 15);
1381#endif
1382         if(cur_live.bit_counter > 43*16) {
1383            live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED);
1384            return;
1385         }
1386
1387         if(cur_live.bit_counter >= 28*16 && cur_live.shift_reg == 0x4489) {
1388            cur_live.crc = 0x443b;
1389            cur_live.data_separator_phase = false;
1390            cur_live.bit_counter = 0;
1391            cur_live.state = READ_DATA_BLOCK_HEADER;
1392         }
1393         break;
1394
1395      case READ_DATA_BLOCK_HEADER: {
1396         if(read_one_bit(limit))
1397            return;
1398#if 0
1399         fprintf(stderr, "%s: shift = %04x data=%02x counter=%d\n", tts(cur_live.tm).cstr(), cur_live.shift_reg,
1400               (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) |
1401               (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) |
1402               (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) |
1403               (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) |
1404               (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) |
1405               (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) |
1406               (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) |
1407               (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00),
1408               cur_live.bit_counter);
1409#endif
1410         if(cur_live.bit_counter & 15)
1411            break;
1412
1413         int slot = cur_live.bit_counter >> 4;
1414
1415         if(slot < 3) {
1416            if(cur_live.shift_reg != 0x4489) {
1417               live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED);
1418               return;
1419            }
1420            break;
1421         }
1422         if((cur_live.data_reg & 0xfe) != 0xfa && (cur_live.data_reg & 0xfe) != 0xfc) {
1423            live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED);
1424            return;
1425         }
1426
1427         cur_live.bit_counter = 0;
1428         cur_live.state = READ_SECTOR_DATA;
1429         break;
1430      }
1431
1432      case SEARCH_ADDRESS_MARK_DATA_FAILED:
1433         status |= S_RNF;
1434         cur_live.state = IDLE;
1435         return;
1436
1437      case READ_SECTOR_DATA: {
1438         if(read_one_bit(limit))
1439            return;
1440         if(cur_live.bit_counter & 15)
1441            break;
1442         int slot = (cur_live.bit_counter >> 4)-1;
1443         if(slot < sector_size) {
1444            // Sector data
1445            live_delay(READ_SECTOR_DATA_BYTE);
1446            return;
1447
1448         } else if(slot < sector_size+2) {
1449            // CRC
1450            if(slot == sector_size+1) {
1451               live_delay(IDLE);
1452               return;
1453            }
1454         }
1455
1456         break;
1457      }
1458
1459      case READ_SECTOR_DATA_BYTE:
1460         data = cur_live.data_reg;
1461         set_drq();
1462         cur_live.state = READ_SECTOR_DATA;
1463         checkpoint();
1464         break;
1465
1466      case READ_TRACK_DATA: {
1467         if(read_one_bit(limit))
1468            return;
1469         if(cur_live.bit_counter != 16
1470            && cur_live.shift_reg != 0x4489
1471            && cur_live.shift_reg != 0x5224)
1472            break;
1473
1474         // Incorrect, hmmm
1475         // Probably >2 + not just after a sync if <16
1476
1477         // Transitions 00..00 -> 4489.4489.4489 at varied syncs:
1478         //  0: 00.00.14.a1   1: ff.fe.c2.a1   2: 00.01.14.a1   3: ff.fc.c2.a1
1479         //  4: 00.02.14.a1   5: ff.f8.c2.a1   6: 00.05.14.a1   7: ff.f0.c2.a1
1480         //  8: 00.00.0a.a1   9: ff.ff.e1.a1  10: 00.00.14.a1  11: ff.ff.ce.a1
1481         // 12: 00.00.14.a1  13: ff.ff.c2.a1  14: 00.00.14.a1  15: ff.ff.c2.a1
1482
1483         bool output_byte = cur_live.bit_counter > 5;
1484
1485         cur_live.data_separator_phase = false;
1486         cur_live.bit_counter = 0;
1487
1488         if(output_byte) {
1489            live_delay(READ_TRACK_DATA_BYTE);
1490            return;
1491         }
1492
1493         break;
1494      }
1495
1496      case READ_TRACK_DATA_BYTE:
1497         data = cur_live.data_reg;
1498         set_drq();
1499         cur_live.state = READ_TRACK_DATA;
1500         checkpoint();
1501         break;
1502
1503      case WRITE_TRACK_DATA:
1504         if(drq) {
1505            status |= S_LOST;
1506            data = 0;
1507         }
1508
1509         switch(data) {
1510         case 0xf5:
1511            live_write_raw(0x4489);
1512            cur_live.crc = 0x968b; // Ensures that the crc is cdb4 after writing the byte
1513            cur_live.previous_type = live_info::PT_NONE;
1514            break;
1515         case 0xf6:
1516            cur_live.previous_type = live_info::PT_NONE;
1517            live_write_raw(0x5224);
1518            break;
1519         case 0xf7:
1520            if(cur_live.previous_type == live_info::PT_CRC_2) {
1521               cur_live.previous_type = live_info::PT_NONE;
1522               live_write_mfm(0xf7);
1523            } else {
1524               cur_live.previous_type = live_info::PT_CRC_1;
1525               live_write_mfm(cur_live.crc >> 8);
1526            }
1527            break;
1528         default:
1529            cur_live.previous_type = live_info::PT_NONE;
1530            live_write_mfm(data);
1531            break;
1532         }
1533         set_drq();
1534         cur_live.state = WRITE_BYTE;
1535         cur_live.bit_counter = 16;
1536         checkpoint();
1537         break;
1538
1539      case WRITE_BYTE:
1540         if(write_one_bit(limit))
1541            return;
1542         if(cur_live.bit_counter == 0) {
1543            live_delay(WRITE_BYTE_DONE);
1544            return;
1545         }
1546         break;
1547
1548      case WRITE_BYTE_DONE:
1549         switch(sub_state) {
1550         case TRACK_DONE:
1551            if(cur_live.previous_type == live_info::PT_CRC_1) {
1552               cur_live.previous_type = live_info::PT_CRC_2;
1553               live_write_mfm(cur_live.crc >> 8);
1554               cur_live.state = WRITE_BYTE;
1555               cur_live.bit_counter = 16;
1556               checkpoint();
1557            } else
1558               cur_live.state = WRITE_TRACK_DATA;
1559            break;
1560
1561         case SECTOR_WRITE:
1562            cur_live.state = WRITE_BYTE;
1563            cur_live.bit_counter = 16;
1564            cur_live.byte_counter++;
1565            if(cur_live.byte_counter <= 11)
1566               live_write_mfm(0x00);
1567            else if(cur_live.byte_counter == 12) {
1568               cur_live.crc = 0xffff;
1569               live_write_raw(0x4489);
1570            } else if(cur_live.byte_counter <= 14)
1571               live_write_raw(0x4489);
1572            else if(cur_live.byte_counter == 15)
1573               live_write_mfm(command & 1 ? 0xf8 : 0xfb);
1574            else if(cur_live.byte_counter <= sector_size + 16-2) {
1575               if(drq) {
1576                  status |= S_LOST;
1577                  data = 0;
1578               }
1579               live_write_mfm(data);
1580               set_drq();
1581            } else if(cur_live.byte_counter == sector_size + 16-1) {
1582               if(drq) {
1583                  status |= S_LOST;
1584                  data = 0;
1585               }
1586               live_write_mfm(data);
1587            } else if(cur_live.byte_counter <= sector_size + 16+1)
1588               live_write_mfm(cur_live.crc >> 8);
1589            else if(cur_live.byte_counter == sector_size + 16+2)
1590               // Is that correct?  It seems required (try ST formatting)
1591               live_write_mfm(0xff);
1592            else {
1593               cur_live.pll.stop_writing(floppy, cur_live.tm);
1594               cur_live.state = IDLE;
1595               return;
1596            }
1597
1598            checkpoint();
1599            break;
1600
1601         default:
1602            logerror("%s: Unknown sub state %d in WRITE_BYTE_DONE\n", tts(cur_live.tm).cstr(), sub_state);
1603            live_abort();
1604            return;
1605         }
1606         break;
1607
1608      case WRITE_SECTOR_PRE:
1609         if(read_one_bit(limit))
1610            return;
1611         if(cur_live.bit_counter != 16)
1612            break;
1613         live_delay(WRITE_SECTOR_PRE_BYTE);
1614         return;
1615
1616      case WRITE_SECTOR_PRE_BYTE:
1617         cur_live.state = WRITE_SECTOR_PRE;
1618         cur_live.byte_counter++;
1619         cur_live.bit_counter = 0;
1620         switch(cur_live.byte_counter) {
1621         case 2:
1622            set_drq();
1623            checkpoint();
1624            break;
1625         case 11:
1626            if(drq) {
1627               status |= S_LOST;
1628               cur_live.state = IDLE;
1629               return;
1630            }
1631            break;
1632         case 22:
1633            cur_live.state = WRITE_BYTE;
1634            cur_live.bit_counter = 16;
1635            cur_live.byte_counter = 0;
1636            cur_live.data_bit_context = cur_live.data_reg & 1;
1637            cur_live.pll.start_writing(cur_live.tm);
1638            live_write_mfm(0x00);
1639            break;
1640         }
1641         break;
1642
1643      default:
1644         logerror("%s: Unknown live state %d\n", tts(cur_live.tm).cstr(), cur_live.state);
1645         return;
1646      }
1647   }
1648}
1649
1650void wd177x_t::set_drq()
1651{
1652   if(drq)
1653      status |= S_LOST;
1654   else {
1655      drq = true;
1656      if(!drq_cb.isnull())
1657         drq_cb(true);
1658   }
1659}
1660
1661void wd177x_t::drop_drq()
1662{
1663   if(drq) {
1664      drq = false;
1665      if(!drq_cb.isnull())
1666         drq_cb(false);
1667   }
1668}
1669
1670void wd177x_t::pll_t::set_clock(attotime period)
1671{
1672   for(int i=0; i<42; i++)
1673      delays[i] = period*(i+1);
1674}
1675
1676void wd177x_t::pll_t::reset(attotime when)
1677{
1678   counter = 0;
1679   increment = 128;
1680   transition_time = 0xffff;
1681   history = 0x80;
1682   slot = 0;
1683   ctime = when;
1684   phase_add = 0x00;
1685   phase_sub = 0x00;
1686   freq_add  = 0x00;
1687   freq_sub  = 0x00;
1688   write_position = 0;
1689   write_start_time = attotime::never;
1690}
1691
1692int wd177x_t::pll_t::get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit)
1693{
1694   attotime when = floppy ? floppy->get_next_transition(ctime) : attotime::never;
1695#if 0
1696   if(!when.is_never())
1697      fprintf(stderr, "transition_time=%s\n", tts(when).cstr());
1698#endif
1699
1700   for(;;) {
1701      //      fprintf(stderr, "slot=%2d, counter=%03x\n", slot, counter);
1702      attotime etime = ctime+delays[slot];
1703      //      fprintf(stderr, "etime=%s\n", tts(etime).cstr());
1704      if(etime > limit)
1705         return -1;
1706      if(transition_time == 0xffff && !when.is_never() && etime >= when)
1707         transition_time = counter;
1708      if(slot < 8) {
1709         UINT8 mask = 1 << slot;
1710         if(phase_add & mask)
1711            counter += 226;
1712         else if(phase_sub & mask)
1713            counter += 30;
1714         else
1715            counter += increment;
1716
1717         if((freq_add & mask) && increment < 140)
1718            increment++;
1719         else if((freq_sub & mask) && increment > 117)
1720            increment--;
1721      } else
1722         counter += increment;
1723
1724      slot++;
1725      tm = etime;
1726      if(counter & 0x800)
1727         break;
1728   }
1729   //  fprintf(stderr, "first transition, time=%03x, inc=%3d\n", transition_time, increment);
1730   int bit = transition_time != 0xffff;
1731
1732   if(transition_time != 0xffff) {
1733      static const UINT8 pha[8] = { 0xf, 0x7, 0x3, 0x1, 0, 0, 0, 0 };
1734      static const UINT8 phs[8] = { 0, 0, 0, 0, 0x1, 0x3, 0x7, 0xf };
1735      static const UINT8 freqa[4][8] = {
1736         { 0xf, 0x7, 0x3, 0x1, 0, 0, 0, 0 },
1737         { 0x7, 0x3, 0x1, 0, 0, 0, 0, 0 },
1738         { 0x7, 0x3, 0x1, 0, 0, 0, 0, 0 },
1739         { 0, 0, 0, 0, 0, 0, 0, 0 }
1740      };
1741      static const UINT8 freqs[4][8] = {
1742         { 0, 0, 0, 0, 0, 0, 0, 0 },
1743         { 0, 0, 0, 0, 0, 0x1, 0x3, 0x7 },
1744         { 0, 0, 0, 0, 0, 0x1, 0x3, 0x7 },
1745         { 0, 0, 0, 0, 0x1, 0x3, 0x7, 0xf },
1746      };
1747
1748      int cslot = transition_time >> 8;
1749      phase_add = pha[cslot];
1750      phase_sub = phs[cslot];
1751      int way = transition_time & 0x400 ? 1 : 0;
1752      if(history & 0x80)
1753         history = way ? 0x80 : 0x83;
1754      else if(history & 0x40)
1755         history = way ? history & 2 : (history & 2) | 1;
1756      freq_add = freqa[history & 3][cslot];
1757      freq_sub = freqs[history & 3][cslot];
1758      history = way ? (history >> 1) | 2 : history >> 1;
1759
1760   } else
1761      phase_add = phase_sub = freq_add = freq_sub = 0;
1762
1763   counter &= 0x7ff;
1764
1765   ctime = tm;
1766   transition_time = 0xffff;
1767   slot = 0;
1768
1769   return bit;
1770}
1771
1772void wd177x_t::pll_t::start_writing(attotime tm)
1773{
1774   write_start_time = tm;
1775   write_position = 0;
1776}
1777
1778void wd177x_t::pll_t::stop_writing(floppy_image_device *floppy, attotime tm)
1779{
1780   commit(floppy, tm);
1781   write_start_time = attotime::never;
1782}
1783
1784bool wd177x_t::pll_t::write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit)
1785{
1786   if(write_start_time.is_never()) {
1787      write_start_time = ctime;
1788      write_position = 0;
1789   }
1790
1791   for(;;) {
1792      attotime etime = ctime+delays[slot];
1793      if(etime > limit)
1794         return true;
1795      UINT16 pre_counter = counter;
1796      counter += increment;
1797      if(bit && !(pre_counter & 0x400) && (counter & 0x400))
1798         if(write_position < ARRAY_LENGTH(write_buffer))
1799            write_buffer[write_position++] = etime;
1800      slot++;
1801      tm = etime;
1802      if(counter & 0x800)
1803         break;
1804   }
1805
1806   counter &= 0x7ff;
1807
1808   ctime = tm;
1809   slot = 0;
1810
1811   return false;
1812}
1813
1814void wd177x_t::pll_t::commit(floppy_image_device *floppy, attotime tm)
1815{
1816   if(write_start_time.is_never() || tm == write_start_time)
1817      return;
1818
1819   if(floppy)
1820      floppy->write_flux(write_start_time, tm, write_position, write_buffer);
1821   write_start_time = tm;
1822   write_position = 0;
1823}
1824
1825int wd177x_t::step_time(int mode) const
1826{
1827   const static int step_times[4] = { 48000, 96000, 160000, 240000 };
1828   return step_times[mode];
1829}
1830
1831int wd177x_t::settle_time() const
1832{
1833   return 240000;
1834}
1835
1836bool wd177x_t::has_ready() const
1837{
1838   return false;
1839}
1840
1841bool wd177x_t::has_head_load() const
1842{
1843   return false;
1844}
1845
1846bool wd177x_t::has_side_check() const
1847{
1848   return false;
1849}
1850
1851bool wd177x_t::has_side_select() const
1852{
1853   return false;
1854}
1855
1856bool wd177x_t::has_sector_length_select() const
1857{
1858   return false;
1859}
1860
1861bool wd177x_t::has_precompensation() const
1862{
1863   return false;
1864}
1865
1866fd1771_t::fd1771_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd177x_t(mconfig, FD1771x, "FD1771", tag, owner, clock)
1867{
1868}
1869
1870fd1793_t::fd1793_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd177x_t(mconfig, FD1793x, "FD1793", tag, owner, clock)
1871{
1872}
1873
1874fd1797_t::fd1797_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd177x_t(mconfig, FD1797x, "FD1797", tag, owner, clock)
1875{
1876}
1877
1878wd2793_t::wd2793_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd177x_t(mconfig, WD2793x, "WD2793", tag, owner, clock)
1879{
1880}
1881
1882wd2797_t::wd2797_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd177x_t(mconfig, WD2797x, "WD2797", tag, owner, clock)
1883{
1884}
1885
1886wd1770_t::wd1770_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd177x_t(mconfig, WD1770x, "WD1770", tag, owner, clock)
1887{
1888}
1889
1890wd1772_t::wd1772_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd177x_t(mconfig, WD1772x, "WD1772", tag, owner, clock)
1891{
1892}
1893
1894int wd1772_t::step_time(int mode) const
1895{
1896   const static int step_times[4] = { 48000, 96000, 16000, 24000 };
1897   return step_times[mode];
1898}
1899
1900int wd1772_t::settle_time() const
1901{
1902   return 120000;
1903}
1904
1905wd1773_t::wd1773_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd177x_t(mconfig, WD1773x, "WD1773", tag, owner, clock)
1906{
1907}
trunk/src/emu/machine/wd1772.h
r19165r19166
1#ifndef WD1772_H
2#define WD1772_H
3
4#include "emu.h"
5#include "imagedev/floppy.h"
6
7#define MCFG_FD1771x_ADD(_tag, _clock)  \
8   MCFG_DEVICE_ADD(_tag, FD1771x, _clock)
9
10#define MCFG_FD1793x_ADD(_tag, _clock)  \
11   MCFG_DEVICE_ADD(_tag, FD1793x, _clock)
12
13#define MCFG_FD1797x_ADD(_tag, _clock)  \
14   MCFG_DEVICE_ADD(_tag, FD1797x, _clock)
15
16#define MCFG_WD2793x_ADD(_tag, _clock)  \
17   MCFG_DEVICE_ADD(_tag, WD2793x, _clock)
18
19#define MCFG_WD2797x_ADD(_tag, _clock)  \
20   MCFG_DEVICE_ADD(_tag, WD2797x, _clock)
21
22#define MCFG_WD1770x_ADD(_tag, _clock)  \
23   MCFG_DEVICE_ADD(_tag, WD1770x, _clock)
24
25#define MCFG_WD1772x_ADD(_tag, _clock)  \
26   MCFG_DEVICE_ADD(_tag, WD1772x, _clock)
27
28#define MCFG_WD1773x_ADD(_tag, _clock)  \
29   MCFG_DEVICE_ADD(_tag, WD1773x, _clock)
30
31class wd177x_t : public device_t {
32public:
33   typedef delegate<void (bool state)> line_cb;
34
35   wd177x_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
36
37   void dden_w(bool dden);
38   void set_floppy(floppy_image_device *floppy);
39   void setup_intrq_cb(line_cb cb);
40   void setup_drq_cb(line_cb cb);
41   void setup_hld_cb(line_cb cb);
42   void setup_enp_cb(line_cb cb);
43
44   void cmd_w(UINT8 val);
45   UINT8 status_r();
46   DECLARE_READ8_MEMBER( status_r ) { return status_r(); }
47   DECLARE_WRITE8_MEMBER( cmd_w ) { cmd_w(data); }
48
49   void track_w(UINT8 val);
50   UINT8 track_r();
51   DECLARE_READ8_MEMBER( track_r ) { return track_r(); }
52   DECLARE_WRITE8_MEMBER( track_w ) { track_w(data); }
53
54   void sector_w(UINT8 val);
55   UINT8 sector_r();
56   DECLARE_READ8_MEMBER( sector_r ) { return sector_r(); }
57   DECLARE_WRITE8_MEMBER( sector_w ) { sector_w(data); }
58
59   void data_w(UINT8 val);
60   UINT8 data_r();
61   DECLARE_READ8_MEMBER( data_r ) { return data_r(); }
62   DECLARE_WRITE8_MEMBER( data_w ) { data_w(data); }
63
64   void gen_w(int reg, UINT8 val);
65   UINT8 gen_r(int reg);
66   DECLARE_READ8_MEMBER( read ) { return gen_r(offset);}
67   DECLARE_WRITE8_MEMBER( write ) { gen_w(offset,data); }
68
69   bool intrq_r();
70   bool drq_r();
71
72   bool hld_r();
73   void hlt_w(bool state);
74
75   bool enp_r();
76
77protected:
78   virtual void device_start();
79   virtual void device_reset();
80   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
81
82   virtual bool has_ready() const;
83   virtual bool has_motor() const = 0;
84   virtual bool has_head_load() const;
85   virtual bool has_side_check() const;
86   virtual bool has_side_select() const;
87   virtual bool has_sector_length_select() const;
88   virtual bool has_precompensation() const;
89   virtual int step_time(int mode) const;
90   virtual int settle_time() const;
91
92private:
93   enum { TM_GEN, TM_CMD, TM_TRACK, TM_SECTOR };
94
95   //  State machine general behaviour:
96   //
97   //  There are three levels of state.
98   //
99   //  Main state is associated to (groups of) commands.  They're set
100   //  by a *_start() function below, and the associated _continue()
101   //  function can then be called at pretty much any time.
102   //
103   //  Sub state is the state of execution within a command.  The
104   //  principle is that the *_start() function selects the initial
105   //  substate, then the *_continue() function decides what to do,
106   //  possibly changing state.  Eventually it can:
107   //  - decide to wait for an event (timer, index)
108   //  - end the command with command_end()
109   //  - start a live state (see below)
110   //
111   //  In the first case, it must first switch to a waiting
112   //  sub-state, then return.  The waiting sub-state must just
113   //  return immediatly when *_continue is called.  Eventually the
114   //  event handler function will advance the state machine to
115   //  another sub-state, and things will continue synchronously.
116   //
117   //  On command end it's also supposed to return immediatly.
118   //
119   //  The last option is to switch to the next sub-state, start a
120   //  live state with live_start() then return.  The next sub-state
121   //  will only be called once the live state is finished.
122   //
123   //  Live states change continually depending on the disk contents
124   //  until the next externally discernable event is found.  They
125   //  are checkpointing, run until an event is found, then they wait
126   //  for it.  When an event eventually happen the the changes are
127   //  either committed or replayed until the sync event time.
128   //
129   //  The transition to IDLE is only done on a synced event.  Some
130   //  other transitions, such as activating drq, are also done after
131   //  syncing without exiting live mode.  Syncing in live mode is
132   //  done by calling live_delay() with the state to change to after
133   //  syncing.
134
135   enum {
136      // General "doing nothing" state
137      IDLE,
138
139      // Main states - the commands
140      RESTORE,
141      SEEK,
142      STEP,
143      READ_SECTOR,
144      READ_TRACK,
145      READ_ID,
146      WRITE_TRACK,
147      WRITE_SECTOR,
148
149      // Sub states
150
151      SPINUP,
152      SPINUP_WAIT,
153      SPINUP_DONE,
154
155      SETTLE_WAIT,
156      SETTLE_DONE,
157
158      DATA_LOAD_WAIT,
159      DATA_LOAD_WAIT_DONE,
160
161      SEEK_MOVE,
162      SEEK_WAIT_STEP_TIME,
163      SEEK_WAIT_STEP_TIME_DONE,
164      SEEK_WAIT_STABILIZATION_TIME,
165      SEEK_WAIT_STABILIZATION_TIME_DONE,
166      SEEK_DONE,
167
168      WAIT_INDEX,
169      WAIT_INDEX_DONE,
170
171      SCAN_ID,
172      SCAN_ID_FAILED,
173
174      SECTOR_READ,
175      SECTOR_WRITE,
176      TRACK_DONE,
177
178      // Live states
179
180      SEARCH_ADDRESS_MARK_HEADER,
181      READ_HEADER_BLOCK_HEADER,
182      READ_DATA_BLOCK_HEADER,
183      READ_ID_BLOCK_TO_LOCAL,
184      READ_ID_BLOCK_TO_DMA,
185      READ_ID_BLOCK_TO_DMA_BYTE,
186      SEARCH_ADDRESS_MARK_DATA,
187      SEARCH_ADDRESS_MARK_DATA_FAILED,
188      READ_SECTOR_DATA,
189      READ_SECTOR_DATA_BYTE,
190      READ_TRACK_DATA,
191      READ_TRACK_DATA_BYTE,
192      WRITE_TRACK_DATA,
193      WRITE_BYTE,
194      WRITE_BYTE_DONE,
195      WRITE_SECTOR_PRE,
196      WRITE_SECTOR_PRE_BYTE,
197   };
198
199   struct pll_t {
200      UINT16 counter;
201      UINT16 increment;
202      UINT16 transition_time;
203      UINT8 history;
204      UINT8 slot;
205      UINT8 phase_add, phase_sub, freq_add, freq_sub;
206      attotime ctime;
207
208      attotime delays[42];
209
210      attotime write_start_time;
211      attotime write_buffer[32];
212      int write_position;
213
214      void set_clock(attotime period);
215      void reset(attotime when);
216      int get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit);
217      bool write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit);
218      void start_writing(attotime tm);
219      void commit(floppy_image_device *floppy, attotime tm);
220      void stop_writing(floppy_image_device *floppy, attotime tm);
221   };
222
223   struct live_info {
224      enum { PT_NONE, PT_CRC_1, PT_CRC_2 };
225
226      attotime tm;
227      int state, next_state;
228      UINT16 shift_reg;
229      UINT16 crc;
230      int bit_counter, byte_counter, previous_type;
231      bool data_separator_phase, data_bit_context;
232      UINT8 data_reg;
233      UINT8 idbuf[6];
234      pll_t pll;
235   };
236
237   enum {
238      S_BUSY = 0x01,
239      S_DRQ  = 0x02,
240      S_IP   = 0x02,
241      S_TR00 = 0x04,
242      S_LOST = 0x04,
243      S_CRC  = 0x08,
244      S_RNF  = 0x10,
245      S_HLD  = 0x20,
246      S_SPIN = 0x20, // WD1770, WD1772
247      S_DDM  = 0x20,
248      S_WF   = 0x20, // WD1773
249      S_WP   = 0x40,
250      S_NRDY = 0x80,
251      S_MON  = 0x80  // WD1770, WD1772
252   };
253
254   enum {
255      I_RDY = 0x01,
256      I_NRDY = 0x02,
257      I_IDX = 0x04,
258      I_IMM = 0x08
259   };
260
261   floppy_image_device *floppy;
262
263   emu_timer *t_gen, *t_cmd, *t_track, *t_sector;
264
265   bool dden, status_type_1, intrq, drq, hld, hlt, enp;
266   int main_state, sub_state;
267   UINT8 command, track, sector, data, status, intrq_cond;
268   int last_dir;
269
270   int counter, motor_timeout, sector_size;
271
272   int cmd_buffer, track_buffer, sector_buffer;
273
274   live_info cur_live, checkpoint_live;
275   line_cb intrq_cb, drq_cb, hld_cb, enp_cb;
276
277   static astring tts(attotime t);
278   astring ttsn();
279
280   void delay_cycles(emu_timer *tm, int cycles);
281
282   // Device timer subfunctions
283   void do_cmd_w();
284   void do_track_w();
285   void do_sector_w();
286   void do_generic();
287
288
289   // Main-state handling functions
290   void seek_start(int state);
291   void seek_continue();
292
293   void read_sector_start();
294   void read_sector_continue();
295
296   void read_track_start();
297   void read_track_continue();
298
299   void read_id_start();
300   void read_id_continue();
301
302   void write_track_start();
303   void write_track_continue();
304
305   void write_sector_start();
306   void write_sector_continue();
307
308   void interrupt_start();
309
310   void general_continue();
311   void command_end();
312
313   void spinup();
314   void index_callback(floppy_image_device *floppy, int state);
315   bool sector_matches() const;
316   bool is_ready();
317
318   void live_start(int live_state);
319   void live_abort();
320   void checkpoint();
321   void rollback();
322   void live_delay(int state);
323   void live_sync();
324   void live_run(attotime limit = attotime::never);
325   bool read_one_bit(attotime limit);
326   bool write_one_bit(attotime limit);
327
328   void live_write_raw(UINT16 raw);
329   void live_write_mfm(UINT8 mfm);
330
331   void drop_drq();
332   void set_drq();
333};
334
335class fd1771_t : public wd177x_t {
336public:
337   fd1771_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
338
339protected:
340   virtual bool has_ready() const { return true; }
341   virtual bool has_motor() const { return false; }
342   virtual bool has_head_load() const { return true; }
343   virtual bool has_side_check() const { return true; }
344};
345
346class fd1793_t : public wd177x_t {
347public:
348   fd1793_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
349
350protected:
351   virtual bool has_ready() const { return true; }
352   virtual bool has_motor() const { return false; }
353   virtual bool has_head_load() const { return true; }
354   virtual bool has_side_check() const { return true; }
355};
356
357class fd1797_t : public wd177x_t {
358public:
359   fd1797_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
360
361protected:
362   virtual bool has_ready() const { return true; }
363   virtual bool has_motor() const { return false; }
364   virtual bool has_head_load() const { return true; }
365   virtual bool has_side_select() const { return true; }
366   virtual bool has_sector_length_select() const { return true; }
367};
368
369class wd2793_t : public wd177x_t {
370public:
371   wd2793_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
372
373protected:
374   virtual bool has_ready() const { return true; }
375   virtual bool has_motor() const { return false; }
376   virtual bool has_head_load() const { return true; }
377   virtual bool has_side_check() const { return true; }
378};
379
380class wd2797_t : public wd177x_t {
381public:
382   wd2797_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
383
384protected:
385   virtual bool has_ready() const { return true; }
386   virtual bool has_motor() const { return false; }
387   virtual bool has_head_load() const { return true; }
388   virtual bool has_side_select() const { return true; }
389   virtual bool has_sector_length_select() const { return true; }
390};
391
392class wd1770_t : public wd177x_t {
393public:
394   wd1770_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
395
396protected:
397   virtual bool has_motor() const { return true; }
398   virtual bool has_precompensation() const { return true; }
399};
400
401class wd1772_t : public wd177x_t {
402public:
403   wd1772_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
404
405protected:
406   virtual bool has_motor() const { return true; }
407   virtual bool has_precompensation() const { return true; }
408   virtual int step_time(int mode) const;
409   virtual int settle_time() const;
410};
411
412class wd1773_t : public wd177x_t {
413public:
414   wd1773_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
415
416protected:
417   virtual bool has_motor() const { return false; }
418   virtual bool has_head_load() const { return true; }
419   virtual bool has_side_check() const { return true; }
420};
421
422extern const device_type FD1771x;
423extern const device_type FD1793x;
424extern const device_type FD1797x;
425extern const device_type WD2793x;
426extern const device_type WD2797x;
427extern const device_type WD1770x;
428extern const device_type WD1772x;
429extern const device_type WD1773x;
430
431#endif
trunk/src/emu/machine/upd765.c
r19165r19166
1#include "debugger.h"
2
3#include "upd765.h"
4
5const device_type UPD765A = &device_creator<upd765a_device>;
6const device_type UPD765B = &device_creator<upd765b_device>;
7const device_type I8272A = &device_creator<i8272a_device>;
8const device_type UPD72065 = &device_creator<upd72065_device>;
9const device_type SMC37C78 = &device_creator<smc37c78_device>;
10const device_type N82077AA = &device_creator<n82077aa_device>;
11const device_type PC_FDC_SUPERIO = &device_creator<pc_fdc_superio_device>;
12
13DEVICE_ADDRESS_MAP_START(map, 8, upd765a_device)
14   AM_RANGE(0x0, 0x0) AM_READ(msr_r)
15   AM_RANGE(0x1, 0x1) AM_READWRITE(fifo_r, fifo_w)
16ADDRESS_MAP_END
17
18DEVICE_ADDRESS_MAP_START(map, 8, upd765b_device)
19   AM_RANGE(0x0, 0x0) AM_READ(msr_r)
20   AM_RANGE(0x1, 0x1) AM_READWRITE(fifo_r, fifo_w)
21ADDRESS_MAP_END
22
23DEVICE_ADDRESS_MAP_START(map, 8, i8272a_device)
24   AM_RANGE(0x0, 0x0) AM_READ(msr_r)
25   AM_RANGE(0x1, 0x1) AM_READWRITE(fifo_r, fifo_w)
26ADDRESS_MAP_END
27
28DEVICE_ADDRESS_MAP_START(map, 8, upd72065_device)
29   AM_RANGE(0x0, 0x0) AM_READ(msr_r)
30   AM_RANGE(0x1, 0x1) AM_READWRITE(fifo_r, fifo_w)
31ADDRESS_MAP_END
32
33DEVICE_ADDRESS_MAP_START(map, 8, smc37c78_device)
34   AM_RANGE(0x2, 0x2) AM_READWRITE(dor_r, dor_w)
35   AM_RANGE(0x3, 0x3) AM_READWRITE(tdr_r, tdr_w)
36   AM_RANGE(0x4, 0x4) AM_READWRITE(msr_r, dsr_w)
37   AM_RANGE(0x5, 0x5) AM_READWRITE(fifo_r, fifo_w)
38   AM_RANGE(0x7, 0x7) AM_READWRITE(dir_r, ccr_w)
39ADDRESS_MAP_END
40
41DEVICE_ADDRESS_MAP_START(map, 8, n82077aa_device)
42   AM_RANGE(0x0, 0x0) AM_READ(sra_r)
43   AM_RANGE(0x1, 0x1) AM_READ(srb_r)
44   AM_RANGE(0x2, 0x2) AM_READWRITE(dor_r, dor_w)
45   AM_RANGE(0x3, 0x3) AM_READWRITE(tdr_r, tdr_w)
46   AM_RANGE(0x4, 0x4) AM_READWRITE(msr_r, dsr_w)
47   AM_RANGE(0x5, 0x5) AM_READWRITE(fifo_r, fifo_w)
48   AM_RANGE(0x7, 0x7) AM_READWRITE(dir_r, ccr_w)
49ADDRESS_MAP_END
50
51DEVICE_ADDRESS_MAP_START(map, 8, pc_fdc_superio_device)
52   AM_RANGE(0x0, 0x0) AM_READ(sra_r)
53   AM_RANGE(0x1, 0x1) AM_READ(srb_r)
54   AM_RANGE(0x2, 0x2) AM_READWRITE(dor_r, dor_w)
55   AM_RANGE(0x3, 0x3) AM_READWRITE(tdr_r, tdr_w)
56   AM_RANGE(0x4, 0x4) AM_READWRITE(msr_r, dsr_w)
57   AM_RANGE(0x5, 0x5) AM_READWRITE(fifo_r, fifo_w)
58   AM_RANGE(0x7, 0x7) AM_READWRITE(dir_r, ccr_w)
59ADDRESS_MAP_END
60
61
62int upd765_family_device::rates[4] = { 500000, 300000, 250000, 1000000 };
63
64upd765_family_device::upd765_family_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) : pc_fdc_interface(mconfig, type, name, tag, owner, clock)
65{
66   ready_polled = true;
67   ready_connected = true;
68   select_connected = true;
69   external_ready = true;
70   dor_reset = 0x00;
71}
72
73void upd765_family_device::set_ready_line_connected(bool _ready)
74{
75   ready_connected = _ready;
76}
77
78void upd765_family_device::set_select_lines_connected(bool _select)
79{
80   select_connected = _select;
81}
82
83void upd765_family_device::set_mode(int _mode)
84{
85   // TODO
86}
87
88void upd765_family_device::setup_intrq_cb(line_cb cb)
89{
90   intrq_cb = cb;
91}
92
93void upd765_family_device::setup_drq_cb(line_cb cb)
94{
95   drq_cb = cb;
96}
97
98void upd765_family_device::device_start()
99{
100   for(int i=0; i != 4; i++) {
101      char name[2];
102      flopi[i].tm = timer_alloc(i);
103      flopi[i].id = i;
104      if(select_connected) {
105         name[0] = '0'+i;
106         name[1] = 0;
107         floppy_connector *con = subdevice<floppy_connector>(name);
108         if(con) {
109            flopi[i].dev = con->get_device();
110            flopi[i].dev->setup_index_pulse_cb(floppy_image_device::index_pulse_cb(FUNC(upd765_family_device::index_callback), this));
111         } else
112            flopi[i].dev = NULL;
113      } else
114         flopi[i].dev = NULL;
115   }
116   cur_rate = 250000;
117   tc = false;
118
119   // reset at upper levels may cause a write to tc ending up with
120   // live_sync, which will crash if the live structure isn't
121   // initialized enough
122
123   cur_live.tm = attotime::never;
124   cur_live.state = IDLE;
125   cur_live.next_state = -1;
126   cur_live.fi = NULL;
127
128   if(ready_polled) {
129      poll_timer = timer_alloc(TIMER_DRIVE_READY_POLLING);
130      poll_timer->adjust(attotime::from_usec(1024), 0, attotime::from_usec(1024));
131   } else
132      poll_timer = NULL;
133
134   cur_irq = false;
135   locked = false;
136}
137
138void upd765_family_device::device_reset()
139{
140   dor = dor_reset;
141   locked = false;
142   soft_reset();
143}
144
145void upd765_family_device::soft_reset()
146{
147   main_phase = PHASE_CMD;
148   for(int i=0; i<4; i++) {
149      flopi[i].main_state = IDLE;
150      flopi[i].sub_state = IDLE;
151      flopi[i].live = false;
152      flopi[i].ready = !ready_polled;
153      flopi[i].irq = floppy_info::IRQ_NONE;
154   }
155   data_irq = false;
156   polled_irq = false;
157   internal_drq = false;
158   fifo_pos = 0;
159   command_pos = 0;
160   result_pos = 0;
161   if(!locked)
162      fifocfg = FIF_DIS;
163   cur_live.fi = 0;
164   drq = false;
165   cur_live.tm = attotime::never;
166   cur_live.state = IDLE;
167   cur_live.next_state = -1;
168   cur_live.fi = NULL;
169   tc_done = false;
170   st0 = st1 = st2 = st3 = 0x00;
171
172   check_irq();
173   if(ready_polled)
174      poll_timer->adjust(attotime::from_usec(1024), 0, attotime::from_usec(1024));
175}
176
177void upd765_family_device::tc_w(bool _tc)
178{
179   logerror("%s: tc=%d\n", tag(), _tc);
180   if(tc != _tc && _tc) {
181      live_sync();
182      tc_done = true;
183      tc = _tc;
184      if(cur_live.fi)
185         general_continue(*cur_live.fi);
186   } else
187      tc = _tc;
188}
189
190void upd765_family_device::ready_w(bool _ready)
191{
192   external_ready = _ready;
193}
194
195bool upd765_family_device::get_ready(int fid)
196{
197   if(ready_connected)
198      return flopi[fid].dev ? !flopi[fid].dev->ready_r() : false;
199   return external_ready;
200}
201
202void upd765_family_device::set_floppy(floppy_image_device *flop)
203{
204   for(int fid=0; fid<4; fid++) {
205      if(flopi[fid].dev)
206         flopi[fid].dev->setup_index_pulse_cb(floppy_image_device::index_pulse_cb());
207      flopi[fid].dev = flop;
208   }
209   if(flop)
210      flop->setup_index_pulse_cb(floppy_image_device::index_pulse_cb(FUNC(upd765_family_device::index_callback), this));
211}
212
213READ8_MEMBER(upd765_family_device::sra_r)
214{
215   UINT8 sra = 0;
216   int fid = dor & 3;
217   floppy_info &fi = flopi[fid];
218   if(fi.dir)
219      sra |= 0x01;
220   if(fi.index)
221      sra |= 0x04;
222   if(cur_rate >= 500000)
223      sra |= 0x08;
224   if(fi.dev && fi.dev->trk00_r())
225      sra |= 0x10;
226   if(fi.main_state == SEEK_WAIT_STEP_SIGNAL_TIME)
227      sra |= 0x20;
228   sra |= 0x40;
229   if(cur_irq)
230      sra |= 0x80;
231   if(mode == MODE_M30)
232      sra ^= 0x1f;
233   return sra;
234}
235
236READ8_MEMBER(upd765_family_device::srb_r)
237{
238   return 0;
239}
240
241READ8_MEMBER(upd765_family_device::dor_r)
242{
243   return dor;
244}
245
246WRITE8_MEMBER(upd765_family_device::dor_w)
247{
248   logerror("%s: dor = %02x\n", tag(), data);
249   UINT8 diff = dor ^ data;
250   dor = data;
251   if(diff & 4)
252      soft_reset();
253
254   for(int i=0; i<4; i++) {
255      floppy_info &fi = flopi[i];
256      if(fi.dev)
257         fi.dev->mon_w(!(dor & (0x10 << i)));
258   }
259   check_irq();
260}
261
262READ8_MEMBER(upd765_family_device::tdr_r)
263{
264   return 0;
265}
266
267WRITE8_MEMBER(upd765_family_device::tdr_w)
268{
269}
270
271READ8_MEMBER(upd765_family_device::msr_r)
272{
273   UINT32 msr = 0;
274   switch(main_phase) {
275   case PHASE_CMD:
276      msr |= MSR_RQM;
277      if(command_pos)
278         msr |= MSR_CB;
279      break;
280   case PHASE_EXEC:
281      msr |= MSR_CB;
282      if(spec & SPEC_ND)
283         msr |= MSR_EXM;
284      if(internal_drq) {
285         msr |= MSR_RQM;
286         if(!fifo_write)
287            msr |= MSR_DIO;
288      }
289      break;
290
291   case PHASE_RESULT:
292      msr |= MSR_RQM|MSR_DIO|MSR_CB;
293      break;
294   }
295   for(int i=0; i<4; i++)
296      if(flopi[i].main_state == RECALIBRATE || flopi[i].main_state == SEEK) {
297         msr |= 1<<i;
298         msr |= MSR_CB;
299      }
300
301   if(data_irq) {
302      data_irq = false;
303      check_irq();
304   }
305
306   return msr;
307}
308
309WRITE8_MEMBER(upd765_family_device::dsr_w)
310{
311   logerror("%s: dsr_w %02x\n", tag(), data);
312   if(data & 0x80)
313      soft_reset();
314   dsr = data & 0x7f;
315   cur_rate = rates[dsr & 3];
316}
317
318void upd765_family_device::set_rate(int rate)
319{
320   cur_rate = rate;
321}
322
323READ8_MEMBER(upd765_family_device::fifo_r)
324{
325   UINT8 r = 0;
326   switch(main_phase) {
327   case PHASE_EXEC:
328      if(internal_drq)
329         return fifo_pop(false);
330      logerror("%s: fifo_r in phase %d\n", tag(), main_phase);
331      break;
332
333   case PHASE_RESULT:
334      r = result[0];
335      result_pos--;
336      memmove(result, result+1, result_pos);
337      if(!result_pos)
338         main_phase = PHASE_CMD;
339      break;
340   default:
341      logerror("%s: fifo_r in phase %d\n", tag(), main_phase);
342      break;
343   }
344
345   return r;
346}
347
348WRITE8_MEMBER(upd765_family_device::fifo_w)
349{
350   switch(main_phase) {
351   case PHASE_CMD: {
352      command[command_pos++] = data;
353      int cmd = check_command();
354      if(cmd == C_INCOMPLETE)
355         break;
356      if(cmd == C_INVALID) {
357         logerror("%s: Invalid on %02x\n", tag(), command[0]);
358         main_phase = PHASE_RESULT;
359         result[0] = 0x80;
360         result_pos = 1;
361         return;
362      }
363      start_command(cmd);
364      break;
365   }
366   case PHASE_EXEC:
367      if(internal_drq) {
368         fifo_push(data, false);
369         return;
370      }
371      logerror("%s: fifo_w in phase %d\n", tag(), main_phase);
372      break;
373
374   default:
375      logerror("%s: fifo_w in phase %d\n", tag(), main_phase);
376      break;
377   }
378}
379
380UINT8 upd765_family_device::do_dir_r()
381{
382   floppy_info &fi = flopi[dor & 3];
383   if(fi.dev)
384      return fi.dev->dskchg_r() ? 0x00 : 0x80;
385   return 0x00;
386}
387
388READ8_MEMBER(upd765_family_device::dir_r)
389{
390   return do_dir_r();
391}
392
393WRITE8_MEMBER(upd765_family_device::ccr_w)
394{
395   dsr = (dsr & 0xfc) | (data & 3);
396   cur_rate = rates[data & 3];
397}
398
399void upd765_family_device::set_drq(bool state)
400{
401   if(state != drq) {
402      drq = state;
403      if(!drq_cb.isnull())
404         drq_cb(drq);
405   }
406}
407
408bool upd765_family_device::get_drq() const
409{
410   return drq;
411}
412
413void upd765_family_device::enable_transfer()
414{
415   if(spec & SPEC_ND) {
416      // PIO
417      if(!internal_drq) {
418         internal_drq = true;
419         check_irq();
420      }
421
422   } else {
423      // DMA
424      if(!drq)
425         set_drq(true);
426   }
427}
428
429void upd765_family_device::disable_transfer()
430{
431   if(spec & SPEC_ND) {
432      internal_drq = false;
433      check_irq();
434   } else
435      set_drq(false);
436}
437
438void upd765_family_device::fifo_push(UINT8 data, bool internal)
439{
440   if(fifo_pos == 16) {
441      if(internal) {
442         if(!(st1 & ST1_OR))
443            logerror("%s: Fifo overrun\n", tag());
444         st1 |= ST1_OR;
445      }
446      return;
447   }
448   fifo[fifo_pos++] = data;
449   fifo_expected--;
450
451   int thr = (fifocfg & FIF_THR)+1;
452   if(!fifo_write && (!fifo_expected || fifo_pos >= thr || (fifocfg & FIF_DIS)))
453      enable_transfer();
454   if(fifo_write && (fifo_pos == 16 || !fifo_expected))
455      disable_transfer();
456}
457
458
459UINT8 upd765_family_device::fifo_pop(bool internal)
460{
461   if(!fifo_pos) {
462      if(internal) {
463         if(!(st1 & ST1_OR))
464            logerror("%s: Fifo underrun\n", tag());
465         st1 |= ST1_OR;
466      }
467      return 0;
468   }
469   UINT8 r = fifo[0];
470   fifo_pos--;
471   memmove(fifo, fifo+1, fifo_pos);
472   if(!fifo_write && !fifo_pos)
473      disable_transfer();
474   int thr = fifocfg & 15;
475   if(fifo_write && fifo_expected && (fifo_pos <= thr || (fifocfg & 0x20)))
476      enable_transfer();
477   return r;
478}
479
480void upd765_family_device::fifo_expect(int size, bool write)
481{
482   fifo_expected = size;
483   fifo_write = write;
484   if(fifo_write)
485      enable_transfer();
486}
487
488READ8_MEMBER(upd765_family_device::mdma_r)
489{
490   return dma_r();
491}
492
493WRITE8_MEMBER(upd765_family_device::mdma_w)
494{
495   dma_w(data);
496}
497
498UINT8 upd765_family_device::dma_r()
499{
500   return fifo_pop(false);
501}
502
503void upd765_family_device::dma_w(UINT8 data)
504{
505   fifo_push(data, false);
506}
507
508void upd765_family_device::live_start(floppy_info &fi, int state)
509{
510   cur_live.tm = machine().time();
511   cur_live.state = state;
512   cur_live.next_state = -1;
513   cur_live.fi = &fi;
514   cur_live.shift_reg = 0;
515   cur_live.crc = 0xffff;
516   cur_live.bit_counter = 0;
517   cur_live.data_separator_phase = false;
518   cur_live.data_reg = 0;
519   cur_live.previous_type = live_info::PT_NONE;
520   cur_live.data_bit_context = false;
521   cur_live.byte_counter = 0;
522   cur_live.pll.reset(cur_live.tm);
523   cur_live.pll.set_clock(attotime::from_hz(mfm ? 2*cur_rate : cur_rate));
524   checkpoint_live = cur_live;
525   fi.live = true;
526
527   live_run();
528}
529
530void upd765_family_device::checkpoint()
531{
532   if(cur_live.fi)
533      cur_live.pll.commit(cur_live.fi->dev, cur_live.tm);
534   checkpoint_live = cur_live;
535}
536
537void upd765_family_device::rollback()
538{
539   cur_live = checkpoint_live;
540}
541
542void upd765_family_device::live_delay(int state)
543{
544   cur_live.next_state = state;
545   if(cur_live.tm != machine().time())
546      cur_live.fi->tm->adjust(cur_live.tm - machine().time());
547   else
548      live_sync();
549}
550
551void upd765_family_device::live_sync()
552{
553   if(!cur_live.tm.is_never()) {
554      if(cur_live.tm > machine().time()) {
555         rollback();
556         live_run(machine().time());
557         cur_live.pll.commit(cur_live.fi->dev, cur_live.tm);
558      } else {
559         cur_live.pll.commit(cur_live.fi->dev, cur_live.tm);
560         if(cur_live.next_state != -1) {
561            cur_live.state = cur_live.next_state;
562            cur_live.next_state = -1;
563         }
564         if(cur_live.state == IDLE) {
565            cur_live.pll.stop_writing(cur_live.fi->dev, cur_live.tm);
566            cur_live.tm = attotime::never;
567            cur_live.fi->live = false;
568            cur_live.fi = 0;
569         }
570      }
571      cur_live.next_state = -1;
572      checkpoint();
573   }
574}
575
576void upd765_family_device::live_abort()
577{
578   if(!cur_live.tm.is_never() && cur_live.tm > machine().time()) {
579      rollback();
580      live_run(machine().time());
581   }
582
583   if(cur_live.fi) {
584      cur_live.pll.stop_writing(cur_live.fi->dev, cur_live.tm);
585      cur_live.fi->live = false;
586      cur_live.fi = 0;
587   }
588
589   cur_live.tm = attotime::never;
590   cur_live.state = IDLE;
591   cur_live.next_state = -1;
592}
593
594void upd765_family_device::live_run(attotime limit)
595{
596   if(cur_live.state == IDLE || cur_live.next_state != -1)
597      return;
598
599   if(limit == attotime::never) {
600      if(cur_live.fi->dev)
601         limit = cur_live.fi->dev->time_next_index();
602      if(limit == attotime::never) {
603         // Happens when there's no disk or if the fdc is not
604         // connected to a drive, hence no index pulse. Force a
605         // sync from time to time in that case, so that the main
606         // cpu timeout isn't too painful.  Avoids looping into
607         // infinity looking for data too.
608
609         limit = machine().time() + attotime::from_msec(1);
610         cur_live.fi->tm->adjust(attotime::from_msec(1));
611      }
612   }
613
614   for(;;) {
615
616      switch(cur_live.state) {
617      case SEARCH_ADDRESS_MARK_HEADER:
618         if(read_one_bit(limit))
619            return;
620#if 0
621         fprintf(stderr, "%s: shift = %04x data=%02x c=%d\n", tts(cur_live.tm).cstr(), cur_live.shift_reg,
622               (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) |
623               (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) |
624               (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) |
625               (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) |
626               (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) |
627               (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) |
628               (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) |
629               (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00),
630               cur_live.bit_counter);
631#endif
632
633         if(mfm && cur_live.shift_reg == 0x4489) {
634            cur_live.crc = 0x443b;
635            cur_live.data_separator_phase = false;
636            cur_live.bit_counter = 0;
637            cur_live.state = READ_HEADER_BLOCK_HEADER;
638         }
639
640         if(!mfm && cur_live.shift_reg == 0xf57e) {
641            cur_live.crc = 0xef21;
642            cur_live.data_separator_phase = false;
643            cur_live.bit_counter = 0;
644            cur_live.state = READ_ID_BLOCK;
645         }
646         break;
647
648      case READ_HEADER_BLOCK_HEADER: {
649         if(read_one_bit(limit))
650            return;
651#if 0
652         fprintf(stderr, "%s: shift = %04x data=%02x counter=%d\n", tts(cur_live.tm).cstr(), cur_live.shift_reg,
653               (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) |
654               (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) |
655               (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) |
656               (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) |
657               (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) |
658               (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) |
659               (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) |
660               (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00),
661               cur_live.bit_counter);
662#endif
663         if(cur_live.bit_counter & 15)
664            break;
665
666         int slot = cur_live.bit_counter >> 4;
667
668         if(slot < 3) {
669            if(cur_live.shift_reg != 0x4489)
670               cur_live.state = SEARCH_ADDRESS_MARK_HEADER;
671            break;
672         }
673         if(cur_live.data_reg != 0xfe) {
674            cur_live.state = SEARCH_ADDRESS_MARK_HEADER;
675            break;
676         }
677
678         cur_live.bit_counter = 0;
679         cur_live.state = READ_ID_BLOCK;
680
681         break;
682      }
683
684      case READ_ID_BLOCK: {
685         if(read_one_bit(limit))
686            return;
687         if(cur_live.bit_counter & 15)
688            break;
689         int slot = (cur_live.bit_counter >> 4)-1;
690
691         if(0)
692            fprintf(stderr, "%s: slot=%d data=%02x crc=%04x\n", tts(cur_live.tm).cstr(), slot, cur_live.data_reg, cur_live.crc);
693         cur_live.idbuf[slot] = cur_live.data_reg;
694         if(slot == 5) {
695            live_delay(IDLE);
696            return;
697         }
698         break;
699      }
700
701      case SEARCH_ADDRESS_MARK_DATA:
702         if(read_one_bit(limit))
703            return;
704#if 0
705         fprintf(stderr, "%s: shift = %04x data=%02x c=%d.%x\n", tts(cur_live.tm).cstr(), cur_live.shift_reg,
706               (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) |
707               (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) |
708               (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) |
709               (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) |
710               (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) |
711               (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) |
712               (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) |
713               (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00),
714               cur_live.bit_counter >> 4, cur_live.bit_counter & 15);
715#endif
716
717         if(mfm) {
718            // Large tolerance due to perpendicular recording at extended density
719            if(cur_live.bit_counter > 62*16) {
720               live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED);
721               return;
722            }
723
724            if(cur_live.bit_counter >= 28*16 && cur_live.shift_reg == 0x4489) {
725               cur_live.crc = 0x443b;
726               cur_live.data_separator_phase = false;
727               cur_live.bit_counter = 0;
728               cur_live.state = READ_DATA_BLOCK_HEADER;
729            }
730
731         } else {
732            if(cur_live.bit_counter > 23*16) {
733               live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED);
734               return;
735            }
736
737            if(cur_live.bit_counter >= 11*16 && (cur_live.shift_reg == 0xf56a || cur_live.shift_reg == 0xf56f)) {
738               cur_live.crc = cur_live.shift_reg == 0xf56a ? 0x8fe7 : 0xbf84;
739               cur_live.data_separator_phase = false;
740               cur_live.bit_counter = 0;
741               cur_live.state = READ_SECTOR_DATA;
742            }
743         }
744
745         break;
746
747      case READ_DATA_BLOCK_HEADER: {
748         if(read_one_bit(limit))
749            return;
750#if 0
751         fprintf(stderr, "%s: shift = %04x data=%02x counter=%d\n", tts(cur_live.tm).cstr(), cur_live.shift_reg,
752               (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) |
753               (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) |
754               (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) |
755               (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) |
756               (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) |
757               (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) |
758               (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) |
759               (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00),
760               cur_live.bit_counter);
761#endif
762         if(cur_live.bit_counter & 15)
763            break;
764
765         int slot = cur_live.bit_counter >> 4;
766
767         if(slot < 3) {
768            if(cur_live.shift_reg != 0x4489) {
769               live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED);
770               return;
771            }
772            break;
773         }
774         if(cur_live.data_reg != 0xfb && cur_live.data_reg != 0xf8) {
775            live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED);
776            return;
777         }
778
779         cur_live.bit_counter = 0;
780         cur_live.state = READ_SECTOR_DATA;
781         break;
782      }
783
784      case SEARCH_ADDRESS_MARK_DATA_FAILED:
785         st1 |= ST1_MA;
786         st2 |= ST2_MD;
787         cur_live.state = IDLE;
788         return;
789
790      case READ_SECTOR_DATA: {
791         if(read_one_bit(limit))
792            return;
793         if(cur_live.bit_counter & 15)
794            break;
795         int slot = (cur_live.bit_counter >> 4)-1;
796         if(slot < sector_size) {
797            // Sector data
798            live_delay(READ_SECTOR_DATA_BYTE);
799            return;
800
801         } else if(slot < sector_size+2) {
802            // CRC
803            if(slot == sector_size+1) {
804               live_delay(IDLE);
805               return;
806            }
807         }
808         break;
809      }
810
811      case READ_SECTOR_DATA_BYTE:
812         if(!tc_done)
813            fifo_push(cur_live.data_reg, true);
814         cur_live.state = READ_SECTOR_DATA;
815         checkpoint();
816         break;
817
818      case WRITE_SECTOR_SKIP_GAP2:
819         cur_live.bit_counter = 0;
820         cur_live.byte_counter = 0;
821         cur_live.state = WRITE_SECTOR_SKIP_GAP2_BYTE;
822         checkpoint();
823         break;
824
825      case WRITE_SECTOR_SKIP_GAP2_BYTE:
826         if(read_one_bit(limit))
827            return;
828         if(mfm && cur_live.bit_counter != 22*16)
829            break;
830         if(!mfm && cur_live.bit_counter != 11*16)
831            break;
832         cur_live.bit_counter = 0;
833         cur_live.byte_counter = 0;
834         live_delay(WRITE_SECTOR_DATA);
835         return;
836
837      case WRITE_SECTOR_DATA:
838         if(mfm) {
839            if(cur_live.byte_counter < 12)
840               live_write_mfm(0x00);
841            else if(cur_live.byte_counter < 15)
842               live_write_raw(0x4489);
843            else if(cur_live.byte_counter < 16) {
844               cur_live.crc = 0xcdb4;
845               live_write_mfm(command[0] & 0x08 ? 0xf8 : 0xfb);
846            } else if(cur_live.byte_counter < 16+sector_size)
847               live_write_mfm(tc_done && !fifo_pos? 0x00 : fifo_pop(true));
848            else if(cur_live.byte_counter < 16+sector_size+2)
849               live_write_mfm(cur_live.crc >> 8);
850            else if(cur_live.byte_counter < 16+sector_size+2+command[7])
851               live_write_mfm(0x4e);
852            else {
853               cur_live.pll.stop_writing(cur_live.fi->dev, cur_live.tm);
854               cur_live.state = IDLE;
855               return;
856            }
857
858         } else {
859            if(cur_live.byte_counter < 6)
860               live_write_fm(0x00);
861            else if(cur_live.byte_counter < 7) {
862               cur_live.crc = 0xffff;
863               live_write_raw(command[0] & 0x08 ? 0xf56a : 0xf56f);
864            } else if(cur_live.byte_counter < 7+sector_size)
865               live_write_fm(tc_done && !fifo_pos? 0x00 : fifo_pop(true));
866            else if(cur_live.byte_counter < 7+sector_size+2)
867               live_write_fm(cur_live.crc >> 8);
868            else if(cur_live.byte_counter < 7+sector_size+2+command[7])
869               live_write_fm(0xff);
870            else {
871               cur_live.pll.stop_writing(cur_live.fi->dev, cur_live.tm);
872               cur_live.state = IDLE;
873               return;
874            }
875         }
876         cur_live.state = WRITE_SECTOR_DATA_BYTE;
877         cur_live.bit_counter = 16;
878         checkpoint();
879         break;
880
881      case WRITE_TRACK_PRE_SECTORS:
882         if(!cur_live.byte_counter && command[3])
883            fifo_expect(4, true);
884         if(mfm) {
885            if(cur_live.byte_counter < 80)
886               live_write_mfm(0x4e);
887            else if(cur_live.byte_counter < 92)
888               live_write_mfm(0x00);
889            else if(cur_live.byte_counter < 95)
890               live_write_raw(0x5224);
891            else if(cur_live.byte_counter < 96)
892               live_write_mfm(0xfc);
893            else if(cur_live.byte_counter < 146)
894               live_write_mfm(0x4e);
895            else {
896               cur_live.state = WRITE_TRACK_SECTOR;
897               cur_live.byte_counter = 0;
898               break;
899            }
900         } else {
901            if(cur_live.byte_counter < 40)
902               live_write_fm(0xff);
903            else if(cur_live.byte_counter < 46)
904               live_write_fm(0x00);
905            else if(cur_live.byte_counter < 47)
906               live_write_raw(0xf77a);
907            else if(cur_live.byte_counter < 73)
908               live_write_fm(0xff);
909            else {
910               cur_live.state = WRITE_TRACK_SECTOR;
911               cur_live.byte_counter = 0;
912               break;
913            }
914         }
915         cur_live.state = WRITE_TRACK_PRE_SECTORS_BYTE;
916         cur_live.bit_counter = 16;
917         checkpoint();
918         break;
919
920      case WRITE_TRACK_SECTOR:
921         if(!cur_live.byte_counter) {
922            command[3]--;
923            if(command[3])
924               fifo_expect(4, true);
925         }
926         if(mfm) {
927            if(cur_live.byte_counter < 12)
928               live_write_mfm(0x00);
929            else if(cur_live.byte_counter < 15)
930               live_write_raw(0x4489);
931            else if(cur_live.byte_counter < 16) {
932               cur_live.crc = 0xcdb4;
933               live_write_mfm(0xfe);
934            } else if(cur_live.byte_counter < 20)
935               live_write_mfm(fifo_pop(true));
936            else if(cur_live.byte_counter < 22)
937               live_write_mfm(cur_live.crc >> 8);
938            else if(cur_live.byte_counter < 44)
939               live_write_mfm(0x4e);
940            else if(cur_live.byte_counter < 56)
941               live_write_mfm(0x00);
942            else if(cur_live.byte_counter < 59)
943               live_write_raw(0x4489);
944            else if(cur_live.byte_counter < 60) {
945               cur_live.crc = 0xcdb4;
946               live_write_mfm(0xfb);
947            } else if(cur_live.byte_counter < 60+sector_size)
948               live_write_mfm(command[5]);
949            else if(cur_live.byte_counter < 62+sector_size)
950               live_write_mfm(cur_live.crc >> 8);
951            else if(cur_live.byte_counter < 62+sector_size+command[4])
952               live_write_mfm(0x4e);
953            else {
954               cur_live.byte_counter = 0;
955               cur_live.state = command[3] ? WRITE_TRACK_SECTOR : WRITE_TRACK_POST_SECTORS;
956               break;
957            }
958
959         } else {
960            if(cur_live.byte_counter < 6)
961               live_write_fm(0x00);
962            else if(cur_live.byte_counter < 7) {
963               cur_live.crc = 0xffff;
964               live_write_raw(0xf57e);
965            } else if(cur_live.byte_counter < 11)
966               live_write_fm(fifo_pop(true));
967            else if(cur_live.byte_counter < 13)
968               live_write_fm(cur_live.crc >> 8);
969            else if(cur_live.byte_counter < 24)
970               live_write_fm(0xff);
971            else if(cur_live.byte_counter < 30)
972               live_write_fm(0x00);
973            else if(cur_live.byte_counter < 31) {
974               cur_live.crc = 0xffff;
975               live_write_raw(0xf56f);
976            } else if(cur_live.byte_counter < 31+sector_size)
977               live_write_fm(command[5]);
978            else if(cur_live.byte_counter < 33+sector_size)
979               live_write_fm(cur_live.crc >> 8);
980            else if(cur_live.byte_counter < 33+sector_size+command[4])
981               live_write_fm(0xff);
982            else {
983               cur_live.byte_counter = 0;
984               cur_live.state = command[3] ? WRITE_TRACK_SECTOR : WRITE_TRACK_POST_SECTORS;
985               break;
986            }
987         }
988         cur_live.state = WRITE_TRACK_SECTOR_BYTE;
989         cur_live.bit_counter = 16;
990         checkpoint();
991         break;
992
993      case WRITE_TRACK_POST_SECTORS:
994         if(mfm)
995            live_write_mfm(0x4e);
996         else
997            live_write_fm(0xff);
998         cur_live.state = WRITE_TRACK_POST_SECTORS_BYTE;
999         cur_live.bit_counter = 16;
1000         checkpoint();
1001         break;
1002
1003      case WRITE_TRACK_PRE_SECTORS_BYTE:
1004      case WRITE_TRACK_SECTOR_BYTE:
1005      case WRITE_TRACK_POST_SECTORS_BYTE:
1006      case WRITE_SECTOR_DATA_BYTE:
1007         if(write_one_bit(limit))
1008            return;
1009         if(cur_live.bit_counter == 0) {
1010            cur_live.byte_counter++;
1011            live_delay(cur_live.state-1);
1012            return;
1013         }
1014         break;
1015
1016      default:
1017         logerror("%s: Unknown live state %d\n", tts(cur_live.tm).cstr(), cur_live.state);
1018         return;
1019      }
1020   }
1021}
1022
1023int upd765_family_device::check_command()
1024{
1025   // 0.000010 read track
1026   // 00000011 specify
1027   // 00000100 sense drive status
1028   // ..000101 write data
1029   // ...00110 read data
1030   // 00000111 recalibrate
1031   // 00001000 sense interrupt status
1032   // ..001001 write deleted data
1033   // 0.001010 read id
1034   // ...01100 read deleted data
1035   // 0.001101 format track
1036   // 00001110 dumpreg
1037   // 00101110 save
1038   // 01001110 restore
1039   // 10001110 drive specification command
1040   // 00001111 seek
1041   // 1.001111 relative seek
1042   // 00010000 version
1043   // ...10001 scan equal
1044   // 00010010 perpendicular mode
1045   // 00010011 configure
1046   // 00110011 option
1047   // .0010100 lock
1048   // ...10110 verify
1049   // 00010111 powerdown mode
1050   // 00011000 part id
1051   // ...11001 scan low or equal
1052   // ...11101 scan high or equal
1053
1054   // MSDOS 6.22 format uses 0xcd to format a track, which makes one
1055   // think only the bottom 5 bits are decoded.
1056
1057   switch(command[0] & 0x1f) {
1058   case 0x02:
1059      return command_pos == 9 ? C_READ_TRACK         : C_INCOMPLETE;
1060
1061   case 0x03:
1062      return command_pos == 3 ? C_SPECIFY            : C_INCOMPLETE;
1063
1064   case 0x04:
1065      return command_pos == 2 ? C_SENSE_DRIVE_STATUS : C_INCOMPLETE;
1066
1067   case 0x05:
1068   case 0x09:
1069      return command_pos == 9 ? C_WRITE_DATA         : C_INCOMPLETE;
1070
1071   case 0x06:
1072   case 0x0c:
1073      return command_pos == 9 ? C_READ_DATA          : C_INCOMPLETE;
1074
1075   case 0x07:
1076      return command_pos == 2 ? C_RECALIBRATE        : C_INCOMPLETE;
1077
1078   case 0x08:
1079      return C_SENSE_INTERRUPT_STATUS;
1080
1081   case 0x0a:
1082      return command_pos == 2 ? C_READ_ID            : C_INCOMPLETE;
1083
1084   case 0x0d:
1085      return command_pos == 6 ? C_FORMAT_TRACK       : C_INCOMPLETE;
1086
1087   case 0x0e:
1088      return C_DUMP_REG;
1089
1090   case 0x0f:
1091      return command_pos == 3 ? C_SEEK               : C_INCOMPLETE;
1092
1093   case 0x12:
1094      return command_pos == 2 ? C_PERPENDICULAR      : C_INCOMPLETE;
1095
1096   case 0x13:
1097      return command_pos == 4 ? C_CONFIGURE          : C_INCOMPLETE;
1098
1099   case 0x14:
1100      return C_LOCK;
1101
1102   default:
1103      return C_INVALID;
1104   }
1105}
1106
1107void upd765_family_device::start_command(int cmd)
1108{
1109   command_pos = 0;
1110   result_pos = 0;
1111   main_phase = PHASE_EXEC;
1112   tc_done = false;
1113   switch(cmd) {
1114   case C_CONFIGURE:
1115      logerror("%s: command configure %02x %02x %02x\n",
1116             tag(),
1117             command[1], command[2], command[3]);
1118      // byte 1 is ignored, byte 3 is precompensation-related
1119      fifocfg = command[2];
1120      precomp = command[3];
1121      main_phase = PHASE_CMD;
1122      break;
1123
1124   case C_DUMP_REG:
1125      logerror("%s: command dump regs\n", tag());
1126      main_phase = PHASE_RESULT;
1127      result[0] = flopi[0].pcn;
1128      result[1] = flopi[1].pcn;
1129      result[2] = flopi[2].pcn;
1130      result[3] = flopi[3].pcn;
1131      result[4] = (spec & 0xff00) >> 8;
1132      result[5] = (spec & 0x00ff);
1133      result[6] = sector_size;
1134      result[7] = locked ? 0x80 : 0x00;
1135      result[7] |= (perpmode & 0x30);
1136      result[8] = fifocfg;
1137      result[9] = precomp;
1138      result_pos = 10;
1139      break;
1140
1141   case C_FORMAT_TRACK:
1142      format_track_start(flopi[command[1] & 3]);
1143      break;
1144
1145   case C_LOCK:
1146      locked = command[0] & 0x80;
1147      main_phase = PHASE_RESULT;
1148      result[0] = locked ? 0x10 : 0x00;
1149      result_pos = 1;
1150      logerror("%s: command lock (%s)\n", tag(), locked ? "on" : "off");
1151      break;
1152
1153   case C_PERPENDICULAR:
1154      logerror("%s: command perpendicular\n", tag());
1155      perpmode = command[1];
1156      main_phase = PHASE_CMD;
1157      break;
1158
1159   case C_READ_DATA:
1160      read_data_start(flopi[command[1] & 3]);
1161      break;
1162
1163   case C_READ_ID:
1164      read_id_start(flopi[command[1] & 3]);
1165      break;
1166
1167   case C_READ_TRACK:
1168      read_track_start(flopi[command[1] & 3]);
1169      break;
1170
1171   case C_RECALIBRATE:
1172      recalibrate_start(flopi[command[1] & 3]);
1173      main_phase = PHASE_CMD;
1174      break;
1175
1176   case C_SEEK:
1177      seek_start(flopi[command[1] & 3]);
1178      main_phase = PHASE_CMD;
1179      break;
1180
1181   case C_SENSE_DRIVE_STATUS: {
1182      floppy_info &fi = flopi[command[1] & 3];
1183      main_phase = PHASE_RESULT;
1184      result[0] = 0x08;
1185      if(fi.ready)
1186         result[0] |= 0x20;
1187      if(fi.dev)
1188         result[0] |=
1189            (fi.dev->wpt_r() ? 0x40 : 0x00) |
1190            (fi.dev->trk00_r() ? 0x00 : 0x10) |
1191            (fi.dev->ss_r() ? 0x04 : 0x00) |
1192            (command[1] & 3);
1193      logerror("%s: command sense drive status (%02x)\n", tag(), result[0]);
1194      result_pos = 1;
1195      break;
1196   }
1197
1198   case C_SENSE_INTERRUPT_STATUS: {
1199      main_phase = PHASE_RESULT;
1200
1201      int fid;
1202      for(fid=0; fid<4 && flopi[fid].irq == floppy_info::IRQ_NONE; fid++);
1203      if(fid == 4) {
1204         st0 = ST0_UNK;
1205         result[0] = st0;
1206         result_pos = 1;
1207         logerror("%s: command sense interrupt status (%02x)\n", tag(), result[0]);
1208         break;
1209      }
1210      floppy_info &fi = flopi[fid];
1211      if(fi.irq == floppy_info::IRQ_POLLED) {
1212         // Documentation is somewhat contradictory w.r.t polling
1213         // and irq.  PC bios, especially 5150, requires that only
1214         // one irq happens.  That's also wait the ns82077a doc
1215         // says it does.  OTOH, a number of docs says you need to
1216         // call SIS 4 times, once per drive...
1217         //
1218         // There's also the interaction with the seek irq.  The
1219         // somewhat borderline tf20 code seems to think that
1220         // essentially ignoring the polling irq should work.
1221         //
1222         // So at that point the best bet seems to drop the
1223         // "polled" irq as soon as a SIS happens, and override any
1224         // polled-in-waiting information when a seek irq happens
1225         // for a given floppy.
1226
1227         st0 = ST0_ABRT | fid;
1228      }
1229      fi.irq = floppy_info::IRQ_NONE;
1230
1231      polled_irq = false;
1232
1233      result[0] = st0;
1234      result[1] = fi.pcn;
1235      logerror("%s: command sense interrupt status (fid=%d %02x %02x)\n", tag(), fid, result[0], result[1]);
1236      result_pos = 2;
1237
1238      check_irq();
1239      break;
1240   }
1241
1242   case C_SPECIFY:
1243      logerror("%s: command specify %02x %02x\n",
1244             tag(),
1245             command[1], command[2]);
1246      spec = (command[1] << 8) | command[2];
1247      main_phase = PHASE_CMD;
1248      break;
1249
1250   case C_WRITE_DATA:
1251      write_data_start(flopi[command[1] & 3]);
1252      break;
1253
1254   default:
1255      fprintf(stderr, "start command %d\n", cmd);
1256      exit(1);
1257   }
1258}
1259
1260void upd765_family_device::command_end(floppy_info &fi, bool data_completion)
1261{
1262   logerror("%s: command done (%s) -", tag(), data_completion ? "data" : "seek");
1263   for(int i=0; i != result_pos; i++)
1264      logerror(" %02x", result[i]);
1265   logerror("\n");
1266   fi.main_state = fi.sub_state = IDLE;
1267   if(data_completion)
1268      data_irq = true;
1269   else
1270      fi.irq = floppy_info::IRQ_SEEK;
1271   check_irq();
1272}
1273
1274void upd765_family_device::recalibrate_start(floppy_info &fi)
1275{
1276   logerror("%s: command recalibrate\n", tag());
1277   fi.main_state = RECALIBRATE;
1278   fi.sub_state = SEEK_WAIT_STEP_TIME_DONE;
1279   fi.dir = 1;
1280   fi.counter = 77;
1281   seek_continue(fi);
1282}
1283
1284void upd765_family_device::seek_start(floppy_info &fi)
1285{
1286   logerror("%s: command %sseek %d\n", tag(), command[0] & 0x80 ? "relative " : "", command[2]);
1287   fi.main_state = SEEK;
1288   fi.sub_state = SEEK_WAIT_STEP_TIME_DONE;
1289   fi.dir = fi.pcn > command[2] ? 1 : 0;
1290   seek_continue(fi);
1291}
1292
1293void upd765_family_device::delay_cycles(emu_timer *tm, int cycles)
1294{
1295   tm->adjust(attotime::from_double(double(cycles)/cur_rate));
1296}
1297
1298void upd765_family_device::seek_continue(floppy_info &fi)
1299{
1300   for(;;) {
1301      switch(fi.sub_state) {
1302      case SEEK_MOVE:
1303         if(fi.dev) {
1304            fi.dev->dir_w(fi.dir);
1305            fi.dev->stp_w(0);
1306         }
1307         fi.sub_state = SEEK_WAIT_STEP_SIGNAL_TIME;
1308         fi.tm->adjust(attotime::from_nsec(2500));
1309         return;
1310
1311      case SEEK_WAIT_STEP_SIGNAL_TIME:
1312         return;
1313
1314      case SEEK_WAIT_STEP_SIGNAL_TIME_DONE:
1315         if(fi.dev)
1316            fi.dev->stp_w(1);
1317
1318         if(fi.main_state == SEEK) {
1319            if(fi.pcn > command[2])
1320               fi.pcn--;
1321            else
1322               fi.pcn++;
1323         }
1324         fi.sub_state = SEEK_WAIT_STEP_TIME;
1325         delay_cycles(fi.tm, 500*(16-(spec >> 12)));
1326         return;
1327
1328      case SEEK_WAIT_STEP_TIME:
1329         return;
1330
1331      case SEEK_WAIT_STEP_TIME_DONE: {
1332         bool done = false;
1333         switch(fi.main_state) {
1334         case RECALIBRATE:
1335            fi.counter--;
1336            done = !fi.dev || !fi.dev->trk00_r();
1337            if(done)
1338               fi.pcn = 0;
1339            else if(!fi.counter) {
1340               st0 = ST0_FAIL|ST0_SE|ST0_EC;
1341               command_end(fi, false);
1342               return;
1343            }
1344            break;
1345         case SEEK:
1346            done = fi.pcn == command[2];
1347            break;
1348         }
1349         if(done) {
1350            st0 = ST0_SE;
1351            command_end(fi, false);
1352            return;
1353         }
1354         fi.sub_state = SEEK_MOVE;
1355         break;
1356      }
1357      }
1358   }
1359}
1360
1361void upd765_family_device::read_data_start(floppy_info &fi)
1362{
1363   fi.main_state = READ_DATA;
1364   fi.sub_state = HEAD_LOAD_DONE;
1365   mfm = command[0] & 0x40;
1366
1367   logerror("%s: command read%s data%s%s%s%s cmd=%02x sel=%x chrn=(%d, %d, %d, %d) eot=%02x gpl=%02x dtl=%02x rate=%d\n",
1368          tag(),
1369          command[0] & 0x08 ? " deleted" : "",
1370          command[0] & 0x80 ? " mt" : "",
1371          command[0] & 0x40 ? " mfm" : "",
1372          command[0] & 0x20 ? " sk" : "",
1373          fifocfg & 0x40 ? " seek" : "",
1374          command[0],
1375          command[1],
1376          command[2],
1377          command[3],
1378          command[4],
1379          128 << (command[5] & 7),
1380          command[6],
1381          command[7],
1382          command[8],
1383          cur_rate);
1384
1385   st0 = command[1] & 7;
1386   st1 = ST1_MA;
1387   st2 = 0x00;
1388
1389   if(fi.dev)
1390      fi.dev->ss_w(command[1] & 4 ? 1 : 0);
1391   read_data_continue(fi);
1392}
1393
1394void upd765_family_device::read_data_continue(floppy_info &fi)
1395{
1396   for(;;) {
1397      switch(fi.sub_state) {
1398      case HEAD_LOAD_DONE:
1399         if(fi.pcn == command[2] || !(fifocfg & 0x40)) {
1400            fi.sub_state = SEEK_DONE;
1401            break;
1402         }
1403         st0 |= ST0_SE;
1404         if(fi.dev) {
1405            fi.dev->dir_w(fi.pcn > command[2] ? 1 : 0);
1406            fi.dev->stp_w(0);
1407         }
1408         fi.sub_state = SEEK_WAIT_STEP_SIGNAL_TIME;
1409         fi.tm->adjust(attotime::from_nsec(2500));
1410         return;
1411
1412      case SEEK_WAIT_STEP_SIGNAL_TIME:
1413         return;
1414
1415      case SEEK_WAIT_STEP_SIGNAL_TIME_DONE:
1416         if(fi.dev)
1417            fi.dev->stp_w(1);
1418
1419         fi.sub_state = SEEK_WAIT_STEP_TIME;
1420         delay_cycles(fi.tm, 500*(16-(spec >> 12)));
1421         return;
1422
1423      case SEEK_WAIT_STEP_TIME:
1424         return;
1425
1426      case SEEK_WAIT_STEP_TIME_DONE:
1427         if(fi.pcn > command[2])
1428            fi.pcn--;
1429         else
1430            fi.pcn++;
1431         fi.sub_state = HEAD_LOAD_DONE;
1432         break;
1433
1434      case SEEK_DONE:
1435         fi.counter = 0;
1436         fi.sub_state = SCAN_ID;
1437         live_start(fi, SEARCH_ADDRESS_MARK_HEADER);
1438         return;
1439
1440      case SCAN_ID:
1441         if(cur_live.crc) {
1442            st0 |= ST0_FAIL;
1443            st1 |= ST1_DE|ST1_ND;
1444            fi.sub_state = COMMAND_DONE;
1445            break;
1446         }
1447         st1 &= ~ST1_MA;
1448         if(!sector_matches()) {
1449            if(cur_live.idbuf[0] != command[2]) {
1450               if(cur_live.idbuf[0] == 0xff)
1451                  st2 |= ST2_WC|ST2_BC;
1452               else
1453                  st2 |= ST2_WC;
1454               st0 |= ST0_FAIL;
1455               fi.sub_state = COMMAND_DONE;
1456               break;
1457            }
1458            live_start(fi, SEARCH_ADDRESS_MARK_HEADER);
1459            return;
1460         }
1461         logerror("%s: reading sector %02x %02x %02x %02x\n",
1462                tag(),
1463                cur_live.idbuf[0],
1464                cur_live.idbuf[1],
1465                cur_live.idbuf[2],
1466                cur_live.idbuf[3]);
1467         sector_size = calc_sector_size(cur_live.idbuf[3]);
1468         fifo_expect(sector_size, false);
1469         fi.sub_state = SECTOR_READ;
1470         live_start(fi, SEARCH_ADDRESS_MARK_DATA);
1471         return;
1472
1473      case SCAN_ID_FAILED:
1474         st0 |= ST0_FAIL;
1475         st1 |= ST1_ND;
1476         fi.sub_state = COMMAND_DONE;
1477         break;
1478
1479      case SECTOR_READ: {
1480         if(st2 & ST2_MD) {
1481            st0 |= ST0_FAIL;
1482            fi.sub_state = COMMAND_DONE;
1483            break;
1484         }
1485         if(cur_live.crc) {
1486            st0 |= ST0_FAIL;
1487            st1 |= ST1_DE;
1488            st2 |= ST2_CM;
1489            fi.sub_state = COMMAND_DONE;
1490            break;
1491         }
1492         bool done = tc_done;
1493         command[4]++;
1494         if(command[4] > command[6]) {
1495            command[4] = 1;
1496            if(command[0] & 0x80) {
1497               command[3] = command[3] ^ 1;
1498               if(fi.dev)
1499                  fi.dev->ss_w(command[3] & 1);
1500            }
1501            if(!(command[0] & 0x80) || !(command[3] & 1)) {
1502               command[2]++;
1503               if(!tc_done) {
1504                  st0 |= ST0_FAIL;
1505                  st1 |= ST1_EN;
1506               }
1507               done = true;
1508            }
1509         }
1510         if(!done) {
1511            fi.sub_state = SEEK_DONE;
1512            break;
1513         }
1514         fi.sub_state = COMMAND_DONE;
1515         break;
1516      }
1517
1518      case COMMAND_DONE:
1519         main_phase = PHASE_RESULT;
1520         result[0] = st0;
1521         result[1] = st1;
1522         result[2] = st2;
1523         result[3] = command[2];
1524         result[4] = command[3];
1525         result[5] = command[4];
1526         result[6] = command[5];
1527         result_pos = 7;
1528         command_end(fi, true);
1529         return;
1530
1531      default:
1532         logerror("%s: read sector unknown sub-state %d\n", ttsn().cstr(), fi.sub_state);
1533         return;
1534      }
1535   }
1536}
1537
1538void upd765_family_device::write_data_start(floppy_info &fi)
1539{
1540   fi.main_state = WRITE_DATA;
1541   fi.sub_state = HEAD_LOAD_DONE;
1542   mfm = command[0] & 0x40;
1543   logerror("%s: command write%s data%s%s cmd=%02x sel=%x chrn=(%d, %d, %d, %d) eot=%02x gpl=%02x dtl=%02x rate=%d\n",
1544          tag(),
1545          command[0] & 0x08 ? " deleted" : "",
1546          command[0] & 0x80 ? " mt" : "",
1547          command[0] & 0x40 ? " mfm" : "",
1548          command[0],
1549          command[1],
1550          command[2],
1551          command[3],
1552          command[4],
1553          128 << (command[5] & 7),
1554          command[6],
1555          command[7],
1556          command[8],
1557          cur_rate);
1558
1559   if(fi.dev)
1560      fi.dev->ss_w(command[1] & 4 ? 1 : 0);
1561
1562   st0 = command[1] & 7;
1563   st1 = ST1_MA;
1564   st2 = 0x00;
1565
1566   write_data_continue(fi);
1567}
1568
1569void upd765_family_device::write_data_continue(floppy_info &fi)
1570{
1571   for(;;) {
1572      switch(fi.sub_state) {
1573      case HEAD_LOAD_DONE:
1574         fi.counter = 0;
1575         fi.sub_state = SCAN_ID;
1576         live_start(fi, SEARCH_ADDRESS_MARK_HEADER);
1577         return;
1578
1579      case SCAN_ID:
1580         if(!sector_matches()) {
1581            live_start(fi, SEARCH_ADDRESS_MARK_HEADER);
1582            return;
1583         }
1584         if(cur_live.crc) {
1585            st0 |= ST0_FAIL;
1586            st1 |= ST1_DE|ST1_ND;
1587            fi.sub_state = COMMAND_DONE;
1588            break;
1589         }
1590         st1 &= ~ST1_MA;
1591         sector_size = calc_sector_size(cur_live.idbuf[3]);
1592         fifo_expect(sector_size, true);
1593         fi.sub_state = SECTOR_WRITTEN;
1594         live_start(fi, WRITE_SECTOR_SKIP_GAP2);
1595         return;
1596
1597      case SCAN_ID_FAILED:
1598         st0 |= ST0_FAIL;
1599         st1 |= ST1_ND;
1600         fi.sub_state = COMMAND_DONE;
1601         break;
1602
1603      case SECTOR_WRITTEN: {
1604         bool done = tc_done;
1605         command[4]++;
1606         if(command[4] > command[6]) {
1607            command[4] = 1;
1608            if(command[0] & 0x80) {
1609               command[3] = command[3] ^ 1;
1610               if(fi.dev)
1611                  fi.dev->ss_w(command[3] & 1);
1612            }
1613            if(!(command[0] & 0x80) || !(command[3] & 1)) {
1614               command[2]++;
1615               if(!tc_done) {
1616                  st0 |= ST0_FAIL;
1617                  st1 |= ST1_EN;
1618               }
1619               done = true;
1620            }
1621         }
1622         if(!done) {
1623            fi.sub_state = HEAD_LOAD_DONE;
1624            break;
1625         }
1626         fi.sub_state = COMMAND_DONE;
1627         break;
1628      }
1629
1630      case COMMAND_DONE:
1631         main_phase = PHASE_RESULT;
1632         result[0] = st0;
1633         result[1] = st1;
1634         result[2] = st2;
1635         result[3] = command[2];
1636         result[4] = command[3];
1637         result[5] = command[4];
1638         result[6] = command[5];
1639         result_pos = 7;
1640         command_end(fi, true);
1641         return;
1642
1643      default:
1644         logerror("%s: write sector unknown sub-state %d\n", ttsn().cstr(), fi.sub_state);
1645         return;
1646      }
1647   }
1648}
1649
1650void upd765_family_device::read_track_start(floppy_info &fi)
1651{
1652   fi.main_state = READ_TRACK;
1653   fi.sub_state = HEAD_LOAD_DONE;
1654   mfm = command[0] & 0x40;
1655
1656   logerror("%s: command read track%s cmd=%02x sel=%x chrn=(%d, %d, %d, %d) eot=%02x gpl=%02x dtl=%02x rate=%d\n",
1657          tag(),
1658          command[0] & 0x40 ? " mfm" : "",
1659          command[0],
1660          command[1],
1661          command[2],
1662          command[3],
1663          command[4],
1664          128 << (command[5] & 7),
1665          command[6],
1666          command[7],
1667          command[8],
1668          cur_rate);
1669
1670   if(fi.dev)
1671      fi.dev->ss_w(command[1] & 4 ? 1 : 0);
1672   read_track_continue(fi);
1673}
1674
1675void upd765_family_device::read_track_continue(floppy_info &fi)
1676{
1677   for(;;) {
1678      switch(fi.sub_state) {
1679      case HEAD_LOAD_DONE:
1680         if(fi.pcn == command[2] || !(fifocfg & 0x40)) {
1681            fi.sub_state = SEEK_DONE;
1682            break;
1683         }
1684         if(fi.dev) {
1685            fi.dev->dir_w(fi.pcn > command[2] ? 1 : 0);
1686            fi.dev->stp_w(0);
1687         }
1688         fi.sub_state = SEEK_WAIT_STEP_SIGNAL_TIME;
1689         fi.tm->adjust(attotime::from_nsec(2500));
1690         return;
1691
1692      case SEEK_WAIT_STEP_SIGNAL_TIME:
1693         return;
1694
1695      case SEEK_WAIT_STEP_SIGNAL_TIME_DONE:
1696         if(fi.dev)
1697            fi.dev->stp_w(1);
1698
1699         fi.sub_state = SEEK_WAIT_STEP_TIME;
1700         delay_cycles(fi.tm, 500*(16-(spec >> 12)));
1701         return;
1702
1703      case SEEK_WAIT_STEP_TIME:
1704         return;
1705
1706      case SEEK_WAIT_STEP_TIME_DONE:
1707         if(fi.pcn > command[2])
1708            fi.pcn--;
1709         else
1710            fi.pcn++;
1711         fi.sub_state = HEAD_LOAD_DONE;
1712         break;
1713
1714      case SEEK_DONE:
1715         fi.counter = 0;
1716         fi.sub_state = SCAN_ID;
1717         live_start(fi, SEARCH_ADDRESS_MARK_HEADER);
1718         return;
1719
1720      case SCAN_ID:
1721         if(cur_live.crc) {
1722            fprintf(stderr, "Header CRC error\n");
1723            live_start(fi, SEARCH_ADDRESS_MARK_HEADER);
1724            return;
1725         }
1726         sector_size = calc_sector_size(cur_live.idbuf[3]);
1727         fifo_expect(sector_size, false);
1728         fi.sub_state = SECTOR_READ;
1729         live_start(fi, SEARCH_ADDRESS_MARK_DATA);
1730         return;
1731
1732      case SCAN_ID_FAILED:
1733         fprintf(stderr, "RNF\n");
1734         //          command_end(fi, true, 1);
1735         return;
1736
1737      case SECTOR_READ:
1738         if(cur_live.crc) {
1739            fprintf(stderr, "CRC error\n");
1740         }
1741         if(command[4] < command[6]) {
1742            command[4]++;
1743            fi.sub_state = HEAD_LOAD_DONE;
1744            break;
1745         }
1746
1747         main_phase = PHASE_RESULT;
1748         result[0] = 0x40 | (fi.dev->ss_r() << 2) | fi.id;
1749         result[1] = 0;
1750         result[2] = 0;
1751         result[3] = command[2];
1752         result[4] = command[3];
1753         result[5] = command[4];
1754         result[6] = command[5];
1755         result_pos = 7;
1756         //          command_end(fi, true, 0);
1757         return;
1758
1759      default:
1760         logerror("%s: read track unknown sub-state %d\n", ttsn().cstr(), fi.sub_state);
1761         return;
1762      }
1763   }
1764}
1765
1766int upd765_family_device::calc_sector_size(UINT8 size)
1767{
1768   return size > 7 ? 16384 : 128 << size;
1769}
1770
1771void upd765_family_device::format_track_start(floppy_info &fi)
1772{
1773   fi.main_state = FORMAT_TRACK;
1774   fi.sub_state = HEAD_LOAD_DONE;
1775   mfm = command[0] & 0x40;
1776
1777   logerror("%s: command format track %s h=%02x n=%02x sc=%02x gpl=%02x d=%02x\n",
1778          tag(),
1779          command[0] & 0x40 ? "mfm" : "fm",
1780          command[1], command[2], command[3], command[4], command[5]);
1781
1782   if(fi.dev)
1783      fi.dev->ss_w(command[1] & 4 ? 1 : 0);
1784   sector_size = calc_sector_size(command[2]);
1785
1786   format_track_continue(fi);
1787}
1788
1789void upd765_family_device::format_track_continue(floppy_info &fi)
1790{
1791   for(;;) {
1792      switch(fi.sub_state) {
1793      case HEAD_LOAD_DONE:
1794         fi.sub_state = WAIT_INDEX;
1795         break;
1796
1797      case WAIT_INDEX:
1798         return;
1799
1800      case WAIT_INDEX_DONE:
1801         logerror("%s: index found, writing track\n", tag());
1802         fi.sub_state = TRACK_DONE;
1803         cur_live.pll.start_writing(machine().time());
1804         live_start(fi, WRITE_TRACK_PRE_SECTORS);
1805         return;
1806
1807      case TRACK_DONE:
1808         main_phase = PHASE_RESULT;
1809         result[0] = (fi.dev->ss_r() << 2) | fi.id;
1810         result[1] = 0;
1811         result[2] = 0;
1812         result[3] = 0;
1813         result[4] = 0;
1814         result[5] = 0;
1815         result[6] = 0;
1816         result_pos = 7;
1817         command_end(fi, true);
1818         return;
1819
1820      default:
1821         logerror("%s: format track unknown sub-state %d\n", ttsn().cstr(), fi.sub_state);
1822         return;
1823      }
1824   }
1825}
1826
1827void upd765_family_device::read_id_start(floppy_info &fi)
1828{
1829   fi.main_state = READ_ID;
1830   fi.sub_state = HEAD_LOAD_DONE;
1831   mfm = command[0] & 0x40;
1832
1833   logerror("%s: command read id%s, rate=%d\n",
1834          tag(),
1835          command[0] & 0x40 ? " mfm" : "",
1836          cur_rate);
1837
1838   if(fi.dev)
1839      fi.dev->ss_w(command[1] & 4 ? 1 : 0);
1840
1841   st0 = command[1] & 7;
1842   st1 = 0x00;
1843   st2 = 0x00;
1844
1845   for(int i=0; i<4; i++)
1846      cur_live.idbuf[i] = 0x00;
1847
1848   read_id_continue(fi);
1849}
1850
1851void upd765_family_device::read_id_continue(floppy_info &fi)
1852{
1853   for(;;) {
1854      switch(fi.sub_state) {
1855      case HEAD_LOAD_DONE:
1856         fi.counter = 0;
1857         fi.sub_state = SCAN_ID;
1858         live_start(fi, SEARCH_ADDRESS_MARK_HEADER);
1859         return;
1860
1861      case SCAN_ID:
1862         if(cur_live.crc) {
1863            st0 |= ST0_FAIL;
1864            st1 |= ST1_MA|ST1_DE|ST1_ND;
1865         }
1866         fi.sub_state = COMMAND_DONE;
1867         break;
1868
1869      case SCAN_ID_FAILED:
1870         st0 |= ST0_FAIL;
1871         st1 |= ST1_ND|ST1_MA;
1872         fi.sub_state = COMMAND_DONE;
1873         break;
1874
1875      case COMMAND_DONE:
1876         main_phase = PHASE_RESULT;
1877         result[0] = st0;
1878         result[1] = st1;
1879         result[2] = st2;
1880         result[3] = cur_live.idbuf[0];
1881         result[4] = cur_live.idbuf[1];
1882         result[5] = cur_live.idbuf[2];
1883         result[6] = cur_live.idbuf[3];
1884         result_pos = 7;
1885         command_end(fi, true);
1886         return;
1887
1888      default:
1889         logerror("%s: read id unknown sub-state %d\n", ttsn().cstr(), fi.sub_state);
1890         return;
1891      }
1892   }
1893}
1894
1895void upd765_family_device::check_irq()
1896{
1897   bool old_irq = cur_irq;
1898   cur_irq = data_irq || polled_irq || internal_drq;
1899   for(int i=0; i<4; i++)
1900      cur_irq = cur_irq || flopi[i].irq == floppy_info::IRQ_SEEK;
1901   cur_irq = cur_irq && (dor & 4) && (dor & 8);
1902   if(cur_irq != old_irq && !intrq_cb.isnull()) {
1903      logerror("%s: irq = %d\n", tag(), cur_irq);
1904      intrq_cb(cur_irq);
1905   }
1906}
1907
1908bool upd765_family_device::get_irq() const
1909{
1910   return cur_irq;
1911}
1912
1913astring upd765_family_device::tts(attotime t)
1914{
1915   char buf[256];
1916   const char *sign = "";
1917   if(t.seconds < 0) {
1918      t = attotime::zero-t;
1919      sign = "-";
1920   }
1921   int nsec = t.attoseconds / ATTOSECONDS_PER_NANOSECOND;
1922   sprintf(buf, "%s%04d.%03d,%03d,%03d", sign, int(t.seconds), nsec/1000000, (nsec/1000)%1000, nsec % 1000);
1923   return buf;
1924}
1925
1926astring upd765_family_device::ttsn()
1927{
1928   return tts(machine().time());
1929}
1930
1931void upd765_family_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
1932{
1933   if(id == TIMER_DRIVE_READY_POLLING) {
1934      run_drive_ready_polling();
1935      return;
1936   }
1937
1938   live_sync();
1939
1940   floppy_info &fi = flopi[id];
1941   switch(fi.sub_state) {
1942   case SEEK_WAIT_STEP_SIGNAL_TIME:
1943      fi.sub_state = SEEK_WAIT_STEP_SIGNAL_TIME_DONE;
1944      break;
1945   case SEEK_WAIT_STEP_TIME:
1946      fi.sub_state = SEEK_WAIT_STEP_TIME_DONE;
1947      break;
1948   }
1949
1950   general_continue(fi);
1951}
1952
1953void upd765_family_device::run_drive_ready_polling()
1954{
1955   if(main_phase != PHASE_CMD || (fifocfg & FIF_POLL))
1956      return;
1957
1958   bool changed = false;
1959   for(int fid=0; fid<4; fid++) {
1960      bool ready = get_ready(fid);
1961      if(ready != flopi[fid].ready) {
1962         logerror("%s: polled %d : %d -> %d\n", tag(), fid, flopi[fid].ready, ready);
1963         flopi[fid].ready = ready;
1964         if(flopi[fid].irq == floppy_info::IRQ_NONE) {
1965            flopi[fid].irq = floppy_info::IRQ_POLLED;
1966            polled_irq = true;
1967            changed = true;
1968         }
1969      }
1970   }
1971   if(changed)
1972      check_irq();
1973}
1974
1975void upd765_family_device::index_callback(floppy_image_device *floppy, int state)
1976{
1977   for(int fid=0; fid<4; fid++) {
1978      floppy_info &fi = flopi[fid];
1979      if(fi.dev != floppy)
1980         continue;
1981
1982      if(fi.live)
1983         live_sync();
1984      fi.index = state;
1985
1986      if(!state) {
1987         general_continue(fi);
1988         continue;
1989      }
1990
1991      switch(fi.sub_state) {
1992      case IDLE:
1993      case SEEK_MOVE:
1994      case SEEK_WAIT_STEP_SIGNAL_TIME:
1995      case SEEK_WAIT_STEP_SIGNAL_TIME_DONE:
1996      case SEEK_WAIT_STEP_TIME:
1997      case SEEK_WAIT_STEP_TIME_DONE:
1998      case HEAD_LOAD_DONE:
1999      case SCAN_ID_FAILED:
2000      case SECTOR_READ:
2001         break;
2002
2003      case WAIT_INDEX:
2004         fi.sub_state = WAIT_INDEX_DONE;
2005         break;
2006
2007      case SCAN_ID:
2008         fi.counter++;
2009         if(fi.counter == 2) {
2010            fi.sub_state = SCAN_ID_FAILED;
2011            live_abort();
2012         }
2013         break;
2014
2015      case TRACK_DONE:
2016         live_abort();
2017         break;
2018
2019      default:
2020         logerror("%s: Index pulse on unknown sub-state %d\n", ttsn().cstr(), fi.sub_state);
2021         break;
2022      }
2023
2024      general_continue(fi);
2025   }
2026}
2027
2028
2029void upd765_family_device::general_continue(floppy_info &fi)
2030{
2031   if(fi.live && cur_live.state != IDLE) {
2032      live_run();
2033      if(cur_live.state != IDLE)
2034         return;
2035   }
2036
2037   switch(fi.main_state) {
2038   case IDLE:
2039      break;
2040
2041   case RECALIBRATE:
2042   case SEEK:
2043      seek_continue(fi);
2044      break;
2045
2046   case READ_DATA:
2047      read_data_continue(fi);
2048      break;
2049
2050   case WRITE_DATA:
2051      write_data_continue(fi);
2052      break;
2053
2054   case READ_TRACK:
2055      read_track_continue(fi);
2056      break;
2057
2058   case FORMAT_TRACK:
2059      format_track_continue(fi);
2060      break;
2061
2062   case READ_ID:
2063      read_id_continue(fi);
2064      break;
2065
2066   default:
2067      logerror("%s: general_continue on unknown main-state %d\n", ttsn().cstr(), fi.main_state);
2068      break;
2069   }
2070}
2071
2072bool upd765_family_device::read_one_bit(attotime limit)
2073{
2074   int bit = cur_live.pll.get_next_bit(cur_live.tm, cur_live.fi->dev, limit);
2075   if(bit < 0)
2076      return true;
2077   cur_live.shift_reg = (cur_live.shift_reg << 1) | bit;
2078   cur_live.bit_counter++;
2079   if(cur_live.data_separator_phase) {
2080      cur_live.data_reg = (cur_live.data_reg << 1) | bit;
2081      if((cur_live.crc ^ (bit ? 0x8000 : 0x0000)) & 0x8000)
2082         cur_live.crc = (cur_live.crc << 1) ^ 0x1021;
2083      else
2084         cur_live.crc = cur_live.crc << 1;
2085   }
2086   cur_live.data_separator_phase = !cur_live.data_separator_phase;
2087   return false;
2088}
2089
2090bool upd765_family_device::write_one_bit(attotime limit)
2091{
2092   bool bit = cur_live.shift_reg & 0x8000;
2093   if(cur_live.pll.write_next_bit(bit, cur_live.tm, cur_live.fi->dev, limit))
2094      return true;
2095   if(cur_live.bit_counter & 1) {
2096      if((cur_live.crc ^ (bit ? 0x8000 : 0x0000)) & 0x8000)
2097         cur_live.crc = (cur_live.crc << 1) ^ 0x1021;
2098      else
2099         cur_live.crc = cur_live.crc << 1;
2100   }
2101   cur_live.shift_reg = cur_live.shift_reg << 1;
2102   cur_live.bit_counter--;
2103   return false;
2104}
2105
2106void upd765_family_device::live_write_raw(UINT16 raw)
2107{
2108   //  logerror("write %04x %04x\n", raw, cur_live.crc);
2109   cur_live.shift_reg = raw;
2110   cur_live.data_bit_context = raw & 1;
2111}
2112
2113void upd765_family_device::live_write_mfm(UINT8 mfm)
2114{
2115   bool context = cur_live.data_bit_context;
2116   UINT16 raw = 0;
2117   for(int i=0; i<8; i++) {
2118      bool bit = mfm & (0x80 >> i);
2119      if(!(bit || context))
2120         raw |= 0x8000 >> (2*i);
2121      if(bit)
2122         raw |= 0x4000 >> (2*i);
2123      context = bit;
2124   }
2125   cur_live.data_reg = mfm;
2126   cur_live.shift_reg = raw;
2127   cur_live.data_bit_context = context;
2128   //  logerror("write %02x   %04x %04x\n", mfm, cur_live.crc, raw);
2129}
2130
2131void upd765_family_device::live_write_fm(UINT8 fm)
2132{
2133   UINT16 raw = 0xaaaa;
2134   for(int i=0; i<8; i++)
2135      if(fm & (0x80 >> i))
2136         raw |= 0x4000 >> (2*i);
2137   cur_live.data_reg = fm;
2138   cur_live.shift_reg = raw;
2139   cur_live.data_bit_context = fm & 1;
2140   //  logerror("write %02x   %04x %04x\n", fm, cur_live.crc, raw);
2141}
2142
2143bool upd765_family_device::sector_matches() const
2144{
2145   if(0)
2146      logerror("%s: matching %02x %02x %02x %02x - %02x %02x %02x %02x\n", tag(),
2147             cur_live.idbuf[0], cur_live.idbuf[1], cur_live.idbuf[2], cur_live.idbuf[3],
2148             command[2], command[3], command[4], command[5]);
2149   return
2150      cur_live.idbuf[0] == command[2] &&
2151      cur_live.idbuf[1] == command[3] &&
2152      cur_live.idbuf[2] == command[4] &&
2153      cur_live.idbuf[3] == command[5];
2154}
2155
2156void upd765_family_device::pll_t::set_clock(attotime _period)
2157{
2158   period = _period;
2159   period_adjust_base = period * 0.05;
2160   min_period = period * 0.75;
2161   max_period = period * 1.25;
2162}
2163
2164void upd765_family_device::pll_t::reset(attotime when)
2165{
2166   ctime = when;
2167   phase_adjust = attotime::zero;
2168   freq_hist = 0;
2169   write_position = 0;
2170   write_start_time = attotime::never;
2171}
2172
2173void upd765_family_device::pll_t::start_writing(attotime tm)
2174{
2175   write_start_time = tm;
2176   write_position = 0;
2177}
2178
2179void upd765_family_device::pll_t::stop_writing(floppy_image_device *floppy, attotime tm)
2180{
2181   commit(floppy, tm);
2182   write_start_time = attotime::never;
2183}
2184
2185void upd765_family_device::pll_t::commit(floppy_image_device *floppy, attotime tm)
2186{
2187   if(write_start_time.is_never() || tm == write_start_time)
2188      return;
2189
2190   if(floppy)
2191      floppy->write_flux(write_start_time, tm, write_position, write_buffer);
2192   write_start_time = tm;
2193   write_position = 0;
2194}
2195
2196int upd765_family_device::pll_t::get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit)
2197{
2198   attotime edge = floppy ? floppy->get_next_transition(ctime) : attotime::never;
2199
2200   attotime next = ctime + period + phase_adjust;
2201
2202#if 0
2203   if(!edge.is_never())
2204      fprintf(stderr, "ctime=%s, transition_time=%s, next=%s, pha=%s\n", tts(ctime).cstr(), tts(edge).cstr(), tts(next).cstr(), tts(phase_adjust).cstr());
2205#endif
2206
2207   if(next > limit)
2208      return -1;
2209
2210   ctime = next;
2211   tm = next;
2212
2213   if(edge.is_never() || edge >= next) {
2214      // No transition in the window means 0 and pll in free run mode
2215      phase_adjust = attotime::zero;
2216      return 0;
2217   }
2218
2219   // Transition in the window means 1, and the pll is adjusted
2220
2221   attotime delta = edge - (next - period/2);
2222
2223   if(delta.seconds < 0)
2224      phase_adjust = attotime::zero - ((attotime::zero - delta)*65)/100;
2225   else
2226      phase_adjust = (delta*65)/100;
2227
2228   if(delta < attotime::zero) {
2229      if(freq_hist < 0)
2230         freq_hist--;
2231      else
2232         freq_hist = -1;
2233   } else if(delta > attotime::zero) {
2234      if(freq_hist > 0)
2235         freq_hist++;
2236      else
2237         freq_hist = 1;
2238   } else
2239      freq_hist = 0;
2240
2241   if(freq_hist) {
2242      int afh = freq_hist < 0 ? -freq_hist : freq_hist;
2243      if(afh > 1) {
2244         attotime aper = attotime::from_double(period_adjust_base.as_double()*delta.as_double()/period.as_double());
2245         period += aper;
2246
2247         if(period < min_period)
2248            period = min_period;
2249         else if(period > max_period)
2250            period = max_period;
2251      }
2252   }
2253
2254   return 1;
2255}
2256
2257bool upd765_family_device::pll_t::write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit)
2258{
2259   if(write_start_time.is_never()) {
2260      write_start_time = ctime;
2261      write_position = 0;
2262   }
2263
2264   attotime etime = ctime + period;
2265   if(etime > limit)
2266      return true;
2267
2268   if(bit && write_position < ARRAY_LENGTH(write_buffer))
2269      write_buffer[write_position++] = ctime + period/2;
2270
2271   tm = etime;
2272   ctime = etime;
2273   return false;
2274}
2275
2276upd765a_device::upd765a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : upd765_family_device(mconfig, UPD765A, "UPD765A", tag, owner, clock)
2277{
2278   m_shortname = "upd765a";
2279   dor_reset = 0x0c;
2280}
2281
2282upd765b_device::upd765b_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : upd765_family_device(mconfig, UPD765B, "UPD765B", tag, owner, clock)
2283{
2284   m_shortname = "upd765b";
2285   dor_reset = 0x0c;
2286}
2287
2288i8272a_device::i8272a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : upd765_family_device(mconfig, I8272A, "I8272A", tag, owner, clock)
2289{
2290   m_shortname = "i8272a";
2291   dor_reset = 0x0c;
2292}
2293
2294upd72065_device::upd72065_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : upd765_family_device(mconfig, UPD72065, "UPD72065", tag, owner, clock)
2295{
2296   m_shortname = "upd72065";
2297   dor_reset = 0x0c;
2298}
2299
2300smc37c78_device::smc37c78_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : upd765_family_device(mconfig, SMC37C78, "SMC37C78", tag, owner, clock)
2301{
2302   m_shortname = "smc37c78";
2303   ready_connected = false;
2304   select_connected = true;
2305}
2306
2307n82077aa_device::n82077aa_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : upd765_family_device(mconfig, N82077AA, "N82077AA", tag, owner, clock)
2308{
2309   m_shortname = "n82077aa";
2310   ready_connected = false;
2311   select_connected = true;
2312}
2313
2314pc_fdc_superio_device::pc_fdc_superio_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : upd765_family_device(mconfig, PC_FDC_SUPERIO, "PC FDC SUPERIO", tag, owner, clock)
2315{
2316   m_shortname = "pc_fdc_superio";
2317   ready_polled = false;
2318   ready_connected = false;
2319   select_connected = true;
2320}
trunk/src/emu/machine/upd765.h
r19165r19166
1#ifndef __UPD765_F_H__
2#define __UPD765_F_H__
3
4#include "emu.h"
5#include "imagedev/floppy.h"
6
7/*
8 * ready = true if the ready line is physically connected to the floppy drive
9 * select = true if the fdc controls the floppy drive selection
10 * mode = MODE_AT, MODE_PS2 or MODE_M30 for the fdcs that have reset-time selection
11 */
12
13#define MCFG_UPD765A_ADD(_tag, _ready, _select)   \
14   MCFG_DEVICE_ADD(_tag, UPD765A, 0)         \
15   downcast<upd765a_device *>(device)->set_ready_line_connected(_ready);   \
16   downcast<upd765a_device *>(device)->set_select_lines_connected(_select);
17
18#define MCFG_UPD765B_ADD(_tag, _ready, _select)   \
19   MCFG_DEVICE_ADD(_tag, UPD765B, 0)         \
20   downcast<upd765b_device *>(device)->set_ready_line_connected(_ready);   \
21   downcast<upd765b_device *>(device)->set_select_lines_connected(_select);
22
23#define MCFG_I8272A_ADD(_tag, _ready)   \
24   MCFG_DEVICE_ADD(_tag, I8272A, 0)   \
25   downcast<i8272a_device *>(device)->set_ready_line_connected(_ready);
26
27#define MCFG_UPD72065_ADD(_tag, _ready, _select)   \
28   MCFG_DEVICE_ADD(_tag, UPD72065, 0)            \
29   downcast<upd72065_device *>(device)->set_ready_line_connected(_ready);   \
30   downcast<upd72065_device *>(device)->set_select_lines_connected(_select);
31
32#define MCFG_SMC37C78_ADD(_tag)   \
33   MCFG_DEVICE_ADD(_tag, SMC37C78, 0)
34
35#define MCFG_N82077AA_ADD(_tag, _mode)   \
36   MCFG_DEVICE_ADD(_tag, N82077AA, 0)   \
37   downcast<n82077aa_device *>(device)->set_mode(_mode);
38
39#define MCFG_PC_FDC_SUPERIO_ADD(_tag)   \
40   MCFG_DEVICE_ADD(_tag, PC_FDC_SUPERIO, 0)
41
42/* Interface required for PC ISA wrapping */
43class pc_fdc_interface : public device_t {
44public:
45   typedef delegate<void (bool state)> line_cb;
46   typedef delegate<UINT8 ()> byte_read_cb;
47   typedef delegate<void (UINT8)> byte_write_cb;
48
49   pc_fdc_interface(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) : device_t(mconfig, type, name, tag, owner, clock) {}
50
51   virtual void setup_intrq_cb(line_cb cb) = 0;
52   virtual void setup_drq_cb(line_cb cb) = 0;
53
54   /* Note that the address map must cover and handle the whole 0-7
55     * range.  The upd765, while conforming to the rest of the
56     * interface, is not eligible as a result.
57     */
58
59   virtual DECLARE_ADDRESS_MAP(map, 8) = 0;
60
61   virtual UINT8 dma_r() = 0;
62   virtual void dma_w(UINT8 data) = 0;
63
64   virtual void tc_w(bool val) = 0;
65   virtual UINT8 do_dir_r() = 0;
66};
67
68class upd765_family_device : public pc_fdc_interface {
69public:
70   enum { MODE_AT, MODE_PS2, MODE_M30 };
71
72   upd765_family_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
73
74   void setup_intrq_cb(line_cb cb);
75   void setup_drq_cb(line_cb cb);
76
77   virtual DECLARE_ADDRESS_MAP(map, 8) = 0;
78
79   DECLARE_READ8_MEMBER (sra_r);
80   DECLARE_READ8_MEMBER (srb_r);
81   DECLARE_READ8_MEMBER (dor_r);
82   DECLARE_WRITE8_MEMBER(dor_w);
83   DECLARE_READ8_MEMBER (tdr_r);
84   DECLARE_WRITE8_MEMBER(tdr_w);
85   DECLARE_READ8_MEMBER (msr_r);
86   DECLARE_WRITE8_MEMBER(dsr_w);
87   DECLARE_READ8_MEMBER (fifo_r);
88   DECLARE_WRITE8_MEMBER(fifo_w);
89   DECLARE_READ8_MEMBER (dir_r);
90   DECLARE_WRITE8_MEMBER(ccr_w);
91
92   virtual UINT8 do_dir_r();
93
94   UINT8 dma_r();
95   void dma_w(UINT8 data);
96
97   // Same as the previous ones, but as memory-mappable members
98   DECLARE_READ8_MEMBER(mdma_r);
99   DECLARE_WRITE8_MEMBER(mdma_w);
100
101   bool get_irq() const;
102   bool get_drq() const;
103   void tc_w(bool val);
104   void ready_w(bool val);
105
106   void set_rate(int rate); // rate in bps, to be used when the fdc is externally frequency-controlled
107
108   void set_mode(int mode);
109   void set_ready_line_connected(bool ready);
110   void set_select_lines_connected(bool select);
111   void set_floppy(floppy_image_device *image);
112
113protected:
114   virtual void device_start();
115   virtual void device_reset();
116   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
117
118   enum {
119      TIMER_DRIVE_READY_POLLING = 4
120   };
121
122   enum {
123      PHASE_CMD, PHASE_EXEC, PHASE_RESULT
124   };
125
126   enum {
127      MSR_DB   = 0x0f,
128      MSR_CB   = 0x10,
129      MSR_EXM  = 0x20,
130      MSR_DIO  = 0x40,
131      MSR_RQM  = 0x80,
132
133      ST0_UNIT = 0x07,
134      ST0_NR   = 0x08,
135      ST0_EC   = 0x10,
136      ST0_SE   = 0x20,
137      ST0_FAIL = 0x40,
138      ST0_UNK  = 0x80,
139      ST0_ABRT = 0xc0,
140
141      ST1_MA   = 0x01,
142      ST1_NW   = 0x02,
143      ST1_ND   = 0x04,
144      ST1_OR   = 0x10,
145      ST1_DE   = 0x20,
146      ST1_EN   = 0x80,
147
148      ST2_MD   = 0x01,
149      ST2_BC   = 0x02,
150      ST2_SN   = 0x04,
151      ST2_SH   = 0x08,
152      ST2_WC   = 0x10,
153      ST2_DD   = 0x20,
154      ST2_CM   = 0x40,
155
156      ST3_UNIT = 0x07,
157      ST3_TS   = 0x08,
158      ST3_T0   = 0x10,
159      ST3_RY   = 0x20,
160      ST3_WP   = 0x40,
161      ST3_FT   = 0x80,
162
163      FIF_THR  = 0x0f,
164      FIF_POLL = 0x10,
165      FIF_DIS  = 0x20,
166      FIF_EIS  = 0x40,
167
168      SPEC_ND  = 0x0001,
169   };
170
171
172   enum {
173      // General "doing nothing" state
174      IDLE,
175
176      // Main states
177      RECALIBRATE,
178      SEEK,
179      READ_DATA,
180      WRITE_DATA,
181      READ_TRACK,
182      FORMAT_TRACK,
183      READ_ID,
184
185      // Sub-states
186      COMMAND_DONE,
187
188      SEEK_MOVE,
189      SEEK_WAIT_STEP_SIGNAL_TIME,
190      SEEK_WAIT_STEP_SIGNAL_TIME_DONE,
191      SEEK_WAIT_STEP_TIME,
192      SEEK_WAIT_STEP_TIME_DONE,
193      SEEK_DONE,
194
195      HEAD_LOAD_DONE,
196
197      WAIT_INDEX,
198      WAIT_INDEX_DONE,
199
200      SCAN_ID,
201      SCAN_ID_FAILED,
202
203      SECTOR_READ,
204      SECTOR_WRITTEN,
205      TC_DONE,
206
207      TRACK_DONE,
208
209      // Live states
210      SEARCH_ADDRESS_MARK_HEADER,
211      READ_HEADER_BLOCK_HEADER,
212      READ_DATA_BLOCK_HEADER,
213      READ_ID_BLOCK,
214      SEARCH_ADDRESS_MARK_DATA,
215      SEARCH_ADDRESS_MARK_DATA_FAILED,
216      READ_SECTOR_DATA,
217      READ_SECTOR_DATA_BYTE,
218
219      WRITE_SECTOR_SKIP_GAP2,
220      WRITE_SECTOR_SKIP_GAP2_BYTE,
221      WRITE_SECTOR_DATA,
222      WRITE_SECTOR_DATA_BYTE,
223
224      WRITE_TRACK_PRE_SECTORS,
225      WRITE_TRACK_PRE_SECTORS_BYTE,
226
227      WRITE_TRACK_SECTOR,
228      WRITE_TRACK_SECTOR_BYTE,
229
230      WRITE_TRACK_POST_SECTORS,
231      WRITE_TRACK_POST_SECTORS_BYTE,
232   };
233
234   struct pll_t {
235      attotime ctime, period, min_period, max_period, period_adjust_base, phase_adjust;
236
237      attotime write_start_time;
238      attotime write_buffer[32];
239      int write_position;
240      int freq_hist;
241
242      void set_clock(attotime period);
243      void reset(attotime when);
244      int get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit);
245      bool write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit);
246      void start_writing(attotime tm);
247      void commit(floppy_image_device *floppy, attotime tm);
248      void stop_writing(floppy_image_device *floppy, attotime tm);
249   };
250
251   struct floppy_info {
252      enum { IRQ_NONE, IRQ_SEEK, IRQ_POLLED };
253      emu_timer *tm;
254      floppy_image_device *dev;
255      int id;
256      int main_state, sub_state;
257      int dir, counter;
258      UINT8 pcn;
259      int irq;
260      bool live, index, ready;
261   };
262
263   struct live_info {
264      enum { PT_NONE, PT_CRC_1, PT_CRC_2 };
265
266      attotime tm;
267      int state, next_state;
268      floppy_info *fi;
269      UINT16 shift_reg;
270      UINT16 crc;
271      int bit_counter, byte_counter, previous_type;
272      bool data_separator_phase, data_bit_context;
273      UINT8 data_reg;
274      UINT8 idbuf[6];
275      pll_t pll;
276   };
277
278   static int rates[4];
279
280   bool ready_connected, ready_polled, select_connected;
281
282   bool external_ready;
283
284   int mode;
285   int main_phase;
286
287   live_info cur_live, checkpoint_live;
288   line_cb intrq_cb, drq_cb;
289   bool cur_irq, polled_irq, data_irq, drq, internal_drq, tc, tc_done, locked, mfm;
290   floppy_info flopi[4];
291
292   int fifo_pos, fifo_expected, command_pos, result_pos;
293   bool fifo_write;
294   UINT8 dor, dsr, msr, fifo[16], command[16], result[16];
295   UINT8 st0, st1, st2, st3;
296   UINT8 fifocfg, dor_reset;
297   UINT8 precomp, perpmode;
298   UINT16 spec;
299   int sector_size;
300   int cur_rate;
301
302   emu_timer *poll_timer;
303
304   static astring tts(attotime t);
305   astring ttsn();
306
307   enum {
308      C_CONFIGURE,
309      C_DUMP_REG,
310      C_FORMAT_TRACK,
311      C_LOCK,
312      C_PERPENDICULAR,
313      C_READ_DATA,
314      C_READ_ID,
315      C_READ_TRACK,
316      C_RECALIBRATE,
317      C_SEEK,
318      C_SENSE_DRIVE_STATUS,
319      C_SENSE_INTERRUPT_STATUS,
320      C_SPECIFY,
321      C_WRITE_DATA,
322
323      C_INVALID,
324      C_INCOMPLETE,
325   };
326
327   void delay_cycles(emu_timer *tm, int cycles);
328   void check_irq();
329   void soft_reset();
330   void fifo_expect(int size, bool write);
331   void fifo_push(UINT8 data, bool internal);
332   UINT8 fifo_pop(bool internal);
333   void set_drq(bool state);
334   bool get_ready(int fid);
335
336   void enable_transfer();
337   void disable_transfer();
338   int calc_sector_size(UINT8 size);
339
340   void run_drive_ready_polling();
341
342   int check_command();
343   void start_command(int cmd);
344   void command_end(floppy_info &fi, bool data_completion);
345
346   void recalibrate_start(floppy_info &fi);
347   void seek_start(floppy_info &fi);
348   void seek_continue(floppy_info &fi);
349
350   void read_data_start(floppy_info &fi);
351   void read_data_continue(floppy_info &fi);
352
353   void write_data_start(floppy_info &fi);
354   void write_data_continue(floppy_info &fi);
355
356   void read_track_start(floppy_info &fi);
357   void read_track_continue(floppy_info &fi);
358
359   void format_track_start(floppy_info &fi);
360   void format_track_continue(floppy_info &fi);
361
362   void read_id_start(floppy_info &fi);
363   void read_id_continue(floppy_info &fi);
364
365   void general_continue(floppy_info &fi);
366   void index_callback(floppy_image_device *floppy, int state);
367   bool sector_matches() const;
368
369   void live_start(floppy_info &fi, int live_state);
370   void live_abort();
371   void checkpoint();
372   void rollback();
373   void live_delay(int state);
374   void live_sync();
375   void live_run(attotime limit = attotime::never);
376   void live_write_raw(UINT16 raw);
377   void live_write_fm(UINT8 fm);
378   void live_write_mfm(UINT8 mfm);
379
380   bool read_one_bit(attotime limit);
381   bool write_one_bit(attotime limit);
382};
383
384class upd765a_device : public upd765_family_device {
385public:
386   upd765a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
387
388   virtual DECLARE_ADDRESS_MAP(map, 8);
389};
390
391class upd765b_device : public upd765_family_device {
392public:
393   upd765b_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
394
395   virtual DECLARE_ADDRESS_MAP(map, 8);
396};
397
398class i8272a_device : public upd765_family_device {
399public:
400   i8272a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
401
402   virtual DECLARE_ADDRESS_MAP(map, 8);
403};
404
405class smc37c78_device : public upd765_family_device {
406public:
407   smc37c78_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
408
409   virtual DECLARE_ADDRESS_MAP(map, 8);
410};
411
412class upd72065_device : public upd765_family_device {
413public:
414   upd72065_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
415
416   virtual DECLARE_ADDRESS_MAP(map, 8);
417};
418
419class n82077aa_device : public upd765_family_device {
420public:
421   n82077aa_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
422
423   virtual DECLARE_ADDRESS_MAP(map, 8);
424};
425
426class pc_fdc_superio_device : public upd765_family_device {
427public:
428   pc_fdc_superio_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
429
430   virtual DECLARE_ADDRESS_MAP(map, 8);
431};
432
433extern const device_type UPD765A;
434extern const device_type UPD765B;
435extern const device_type I8272A;
436extern const device_type UPD72065;
437extern const device_type SMC37C78;
438extern const device_type N82077AA;
439extern const device_type PC_FDC_SUPERIO;
440
441#endif
trunk/src/mess/mess.mak
r19165r19166
526526   $(MESS_MACHINE)/mos6530.o   \
527527   $(MESS_MACHINE)/s100.o      \
528528   $(MESS_MACHINE)/serial.o   \
529   $(MESS_MACHINE)/upd765.o   \
530529   $(MESS_MACHINE)/ncr5380.o   \
531530   $(MESS_MACHINE)/ncr5390.o   \
532531   $(MESS_MACHINE)/pc_kbdc.o   \
r19165r19166
554553   $(MESS_MACHINE)/dp8390.o   \
555554   $(MESS_MACHINE)/ne1000.o   \
556555   $(MESS_MACHINE)/ne2000.o   \
557   $(MESS_MACHINE)/wd1772.o   \
558556   $(MESS_MACHINE)/3c503.o      \
559557   $(MESS_FORMATS)/z80bin.o   \
560558   $(MESS_MACHINE)/mb8795.o   \
trunk/src/mess/machine/upd765.c
r19165r19166
1#include "debugger.h"
2
3#include "upd765.h"
4
5const device_type UPD765A = &device_creator<upd765a_device>;
6const device_type UPD765B = &device_creator<upd765b_device>;
7const device_type I8272A = &device_creator<i8272a_device>;
8const device_type UPD72065 = &device_creator<upd72065_device>;
9const device_type SMC37C78 = &device_creator<smc37c78_device>;
10const device_type N82077AA = &device_creator<n82077aa_device>;
11const device_type PC_FDC_SUPERIO = &device_creator<pc_fdc_superio_device>;
12
13DEVICE_ADDRESS_MAP_START(map, 8, upd765a_device)
14   AM_RANGE(0x0, 0x0) AM_READ(msr_r)
15   AM_RANGE(0x1, 0x1) AM_READWRITE(fifo_r, fifo_w)
16ADDRESS_MAP_END
17
18DEVICE_ADDRESS_MAP_START(map, 8, upd765b_device)
19   AM_RANGE(0x0, 0x0) AM_READ(msr_r)
20   AM_RANGE(0x1, 0x1) AM_READWRITE(fifo_r, fifo_w)
21ADDRESS_MAP_END
22
23DEVICE_ADDRESS_MAP_START(map, 8, i8272a_device)
24   AM_RANGE(0x0, 0x0) AM_READ(msr_r)
25   AM_RANGE(0x1, 0x1) AM_READWRITE(fifo_r, fifo_w)
26ADDRESS_MAP_END
27
28DEVICE_ADDRESS_MAP_START(map, 8, upd72065_device)
29   AM_RANGE(0x0, 0x0) AM_READ(msr_r)
30   AM_RANGE(0x1, 0x1) AM_READWRITE(fifo_r, fifo_w)
31ADDRESS_MAP_END
32
33DEVICE_ADDRESS_MAP_START(map, 8, smc37c78_device)
34   AM_RANGE(0x2, 0x2) AM_READWRITE(dor_r, dor_w)
35   AM_RANGE(0x3, 0x3) AM_READWRITE(tdr_r, tdr_w)
36   AM_RANGE(0x4, 0x4) AM_READWRITE(msr_r, dsr_w)
37   AM_RANGE(0x5, 0x5) AM_READWRITE(fifo_r, fifo_w)
38   AM_RANGE(0x7, 0x7) AM_READWRITE(dir_r, ccr_w)
39ADDRESS_MAP_END
40
41DEVICE_ADDRESS_MAP_START(map, 8, n82077aa_device)
42   AM_RANGE(0x0, 0x0) AM_READ(sra_r)
43   AM_RANGE(0x1, 0x1) AM_READ(srb_r)
44   AM_RANGE(0x2, 0x2) AM_READWRITE(dor_r, dor_w)
45   AM_RANGE(0x3, 0x3) AM_READWRITE(tdr_r, tdr_w)
46   AM_RANGE(0x4, 0x4) AM_READWRITE(msr_r, dsr_w)
47   AM_RANGE(0x5, 0x5) AM_READWRITE(fifo_r, fifo_w)
48   AM_RANGE(0x7, 0x7) AM_READWRITE(dir_r, ccr_w)
49ADDRESS_MAP_END
50
51DEVICE_ADDRESS_MAP_START(map, 8, pc_fdc_superio_device)
52   AM_RANGE(0x0, 0x0) AM_READ(sra_r)
53   AM_RANGE(0x1, 0x1) AM_READ(srb_r)
54   AM_RANGE(0x2, 0x2) AM_READWRITE(dor_r, dor_w)
55   AM_RANGE(0x3, 0x3) AM_READWRITE(tdr_r, tdr_w)
56   AM_RANGE(0x4, 0x4) AM_READWRITE(msr_r, dsr_w)
57   AM_RANGE(0x5, 0x5) AM_READWRITE(fifo_r, fifo_w)
58   AM_RANGE(0x7, 0x7) AM_READWRITE(dir_r, ccr_w)
59ADDRESS_MAP_END
60
61
62int upd765_family_device::rates[4] = { 500000, 300000, 250000, 1000000 };
63
64upd765_family_device::upd765_family_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) : pc_fdc_interface(mconfig, type, name, tag, owner, clock)
65{
66   ready_polled = true;
67   ready_connected = true;
68   select_connected = true;
69   external_ready = true;
70   dor_reset = 0x00;
71}
72
73void upd765_family_device::set_ready_line_connected(bool _ready)
74{
75   ready_connected = _ready;
76}
77
78void upd765_family_device::set_select_lines_connected(bool _select)
79{
80   select_connected = _select;
81}
82
83void upd765_family_device::set_mode(int _mode)
84{
85   // TODO
86}
87
88void upd765_family_device::setup_intrq_cb(line_cb cb)
89{
90   intrq_cb = cb;
91}
92
93void upd765_family_device::setup_drq_cb(line_cb cb)
94{
95   drq_cb = cb;
96}
97
98void upd765_family_device::device_start()
99{
100   for(int i=0; i != 4; i++) {
101      char name[2];
102      flopi[i].tm = timer_alloc(i);
103      flopi[i].id = i;
104      if(select_connected) {
105         name[0] = '0'+i;
106         name[1] = 0;
107         floppy_connector *con = subdevice<floppy_connector>(name);
108         if(con) {
109            flopi[i].dev = con->get_device();
110            flopi[i].dev->setup_index_pulse_cb(floppy_image_device::index_pulse_cb(FUNC(upd765_family_device::index_callback), this));
111         } else
112            flopi[i].dev = NULL;
113      } else
114         flopi[i].dev = NULL;
115   }
116   cur_rate = 250000;
117   tc = false;
118
119   // reset at upper levels may cause a write to tc ending up with
120   // live_sync, which will crash if the live structure isn't
121   // initialized enough
122
123   cur_live.tm = attotime::never;
124   cur_live.state = IDLE;
125   cur_live.next_state = -1;
126   cur_live.fi = NULL;
127
128   if(ready_polled) {
129      poll_timer = timer_alloc(TIMER_DRIVE_READY_POLLING);
130      poll_timer->adjust(attotime::from_usec(1024), 0, attotime::from_usec(1024));
131   } else
132      poll_timer = NULL;
133
134   cur_irq = false;
135   locked = false;
136}
137
138void upd765_family_device::device_reset()
139{
140   dor = dor_reset;
141   locked = false;
142   soft_reset();
143}
144
145void upd765_family_device::soft_reset()
146{
147   main_phase = PHASE_CMD;
148   for(int i=0; i<4; i++) {
149      flopi[i].main_state = IDLE;
150      flopi[i].sub_state = IDLE;
151      flopi[i].live = false;
152      flopi[i].ready = !ready_polled;
153      flopi[i].irq = floppy_info::IRQ_NONE;
154   }
155   data_irq = false;
156   polled_irq = false;
157   internal_drq = false;
158   fifo_pos = 0;
159   command_pos = 0;
160   result_pos = 0;
161   if(!locked)
162      fifocfg = FIF_DIS;
163   cur_live.fi = 0;
164   drq = false;
165   cur_live.tm = attotime::never;
166   cur_live.state = IDLE;
167   cur_live.next_state = -1;
168   cur_live.fi = NULL;
169   tc_done = false;
170   st0 = st1 = st2 = st3 = 0x00;
171
172   check_irq();
173   if(ready_polled)
174      poll_timer->adjust(attotime::from_usec(1024), 0, attotime::from_usec(1024));
175}
176
177void upd765_family_device::tc_w(bool _tc)
178{
179   logerror("%s: tc=%d\n", tag(), _tc);
180   if(tc != _tc && _tc) {
181      live_sync();
182      tc_done = true;
183      tc = _tc;
184      if(cur_live.fi)
185         general_continue(*cur_live.fi);
186   } else
187      tc = _tc;
188}
189
190void upd765_family_device::ready_w(bool _ready)
191{
192   external_ready = _ready;
193}
194
195bool upd765_family_device::get_ready(int fid)
196{
197   if(ready_connected)
198      return flopi[fid].dev ? !flopi[fid].dev->ready_r() : false;
199   return external_ready;
200}
201
202void upd765_family_device::set_floppy(floppy_image_device *flop)
203{
204   for(int fid=0; fid<4; fid++) {
205      if(flopi[fid].dev)
206         flopi[fid].dev->setup_index_pulse_cb(floppy_image_device::index_pulse_cb());
207      flopi[fid].dev = flop;
208   }
209   if(flop)
210      flop->setup_index_pulse_cb(floppy_image_device::index_pulse_cb(FUNC(upd765_family_device::index_callback), this));
211}
212
213READ8_MEMBER(upd765_family_device::sra_r)
214{
215   UINT8 sra = 0;
216   int fid = dor & 3;
217   floppy_info &fi = flopi[fid];
218   if(fi.dir)
219      sra |= 0x01;
220   if(fi.index)
221      sra |= 0x04;
222   if(cur_rate >= 500000)
223      sra |= 0x08;
224   if(fi.dev && fi.dev->trk00_r())
225      sra |= 0x10;
226   if(fi.main_state == SEEK_WAIT_STEP_SIGNAL_TIME)
227      sra |= 0x20;
228   sra |= 0x40;
229   if(cur_irq)
230      sra |= 0x80;
231   if(mode == MODE_M30)
232      sra ^= 0x1f;
233   return sra;
234}
235
236READ8_MEMBER(upd765_family_device::srb_r)
237{
238   return 0;
239}
240
241READ8_MEMBER(upd765_family_device::dor_r)
242{
243   return dor;
244}
245
246WRITE8_MEMBER(upd765_family_device::dor_w)
247{
248   logerror("%s: dor = %02x\n", tag(), data);
249   UINT8 diff = dor ^ data;
250   dor = data;
251   if(diff & 4)
252      soft_reset();
253
254   for(int i=0; i<4; i++) {
255      floppy_info &fi = flopi[i];
256      if(fi.dev)
257         fi.dev->mon_w(!(dor & (0x10 << i)));
258   }
259   check_irq();
260}
261
262READ8_MEMBER(upd765_family_device::tdr_r)
263{
264   return 0;
265}
266
267WRITE8_MEMBER(upd765_family_device::tdr_w)
268{
269}
270
271READ8_MEMBER(upd765_family_device::msr_r)
272{
273   UINT32 msr = 0;
274   switch(main_phase) {
275   case PHASE_CMD:
276      msr |= MSR_RQM;
277      if(command_pos)
278         msr |= MSR_CB;
279      break;
280   case PHASE_EXEC:
281      msr |= MSR_CB;
282      if(spec & SPEC_ND)
283         msr |= MSR_EXM;
284      if(internal_drq) {
285         msr |= MSR_RQM;
286         if(!fifo_write)
287            msr |= MSR_DIO;
288      }
289      break;
290
291   case PHASE_RESULT:
292      msr |= MSR_RQM|MSR_DIO|MSR_CB;
293      break;
294   }
295   for(int i=0; i<4; i++)
296      if(flopi[i].main_state == RECALIBRATE || flopi[i].main_state == SEEK) {
297         msr |= 1<<i;
298         msr |= MSR_CB;
299      }
300
301   if(data_irq) {
302      data_irq = false;
303      check_irq();
304   }
305
306   return msr;
307}
308
309WRITE8_MEMBER(upd765_family_device::dsr_w)
310{
311   logerror("%s: dsr_w %02x\n", tag(), data);
312   if(data & 0x80)
313      soft_reset();
314   dsr = data & 0x7f;
315   cur_rate = rates[dsr & 3];
316}
317
318void upd765_family_device::set_rate(int rate)
319{
320   cur_rate = rate;
321}
322
323READ8_MEMBER(upd765_family_device::fifo_r)
324{
325   UINT8 r = 0;
326   switch(main_phase) {
327   case PHASE_EXEC:
328      if(internal_drq)
329         return fifo_pop(false);
330      logerror("%s: fifo_r in phase %d\n", tag(), main_phase);
331      break;
332
333   case PHASE_RESULT:
334      r = result[0];
335      result_pos--;
336      memmove(result, result+1, result_pos);
337      if(!result_pos)
338         main_phase = PHASE_CMD;
339      break;
340   default:
341      logerror("%s: fifo_r in phase %d\n", tag(), main_phase);
342      break;
343   }
344
345   return r;
346}
347
348WRITE8_MEMBER(upd765_family_device::fifo_w)
349{
350   switch(main_phase) {
351   case PHASE_CMD: {
352      command[command_pos++] = data;
353      int cmd = check_command();
354      if(cmd == C_INCOMPLETE)
355         break;
356      if(cmd == C_INVALID) {
357         logerror("%s: Invalid on %02x\n", tag(), command[0]);
358         main_phase = PHASE_RESULT;
359         result[0] = 0x80;
360         result_pos = 1;
361         return;
362      }
363      start_command(cmd);
364      break;
365   }
366   case PHASE_EXEC:
367      if(internal_drq) {
368         fifo_push(data, false);
369         return;
370      }
371      logerror("%s: fifo_w in phase %d\n", tag(), main_phase);
372      break;
373
374   default:
375      logerror("%s: fifo_w in phase %d\n", tag(), main_phase);
376      break;
377   }
378}
379
380UINT8 upd765_family_device::do_dir_r()
381{
382   floppy_info &fi = flopi[dor & 3];
383   if(fi.dev)
384      return fi.dev->dskchg_r() ? 0x00 : 0x80;
385   return 0x00;
386}
387
388READ8_MEMBER(upd765_family_device::dir_r)
389{
390   return do_dir_r();
391}
392
393WRITE8_MEMBER(upd765_family_device::ccr_w)
394{
395   dsr = (dsr & 0xfc) | (data & 3);
396   cur_rate = rates[data & 3];
397}
398
399void upd765_family_device::set_drq(bool state)
400{
401   if(state != drq) {
402      drq = state;
403      if(!drq_cb.isnull())
404         drq_cb(drq);
405   }
406}
407
408bool upd765_family_device::get_drq() const
409{
410   return drq;
411}
412
413void upd765_family_device::enable_transfer()
414{
415   if(spec & SPEC_ND) {
416      // PIO
417      if(!internal_drq) {
418         internal_drq = true;
419         check_irq();
420      }
421
422   } else {
423      // DMA
424      if(!drq)
425         set_drq(true);
426   }
427}
428
429void upd765_family_device::disable_transfer()
430{
431   if(spec & SPEC_ND) {
432      internal_drq = false;
433      check_irq();
434   } else
435      set_drq(false);
436}
437
438void upd765_family_device::fifo_push(UINT8 data, bool internal)
439{
440   if(fifo_pos == 16) {
441      if(internal) {
442         if(!(st1 & ST1_OR))
443            logerror("%s: Fifo overrun\n", tag());
444         st1 |= ST1_OR;
445      }
446      return;
447   }
448   fifo[fifo_pos++] = data;
449   fifo_expected--;
450
451   int thr = (fifocfg & FIF_THR)+1;
452   if(!fifo_write && (!fifo_expected || fifo_pos >= thr || (fifocfg & FIF_DIS)))
453      enable_transfer();
454   if(fifo_write && (fifo_pos == 16 || !fifo_expected))
455      disable_transfer();
456}
457
458
459UINT8 upd765_family_device::fifo_pop(bool internal)
460{
461   if(!fifo_pos) {
462      if(internal) {
463         if(!(st1 & ST1_OR))
464            logerror("%s: Fifo underrun\n", tag());
465         st1 |= ST1_OR;
466      }
467      return 0;
468   }
469   UINT8 r = fifo[0];
470   fifo_pos--;
471   memmove(fifo, fifo+1, fifo_pos);
472   if(!fifo_write && !fifo_pos)
473      disable_transfer();
474   int thr = fifocfg & 15;
475   if(fifo_write && fifo_expected && (fifo_pos <= thr || (fifocfg & 0x20)))
476      enable_transfer();
477   return r;
478}
479
480void upd765_family_device::fifo_expect(int size, bool write)
481{
482   fifo_expected = size;
483   fifo_write = write;
484   if(fifo_write)
485      enable_transfer();
486}
487
488READ8_MEMBER(upd765_family_device::mdma_r)
489{
490   return dma_r();
491}
492
493WRITE8_MEMBER(upd765_family_device::mdma_w)
494{
495   dma_w(data);
496}
497
498UINT8 upd765_family_device::dma_r()
499{
500   return fifo_pop(false);
501}
502
503void upd765_family_device::dma_w(UINT8 data)
504{
505   fifo_push(data, false);
506}
507
508void upd765_family_device::live_start(floppy_info &fi, int state)
509{
510   cur_live.tm = machine().time();
511   cur_live.state = state;
512   cur_live.next_state = -1;
513   cur_live.fi = &fi;
514   cur_live.shift_reg = 0;
515   cur_live.crc = 0xffff;
516   cur_live.bit_counter = 0;
517   cur_live.data_separator_phase = false;
518   cur_live.data_reg = 0;
519   cur_live.previous_type = live_info::PT_NONE;
520   cur_live.data_bit_context = false;
521   cur_live.byte_counter = 0;
522   cur_live.pll.reset(cur_live.tm);
523   cur_live.pll.set_clock(attotime::from_hz(mfm ? 2*cur_rate : cur_rate));
524   checkpoint_live = cur_live;
525   fi.live = true;
526
527   live_run();
528}
529
530void upd765_family_device::checkpoint()
531{
532   if(cur_live.fi)
533      cur_live.pll.commit(cur_live.fi->dev, cur_live.tm);
534   checkpoint_live = cur_live;
535}
536
537void upd765_family_device::rollback()
538{
539   cur_live = checkpoint_live;
540}
541
542void upd765_family_device::live_delay(int state)
543{
544   cur_live.next_state = state;
545   if(cur_live.tm != machine().time())
546      cur_live.fi->tm->adjust(cur_live.tm - machine().time());
547   else
548      live_sync();
549}
550
551void upd765_family_device::live_sync()
552{
553   if(!cur_live.tm.is_never()) {
554      if(cur_live.tm > machine().time()) {
555         rollback();
556         live_run(machine().time());
557         cur_live.pll.commit(cur_live.fi->dev, cur_live.tm);
558      } else {
559         cur_live.pll.commit(cur_live.fi->dev, cur_live.tm);
560         if(cur_live.next_state != -1) {
561            cur_live.state = cur_live.next_state;
562            cur_live.next_state = -1;
563         }
564         if(cur_live.state == IDLE) {
565            cur_live.pll.stop_writing(cur_live.fi->dev, cur_live.tm);
566            cur_live.tm = attotime::never;
567            cur_live.fi->live = false;
568            cur_live.fi = 0;
569         }
570      }
571      cur_live.next_state = -1;
572      checkpoint();
573   }
574}
575
576void upd765_family_device::live_abort()
577{
578   if(!cur_live.tm.is_never() && cur_live.tm > machine().time()) {
579      rollback();
580      live_run(machine().time());
581   }
582
583   if(cur_live.fi) {
584      cur_live.pll.stop_writing(cur_live.fi->dev, cur_live.tm);
585      cur_live.fi->live = false;
586      cur_live.fi = 0;
587   }
588
589   cur_live.tm = attotime::never;
590   cur_live.state = IDLE;
591   cur_live.next_state = -1;
592}
593
594void upd765_family_device::live_run(attotime limit)
595{
596   if(cur_live.state == IDLE || cur_live.next_state != -1)
597      return;
598
599   if(limit == attotime::never) {
600      if(cur_live.fi->dev)
601         limit = cur_live.fi->dev->time_next_index();
602      if(limit == attotime::never) {
603         // Happens when there's no disk or if the fdc is not
604         // connected to a drive, hence no index pulse. Force a
605         // sync from time to time in that case, so that the main
606         // cpu timeout isn't too painful.  Avoids looping into
607         // infinity looking for data too.
608
609         limit = machine().time() + attotime::from_msec(1);
610         cur_live.fi->tm->adjust(attotime::from_msec(1));
611      }
612   }
613
614   for(;;) {
615
616      switch(cur_live.state) {
617      case SEARCH_ADDRESS_MARK_HEADER:
618         if(read_one_bit(limit))
619            return;
620#if 0
621         fprintf(stderr, "%s: shift = %04x data=%02x c=%d\n", tts(cur_live.tm).cstr(), cur_live.shift_reg,
622               (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) |
623               (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) |
624               (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) |
625               (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) |
626               (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) |
627               (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) |
628               (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) |
629               (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00),
630               cur_live.bit_counter);
631#endif
632
633         if(mfm && cur_live.shift_reg == 0x4489) {
634            cur_live.crc = 0x443b;
635            cur_live.data_separator_phase = false;
636            cur_live.bit_counter = 0;
637            cur_live.state = READ_HEADER_BLOCK_HEADER;
638         }
639
640         if(!mfm && cur_live.shift_reg == 0xf57e) {
641            cur_live.crc = 0xef21;
642            cur_live.data_separator_phase = false;
643            cur_live.bit_counter = 0;
644            cur_live.state = READ_ID_BLOCK;
645         }
646         break;
647
648      case READ_HEADER_BLOCK_HEADER: {
649         if(read_one_bit(limit))
650            return;
651#if 0
652         fprintf(stderr, "%s: shift = %04x data=%02x counter=%d\n", tts(cur_live.tm).cstr(), cur_live.shift_reg,
653               (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) |
654               (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) |
655               (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) |
656               (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) |
657               (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) |
658               (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) |
659               (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) |
660               (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00),
661               cur_live.bit_counter);
662#endif
663         if(cur_live.bit_counter & 15)
664            break;
665
666         int slot = cur_live.bit_counter >> 4;
667
668         if(slot < 3) {
669            if(cur_live.shift_reg != 0x4489)
670               cur_live.state = SEARCH_ADDRESS_MARK_HEADER;
671            break;
672         }
673         if(cur_live.data_reg != 0xfe) {
674            cur_live.state = SEARCH_ADDRESS_MARK_HEADER;
675            break;
676         }
677
678         cur_live.bit_counter = 0;
679         cur_live.state = READ_ID_BLOCK;
680
681         break;
682      }
683
684      case READ_ID_BLOCK: {
685         if(read_one_bit(limit))
686            return;
687         if(cur_live.bit_counter & 15)
688            break;
689         int slot = (cur_live.bit_counter >> 4)-1;
690
691         if(0)
692            fprintf(stderr, "%s: slot=%d data=%02x crc=%04x\n", tts(cur_live.tm).cstr(), slot, cur_live.data_reg, cur_live.crc);
693         cur_live.idbuf[slot] = cur_live.data_reg;
694         if(slot == 5) {
695            live_delay(IDLE);
696            return;
697         }
698         break;
699      }
700
701      case SEARCH_ADDRESS_MARK_DATA:
702         if(read_one_bit(limit))
703            return;
704#if 0
705         fprintf(stderr, "%s: shift = %04x data=%02x c=%d.%x\n", tts(cur_live.tm).cstr(), cur_live.shift_reg,
706               (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) |
707               (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) |
708               (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) |
709               (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) |
710               (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) |
711               (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) |
712               (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) |
713               (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00),
714               cur_live.bit_counter >> 4, cur_live.bit_counter & 15);
715#endif
716
717         if(mfm) {
718            // Large tolerance due to perpendicular recording at extended density
719            if(cur_live.bit_counter > 62*16) {
720               live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED);
721               return;
722            }
723
724            if(cur_live.bit_counter >= 28*16 && cur_live.shift_reg == 0x4489) {
725               cur_live.crc = 0x443b;
726               cur_live.data_separator_phase = false;
727               cur_live.bit_counter = 0;
728               cur_live.state = READ_DATA_BLOCK_HEADER;
729            }
730
731         } else {
732            if(cur_live.bit_counter > 23*16) {
733               live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED);
734               return;
735            }
736
737            if(cur_live.bit_counter >= 11*16 && (cur_live.shift_reg == 0xf56a || cur_live.shift_reg == 0xf56f)) {
738               cur_live.crc = cur_live.shift_reg == 0xf56a ? 0x8fe7 : 0xbf84;
739               cur_live.data_separator_phase = false;
740               cur_live.bit_counter = 0;
741               cur_live.state = READ_SECTOR_DATA;
742            }
743         }
744
745         break;
746
747      case READ_DATA_BLOCK_HEADER: {
748         if(read_one_bit(limit))
749            return;
750#if 0
751         fprintf(stderr, "%s: shift = %04x data=%02x counter=%d\n", tts(cur_live.tm).cstr(), cur_live.shift_reg,
752               (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) |
753               (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) |
754               (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) |
755               (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) |
756               (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) |
757               (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) |
758               (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) |
759               (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00),
760               cur_live.bit_counter);
761#endif
762         if(cur_live.bit_counter & 15)
763            break;
764
765         int slot = cur_live.bit_counter >> 4;
766
767         if(slot < 3) {
768            if(cur_live.shift_reg != 0x4489) {
769               live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED);
770               return;
771            }
772            break;
773         }
774         if(cur_live.data_reg != 0xfb && cur_live.data_reg != 0xf8) {
775            live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED);
776            return;
777         }
778
779         cur_live.bit_counter = 0;
780         cur_live.state = READ_SECTOR_DATA;
781         break;
782      }
783
784      case SEARCH_ADDRESS_MARK_DATA_FAILED:
785         st1 |= ST1_MA;
786         st2 |= ST2_MD;
787         cur_live.state = IDLE;
788         return;
789
790      case READ_SECTOR_DATA: {
791         if(read_one_bit(limit))
792            return;
793         if(cur_live.bit_counter & 15)
794            break;
795         int slot = (cur_live.bit_counter >> 4)-1;
796         if(slot < sector_size) {
797            // Sector data
798            live_delay(READ_SECTOR_DATA_BYTE);
799            return;
800
801         } else if(slot < sector_size+2) {
802            // CRC
803            if(slot == sector_size+1) {
804               live_delay(IDLE);
805               return;
806            }
807         }
808         break;
809      }
810
811      case READ_SECTOR_DATA_BYTE:
812         if(!tc_done)
813            fifo_push(cur_live.data_reg, true);
814         cur_live.state = READ_SECTOR_DATA;
815         checkpoint();
816         break;
817
818      case WRITE_SECTOR_SKIP_GAP2:
819         cur_live.bit_counter = 0;
820         cur_live.byte_counter = 0;
821         cur_live.state = WRITE_SECTOR_SKIP_GAP2_BYTE;
822         checkpoint();
823         break;
824
825      case WRITE_SECTOR_SKIP_GAP2_BYTE:
826         if(read_one_bit(limit))
827            return;
828         if(mfm && cur_live.bit_counter != 22*16)
829            break;
830         if(!mfm && cur_live.bit_counter != 11*16)
831            break;
832         cur_live.bit_counter = 0;
833         cur_live.byte_counter = 0;
834         live_delay(WRITE_SECTOR_DATA);
835         return;
836
837      case WRITE_SECTOR_DATA:
838         if(mfm) {
839            if(cur_live.byte_counter < 12)
840               live_write_mfm(0x00);
841            else if(cur_live.byte_counter < 15)
842               live_write_raw(0x4489);
843            else if(cur_live.byte_counter < 16) {
844               cur_live.crc = 0xcdb4;
845               live_write_mfm(command[0] & 0x08 ? 0xf8 : 0xfb);
846            } else if(cur_live.byte_counter < 16+sector_size)
847               live_write_mfm(tc_done && !fifo_pos? 0x00 : fifo_pop(true));
848            else if(cur_live.byte_counter < 16+sector_size+2)
849               live_write_mfm(cur_live.crc >> 8);
850            else if(cur_live.byte_counter < 16+sector_size+2+command[7])
851               live_write_mfm(0x4e);
852            else {
853               cur_live.pll.stop_writing(cur_live.fi->dev, cur_live.tm);
854               cur_live.state = IDLE;
855               return;
856            }
857
858         } else {
859            if(cur_live.byte_counter < 6)
860               live_write_fm(0x00);
861            else if(cur_live.byte_counter < 7) {
862               cur_live.crc = 0xffff;
863               live_write_raw(command[0] & 0x08 ? 0xf56a : 0xf56f);
864            } else if(cur_live.byte_counter < 7+sector_size)
865               live_write_fm(tc_done && !fifo_pos? 0x00 : fifo_pop(true));
866            else if(cur_live.byte_counter < 7+sector_size+2)
867               live_write_fm(cur_live.crc >> 8);
868            else if(cur_live.byte_counter < 7+sector_size+2+command[7])
869               live_write_fm(0xff);
870            else {
871               cur_live.pll.stop_writing(cur_live.fi->dev, cur_live.tm);
872               cur_live.state = IDLE;
873               return;
874            }
875         }
876         cur_live.state = WRITE_SECTOR_DATA_BYTE;
877         cur_live.bit_counter = 16;
878         checkpoint();
879         break;
880
881      case WRITE_TRACK_PRE_SECTORS:
882         if(!cur_live.byte_counter && command[3])
883            fifo_expect(4, true);
884         if(mfm) {
885            if(cur_live.byte_counter < 80)
886               live_write_mfm(0x4e);
887            else if(cur_live.byte_counter < 92)
888               live_write_mfm(0x00);
889            else if(cur_live.byte_counter < 95)
890               live_write_raw(0x5224);
891            else if(cur_live.byte_counter < 96)
892               live_write_mfm(0xfc);
893            else if(cur_live.byte_counter < 146)
894               live_write_mfm(0x4e);
895            else {
896               cur_live.state = WRITE_TRACK_SECTOR;
897               cur_live.byte_counter = 0;
898               break;
899            }
900         } else {
901            if(cur_live.byte_counter < 40)
902               live_write_fm(0xff);
903            else if(cur_live.byte_counter < 46)
904               live_write_fm(0x00);
905            else if(cur_live.byte_counter < 47)
906               live_write_raw(0xf77a);
907            else if(cur_live.byte_counter < 73)
908               live_write_fm(0xff);
909            else {
910               cur_live.state = WRITE_TRACK_SECTOR;
911               cur_live.byte_counter = 0;
912               break;
913            }
914         }
915         cur_live.state = WRITE_TRACK_PRE_SECTORS_BYTE;
916         cur_live.bit_counter = 16;
917         checkpoint();
918         break;
919
920      case WRITE_TRACK_SECTOR:
921         if(!cur_live.byte_counter) {
922            command[3]--;
923            if(command[3])
924               fifo_expect(4, true);
925         }
926         if(mfm) {
927            if(cur_live.byte_counter < 12)
928               live_write_mfm(0x00);
929            else if(cur_live.byte_counter < 15)
930               live_write_raw(0x4489);
931            else if(cur_live.byte_counter < 16) {
932               cur_live.crc = 0xcdb4;
933               live_write_mfm(0xfe);
934            } else if(cur_live.byte_counter < 20)
935               live_write_mfm(fifo_pop(true));
936            else if(cur_live.byte_counter < 22)
937               live_write_mfm(cur_live.crc >> 8);
938            else if(cur_live.byte_counter < 44)
939               live_write_mfm(0x4e);
940            else if(cur_live.byte_counter < 56)
941               live_write_mfm(0x00);
942            else if(cur_live.byte_counter < 59)
943               live_write_raw(0x4489);
944            else if(cur_live.byte_counter < 60) {
945               cur_live.crc = 0xcdb4;
946               live_write_mfm(0xfb);
947            } else if(cur_live.byte_counter < 60+sector_size)
948               live_write_mfm(command[5]);
949            else if(cur_live.byte_counter < 62+sector_size)
950               live_write_mfm(cur_live.crc >> 8);
951            else if(cur_live.byte_counter < 62+sector_size+command[4])
952               live_write_mfm(0x4e);
953            else {
954               cur_live.byte_counter = 0;
955               cur_live.state = command[3] ? WRITE_TRACK_SECTOR : WRITE_TRACK_POST_SECTORS;
956               break;
957            }
958
959         } else {
960            if(cur_live.byte_counter < 6)
961               live_write_fm(0x00);
962            else if(cur_live.byte_counter < 7) {
963               cur_live.crc = 0xffff;
964               live_write_raw(0xf57e);
965            } else if(cur_live.byte_counter < 11)
966               live_write_fm(fifo_pop(true));
967            else if(cur_live.byte_counter < 13)
968               live_write_fm(cur_live.crc >> 8);
969            else if(cur_live.byte_counter < 24)
970               live_write_fm(0xff);
971            else if(cur_live.byte_counter < 30)
972               live_write_fm(0x00);
973            else if(cur_live.byte_counter < 31) {
974               cur_live.crc = 0xffff;
975               live_write_raw(0xf56f);
976            } else if(cur_live.byte_counter < 31+sector_size)
977               live_write_fm(command[5]);
978            else if(cur_live.byte_counter < 33+sector_size)
979               live_write_fm(cur_live.crc >> 8);
980            else if(cur_live.byte_counter < 33+sector_size+command[4])
981               live_write_fm(0xff);
982            else {
983               cur_live.byte_counter = 0;
984               cur_live.state = command[3] ? WRITE_TRACK_SECTOR : WRITE_TRACK_POST_SECTORS;
985               break;
986            }
987         }
988         cur_live.state = WRITE_TRACK_SECTOR_BYTE;
989         cur_live.bit_counter = 16;
990         checkpoint();
991         break;
992
993      case WRITE_TRACK_POST_SECTORS:
994         if(mfm)
995            live_write_mfm(0x4e);
996         else
997            live_write_fm(0xff);
998         cur_live.state = WRITE_TRACK_POST_SECTORS_BYTE;
999         cur_live.bit_counter = 16;
1000         checkpoint();
1001         break;
1002
1003      case WRITE_TRACK_PRE_SECTORS_BYTE:
1004      case WRITE_TRACK_SECTOR_BYTE:
1005      case WRITE_TRACK_POST_SECTORS_BYTE:
1006      case WRITE_SECTOR_DATA_BYTE:
1007         if(write_one_bit(limit))
1008            return;
1009         if(cur_live.bit_counter == 0) {
1010            cur_live.byte_counter++;
1011            live_delay(cur_live.state-1);
1012            return;
1013         }
1014         break;
1015
1016      default:
1017         logerror("%s: Unknown live state %d\n", tts(cur_live.tm).cstr(), cur_live.state);
1018         return;
1019      }
1020   }
1021}
1022
1023int upd765_family_device::check_command()
1024{
1025   // 0.000010 read track
1026   // 00000011 specify
1027   // 00000100 sense drive status
1028   // ..000101 write data
1029   // ...00110 read data
1030   // 00000111 recalibrate
1031   // 00001000 sense interrupt status
1032   // ..001001 write deleted data
1033   // 0.001010 read id
1034   // ...01100 read deleted data
1035   // 0.001101 format track
1036   // 00001110 dumpreg
1037   // 00101110 save
1038   // 01001110 restore
1039   // 10001110 drive specification command
1040   // 00001111 seek
1041   // 1.001111 relative seek
1042   // 00010000 version
1043   // ...10001 scan equal
1044   // 00010010 perpendicular mode
1045   // 00010011 configure
1046   // 00110011 option
1047   // .0010100 lock
1048   // ...10110 verify
1049   // 00010111 powerdown mode
1050   // 00011000 part id
1051   // ...11001 scan low or equal
1052   // ...11101 scan high or equal
1053
1054   // MSDOS 6.22 format uses 0xcd to format a track, which makes one
1055   // think only the bottom 5 bits are decoded.
1056
1057   switch(command[0] & 0x1f) {
1058   case 0x02:
1059      return command_pos == 9 ? C_READ_TRACK         : C_INCOMPLETE;
1060
1061   case 0x03:
1062      return command_pos == 3 ? C_SPECIFY            : C_INCOMPLETE;
1063
1064   case 0x04:
1065      return command_pos == 2 ? C_SENSE_DRIVE_STATUS : C_INCOMPLETE;
1066
1067   case 0x05:
1068   case 0x09:
1069      return command_pos == 9 ? C_WRITE_DATA         : C_INCOMPLETE;
1070
1071   case 0x06:
1072   case 0x0c:
1073      return command_pos == 9 ? C_READ_DATA          : C_INCOMPLETE;
1074
1075   case 0x07:
1076      return command_pos == 2 ? C_RECALIBRATE        : C_INCOMPLETE;
1077
1078   case 0x08:
1079      return C_SENSE_INTERRUPT_STATUS;
1080
1081   case 0x0a:
1082      return command_pos == 2 ? C_READ_ID            : C_INCOMPLETE;
1083
1084   case 0x0d:
1085      return command_pos == 6 ? C_FORMAT_TRACK       : C_INCOMPLETE;
1086
1087   case 0x0e:
1088      return C_DUMP_REG;
1089
1090   case 0x0f:
1091      return command_pos == 3 ? C_SEEK               : C_INCOMPLETE;
1092
1093   case 0x12:
1094      return command_pos == 2 ? C_PERPENDICULAR      : C_INCOMPLETE;
1095
1096   case 0x13:
1097      return command_pos == 4 ? C_CONFIGURE          : C_INCOMPLETE;
1098
1099   case 0x14:
1100      return C_LOCK;
1101
1102   default:
1103      return C_INVALID;
1104   }
1105}
1106
1107void upd765_family_device::start_command(int cmd)
1108{
1109   command_pos = 0;
1110   result_pos = 0;
1111   main_phase = PHASE_EXEC;
1112   tc_done = false;
1113   switch(cmd) {
1114   case C_CONFIGURE:
1115      logerror("%s: command configure %02x %02x %02x\n",
1116             tag(),
1117             command[1], command[2], command[3]);
1118      // byte 1 is ignored, byte 3 is precompensation-related
1119      fifocfg = command[2];
1120      precomp = command[3];
1121      main_phase = PHASE_CMD;
1122      break;
1123
1124   case C_DUMP_REG:
1125      logerror("%s: command dump regs\n", tag());
1126      main_phase = PHASE_RESULT;
1127      result[0] = flopi[0].pcn;
1128      result[1] = flopi[1].pcn;
1129      result[2] = flopi[2].pcn;
1130      result[3] = flopi[3].pcn;
1131      result[4] = (spec & 0xff00) >> 8;
1132      result[5] = (spec & 0x00ff);
1133      result[6] = sector_size;
1134      result[7] = locked ? 0x80 : 0x00;
1135      result[7] |= (perpmode & 0x30);
1136      result[8] = fifocfg;
1137      result[9] = precomp;
1138      result_pos = 10;
1139      break;
1140
1141   case C_FORMAT_TRACK:
1142      format_track_start(flopi[command[1] & 3]);
1143      break;
1144
1145   case C_LOCK:
1146      locked = command[0] & 0x80;
1147      main_phase = PHASE_RESULT;
1148      result[0] = locked ? 0x10 : 0x00;
1149      result_pos = 1;
1150      logerror("%s: command lock (%s)\n", tag(), locked ? "on" : "off");
1151      break;
1152
1153   case C_PERPENDICULAR:
1154      logerror("%s: command perpendicular\n", tag());
1155      perpmode = command[1];
1156      main_phase = PHASE_CMD;
1157      break;
1158
1159   case C_READ_DATA:
1160      read_data_start(flopi[command[1] & 3]);
1161      break;
1162
1163   case C_READ_ID:
1164      read_id_start(flopi[command[1] & 3]);
1165      break;
1166
1167   case C_READ_TRACK:
1168      read_track_start(flopi[command[1] & 3]);
1169      break;
1170
1171   case C_RECALIBRATE:
1172      recalibrate_start(flopi[command[1] & 3]);
1173      main_phase = PHASE_CMD;
1174      break;
1175
1176   case C_SEEK:
1177      seek_start(flopi[command[1] & 3]);
1178      main_phase = PHASE_CMD;
1179      break;
1180
1181   case C_SENSE_DRIVE_STATUS: {
1182      floppy_info &fi = flopi[command[1] & 3];
1183      main_phase = PHASE_RESULT;
1184      result[0] = 0x08;
1185      if(fi.ready)
1186         result[0] |= 0x20;
1187      if(fi.dev)
1188         result[0] |=
1189            (fi.dev->wpt_r() ? 0x40 : 0x00) |
1190            (fi.dev->trk00_r() ? 0x00 : 0x10) |
1191            (fi.dev->ss_r() ? 0x04 : 0x00) |
1192            (command[1] & 3);
1193      logerror("%s: command sense drive status (%02x)\n", tag(), result[0]);
1194      result_pos = 1;
1195      break;
1196   }
1197
1198   case C_SENSE_INTERRUPT_STATUS: {
1199      main_phase = PHASE_RESULT;
1200
1201      int fid;
1202      for(fid=0; fid<4 && flopi[fid].irq == floppy_info::IRQ_NONE; fid++);
1203      if(fid == 4) {
1204         st0 = ST0_UNK;
1205         result[0] = st0;
1206         result_pos = 1;
1207         logerror("%s: command sense interrupt status (%02x)\n", tag(), result[0]);
1208         break;
1209      }
1210      floppy_info &fi = flopi[fid];
1211      if(fi.irq == floppy_info::IRQ_POLLED) {
1212         // Documentation is somewhat contradictory w.r.t polling
1213         // and irq.  PC bios, especially 5150, requires that only
1214         // one irq happens.  That's also wait the ns82077a doc
1215         // says it does.  OTOH, a number of docs says you need to
1216         // call SIS 4 times, once per drive...
1217         //
1218         // There's also the interaction with the seek irq.  The
1219         // somewhat borderline tf20 code seems to think that
1220         // essentially ignoring the polling irq should work.
1221         //
1222         // So at that point the best bet seems to drop the
1223         // "polled" irq as soon as a SIS happens, and override any
1224         // polled-in-waiting information when a seek irq happens
1225         // for a given floppy.
1226
1227         st0 = ST0_ABRT | fid;
1228      }
1229      fi.irq = floppy_info::IRQ_NONE;
1230
1231      polled_irq = false;
1232
1233      result[0] = st0;
1234      result[1] = fi.pcn;
1235      logerror("%s: command sense interrupt status (fid=%d %02x %02x)\n", tag(), fid, result[0], result[1]);
1236      result_pos = 2;
1237
1238      check_irq();
1239      break;
1240   }
1241
1242   case C_SPECIFY:
1243      logerror("%s: command specify %02x %02x\n",
1244             tag(),
1245             command[1], command[2]);
1246      spec = (command[1] << 8) | command[2];
1247      main_phase = PHASE_CMD;
1248      break;
1249
1250   case C_WRITE_DATA:
1251      write_data_start(flopi[command[1] & 3]);
1252      break;
1253
1254   default:
1255      fprintf(stderr, "start command %d\n", cmd);
1256      exit(1);
1257   }
1258}
1259
1260void upd765_family_device::command_end(floppy_info &fi, bool data_completion)
1261{
1262   logerror("%s: command done (%s) -", tag(), data_completion ? "data" : "seek");
1263   for(int i=0; i != result_pos; i++)
1264      logerror(" %02x", result[i]);
1265   logerror("\n");
1266   fi.main_state = fi.sub_state = IDLE;
1267   if(data_completion)
1268      data_irq = true;
1269   else
1270      fi.irq = floppy_info::IRQ_SEEK;
1271   check_irq();
1272}
1273
1274void upd765_family_device::recalibrate_start(floppy_info &fi)
1275{
1276   logerror("%s: command recalibrate\n", tag());
1277   fi.main_state = RECALIBRATE;
1278   fi.sub_state = SEEK_WAIT_STEP_TIME_DONE;
1279   fi.dir = 1;
1280   fi.counter = 77;
1281   seek_continue(fi);
1282}
1283
1284void upd765_family_device::seek_start(floppy_info &fi)
1285{
1286   logerror("%s: command %sseek %d\n", tag(), command[0] & 0x80 ? "relative " : "", command[2]);
1287   fi.main_state = SEEK;
1288   fi.sub_state = SEEK_WAIT_STEP_TIME_DONE;
1289   fi.dir = fi.pcn > command[2] ? 1 : 0;
1290   seek_continue(fi);
1291}
1292
1293void upd765_family_device::delay_cycles(emu_timer *tm, int cycles)
1294{
1295   tm->adjust(attotime::from_double(double(cycles)/cur_rate));
1296}
1297
1298void upd765_family_device::seek_continue(floppy_info &fi)
1299{
1300   for(;;) {
1301      switch(fi.sub_state) {
1302      case SEEK_MOVE:
1303         if(fi.dev) {
1304            fi.dev->dir_w(fi.dir);
1305            fi.dev->stp_w(0);
1306         }
1307         fi.sub_state = SEEK_WAIT_STEP_SIGNAL_TIME;
1308         fi.tm->adjust(attotime::from_nsec(2500));
1309         return;
1310
1311      case SEEK_WAIT_STEP_SIGNAL_TIME:
1312         return;
1313
1314      case SEEK_WAIT_STEP_SIGNAL_TIME_DONE:
1315         if(fi.dev)
1316            fi.dev->stp_w(1);
1317
1318         if(fi.main_state == SEEK) {
1319            if(fi.pcn > command[2])
1320               fi.pcn--;
1321            else
1322               fi.pcn++;
1323         }
1324         fi.sub_state = SEEK_WAIT_STEP_TIME;
1325         delay_cycles(fi.tm, 500*(16-(spec >> 12)));
1326         return;
1327
1328      case SEEK_WAIT_STEP_TIME:
1329         return;
1330
1331      case SEEK_WAIT_STEP_TIME_DONE: {
1332         bool done = false;
1333         switch(fi.main_state) {
1334         case RECALIBRATE:
1335            fi.counter--;
1336            done = !fi.dev || !fi.dev->trk00_r();
1337            if(done)
1338               fi.pcn = 0;
1339            else if(!fi.counter) {
1340               st0 = ST0_FAIL|ST0_SE|ST0_EC;
1341               command_end(fi, false);
1342               return;
1343            }
1344            break;
1345         case SEEK:
1346            done = fi.pcn == command[2];
1347            break;
1348         }
1349         if(done) {
1350            st0 = ST0_SE;
1351            command_end(fi, false);
1352            return;
1353         }
1354         fi.sub_state = SEEK_MOVE;
1355         break;
1356      }
1357      }
1358   }
1359}
1360
1361void upd765_family_device::read_data_start(floppy_info &fi)
1362{
1363   fi.main_state = READ_DATA;
1364   fi.sub_state = HEAD_LOAD_DONE;
1365   mfm = command[0] & 0x40;
1366
1367   logerror("%s: command read%s data%s%s%s%s cmd=%02x sel=%x chrn=(%d, %d, %d, %d) eot=%02x gpl=%02x dtl=%02x rate=%d\n",
1368          tag(),
1369          command[0] & 0x08 ? " deleted" : "",
1370          command[0] & 0x80 ? " mt" : "",
1371          command[0] & 0x40 ? " mfm" : "",
1372          command[0] & 0x20 ? " sk" : "",
1373          fifocfg & 0x40 ? " seek" : "",
1374          command[0],
1375          command[1],
1376          command[2],
1377          command[3],
1378          command[4],
1379          128 << (command[5] & 7),
1380          command[6],
1381          command[7],
1382          command[8],
1383          cur_rate);
1384
1385   st0 = command[1] & 7;
1386   st1 = ST1_MA;
1387   st2 = 0x00;
1388
1389   if(fi.dev)
1390      fi.dev->ss_w(command[1] & 4 ? 1 : 0);
1391   read_data_continue(fi);
1392}
1393
1394void upd765_family_device::read_data_continue(floppy_info &fi)
1395{
1396   for(;;) {
1397      switch(fi.sub_state) {
1398      case HEAD_LOAD_DONE:
1399         if(fi.pcn == command[2] || !(fifocfg & 0x40)) {
1400            fi.sub_state = SEEK_DONE;
1401            break;
1402         }
1403         st0 |= ST0_SE;
1404         if(fi.dev) {
1405            fi.dev->dir_w(fi.pcn > command[2] ? 1 : 0);
1406            fi.dev->stp_w(0);
1407         }
1408         fi.sub_state = SEEK_WAIT_STEP_SIGNAL_TIME;
1409         fi.tm->adjust(attotime::from_nsec(2500));
1410         return;
1411
1412      case SEEK_WAIT_STEP_SIGNAL_TIME:
1413         return;
1414
1415      case SEEK_WAIT_STEP_SIGNAL_TIME_DONE:
1416         if(fi.dev)
1417            fi.dev->stp_w(1);
1418
1419         fi.sub_state = SEEK_WAIT_STEP_TIME;
1420         delay_cycles(fi.tm, 500*(16-(spec >> 12)));
1421         return;
1422
1423      case SEEK_WAIT_STEP_TIME:
1424         return;
1425
1426      case SEEK_WAIT_STEP_TIME_DONE:
1427         if(fi.pcn > command[2])
1428            fi.pcn--;
1429         else
1430            fi.pcn++;
1431         fi.sub_state = HEAD_LOAD_DONE;
1432         break;
1433
1434      case SEEK_DONE:
1435         fi.counter = 0;
1436         fi.sub_state = SCAN_ID;
1437         live_start(fi, SEARCH_ADDRESS_MARK_HEADER);
1438         return;
1439
1440      case SCAN_ID:
1441         if(cur_live.crc) {
1442            st0 |= ST0_FAIL;
1443            st1 |= ST1_DE|ST1_ND;
1444            fi.sub_state = COMMAND_DONE;
1445            break;
1446         }
1447         st1 &= ~ST1_MA;
1448         if(!sector_matches()) {
1449            if(cur_live.idbuf[0] != command[2]) {
1450               if(cur_live.idbuf[0] == 0xff)
1451                  st2 |= ST2_WC|ST2_BC;
1452               else
1453                  st2 |= ST2_WC;
1454               st0 |= ST0_FAIL;
1455               fi.sub_state = COMMAND_DONE;
1456               break;
1457            }
1458            live_start(fi, SEARCH_ADDRESS_MARK_HEADER);
1459            return;
1460         }
1461         logerror("%s: reading sector %02x %02x %02x %02x\n",
1462                tag(),
1463                cur_live.idbuf[0],
1464                cur_live.idbuf[1],
1465                cur_live.idbuf[2],
1466                cur_live.idbuf[3]);
1467         sector_size = calc_sector_size(cur_live.idbuf[3]);
1468         fifo_expect(sector_size, false);
1469         fi.sub_state = SECTOR_READ;
1470         live_start(fi, SEARCH_ADDRESS_MARK_DATA);
1471         return;
1472
1473      case SCAN_ID_FAILED:
1474         st0 |= ST0_FAIL;
1475         st1 |= ST1_ND;
1476         fi.sub_state = COMMAND_DONE;
1477         break;
1478
1479      case SECTOR_READ: {
1480         if(st2 & ST2_MD) {
1481            st0 |= ST0_FAIL;
1482            fi.sub_state = COMMAND_DONE;
1483            break;
1484         }
1485         if(cur_live.crc) {
1486            st0 |= ST0_FAIL;
1487            st1 |= ST1_DE;
1488            st2 |= ST2_CM;
1489            fi.sub_state = COMMAND_DONE;
1490            break;
1491         }
1492         bool done = tc_done;
1493         command[4]++;
1494         if(command[4] > command[6]) {
1495            command[4] = 1;
1496            if(command[0] & 0x80) {
1497               command[3] = command[3] ^ 1;
1498               if(fi.dev)
1499                  fi.dev->ss_w(command[3] & 1);
1500            }
1501            if(!(command[0] & 0x80) || !(command[3] & 1)) {
1502               command[2]++;
1503               if(!tc_done) {
1504                  st0 |= ST0_FAIL;
1505                  st1 |= ST1_EN;
1506               }
1507               done = true;
1508            }
1509         }
1510         if(!done) {
1511            fi.sub_state = SEEK_DONE;
1512            break;
1513         }
1514         fi.sub_state = COMMAND_DONE;
1515         break;
1516      }
1517
1518      case COMMAND_DONE:
1519         main_phase = PHASE_RESULT;
1520         result[0] = st0;
1521         result[1] = st1;
1522         result[2] = st2;
1523         result[3] = command[2];
1524         result[4] = command[3];
1525         result[5] = command[4];
1526         result[6] = command[5];
1527         result_pos = 7;
1528         command_end(fi, true);
1529         return;
1530
1531      default:
1532         logerror("%s: read sector unknown sub-state %d\n", ttsn().cstr(), fi.sub_state);
1533         return;
1534      }
1535   }
1536}
1537
1538void upd765_family_device::write_data_start(floppy_info &fi)
1539{
1540   fi.main_state = WRITE_DATA;
1541   fi.sub_state = HEAD_LOAD_DONE;
1542   mfm = command[0] & 0x40;
1543   logerror("%s: command write%s data%s%s cmd=%02x sel=%x chrn=(%d, %d, %d, %d) eot=%02x gpl=%02x dtl=%02x rate=%d\n",
1544          tag(),
1545          command[0] & 0x08 ? " deleted" : "",
1546          command[0] & 0x80 ? " mt" : "",
1547          command[0] & 0x40 ? " mfm" : "",
1548          command[0],
1549          command[1],
1550          command[2],
1551          command[3],
1552          command[4],
1553          128 << (command[5] & 7),
1554          command[6],
1555          command[7],
1556          command[8],
1557          cur_rate);
1558
1559   if(fi.dev)
1560      fi.dev->ss_w(command[1] & 4 ? 1 : 0);
1561
1562   st0 = command[1] & 7;
1563   st1 = ST1_MA;
1564   st2 = 0x00;
1565
1566   write_data_continue(fi);
1567}
1568
1569void upd765_family_device::write_data_continue(floppy_info &fi)
1570{
1571   for(;;) {
1572      switch(fi.sub_state) {
1573      case HEAD_LOAD_DONE:
1574         fi.counter = 0;
1575         fi.sub_state = SCAN_ID;
1576         live_start(fi, SEARCH_ADDRESS_MARK_HEADER);
1577         return;
1578
1579      case SCAN_ID:
1580         if(!sector_matches()) {
1581            live_start(fi, SEARCH_ADDRESS_MARK_HEADER);
1582            return;
1583         }
1584         if(cur_live.crc) {
1585            st0 |= ST0_FAIL;
1586            st1 |= ST1_DE|ST1_ND;
1587            fi.sub_state = COMMAND_DONE;
1588            break;
1589         }
1590         st1 &= ~ST1_MA;
1591         sector_size = calc_sector_size(cur_live.idbuf[3]);
1592         fifo_expect(sector_size, true);
1593         fi.sub_state = SECTOR_WRITTEN;
1594         live_start(fi, WRITE_SECTOR_SKIP_GAP2);
1595         return;
1596
1597      case SCAN_ID_FAILED:
1598         st0 |= ST0_FAIL;
1599         st1 |= ST1_ND;
1600         fi.sub_state = COMMAND_DONE;
1601         break;
1602
1603      case SECTOR_WRITTEN: {
1604         bool done = tc_done;
1605         command[4]++;
1606         if(command[4] > command[6]) {
1607            command[4] = 1;
1608            if(command[0] & 0x80) {
1609               command[3] = command[3] ^ 1;
1610               if(fi.dev)
1611                  fi.dev->ss_w(command[3] & 1);
1612            }
1613            if(!(command[0] & 0x80) || !(command[3] & 1)) {
1614               command[2]++;
1615               if(!tc_done) {
1616                  st0 |= ST0_FAIL;
1617                  st1 |= ST1_EN;
1618               }
1619               done = true;
1620            }
1621         }
1622         if(!done) {
1623            fi.sub_state = HEAD_LOAD_DONE;
1624            break;
1625         }
1626         fi.sub_state = COMMAND_DONE;
1627         break;
1628      }
1629
1630      case COMMAND_DONE:
1631         main_phase = PHASE_RESULT;
1632         result[0] = st0;
1633         result[1] = st1;
1634         result[2] = st2;
1635         result[3] = command[2];
1636         result[4] = command[3];
1637         result[5] = command[4];
1638         result[6] = command[5];
1639         result_pos = 7;
1640         command_end(fi, true);
1641         return;
1642
1643      default:
1644         logerror("%s: write sector unknown sub-state %d\n", ttsn().cstr(), fi.sub_state);
1645         return;
1646      }
1647   }
1648}
1649
1650void upd765_family_device::read_track_start(floppy_info &fi)
1651{
1652   fi.main_state = READ_TRACK;
1653   fi.sub_state = HEAD_LOAD_DONE;
1654   mfm = command[0] & 0x40;
1655
1656   logerror("%s: command read track%s cmd=%02x sel=%x chrn=(%d, %d, %d, %d) eot=%02x gpl=%02x dtl=%02x rate=%d\n",
1657          tag(),
1658          command[0] & 0x40 ? " mfm" : "",
1659          command[0],
1660          command[1],
1661          command[2],
1662          command[3],
1663          command[4],
1664          128 << (command[5] & 7),
1665          command[6],
1666          command[7],
1667          command[8],
1668          cur_rate);
1669
1670   if(fi.dev)
1671      fi.dev->ss_w(command[1] & 4 ? 1 : 0);
1672   read_track_continue(fi);
1673}
1674
1675void upd765_family_device::read_track_continue(floppy_info &fi)
1676{
1677   for(;;) {
1678      switch(fi.sub_state) {
1679      case HEAD_LOAD_DONE:
1680         if(fi.pcn == command[2] || !(fifocfg & 0x40)) {
1681            fi.sub_state = SEEK_DONE;
1682            break;
1683         }
1684         if(fi.dev) {
1685            fi.dev->dir_w(fi.pcn > command[2] ? 1 : 0);
1686            fi.dev->stp_w(0);
1687         }
1688         fi.sub_state = SEEK_WAIT_STEP_SIGNAL_TIME;
1689         fi.tm->adjust(attotime::from_nsec(2500));
1690         return;
1691
1692      case SEEK_WAIT_STEP_SIGNAL_TIME:
1693         return;
1694
1695      case SEEK_WAIT_STEP_SIGNAL_TIME_DONE:
1696         if(fi.dev)
1697            fi.dev->stp_w(1);
1698
1699         fi.sub_state = SEEK_WAIT_STEP_TIME;
1700         delay_cycles(fi.tm, 500*(16-(spec >> 12)));
1701         return;
1702
1703      case SEEK_WAIT_STEP_TIME:
1704         return;
1705
1706      case SEEK_WAIT_STEP_TIME_DONE:
1707         if(fi.pcn > command[2])
1708            fi.pcn--;
1709         else
1710            fi.pcn++;
1711         fi.sub_state = HEAD_LOAD_DONE;
1712         break;
1713
1714      case SEEK_DONE:
1715         fi.counter = 0;
1716         fi.sub_state = SCAN_ID;
1717         live_start(fi, SEARCH_ADDRESS_MARK_HEADER);
1718         return;
1719
1720      case SCAN_ID:
1721         if(cur_live.crc) {
1722            fprintf(stderr, "Header CRC error\n");
1723            live_start(fi, SEARCH_ADDRESS_MARK_HEADER);
1724            return;
1725         }
1726         sector_size = calc_sector_size(cur_live.idbuf[3]);
1727         fifo_expect(sector_size, false);
1728         fi.sub_state = SECTOR_READ;
1729         live_start(fi, SEARCH_ADDRESS_MARK_DATA);
1730         return;
1731
1732      case SCAN_ID_FAILED:
1733         fprintf(stderr, "RNF\n");
1734         //          command_end(fi, true, 1);
1735         return;
1736
1737      case SECTOR_READ:
1738         if(cur_live.crc) {
1739            fprintf(stderr, "CRC error\n");
1740         }
1741         if(command[4] < command[6]) {
1742            command[4]++;
1743            fi.sub_state = HEAD_LOAD_DONE;
1744            break;
1745         }
1746
1747         main_phase = PHASE_RESULT;
1748         result[0] = 0x40 | (fi.dev->ss_r() << 2) | fi.id;
1749         result[1] = 0;
1750         result[2] = 0;
1751         result[3] = command[2];
1752         result[4] = command[3];
1753         result[5] = command[4];
1754         result[6] = command[5];
1755         result_pos = 7;
1756         //          command_end(fi, true, 0);
1757         return;
1758
1759      default:
1760         logerror("%s: read track unknown sub-state %d\n", ttsn().cstr(), fi.sub_state);
1761         return;
1762      }
1763   }
1764}
1765
1766int upd765_family_device::calc_sector_size(UINT8 size)
1767{
1768   return size > 7 ? 16384 : 128 << size;
1769}
1770
1771void upd765_family_device::format_track_start(floppy_info &fi)
1772{
1773   fi.main_state = FORMAT_TRACK;
1774   fi.sub_state = HEAD_LOAD_DONE;
1775   mfm = command[0] & 0x40;
1776
1777   logerror("%s: command format track %s h=%02x n=%02x sc=%02x gpl=%02x d=%02x\n",
1778          tag(),
1779          command[0] & 0x40 ? "mfm" : "fm",
1780          command[1], command[2], command[3], command[4], command[5]);
1781
1782   if(fi.dev)
1783      fi.dev->ss_w(command[1] & 4 ? 1 : 0);
1784   sector_size = calc_sector_size(command[2]);
1785
1786   format_track_continue(fi);
1787}
1788
1789void upd765_family_device::format_track_continue(floppy_info &fi)
1790{
1791   for(;;) {
1792      switch(fi.sub_state) {
1793      case HEAD_LOAD_DONE:
1794         fi.sub_state = WAIT_INDEX;
1795         break;
1796
1797      case WAIT_INDEX:
1798         return;
1799
1800      case WAIT_INDEX_DONE:
1801         logerror("%s: index found, writing track\n", tag());
1802         fi.sub_state = TRACK_DONE;
1803         cur_live.pll.start_writing(machine().time());
1804         live_start(fi, WRITE_TRACK_PRE_SECTORS);
1805         return;
1806
1807      case TRACK_DONE:
1808         main_phase = PHASE_RESULT;
1809         result[0] = (fi.dev->ss_r() << 2) | fi.id;
1810         result[1] = 0;
1811         result[2] = 0;
1812         result[3] = 0;
1813         result[4] = 0;
1814         result[5] = 0;
1815         result[6] = 0;
1816         result_pos = 7;
1817         command_end(fi, true);
1818         return;
1819
1820      default:
1821         logerror("%s: format track unknown sub-state %d\n", ttsn().cstr(), fi.sub_state);
1822         return;
1823      }
1824   }
1825}
1826
1827void upd765_family_device::read_id_start(floppy_info &fi)
1828{
1829   fi.main_state = READ_ID;
1830   fi.sub_state = HEAD_LOAD_DONE;
1831   mfm = command[0] & 0x40;
1832
1833   logerror("%s: command read id%s, rate=%d\n",
1834          tag(),
1835          command[0] & 0x40 ? " mfm" : "",
1836          cur_rate);
1837
1838   if(fi.dev)
1839      fi.dev->ss_w(command[1] & 4 ? 1 : 0);
1840
1841   st0 = command[1] & 7;
1842   st1 = 0x00;
1843   st2 = 0x00;
1844
1845   for(int i=0; i<4; i++)
1846      cur_live.idbuf[i] = 0x00;
1847
1848   read_id_continue(fi);
1849}
1850
1851void upd765_family_device::read_id_continue(floppy_info &fi)
1852{
1853   for(;;) {
1854      switch(fi.sub_state) {
1855      case HEAD_LOAD_DONE:
1856         fi.counter = 0;
1857         fi.sub_state = SCAN_ID;
1858         live_start(fi, SEARCH_ADDRESS_MARK_HEADER);
1859         return;
1860
1861      case SCAN_ID:
1862         if(cur_live.crc) {
1863            st0 |= ST0_FAIL;
1864            st1 |= ST1_MA|ST1_DE|ST1_ND;
1865         }
1866         fi.sub_state = COMMAND_DONE;
1867         break;
1868
1869      case SCAN_ID_FAILED:
1870         st0 |= ST0_FAIL;
1871         st1 |= ST1_ND|ST1_MA;
1872         fi.sub_state = COMMAND_DONE;
1873         break;
1874
1875      case COMMAND_DONE:
1876         main_phase = PHASE_RESULT;
1877         result[0] = st0;
1878         result[1] = st1;
1879         result[2] = st2;
1880         result[3] = cur_live.idbuf[0];
1881         result[4] = cur_live.idbuf[1];
1882         result[5] = cur_live.idbuf[2];
1883         result[6] = cur_live.idbuf[3];
1884         result_pos = 7;
1885         command_end(fi, true);
1886         return;
1887
1888      default:
1889         logerror("%s: read id unknown sub-state %d\n", ttsn().cstr(), fi.sub_state);
1890         return;
1891      }
1892   }
1893}
1894
1895void upd765_family_device::check_irq()
1896{
1897   bool old_irq = cur_irq;
1898   cur_irq = data_irq || polled_irq || internal_drq;
1899   for(int i=0; i<4; i++)
1900      cur_irq = cur_irq || flopi[i].irq == floppy_info::IRQ_SEEK;
1901   cur_irq = cur_irq && (dor & 4) && (dor & 8);
1902   if(cur_irq != old_irq && !intrq_cb.isnull()) {
1903      logerror("%s: irq = %d\n", tag(), cur_irq);
1904      intrq_cb(cur_irq);
1905   }
1906}
1907
1908bool upd765_family_device::get_irq() const
1909{
1910   return cur_irq;
1911}
1912
1913astring upd765_family_device::tts(attotime t)
1914{
1915   char buf[256];
1916   const char *sign = "";
1917   if(t.seconds < 0) {
1918      t = attotime::zero-t;
1919      sign = "-";
1920   }
1921   int nsec = t.attoseconds / ATTOSECONDS_PER_NANOSECOND;
1922   sprintf(buf, "%s%04d.%03d,%03d,%03d", sign, int(t.seconds), nsec/1000000, (nsec/1000)%1000, nsec % 1000);
1923   return buf;
1924}
1925
1926astring upd765_family_device::ttsn()
1927{
1928   return tts(machine().time());
1929}
1930
1931void upd765_family_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
1932{
1933   if(id == TIMER_DRIVE_READY_POLLING) {
1934      run_drive_ready_polling();
1935      return;
1936   }
1937
1938   live_sync();
1939
1940   floppy_info &fi = flopi[id];
1941   switch(fi.sub_state) {
1942   case SEEK_WAIT_STEP_SIGNAL_TIME:
1943      fi.sub_state = SEEK_WAIT_STEP_SIGNAL_TIME_DONE;
1944      break;
1945   case SEEK_WAIT_STEP_TIME:
1946      fi.sub_state = SEEK_WAIT_STEP_TIME_DONE;
1947      break;
1948   }
1949
1950   general_continue(fi);
1951}
1952
1953void upd765_family_device::run_drive_ready_polling()
1954{
1955   if(main_phase != PHASE_CMD || (fifocfg & FIF_POLL))
1956      return;
1957
1958   bool changed = false;
1959   for(int fid=0; fid<4; fid++) {
1960      bool ready = get_ready(fid);
1961      if(ready != flopi[fid].ready) {
1962         logerror("%s: polled %d : %d -> %d\n", tag(), fid, flopi[fid].ready, ready);
1963         flopi[fid].ready = ready;
1964         if(flopi[fid].irq == floppy_info::IRQ_NONE) {
1965            flopi[fid].irq = floppy_info::IRQ_POLLED;
1966            polled_irq = true;
1967            changed = true;
1968         }
1969      }
1970   }
1971   if(changed)
1972      check_irq();
1973}
1974
1975void upd765_family_device::index_callback(floppy_image_device *floppy, int state)
1976{
1977   for(int fid=0; fid<4; fid++) {
1978      floppy_info &fi = flopi[fid];
1979      if(fi.dev != floppy)
1980         continue;
1981
1982      if(fi.live)
1983         live_sync();
1984      fi.index = state;
1985
1986      if(!state) {
1987         general_continue(fi);
1988         continue;
1989      }
1990
1991      switch(fi.sub_state) {
1992      case IDLE:
1993      case SEEK_MOVE:
1994      case SEEK_WAIT_STEP_SIGNAL_TIME:
1995      case SEEK_WAIT_STEP_SIGNAL_TIME_DONE:
1996      case SEEK_WAIT_STEP_TIME:
1997      case SEEK_WAIT_STEP_TIME_DONE:
1998      case HEAD_LOAD_DONE:
1999      case SCAN_ID_FAILED:
2000      case SECTOR_READ:
2001         break;
2002
2003      case WAIT_INDEX:
2004         fi.sub_state = WAIT_INDEX_DONE;
2005         break;
2006
2007      case SCAN_ID:
2008         fi.counter++;
2009         if(fi.counter == 2) {
2010            fi.sub_state = SCAN_ID_FAILED;
2011            live_abort();
2012         }
2013         break;
2014
2015      case TRACK_DONE:
2016         live_abort();
2017         break;
2018
2019      default:
2020         logerror("%s: Index pulse on unknown sub-state %d\n", ttsn().cstr(), fi.sub_state);
2021         break;
2022      }
2023
2024      general_continue(fi);
2025   }
2026}
2027
2028
2029void upd765_family_device::general_continue(floppy_info &fi)
2030{
2031   if(fi.live && cur_live.state != IDLE) {
2032      live_run();
2033      if(cur_live.state != IDLE)
2034         return;
2035   }
2036
2037   switch(fi.main_state) {
2038   case IDLE:
2039      break;
2040
2041   case RECALIBRATE:
2042   case SEEK:
2043      seek_continue(fi);
2044      break;
2045
2046   case READ_DATA:
2047      read_data_continue(fi);
2048      break;
2049
2050   case WRITE_DATA:
2051      write_data_continue(fi);
2052      break;
2053
2054   case READ_TRACK:
2055      read_track_continue(fi);
2056      break;
2057
2058   case FORMAT_TRACK:
2059      format_track_continue(fi);
2060      break;
2061
2062   case READ_ID:
2063      read_id_continue(fi);
2064      break;
2065
2066   default:
2067      logerror("%s: general_continue on unknown main-state %d\n", ttsn().cstr(), fi.main_state);
2068      break;
2069   }
2070}
2071
2072bool upd765_family_device::read_one_bit(attotime limit)
2073{
2074   int bit = cur_live.pll.get_next_bit(cur_live.tm, cur_live.fi->dev, limit);
2075   if(bit < 0)
2076      return true;
2077   cur_live.shift_reg = (cur_live.shift_reg << 1) | bit;
2078   cur_live.bit_counter++;
2079   if(cur_live.data_separator_phase) {
2080      cur_live.data_reg = (cur_live.data_reg << 1) | bit;
2081      if((cur_live.crc ^ (bit ? 0x8000 : 0x0000)) & 0x8000)
2082         cur_live.crc = (cur_live.crc << 1) ^ 0x1021;
2083      else
2084         cur_live.crc = cur_live.crc << 1;
2085   }
2086   cur_live.data_separator_phase = !cur_live.data_separator_phase;
2087   return false;
2088}
2089
2090bool upd765_family_device::write_one_bit(attotime limit)
2091{
2092   bool bit = cur_live.shift_reg & 0x8000;
2093   if(cur_live.pll.write_next_bit(bit, cur_live.tm, cur_live.fi->dev, limit))
2094      return true;
2095   if(cur_live.bit_counter & 1) {
2096      if((cur_live.crc ^ (bit ? 0x8000 : 0x0000)) & 0x8000)
2097         cur_live.crc = (cur_live.crc << 1) ^ 0x1021;
2098      else
2099         cur_live.crc = cur_live.crc << 1;
2100   }
2101   cur_live.shift_reg = cur_live.shift_reg << 1;
2102   cur_live.bit_counter--;
2103   return false;
2104}
2105
2106void upd765_family_device::live_write_raw(UINT16 raw)
2107{
2108   //  logerror("write %04x %04x\n", raw, cur_live.crc);
2109   cur_live.shift_reg = raw;
2110   cur_live.data_bit_context = raw & 1;
2111}
2112
2113void upd765_family_device::live_write_mfm(UINT8 mfm)
2114{
2115   bool context = cur_live.data_bit_context;
2116   UINT16 raw = 0;
2117   for(int i=0; i<8; i++) {
2118      bool bit = mfm & (0x80 >> i);
2119      if(!(bit || context))
2120         raw |= 0x8000 >> (2*i);
2121      if(bit)
2122         raw |= 0x4000 >> (2*i);
2123      context = bit;
2124   }
2125   cur_live.data_reg = mfm;
2126   cur_live.shift_reg = raw;
2127   cur_live.data_bit_context = context;
2128   //  logerror("write %02x   %04x %04x\n", mfm, cur_live.crc, raw);
2129}
2130
2131void upd765_family_device::live_write_fm(UINT8 fm)
2132{
2133   UINT16 raw = 0xaaaa;
2134   for(int i=0; i<8; i++)
2135      if(fm & (0x80 >> i))
2136         raw |= 0x4000 >> (2*i);
2137   cur_live.data_reg = fm;
2138   cur_live.shift_reg = raw;
2139   cur_live.data_bit_context = fm & 1;
2140   //  logerror("write %02x   %04x %04x\n", fm, cur_live.crc, raw);
2141}
2142
2143bool upd765_family_device::sector_matches() const
2144{
2145   if(0)
2146      logerror("%s: matching %02x %02x %02x %02x - %02x %02x %02x %02x\n", tag(),
2147             cur_live.idbuf[0], cur_live.idbuf[1], cur_live.idbuf[2], cur_live.idbuf[3],
2148             command[2], command[3], command[4], command[5]);
2149   return
2150      cur_live.idbuf[0] == command[2] &&
2151      cur_live.idbuf[1] == command[3] &&
2152      cur_live.idbuf[2] == command[4] &&
2153      cur_live.idbuf[3] == command[5];
2154}
2155
2156void upd765_family_device::pll_t::set_clock(attotime _period)
2157{
2158   period = _period;
2159   period_adjust_base = period * 0.05;
2160   min_period = period * 0.75;
2161   max_period = period * 1.25;
2162}
2163
2164void upd765_family_device::pll_t::reset(attotime when)
2165{
2166   ctime = when;
2167   phase_adjust = attotime::zero;
2168   freq_hist = 0;
2169   write_position = 0;
2170   write_start_time = attotime::never;
2171}
2172
2173void upd765_family_device::pll_t::start_writing(attotime tm)
2174{
2175   write_start_time = tm;
2176   write_position = 0;
2177}
2178
2179void upd765_family_device::pll_t::stop_writing(floppy_image_device *floppy, attotime tm)
2180{
2181   commit(floppy, tm);
2182   write_start_time = attotime::never;
2183}
2184
2185void upd765_family_device::pll_t::commit(floppy_image_device *floppy, attotime tm)
2186{
2187   if(write_start_time.is_never() || tm == write_start_time)
2188      return;
2189
2190   if(floppy)
2191      floppy->write_flux(write_start_time, tm, write_position, write_buffer);
2192   write_start_time = tm;
2193   write_position = 0;
2194}
2195
2196int upd765_family_device::pll_t::get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit)
2197{
2198   attotime edge = floppy ? floppy->get_next_transition(ctime) : attotime::never;
2199
2200   attotime next = ctime + period + phase_adjust;
2201
2202#if 0
2203   if(!edge.is_never())
2204      fprintf(stderr, "ctime=%s, transition_time=%s, next=%s, pha=%s\n", tts(ctime).cstr(), tts(edge).cstr(), tts(next).cstr(), tts(phase_adjust).cstr());
2205#endif
2206
2207   if(next > limit)
2208      return -1;
2209
2210   ctime = next;
2211   tm = next;
2212
2213   if(edge.is_never() || edge >= next) {
2214      // No transition in the window means 0 and pll in free run mode
2215      phase_adjust = attotime::zero;
2216      return 0;
2217   }
2218
2219   // Transition in the window means 1, and the pll is adjusted
2220
2221   attotime delta = edge - (next - period/2);
2222
2223   if(delta.seconds < 0)
2224      phase_adjust = attotime::zero - ((attotime::zero - delta)*65)/100;
2225   else
2226      phase_adjust = (delta*65)/100;
2227
2228   if(delta < attotime::zero) {
2229      if(freq_hist < 0)
2230         freq_hist--;
2231      else
2232         freq_hist = -1;
2233   } else if(delta > attotime::zero) {
2234      if(freq_hist > 0)
2235         freq_hist++;
2236      else
2237         freq_hist = 1;
2238   } else
2239      freq_hist = 0;
2240
2241   if(freq_hist) {
2242      int afh = freq_hist < 0 ? -freq_hist : freq_hist;
2243      if(afh > 1) {
2244         attotime aper = attotime::from_double(period_adjust_base.as_double()*delta.as_double()/period.as_double());
2245         period += aper;
2246
2247         if(period < min_period)
2248            period = min_period;
2249         else if(period > max_period)
2250            period = max_period;
2251      }
2252   }
2253
2254   return 1;
2255}
2256
2257bool upd765_family_device::pll_t::write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit)
2258{
2259   if(write_start_time.is_never()) {
2260      write_start_time = ctime;
2261      write_position = 0;
2262   }
2263
2264   attotime etime = ctime + period;
2265   if(etime > limit)
2266      return true;
2267
2268   if(bit && write_position < ARRAY_LENGTH(write_buffer))
2269      write_buffer[write_position++] = ctime + period/2;
2270
2271   tm = etime;
2272   ctime = etime;
2273   return false;
2274}
2275
2276upd765a_device::upd765a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : upd765_family_device(mconfig, UPD765A, "UPD765A", tag, owner, clock)
2277{
2278   m_shortname = "upd765a";
2279   dor_reset = 0x0c;
2280}
2281
2282upd765b_device::upd765b_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : upd765_family_device(mconfig, UPD765B, "UPD765B", tag, owner, clock)
2283{
2284   m_shortname = "upd765b";
2285   dor_reset = 0x0c;
2286}
2287
2288i8272a_device::i8272a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : upd765_family_device(mconfig, I8272A, "I8272A", tag, owner, clock)
2289{
2290   m_shortname = "i8272a";
2291   dor_reset = 0x0c;
2292}
2293
2294upd72065_device::upd72065_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : upd765_family_device(mconfig, UPD72065, "UPD72065", tag, owner, clock)
2295{
2296   m_shortname = "upd72065";
2297   dor_reset = 0x0c;
2298}
2299
2300smc37c78_device::smc37c78_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : upd765_family_device(mconfig, SMC37C78, "SMC37C78", tag, owner, clock)
2301{
2302   m_shortname = "smc37c78";
2303   ready_connected = false;
2304   select_connected = true;
2305}
2306
2307n82077aa_device::n82077aa_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : upd765_family_device(mconfig, N82077AA, "N82077AA", tag, owner, clock)
2308{
2309   m_shortname = "n82077aa";
2310   ready_connected = false;
2311   select_connected = true;
2312}
2313
2314pc_fdc_superio_device::pc_fdc_superio_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : upd765_family_device(mconfig, PC_FDC_SUPERIO, "PC FDC SUPERIO", tag, owner, clock)
2315{
2316   m_shortname = "pc_fdc_superio";
2317   ready_polled = false;
2318   ready_connected = false;
2319   select_connected = true;
2320}
trunk/src/mess/machine/upd765.h
r19165r19166
1#ifndef __UPD765_F_H__
2#define __UPD765_F_H__
3
4#include "emu.h"
5#include "imagedev/floppy.h"
6
7/*
8 * ready = true if the ready line is physically connected to the floppy drive
9 * select = true if the fdc controls the floppy drive selection
10 * mode = MODE_AT, MODE_PS2 or MODE_M30 for the fdcs that have reset-time selection
11 */
12
13#define MCFG_UPD765A_ADD(_tag, _ready, _select)   \
14   MCFG_DEVICE_ADD(_tag, UPD765A, 0)         \
15   downcast<upd765a_device *>(device)->set_ready_line_connected(_ready);   \
16   downcast<upd765a_device *>(device)->set_select_lines_connected(_select);
17
18#define MCFG_UPD765B_ADD(_tag, _ready, _select)   \
19   MCFG_DEVICE_ADD(_tag, UPD765B, 0)         \
20   downcast<upd765b_device *>(device)->set_ready_line_connected(_ready);   \
21   downcast<upd765b_device *>(device)->set_select_lines_connected(_select);
22
23#define MCFG_I8272A_ADD(_tag, _ready)   \
24   MCFG_DEVICE_ADD(_tag, I8272A, 0)   \
25   downcast<i8272a_device *>(device)->set_ready_line_connected(_ready);
26
27#define MCFG_UPD72065_ADD(_tag, _ready, _select)   \
28   MCFG_DEVICE_ADD(_tag, UPD72065, 0)            \
29   downcast<upd72065_device *>(device)->set_ready_line_connected(_ready);   \
30   downcast<upd72065_device *>(device)->set_select_lines_connected(_select);
31
32#define MCFG_SMC37C78_ADD(_tag)   \
33   MCFG_DEVICE_ADD(_tag, SMC37C78, 0)
34
35#define MCFG_N82077AA_ADD(_tag, _mode)   \
36   MCFG_DEVICE_ADD(_tag, N82077AA, 0)   \
37   downcast<n82077aa_device *>(device)->set_mode(_mode);
38
39#define MCFG_PC_FDC_SUPERIO_ADD(_tag)   \
40   MCFG_DEVICE_ADD(_tag, PC_FDC_SUPERIO, 0)
41
42/* Interface required for PC ISA wrapping */
43class pc_fdc_interface : public device_t {
44public:
45   typedef delegate<void (bool state)> line_cb;
46   typedef delegate<UINT8 ()> byte_read_cb;
47   typedef delegate<void (UINT8)> byte_write_cb;
48
49   pc_fdc_interface(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) : device_t(mconfig, type, name, tag, owner, clock) {}
50
51   virtual void setup_intrq_cb(line_cb cb) = 0;
52   virtual void setup_drq_cb(line_cb cb) = 0;
53
54   /* Note that the address map must cover and handle the whole 0-7
55     * range.  The upd765, while conforming to the rest of the
56     * interface, is not eligible as a result.
57     */
58
59   virtual DECLARE_ADDRESS_MAP(map, 8) = 0;
60
61   virtual UINT8 dma_r() = 0;
62   virtual void dma_w(UINT8 data) = 0;
63
64   virtual void tc_w(bool val) = 0;
65   virtual UINT8 do_dir_r() = 0;
66};
67
68class upd765_family_device : public pc_fdc_interface {
69public:
70   enum { MODE_AT, MODE_PS2, MODE_M30 };
71
72   upd765_family_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
73
74   void setup_intrq_cb(line_cb cb);
75   void setup_drq_cb(line_cb cb);
76
77   virtual DECLARE_ADDRESS_MAP(map, 8) = 0;
78
79   DECLARE_READ8_MEMBER (sra_r);
80   DECLARE_READ8_MEMBER (srb_r);
81   DECLARE_READ8_MEMBER (dor_r);
82   DECLARE_WRITE8_MEMBER(dor_w);
83   DECLARE_READ8_MEMBER (tdr_r);
84   DECLARE_WRITE8_MEMBER(tdr_w);
85   DECLARE_READ8_MEMBER (msr_r);
86   DECLARE_WRITE8_MEMBER(dsr_w);
87   DECLARE_READ8_MEMBER (fifo_r);
88   DECLARE_WRITE8_MEMBER(fifo_w);
89   DECLARE_READ8_MEMBER (dir_r);
90   DECLARE_WRITE8_MEMBER(ccr_w);
91
92   virtual UINT8 do_dir_r();
93
94   UINT8 dma_r();
95   void dma_w(UINT8 data);
96
97   // Same as the previous ones, but as memory-mappable members
98   DECLARE_READ8_MEMBER(mdma_r);
99   DECLARE_WRITE8_MEMBER(mdma_w);
100
101   bool get_irq() const;
102   bool get_drq() const;
103   void tc_w(bool val);
104   void ready_w(bool val);
105
106   void set_rate(int rate); // rate in bps, to be used when the fdc is externally frequency-controlled
107
108   void set_mode(int mode);
109   void set_ready_line_connected(bool ready);
110   void set_select_lines_connected(bool select);
111   void set_floppy(floppy_image_device *image);
112
113protected:
114   virtual void device_start();
115   virtual void device_reset();
116   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
117
118   enum {
119      TIMER_DRIVE_READY_POLLING = 4
120   };
121
122   enum {
123      PHASE_CMD, PHASE_EXEC, PHASE_RESULT
124   };
125
126   enum {
127      MSR_DB   = 0x0f,
128      MSR_CB   = 0x10,
129      MSR_EXM  = 0x20,
130      MSR_DIO  = 0x40,
131      MSR_RQM  = 0x80,
132
133      ST0_UNIT = 0x07,
134      ST0_NR   = 0x08,
135      ST0_EC   = 0x10,
136      ST0_SE   = 0x20,
137      ST0_FAIL = 0x40,
138      ST0_UNK  = 0x80,
139      ST0_ABRT = 0xc0,
140
141      ST1_MA   = 0x01,
142      ST1_NW   = 0x02,
143      ST1_ND   = 0x04,
144      ST1_OR   = 0x10,
145      ST1_DE   = 0x20,
146      ST1_EN   = 0x80,
147
148      ST2_MD   = 0x01,
149      ST2_BC   = 0x02,
150      ST2_SN   = 0x04,
151      ST2_SH   = 0x08,
152      ST2_WC   = 0x10,
153      ST2_DD   = 0x20,
154      ST2_CM   = 0x40,
155
156      ST3_UNIT = 0x07,
157      ST3_TS   = 0x08,
158      ST3_T0   = 0x10,
159      ST3_RY   = 0x20,
160      ST3_WP   = 0x40,
161      ST3_FT   = 0x80,
162
163      FIF_THR  = 0x0f,
164      FIF_POLL = 0x10,
165      FIF_DIS  = 0x20,
166      FIF_EIS  = 0x40,
167
168      SPEC_ND  = 0x0001,
169   };
170
171
172   enum {
173      // General "doing nothing" state
174      IDLE,
175
176      // Main states
177      RECALIBRATE,
178      SEEK,
179      READ_DATA,
180      WRITE_DATA,
181      READ_TRACK,
182      FORMAT_TRACK,
183      READ_ID,
184
185      // Sub-states
186      COMMAND_DONE,
187
188      SEEK_MOVE,
189      SEEK_WAIT_STEP_SIGNAL_TIME,
190      SEEK_WAIT_STEP_SIGNAL_TIME_DONE,
191      SEEK_WAIT_STEP_TIME,
192      SEEK_WAIT_STEP_TIME_DONE,
193      SEEK_DONE,
194
195      HEAD_LOAD_DONE,
196
197      WAIT_INDEX,
198      WAIT_INDEX_DONE,
199
200      SCAN_ID,
201      SCAN_ID_FAILED,
202
203      SECTOR_READ,
204      SECTOR_WRITTEN,
205      TC_DONE,
206
207      TRACK_DONE,
208
209      // Live states
210      SEARCH_ADDRESS_MARK_HEADER,
211      READ_HEADER_BLOCK_HEADER,
212      READ_DATA_BLOCK_HEADER,
213      READ_ID_BLOCK,
214      SEARCH_ADDRESS_MARK_DATA,
215      SEARCH_ADDRESS_MARK_DATA_FAILED,
216      READ_SECTOR_DATA,
217      READ_SECTOR_DATA_BYTE,
218
219      WRITE_SECTOR_SKIP_GAP2,
220      WRITE_SECTOR_SKIP_GAP2_BYTE,
221      WRITE_SECTOR_DATA,
222      WRITE_SECTOR_DATA_BYTE,
223
224      WRITE_TRACK_PRE_SECTORS,
225      WRITE_TRACK_PRE_SECTORS_BYTE,
226
227      WRITE_TRACK_SECTOR,
228      WRITE_TRACK_SECTOR_BYTE,
229
230      WRITE_TRACK_POST_SECTORS,
231      WRITE_TRACK_POST_SECTORS_BYTE,
232   };
233
234   struct pll_t {
235      attotime ctime, period, min_period, max_period, period_adjust_base, phase_adjust;
236
237      attotime write_start_time;
238      attotime write_buffer[32];
239      int write_position;
240      int freq_hist;
241
242      void set_clock(attotime period);
243      void reset(attotime when);
244      int get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit);
245      bool write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit);
246      void start_writing(attotime tm);
247      void commit(floppy_image_device *floppy, attotime tm);
248      void stop_writing(floppy_image_device *floppy, attotime tm);
249   };
250
251   struct floppy_info {
252      enum { IRQ_NONE, IRQ_SEEK, IRQ_POLLED };
253      emu_timer *tm;
254      floppy_image_device *dev;
255      int id;
256      int main_state, sub_state;
257      int dir, counter;
258      UINT8 pcn;
259      int irq;
260      bool live, index, ready;
261   };
262
263   struct live_info {
264      enum { PT_NONE, PT_CRC_1, PT_CRC_2 };
265
266      attotime tm;
267      int state, next_state;
268      floppy_info *fi;
269      UINT16 shift_reg;
270      UINT16 crc;
271      int bit_counter, byte_counter, previous_type;
272      bool data_separator_phase, data_bit_context;
273      UINT8 data_reg;
274      UINT8 idbuf[6];
275      pll_t pll;
276   };
277
278   static int rates[4];
279
280   bool ready_connected, ready_polled, select_connected;
281
282   bool external_ready;
283
284   int mode;
285   int main_phase;
286
287   live_info cur_live, checkpoint_live;
288   line_cb intrq_cb, drq_cb;
289   bool cur_irq, polled_irq, data_irq, drq, internal_drq, tc, tc_done, locked, mfm;
290   floppy_info flopi[4];
291
292   int fifo_pos, fifo_expected, command_pos, result_pos;
293   bool fifo_write;
294   UINT8 dor, dsr, msr, fifo[16], command[16], result[16];
295   UINT8 st0, st1, st2, st3;
296   UINT8 fifocfg, dor_reset;
297   UINT8 precomp, perpmode;
298   UINT16 spec;
299   int sector_size;
300   int cur_rate;
301
302   emu_timer *poll_timer;
303
304   static astring tts(attotime t);
305   astring ttsn();
306
307   enum {
308      C_CONFIGURE,
309      C_DUMP_REG,
310      C_FORMAT_TRACK,
311      C_LOCK,
312      C_PERPENDICULAR,
313      C_READ_DATA,
314      C_READ_ID,
315      C_READ_TRACK,
316      C_RECALIBRATE,
317      C_SEEK,
318      C_SENSE_DRIVE_STATUS,
319      C_SENSE_INTERRUPT_STATUS,
320      C_SPECIFY,
321      C_WRITE_DATA,
322
323      C_INVALID,
324      C_INCOMPLETE,
325   };
326
327   void delay_cycles(emu_timer *tm, int cycles);
328   void check_irq();
329   void soft_reset();
330   void fifo_expect(int size, bool write);
331   void fifo_push(UINT8 data, bool internal);
332   UINT8 fifo_pop(bool internal);
333   void set_drq(bool state);
334   bool get_ready(int fid);
335
336   void enable_transfer();
337   void disable_transfer();
338   int calc_sector_size(UINT8 size);
339
340   void run_drive_ready_polling();
341
342   int check_command();
343   void start_command(int cmd);
344   void command_end(floppy_info &fi, bool data_completion);
345
346   void recalibrate_start(floppy_info &fi);
347   void seek_start(floppy_info &fi);
348   void seek_continue(floppy_info &fi);
349
350   void read_data_start(floppy_info &fi);
351   void read_data_continue(floppy_info &fi);
352
353   void write_data_start(floppy_info &fi);
354   void write_data_continue(floppy_info &fi);
355
356   void read_track_start(floppy_info &fi);
357   void read_track_continue(floppy_info &fi);
358
359   void format_track_start(floppy_info &fi);
360   void format_track_continue(floppy_info &fi);
361
362   void read_id_start(floppy_info &fi);
363   void read_id_continue(floppy_info &fi);
364
365   void general_continue(floppy_info &fi);
366   void index_callback(floppy_image_device *floppy, int state);
367   bool sector_matches() const;
368
369   void live_start(floppy_info &fi, int live_state);
370   void live_abort();
371   void checkpoint();
372   void rollback();
373   void live_delay(int state);
374   void live_sync();
375   void live_run(attotime limit = attotime::never);
376   void live_write_raw(UINT16 raw);
377   void live_write_fm(UINT8 fm);
378   void live_write_mfm(UINT8 mfm);
379
380   bool read_one_bit(attotime limit);
381   bool write_one_bit(attotime limit);
382};
383
384class upd765a_device : public upd765_family_device {
385public:
386   upd765a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
387
388   virtual DECLARE_ADDRESS_MAP(map, 8);
389};
390
391class upd765b_device : public upd765_family_device {
392public:
393   upd765b_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
394
395   virtual DECLARE_ADDRESS_MAP(map, 8);
396};
397
398class i8272a_device : public upd765_family_device {
399public:
400   i8272a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
401
402   virtual DECLARE_ADDRESS_MAP(map, 8);
403};
404
405class smc37c78_device : public upd765_family_device {
406public:
407   smc37c78_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
408
409   virtual DECLARE_ADDRESS_MAP(map, 8);
410};
411
412class upd72065_device : public upd765_family_device {
413public:
414   upd72065_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
415
416   virtual DECLARE_ADDRESS_MAP(map, 8);
417};
418
419class n82077aa_device : public upd765_family_device {
420public:
421   n82077aa_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
422
423   virtual DECLARE_ADDRESS_MAP(map, 8);
424};
425
426class pc_fdc_superio_device : public upd765_family_device {
427public:
428   pc_fdc_superio_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
429
430   virtual DECLARE_ADDRESS_MAP(map, 8);
431};
432
433extern const device_type UPD765A;
434extern const device_type UPD765B;
435extern const device_type I8272A;
436extern const device_type UPD72065;
437extern const device_type SMC37C78;
438extern const device_type N82077AA;
439extern const device_type PC_FDC_SUPERIO;
440
441#endif
trunk/src/mess/machine/wd1772.c
r19165r19166
1/***************************************************************************
2
3    Copyright Olivier Galibert
4    All rights reserved.
5
6    Redistribution and use in source and binary forms, with or without
7    modification, are permitted provided that the following conditions are
8    met:
9
10        * Redistributions of source code must retain the above copyright
11          notice, this list of conditions and the following disclaimer.
12        * Redistributions in binary form must reproduce the above copyright
13          notice, this list of conditions and the following disclaimer in
14          the documentation and/or other materials provided with the
15          distribution.
16        * Neither the name 'MAME' nor the names of its contributors may be
17          used to endorse or promote products derived from this software
18          without specific prior written permission.
19
20    THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
21    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23    DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
24    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
29    IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30    POSSIBILITY OF SUCH DAMAGE.
31
32****************************************************************************/
33
34#include "wd1772.h"
35
36#include "debugger.h"
37
38const device_type FD1771x = &device_creator<fd1771_t>;
39const device_type FD1793x = &device_creator<fd1793_t>;
40const device_type FD1797x = &device_creator<fd1797_t>;
41const device_type WD2793x = &device_creator<wd2793_t>;
42const device_type WD2797x = &device_creator<wd2797_t>;
43const device_type WD1770x = &device_creator<wd1770_t>;
44const device_type WD1772x = &device_creator<wd1772_t>;
45const device_type WD1773x = &device_creator<wd1773_t>;
46
47wd177x_t::wd177x_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) :
48   device_t(mconfig, type, name, tag, owner, clock)
49{
50}
51
52void wd177x_t::device_start()
53{
54   t_gen = timer_alloc(TM_GEN);
55   t_cmd = timer_alloc(TM_CMD);
56   t_track = timer_alloc(TM_TRACK);
57   t_sector = timer_alloc(TM_SECTOR);
58   dden = false;
59   floppy = 0;
60
61   save_item(NAME(status));
62   save_item(NAME(command));
63   save_item(NAME(main_state));
64   save_item(NAME(sub_state));
65   save_item(NAME(track));
66   save_item(NAME(sector));
67   save_item(NAME(intrq_cond));
68   save_item(NAME(cmd_buffer));
69   save_item(NAME(track_buffer));
70   save_item(NAME(sector_buffer));
71   save_item(NAME(counter));
72   save_item(NAME(status_type_1));
73   save_item(NAME(last_dir));
74}
75
76void wd177x_t::device_reset()
77{
78   command = 0x00;
79   main_state = IDLE;
80   sub_state = IDLE;
81   cur_live.state = IDLE;
82   track = 0x00;
83   sector = 0x00;
84   status = 0x00;
85   data = 0x00;
86   cmd_buffer = track_buffer = sector_buffer = -1;
87   counter = 0;
88   status_type_1 = true;
89   last_dir = 1;
90   intrq = false;
91   drq = false;
92   hld = false;
93   live_abort();
94}
95
96void wd177x_t::set_floppy(floppy_image_device *_floppy)
97{
98   if(floppy == _floppy)
99      return;
100
101   if(floppy) {
102      floppy->mon_w(1);
103      floppy->setup_index_pulse_cb(floppy_image_device::index_pulse_cb());
104   }
105
106   floppy = _floppy;
107
108   if(floppy) {
109      if(has_motor())
110         floppy->mon_w(status & S_MON ? 0 : 1);
111      floppy->setup_index_pulse_cb(floppy_image_device::index_pulse_cb(FUNC(wd177x_t::index_callback), this));
112   }
113}
114
115void wd177x_t::setup_intrq_cb(line_cb cb)
116{
117   intrq_cb = cb;
118}
119
120void wd177x_t::setup_drq_cb(line_cb cb)
121{
122   drq_cb = cb;
123}
124
125void wd177x_t::setup_hld_cb(line_cb cb)
126{
127   hld_cb = cb;
128}
129
130void wd177x_t::setup_enp_cb(line_cb cb)
131{
132   enp_cb = cb;
133}
134
135void wd177x_t::dden_w(bool _dden)
136{
137   dden = _dden;
138}
139
140astring wd177x_t::tts(attotime t)
141{
142   char buf[256];
143   int nsec = t.attoseconds / ATTOSECONDS_PER_NANOSECOND;
144   sprintf(buf, "%4d.%03d,%03d,%03d", int(t.seconds), nsec/1000000, (nsec/1000)%1000, nsec % 1000);
145   return buf;
146}
147
148astring wd177x_t::ttsn()
149{
150   return tts(machine().time());
151}
152
153void wd177x_t::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
154{
155   live_sync();
156
157   switch(id) {
158   case TM_GEN: do_generic(); break;
159   case TM_CMD: do_cmd_w(); break;
160   case TM_TRACK: do_track_w(); break;
161   case TM_SECTOR: do_sector_w(); break;
162   }
163
164   general_continue();
165}
166
167void wd177x_t::command_end()
168{
169   main_state = sub_state = IDLE;
170   status &= ~S_BUSY;
171   intrq = true;
172   motor_timeout = 0;
173   if(!intrq_cb.isnull())
174      intrq_cb(intrq);
175}
176
177void wd177x_t::seek_start(int state)
178{
179   main_state = state;
180   status = (status & ~(S_CRC|S_RNF|S_SPIN)) | S_BUSY;
181   if(has_head_load()) {
182      // TODO get value from HLT callback
183      if (command & 8)
184         status |= S_HLD;
185      else
186         status &= ~S_HLD;
187   }
188   sub_state = has_motor() && !has_head_load() ? SPINUP : SPINUP_DONE;
189   status_type_1 = true;
190   seek_continue();
191}
192
193void wd177x_t::seek_continue()
194{
195   for(;;) {
196      switch(sub_state) {
197      case SPINUP:
198         if(!(status & S_MON)) {
199            spinup();
200            return;
201         }
202         if(!(command & 0x08))
203            status |= S_SPIN;
204         sub_state = SPINUP_DONE;
205         break;
206
207      case SPINUP_WAIT:
208         return;
209
210      case SPINUP_DONE:
211         if(main_state == RESTORE && floppy && !floppy->trk00_r())
212            sub_state = SEEK_DONE;
213
214         if(main_state == SEEK && track == data)
215            sub_state = SEEK_DONE;
216
217         if(sub_state == SPINUP_DONE) {
218            counter = 0;
219            sub_state = SEEK_MOVE;
220         }
221         break;
222
223      case SEEK_MOVE:
224         if(floppy) {
225            floppy->dir_w(last_dir);
226            floppy->stp_w(0);
227            floppy->stp_w(1);
228         }
229         // When stepping with update, the track register is updated before seeking.
230         // Important for the sam coupe format code.
231         if(main_state == STEP && (command & 0x10))
232            track += last_dir ? -1 : 1;
233         counter++;
234         sub_state = SEEK_WAIT_STEP_TIME;
235         delay_cycles(t_gen, step_time(command & 3));
236         return;
237
238      case SEEK_WAIT_STEP_TIME:
239         return;
240
241      case SEEK_WAIT_STEP_TIME_DONE: {
242         bool done = false;
243         switch(main_state) {
244         case RESTORE:
245            done = !floppy || !floppy->trk00_r();
246            break;
247         case SEEK:
248            track += last_dir ? -1 : 1;
249            done = track == data;
250            break;
251         case STEP:
252            done = true;
253            break;
254         }
255
256         if(done || counter == 255) {
257            if(main_state == RESTORE)
258               track = 0;
259
260            if(command & 0x04) {
261               sub_state = SEEK_WAIT_STABILIZATION_TIME;
262               delay_cycles(t_gen, 120000);
263               return;
264            } else
265               sub_state = SEEK_DONE;
266
267         } else
268            sub_state = SEEK_MOVE;
269
270         break;
271      }
272
273      case SEEK_WAIT_STABILIZATION_TIME:
274         return;
275
276      case SEEK_WAIT_STABILIZATION_TIME_DONE:
277         sub_state = SEEK_DONE;
278         break;
279
280      case SEEK_DONE:
281         if(command & 0x04) {
282            if(has_ready() && !is_ready()) {
283               status |= S_RNF;
284               command_end();
285               return;
286            }
287            sub_state = SCAN_ID;
288            counter = 0;
289            live_start(SEARCH_ADDRESS_MARK_HEADER);
290            return;
291         }
292         command_end();
293         return;
294
295      case SCAN_ID:
296         if(cur_live.idbuf[0] != track) {
297            live_start(SEARCH_ADDRESS_MARK_HEADER);
298            return;
299         }
300         if(cur_live.crc) {
301            status |= S_CRC;
302            live_start(SEARCH_ADDRESS_MARK_HEADER);
303            return;
304         }
305         command_end();
306         return;
307
308      case SCAN_ID_FAILED:
309         status |= S_RNF;
310         command_end();
311         return;
312
313      default:
314         logerror("%s: seek unknown sub-state %d\n", ttsn().cstr(), sub_state);
315         return;
316      }
317   }
318}
319
320bool wd177x_t::sector_matches() const
321{
322   if(cur_live.idbuf[0] != track || cur_live.idbuf[2] != sector)
323      return false;
324   if(!has_side_check() || (command & 2))
325      return true;
326   if(command & 8)
327      return cur_live.idbuf[1] & 1;
328   else
329      return !(cur_live.idbuf[1] & 1);
330}
331
332bool wd177x_t::is_ready()
333{
334   return (floppy && !floppy->ready_r());
335}
336
337void wd177x_t::read_sector_start()
338{
339   if(has_ready() && !is_ready())
340      command_end();
341
342   main_state = READ_SECTOR;
343   status = (status & ~(S_CRC|S_LOST|S_RNF|S_WP|S_DDM)) | S_BUSY;
344   drop_drq();
345   if (has_side_select() && floppy)
346      floppy->ss_w(BIT(command, 1));
347   sub_state = has_motor() && !has_head_load() ? SPINUP : SPINUP_DONE;
348   status_type_1 = false;
349   read_sector_continue();
350}
351
352void wd177x_t::read_sector_continue()
353{
354   for(;;) {
355      switch(sub_state) {
356      case SPINUP:
357         if(!(status & S_MON)) {
358            spinup();
359            return;
360         }
361         sub_state = SPINUP_DONE;
362         break;
363
364      case SPINUP_WAIT:
365         return;
366
367      case SPINUP_DONE:
368         if(command & 4) {
369            sub_state = SETTLE_WAIT;
370            delay_cycles(t_gen, settle_time());
371            return;
372         } else {
373            sub_state = SETTLE_DONE;
374            break;
375         }
376
377      case SETTLE_WAIT:
378         return;
379
380      case SETTLE_DONE:
381         sub_state = SCAN_ID;
382         counter = 0;
383         live_start(SEARCH_ADDRESS_MARK_HEADER);
384         return;
385
386      case SCAN_ID:
387         if(!sector_matches()) {
388            live_start(SEARCH_ADDRESS_MARK_HEADER);
389            return;
390         }
391         if(cur_live.crc) {
392            status |= S_CRC;
393            live_start(SEARCH_ADDRESS_MARK_HEADER);
394            return;
395         }
396         // TODO WD2795/7 alternate sector size
397         sector_size = 128 << (cur_live.idbuf[3] & 3);
398         sub_state = SECTOR_READ;
399         live_start(SEARCH_ADDRESS_MARK_DATA);
400         return;
401
402      case SCAN_ID_FAILED:
403         status |= S_RNF;
404         command_end();
405         return;
406
407      case SECTOR_READ:
408         if(cur_live.crc)
409            status |= S_CRC;
410
411         if(command & 0x10 && !(status & S_RNF)) {
412            sector++;
413            sub_state = SETTLE_DONE;
414         } else {
415            command_end();
416            return;
417         }
418         break;
419
420      default:
421         logerror("%s: read sector unknown sub-state %d\n", ttsn().cstr(), sub_state);
422         return;
423      }
424   }
425}
426
427void wd177x_t::read_track_start()
428{
429   if(has_ready() && !is_ready())
430      command_end();
431   
432   main_state = READ_TRACK;
433   status = (status & ~(S_LOST|S_RNF)) | S_BUSY;
434   drop_drq();
435   if (has_side_select() && floppy)
436      floppy->ss_w(BIT(command, 1));
437   sub_state = has_motor() && !has_head_load()  ? SPINUP : SPINUP_DONE;
438   status_type_1 = false;
439   read_track_continue();
440}
441
442void wd177x_t::read_track_continue()
443{
444   for(;;) {
445      switch(sub_state) {
446      case SPINUP:
447         if(!(status & S_MON)) {
448            spinup();
449            return;
450         }
451         sub_state = SPINUP_DONE;
452         break;
453
454      case SPINUP_WAIT:
455         return;
456
457      case SPINUP_DONE:
458         if(command & 4) {
459            sub_state = SETTLE_WAIT;
460            delay_cycles(t_gen, settle_time());
461            return;
462
463         } else {
464            sub_state = SETTLE_DONE;
465            break;
466         }
467
468      case SETTLE_WAIT:
469         return;
470
471      case SETTLE_DONE:
472         sub_state = WAIT_INDEX;
473         return;
474
475      case WAIT_INDEX:
476         return;
477
478      case WAIT_INDEX_DONE:
479         sub_state = TRACK_DONE;
480         live_start(READ_TRACK_DATA);
481         return;
482
483      case TRACK_DONE:
484         command_end();
485         return;
486
487      default:
488         logerror("%s: read track unknown sub-state %d\n", ttsn().cstr(), sub_state);
489         return;
490      }
491   }
492}
493
494void wd177x_t::read_id_start()
495{
496   if(has_ready() && !is_ready())
497      command_end();
498   
499   main_state = READ_ID;
500   status = (status & ~(S_WP|S_DDM|S_LOST|S_RNF)) | S_BUSY;
501   drop_drq();
502   if (has_side_select() && floppy)
503      floppy->ss_w(BIT(command, 1));
504   sub_state = has_motor() && !has_head_load()  ? SPINUP : SPINUP_DONE;
505   status_type_1 = false;
506   read_id_continue();
507}
508
509void wd177x_t::read_id_continue()
510{
511   for(;;) {
512      switch(sub_state) {
513      case SPINUP:
514         if(!(status & S_MON)) {
515            spinup();
516            return;
517         }
518         sub_state = SPINUP_DONE;
519         break;
520
521      case SPINUP_WAIT:
522         return;
523
524      case SPINUP_DONE:
525         if(command & 4) {
526            sub_state = SETTLE_WAIT;
527            delay_cycles(t_gen, settle_time());
528            return;
529         } else {
530            sub_state = SETTLE_DONE;
531            break;
532         }
533
534      case SETTLE_WAIT:
535         return;
536
537      case SETTLE_DONE:
538         sub_state = SCAN_ID;
539         counter = 0;
540         live_start(SEARCH_ADDRESS_MARK_HEADER);
541         return;
542
543      case SCAN_ID:
544         command_end();
545         return;
546
547      case SCAN_ID_FAILED:
548         status |= S_RNF;
549         command_end();
550         return;
551
552      default:
553         logerror("%s: read id unknown sub-state %d\n", ttsn().cstr(), sub_state);
554         return;
555      }
556   }
557}
558
559void wd177x_t::write_track_start()
560{
561   if(has_ready() && !is_ready())
562      command_end();
563   
564   main_state = WRITE_TRACK;
565   status = (status & ~(S_WP|S_DDM|S_LOST|S_RNF)) | S_BUSY;
566   drop_drq();
567   if (has_side_select() && floppy)
568      floppy->ss_w(BIT(command, 1));
569   sub_state = has_motor()  && !has_head_load() ? SPINUP : SPINUP_DONE;
570   status_type_1 = false;
571   write_track_continue();
572}
573
574void wd177x_t::write_track_continue()
575{
576   for(;;) {
577      switch(sub_state) {
578      case SPINUP:
579         if(!(status & S_MON)) {
580            spinup();
581            return;
582         }
583         sub_state = SPINUP_DONE;
584         break;
585
586      case SPINUP_WAIT:
587         return;
588
589      case SPINUP_DONE:
590         if(command & 4) {
591            sub_state = SETTLE_WAIT;
592            delay_cycles(t_gen, settle_time());
593            return;
594         } else {
595            sub_state = SETTLE_DONE;
596            break;
597         }
598
599      case SETTLE_WAIT:
600         return;
601
602      case SETTLE_DONE:
603         set_drq();
604         sub_state = DATA_LOAD_WAIT;
605         delay_cycles(t_gen, 768);
606         return;
607
608      case DATA_LOAD_WAIT:
609         return;
610
611      case DATA_LOAD_WAIT_DONE:
612         if(drq) {
613            status |= S_LOST;
614            command_end();
615            return;
616         }
617         sub_state = WAIT_INDEX;
618         break;
619
620      case WAIT_INDEX:
621         return;
622
623      case WAIT_INDEX_DONE:
624         sub_state = TRACK_DONE;
625         live_start(WRITE_TRACK_DATA);
626         cur_live.pll.start_writing(machine().time());
627         return;
628
629      case TRACK_DONE:
630         command_end();
631         return;
632
633      default:
634         logerror("%s: write track unknown sub-state %d\n", ttsn().cstr(), sub_state);
635         return;
636      }
637   }
638}
639
640
641void wd177x_t::write_sector_start()
642{
643   if(has_ready() && !is_ready())
644      command_end();
645   
646   main_state = WRITE_SECTOR;
647   status = (status & ~(S_CRC|S_LOST|S_RNF|S_WP|S_DDM)) | S_BUSY;
648   drop_drq();
649   if (has_side_select() && floppy)
650      floppy->ss_w(BIT(command, 1));
651   sub_state = has_motor() && !has_head_load()  ? SPINUP : SPINUP_DONE;
652   status_type_1 = false;
653   write_sector_continue();
654}
655
656void wd177x_t::write_sector_continue()
657{
658   for(;;) {
659      switch(sub_state) {
660      case SPINUP:
661         if(!(status & S_MON)) {
662            spinup();
663            return;
664         }
665         sub_state = SPINUP_DONE;
666         break;
667
668      case SPINUP_WAIT:
669         return;
670
671      case SPINUP_DONE:
672         if(command & 4) {
673            sub_state = SETTLE_WAIT;
674            delay_cycles(t_gen, settle_time());
675            return;
676         } else {
677            sub_state = SETTLE_DONE;
678            break;
679         }
680
681      case SETTLE_WAIT:
682         return;
683
684      case SETTLE_DONE:
685         sub_state = SCAN_ID;
686         counter = 0;
687         live_start(SEARCH_ADDRESS_MARK_HEADER);
688         return;
689
690      case SCAN_ID:
691         if(!sector_matches()) {
692            live_start(SEARCH_ADDRESS_MARK_HEADER);
693            return;
694         }
695         if(cur_live.crc) {
696            status |= S_CRC;
697            live_start(SEARCH_ADDRESS_MARK_HEADER);
698            return;
699         }
700         // TODO WD2795/7 alternate sector size
701         sector_size = 128 << (cur_live.idbuf[3] & 3);
702         sub_state = SECTOR_WRITE;
703         live_start(WRITE_SECTOR_PRE);
704         return;
705
706      case SCAN_ID_FAILED:
707         status |= S_RNF;
708         command_end();
709         return;
710
711      case SECTOR_WRITE:
712         if(command & 0x10) {
713            sector++;
714            sub_state = SPINUP_DONE;
715         } else {
716            command_end();
717            return;
718         }
719         break;
720
721      default:
722         logerror("%s: write sector unknown sub-state %d\n", ttsn().cstr(), sub_state);
723         return;
724      }
725   }
726}
727
728void wd177x_t::interrupt_start()
729{
730   if(status & S_BUSY) {
731      main_state = sub_state = cur_live.state = IDLE;
732      cur_live.tm = attotime::never;
733      status &= ~S_BUSY;
734      drop_drq();
735      motor_timeout = 0;
736   }
737   
738   if(!(command & 0x0f)) {
739      intrq_cond = 0;
740   } else {
741      intrq_cond = (intrq_cond & I_IMM) | (command & 0x07);
742   }
743
744   if(intrq_cond & I_IMM) {
745      intrq = true;
746      if(!intrq_cb.isnull())
747         intrq_cb(intrq);
748   }
749
750   if(command & 0x03) {
751      logerror("%s: unhandled interrupt generation (%02x)\n", ttsn().cstr(), command);
752   }
753}
754
755void wd177x_t::general_continue()
756{
757   if(cur_live.state != IDLE) {
758      live_run();
759      if(cur_live.state != IDLE)
760         return;
761   }
762
763   switch(main_state) {
764   case IDLE:
765      break;
766   case RESTORE: case SEEK: case STEP:
767      seek_continue();
768      break;
769   case READ_SECTOR:
770      read_sector_continue();
771      break;
772   case READ_TRACK:
773      read_track_continue();
774      break;
775   case READ_ID:
776      read_id_continue();
777      break;
778   case WRITE_TRACK:
779      write_track_continue();
780      break;
781   case WRITE_SECTOR:
782      write_sector_continue();
783      break;
784   default:
785      logerror("%s: general_continue on unknown main-state %d\n", ttsn().cstr(), main_state);
786      break;
787   }
788}
789
790void wd177x_t::do_generic()
791{
792   switch(sub_state) {
793   case IDLE:
794   case SCAN_ID:
795   case SECTOR_READ:
796      break;
797
798   case SETTLE_WAIT:
799      sub_state = SETTLE_DONE;
800      break;
801
802   case SEEK_WAIT_STEP_TIME:
803      sub_state = SEEK_WAIT_STEP_TIME_DONE;
804      break;
805
806   case SEEK_WAIT_STABILIZATION_TIME:
807      sub_state = SEEK_WAIT_STABILIZATION_TIME_DONE;
808      break;
809
810   case DATA_LOAD_WAIT:
811      sub_state = DATA_LOAD_WAIT_DONE;
812      break;
813
814   default:
815      if(cur_live.tm.is_never())
816         logerror("%s: do_generic on unknown sub-state %d\n", ttsn().cstr(), sub_state);
817      break;
818   }
819}
820
821void wd177x_t::do_cmd_w()
822{
823   //  fprintf(stderr, "%s: command %02x\n", ttsn().cstr(), cmd_buffer);
824
825   // Only available command when busy is interrupt
826   if(main_state != IDLE && (cmd_buffer & 0xf0) != 0xd0) {
827      cmd_buffer = -1;
828      return;
829   }
830   command = cmd_buffer;
831   cmd_buffer = -1;
832
833   switch(command & 0xf0) {
834   case 0x00: logerror("wd1772: restore\n"); last_dir = 1; seek_start(RESTORE); break;
835   case 0x10: logerror("wd1772: seek %d\n", data); last_dir = data > track ? 0 : 1; seek_start(SEEK); break;
836   case 0x20: case 0x30: logerror("wd1772: step\n"); seek_start(STEP); break;
837   case 0x40: case 0x50: logerror("wd1772: step +\n"); last_dir = 0; seek_start(STEP); break;
838   case 0x60: case 0x70: logerror("wd1772: step -\n"); last_dir = 1; seek_start(STEP); break;
839   case 0x80: case 0x90: logerror("wd1772: read sector%s %d, %d\n", command & 0x10 ? " multiple" : "", track, sector); read_sector_start(); break;
840   case 0xa0: case 0xb0: logerror("wd1772: write sector%s %d, %d\n", command & 0x10 ? " multiple" : "", track, sector); write_sector_start(); break;
841   case 0xc0: logerror("wd1772: read id\n"); read_id_start(); break;
842   case 0xd0: logerror("wd1772: interrupt\n"); interrupt_start(); break;
843   case 0xe0: logerror("wd1772: read track %d\n", track); read_track_start(); break;
844   case 0xf0: logerror("wd1772: write track %d\n", track); write_track_start(); break;
845   }
846}
847
848void wd177x_t::cmd_w(UINT8 val)
849{
850   logerror("wd1772 cmd: %02x\n", val);
851   
852   if(intrq && !(intrq_cond & I_IMM)) {
853      intrq = false;
854      if(!intrq_cb.isnull())
855         intrq_cb(intrq);
856   }
857
858   // No more than one write in flight
859   if(cmd_buffer != -1)
860      return;
861
862   cmd_buffer = val;
863
864   delay_cycles(t_cmd, dden ? 384 : 184);
865}
866
867UINT8 wd177x_t::status_r()
868{
869   if(intrq && !(intrq_cond & I_IMM)) {
870      intrq = false;
871      if(!intrq_cb.isnull())
872         intrq_cb(intrq);
873   }
874
875   if(main_state == IDLE || status_type_1) {
876      if(floppy && floppy->idx_r())
877         status |= S_IP;
878      else
879         status &= ~S_IP;
880   } else {
881      if(drq)
882         status |= S_DRQ;
883      else
884         status &= ~S_DRQ;
885   }
886
887   if(status_type_1) {
888      status &= ~(S_TR00|S_WP);
889      if(floppy) {
890         if(floppy->wpt_r())
891            status |= S_WP;
892         if(!floppy->trk00_r())
893            status |= S_TR00;
894      }
895   }
896
897   if(has_ready()) {
898      if(!is_ready())
899         status |= S_NRDY;
900      else
901         status &= ~S_NRDY;
902   }
903
904   return status;
905}
906
907void wd177x_t::do_track_w()
908{
909   track = track_buffer;
910   track_buffer = -1;
911}
912
913void wd177x_t::track_w(UINT8 val)
914{
915   // No more than one write in flight
916   if(track_buffer != -1)
917      return;
918
919   track_buffer = val;
920   delay_cycles(t_track, dden ? 256 : 128);
921}
922
923UINT8 wd177x_t::track_r()
924{
925   return track;
926}
927
928void wd177x_t::do_sector_w()
929{
930   sector = sector_buffer;
931   sector_buffer = -1;
932}
933
934void wd177x_t::sector_w(UINT8 val)
935{
936   // No more than one write in flight
937   if(sector_buffer != -1)
938      return;
939
940   sector_buffer = val;
941   delay_cycles(t_sector, dden ? 256 : 128);
942}
943
944UINT8 wd177x_t::sector_r()
945{
946   return sector;
947}
948
949void wd177x_t::data_w(UINT8 val)
950{
951   data = val;
952   drop_drq();
953}
954
955UINT8 wd177x_t::data_r()
956{
957   drop_drq();
958   return data;
959}
960
961void wd177x_t::gen_w(int reg, UINT8 val)
962{
963   switch(reg) {
964   case 0: cmd_w(val); break;
965   case 1: track_w(val); break;
966   case 2: sector_w(val); break;
967   case 3: data_w(val); break;
968   }
969}
970
971UINT8 wd177x_t::gen_r(int reg)
972{
973   switch(reg) {
974   case 0: return status_r(); break;
975   case 1: return track_r(); break;
976   case 2: return sector_r(); break;
977   case 3: return data_r(); break;
978   }
979   return 0xff;
980}
981
982void wd177x_t::delay_cycles(emu_timer *tm, int cycles)
983{
984   tm->adjust(clocks_to_attotime(cycles));
985}
986
987void wd177x_t::spinup()
988{
989   if(command & 0x08)
990      sub_state = SPINUP_DONE;
991   else {
992      sub_state = SPINUP_WAIT;
993      counter = 0;
994   }
995
996   status |= S_MON;
997   if(floppy)
998      floppy->mon_w(0);
999
1000}
1001
1002void wd177x_t::index_callback(floppy_image_device *floppy, int state)
1003{
1004   live_sync();
1005
1006   if(!state) {
1007      general_continue();
1008      return;
1009   }
1010
1011   if(intrq_cond & I_IDX) {
1012      intrq = true;
1013      if(!intrq_cb.isnull())
1014         intrq_cb(intrq);
1015   }
1016
1017   switch(sub_state) {
1018   case IDLE:
1019      if(has_motor()) {
1020         motor_timeout ++;
1021         if(motor_timeout >= 5) {
1022            status &= ~S_MON;
1023            if(floppy)
1024               floppy->mon_w(1);
1025         }
1026      }
1027      break;
1028
1029   case SPINUP:
1030      break;
1031
1032   case SPINUP_WAIT:
1033      counter++;
1034      if(counter == 6) {
1035         sub_state = SPINUP_DONE;
1036         if(status_type_1)
1037            status |= S_SPIN;
1038      }
1039      break;
1040
1041   case SPINUP_DONE:
1042   case SETTLE_WAIT:
1043   case SETTLE_DONE:
1044   case DATA_LOAD_WAIT:
1045   case DATA_LOAD_WAIT_DONE:
1046   case SEEK_MOVE:
1047   case SEEK_WAIT_STEP_TIME:
1048   case SEEK_WAIT_STEP_TIME_DONE:
1049   case SEEK_WAIT_STABILIZATION_TIME:
1050   case SEEK_WAIT_STABILIZATION_TIME_DONE:
1051   case SEEK_DONE:
1052   case WAIT_INDEX_DONE:
1053   case SCAN_ID_FAILED:
1054   case SECTOR_READ:
1055   case SECTOR_WRITE:
1056      break;
1057
1058   case SCAN_ID:
1059      counter++;
1060      if(counter == 5) {
1061         sub_state = SCAN_ID_FAILED;
1062         live_abort();
1063      }
1064      break;
1065
1066   case WAIT_INDEX:
1067      sub_state = WAIT_INDEX_DONE;
1068      break;
1069
1070   case TRACK_DONE:
1071      live_abort();
1072      break;
1073
1074   default:
1075      logerror("%s: Index pulse on unknown sub-state %d\n", ttsn().cstr(), sub_state);
1076      break;
1077   }
1078
1079   general_continue();
1080}
1081
1082bool wd177x_t::intrq_r()
1083{
1084   return intrq;
1085}
1086
1087bool wd177x_t::drq_r()
1088{
1089   return drq;
1090}
1091
1092bool wd177x_t::hld_r()
1093{
1094   return hld;
1095}
1096
1097void wd177x_t::hlt_w(bool state)
1098{
1099   hlt = state;
1100}
1101
1102bool wd177x_t::enp_r()
1103{
1104   return enp;
1105}
1106
1107void wd177x_t::live_start(int state)
1108{
1109   cur_live.tm = machine().time();
1110   cur_live.state = state;
1111   cur_live.next_state = -1;
1112   cur_live.shift_reg = 0;
1113   cur_live.crc = 0xffff;
1114   cur_live.bit_counter = 0;
1115   cur_live.data_separator_phase = false;
1116   cur_live.data_reg = 0;
1117   cur_live.previous_type = live_info::PT_NONE;
1118   cur_live.data_bit_context = false;
1119   cur_live.byte_counter = 0;
1120   cur_live.pll.reset(cur_live.tm);
1121   cur_live.pll.set_clock(clocks_to_attotime(1));
1122   checkpoint_live = cur_live;
1123
1124   live_run();
1125}
1126
1127void wd177x_t::checkpoint()
1128{
1129   cur_live.pll.commit(floppy, cur_live.tm);
1130   checkpoint_live = cur_live;
1131}
1132
1133void wd177x_t::rollback()
1134{
1135   cur_live = checkpoint_live;
1136}
1137
1138void wd177x_t::live_delay(int state)
1139{
1140   cur_live.next_state = state;
1141   t_gen->adjust(cur_live.tm - machine().time());
1142}
1143
1144void wd177x_t::live_sync()
1145{
1146   if(!cur_live.tm.is_never()) {
1147      if(cur_live.tm > machine().time()) {
1148         //          fprintf(stderr, "%s: Rolling back and replaying (%s)\n", ttsn().cstr(), tts(cur_live.tm).cstr());
1149         rollback();
1150         live_run(machine().time());
1151         cur_live.pll.commit(floppy, cur_live.tm);
1152      } else {
1153         //          fprintf(stderr, "%s: Committing (%s)\n", ttsn().cstr(), tts(cur_live.tm).cstr());
1154         cur_live.pll.commit(floppy, cur_live.tm);
1155         if(cur_live.next_state != -1) {
1156            cur_live.state = cur_live.next_state;
1157            cur_live.next_state = -1;
1158         }
1159         if(cur_live.state == IDLE) {
1160            cur_live.pll.stop_writing(floppy, cur_live.tm);
1161            cur_live.tm = attotime::never;
1162         }
1163      }
1164      cur_live.next_state = -1;
1165      checkpoint();
1166   }
1167}
1168
1169void wd177x_t::live_abort()
1170{
1171   if(!cur_live.tm.is_never() && cur_live.tm > machine().time()) {
1172      rollback();
1173      live_run(machine().time());
1174   }
1175
1176   cur_live.pll.stop_writing(floppy, cur_live.tm);
1177   cur_live.tm = attotime::never;
1178   cur_live.state = IDLE;
1179   cur_live.next_state = -1;
1180}
1181
1182bool wd177x_t::read_one_bit(attotime limit)
1183{
1184   int bit = cur_live.pll.get_next_bit(cur_live.tm, floppy, limit);
1185   if(bit < 0)
1186      return true;
1187   cur_live.shift_reg = (cur_live.shift_reg << 1) | bit;
1188   cur_live.bit_counter++;
1189   if(cur_live.data_separator_phase) {
1190      cur_live.data_reg = (cur_live.data_reg << 1) | bit;
1191      if((cur_live.crc ^ (bit ? 0x8000 : 0x0000)) & 0x8000)
1192         cur_live.crc = (cur_live.crc << 1) ^ 0x1021;
1193      else
1194         cur_live.crc = cur_live.crc << 1;
1195   }
1196   cur_live.data_separator_phase = !cur_live.data_separator_phase;
1197   return false;
1198}
1199
1200bool wd177x_t::write_one_bit(attotime limit)
1201{
1202   bool bit = cur_live.shift_reg & 0x8000;
1203   if(cur_live.pll.write_next_bit(bit, cur_live.tm, floppy, limit))
1204      return true;
1205   if(cur_live.bit_counter & 1) {
1206      if((cur_live.crc ^ (bit ? 0x8000 : 0x0000)) & 0x8000)
1207         cur_live.crc = (cur_live.crc << 1) ^ 0x1021;
1208      else
1209         cur_live.crc = cur_live.crc << 1;
1210   }
1211   cur_live.shift_reg = cur_live.shift_reg << 1;
1212   cur_live.bit_counter--;
1213   return false;
1214}
1215
1216void wd177x_t::live_write_raw(UINT16 raw)
1217{
1218   //  logerror("write %04x %04x\n", raw, cur_live.crc);
1219   cur_live.shift_reg = raw;
1220   cur_live.data_bit_context = raw & 1;
1221}
1222
1223void wd177x_t::live_write_mfm(UINT8 mfm)
1224{
1225   bool context = cur_live.data_bit_context;
1226   UINT16 raw = 0;
1227   for(int i=0; i<8; i++) {
1228      bool bit = mfm & (0x80 >> i);
1229      if(!(bit || context))
1230         raw |= 0x8000 >> (2*i);
1231      if(bit)
1232         raw |= 0x4000 >> (2*i);
1233      context = bit;
1234   }
1235   cur_live.shift_reg = raw;
1236   cur_live.data_bit_context = context;
1237   //  logerror("write %02x   %04x %04x\n", mfm, cur_live.crc, raw);
1238}
1239
1240void wd177x_t::live_run(attotime limit)
1241{
1242   if(cur_live.state == IDLE || cur_live.next_state != -1)
1243      return;
1244
1245   if(limit == attotime::never) {
1246      if(floppy)
1247         limit = floppy->time_next_index();
1248      if(limit == attotime::never) {
1249         // Happens when there's no disk or if the wd is not
1250         // connected to a drive, hence no index pulse. Force a
1251         // sync from time to time in that case, so that the main
1252         // cpu timeout isn't too painful.  Avoids looping into
1253         // infinity looking for data too.
1254
1255         limit = machine().time() + attotime::from_msec(1);
1256         t_gen->adjust(attotime::from_msec(1));
1257      }
1258   }
1259
1260   //  fprintf(stderr, "%s: live_run(%s)\n", ttsn().cstr(), tts(limit).cstr());
1261
1262   for(;;) {
1263      switch(cur_live.state) {
1264      case SEARCH_ADDRESS_MARK_HEADER:
1265         if(read_one_bit(limit))
1266            return;
1267#if 0
1268         fprintf(stderr, "%s: shift = %04x data=%02x c=%d\n", tts(cur_live.tm).cstr(), cur_live.shift_reg,
1269               (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) |
1270               (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) |
1271               (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) |
1272               (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) |
1273               (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) |
1274               (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) |
1275               (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) |
1276               (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00),
1277               cur_live.bit_counter);
1278#endif
1279
1280         if(cur_live.shift_reg == 0x4489) {
1281            cur_live.crc = 0x443b;
1282            cur_live.data_separator_phase = false;
1283            cur_live.bit_counter = 0;
1284            cur_live.state = READ_HEADER_BLOCK_HEADER;
1285         }
1286         break;
1287
1288      case READ_HEADER_BLOCK_HEADER: {
1289         if(read_one_bit(limit))
1290            return;
1291#if 0
1292         fprintf(stderr, "%s: shift = %04x data=%02x counter=%d\n", tts(cur_live.tm).cstr(), cur_live.shift_reg,
1293               (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) |
1294               (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) |
1295               (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) |
1296               (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) |
1297               (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) |
1298               (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) |
1299               (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) |
1300               (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00),
1301               cur_live.bit_counter);
1302#endif
1303         if(cur_live.bit_counter & 15)
1304            break;
1305
1306         int slot = cur_live.bit_counter >> 4;
1307
1308         if(slot < 3) {
1309            if(cur_live.shift_reg != 0x4489)
1310               cur_live.state = SEARCH_ADDRESS_MARK_HEADER;
1311            break;
1312         }
1313         if(cur_live.data_reg != 0xfe && cur_live.data_reg != 0xff) {
1314            cur_live.state = SEARCH_ADDRESS_MARK_HEADER;
1315            break;
1316         }
1317
1318         cur_live.bit_counter = 0;
1319
1320         if(main_state == READ_ID)
1321            cur_live.state = READ_ID_BLOCK_TO_DMA;
1322         else
1323            cur_live.state = READ_ID_BLOCK_TO_LOCAL;
1324
1325         break;
1326      }
1327
1328      case READ_ID_BLOCK_TO_LOCAL: {
1329         if(read_one_bit(limit))
1330            return;
1331         if(cur_live.bit_counter & 15)
1332            break;
1333         int slot = (cur_live.bit_counter >> 4)-1;
1334         cur_live.idbuf[slot] = cur_live.data_reg;
1335         if(slot == 5) {
1336            live_delay(IDLE);
1337            return;
1338         }
1339         break;
1340      }
1341
1342      case READ_ID_BLOCK_TO_DMA: {
1343         if(read_one_bit(limit))
1344            return;
1345         if(cur_live.bit_counter & 15)
1346            break;
1347         live_delay(READ_ID_BLOCK_TO_DMA_BYTE);
1348         return;
1349      }
1350
1351      case READ_ID_BLOCK_TO_DMA_BYTE:
1352         data = cur_live.data_reg;
1353         if(cur_live.bit_counter == 16)
1354            sector = data;
1355         set_drq();
1356
1357         if(cur_live.bit_counter == 16*6) {
1358            // Already synchronous
1359            cur_live.state = IDLE;
1360            return;
1361         }
1362
1363         cur_live.state = READ_ID_BLOCK_TO_DMA;
1364         checkpoint();
1365         break;
1366
1367      case SEARCH_ADDRESS_MARK_DATA:
1368         if(read_one_bit(limit))
1369            return;
1370#if 0
1371         fprintf(stderr, "%s: shift = %04x data=%02x c=%d.%x\n", tts(cur_live.tm).cstr(), cur_live.shift_reg,
1372               (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) |
1373               (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) |
1374               (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) |
1375               (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) |
1376               (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) |
1377               (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) |
1378               (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) |
1379               (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00),
1380               cur_live.bit_counter >> 4, cur_live.bit_counter & 15);
1381#endif
1382         if(cur_live.bit_counter > 43*16) {
1383            live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED);
1384            return;
1385         }
1386
1387         if(cur_live.bit_counter >= 28*16 && cur_live.shift_reg == 0x4489) {
1388            cur_live.crc = 0x443b;
1389            cur_live.data_separator_phase = false;
1390            cur_live.bit_counter = 0;
1391            cur_live.state = READ_DATA_BLOCK_HEADER;
1392         }
1393         break;
1394
1395      case READ_DATA_BLOCK_HEADER: {
1396         if(read_one_bit(limit))
1397            return;
1398#if 0
1399         fprintf(stderr, "%s: shift = %04x data=%02x counter=%d\n", tts(cur_live.tm).cstr(), cur_live.shift_reg,
1400               (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) |
1401               (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) |
1402               (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) |
1403               (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) |
1404               (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) |
1405               (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) |
1406               (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) |
1407               (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00),
1408               cur_live.bit_counter);
1409#endif
1410         if(cur_live.bit_counter & 15)
1411            break;
1412
1413         int slot = cur_live.bit_counter >> 4;
1414
1415         if(slot < 3) {
1416            if(cur_live.shift_reg != 0x4489) {
1417               live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED);
1418               return;
1419            }
1420            break;
1421         }
1422         if((cur_live.data_reg & 0xfe) != 0xfa && (cur_live.data_reg & 0xfe) != 0xfc) {
1423            live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED);
1424            return;
1425         }
1426
1427         cur_live.bit_counter = 0;
1428         cur_live.state = READ_SECTOR_DATA;
1429         break;
1430      }
1431
1432      case SEARCH_ADDRESS_MARK_DATA_FAILED:
1433         status |= S_RNF;
1434         cur_live.state = IDLE;
1435         return;
1436
1437      case READ_SECTOR_DATA: {
1438         if(read_one_bit(limit))
1439            return;
1440         if(cur_live.bit_counter & 15)
1441            break;
1442         int slot = (cur_live.bit_counter >> 4)-1;
1443         if(slot < sector_size) {
1444            // Sector data
1445            live_delay(READ_SECTOR_DATA_BYTE);
1446            return;
1447
1448         } else if(slot < sector_size+2) {
1449            // CRC
1450            if(slot == sector_size+1) {
1451               live_delay(IDLE);
1452               return;
1453            }
1454         }
1455
1456         break;
1457      }
1458
1459      case READ_SECTOR_DATA_BYTE:
1460         data = cur_live.data_reg;
1461         set_drq();
1462         cur_live.state = READ_SECTOR_DATA;
1463         checkpoint();
1464         break;
1465
1466      case READ_TRACK_DATA: {
1467         if(read_one_bit(limit))
1468            return;
1469         if(cur_live.bit_counter != 16
1470            && cur_live.shift_reg != 0x4489
1471            && cur_live.shift_reg != 0x5224)
1472            break;
1473
1474         // Incorrect, hmmm
1475         // Probably >2 + not just after a sync if <16
1476
1477         // Transitions 00..00 -> 4489.4489.4489 at varied syncs:
1478         //  0: 00.00.14.a1   1: ff.fe.c2.a1   2: 00.01.14.a1   3: ff.fc.c2.a1
1479         //  4: 00.02.14.a1   5: ff.f8.c2.a1   6: 00.05.14.a1   7: ff.f0.c2.a1
1480         //  8: 00.00.0a.a1   9: ff.ff.e1.a1  10: 00.00.14.a1  11: ff.ff.ce.a1
1481         // 12: 00.00.14.a1  13: ff.ff.c2.a1  14: 00.00.14.a1  15: ff.ff.c2.a1
1482
1483         bool output_byte = cur_live.bit_counter > 5;
1484
1485         cur_live.data_separator_phase = false;
1486         cur_live.bit_counter = 0;
1487
1488         if(output_byte) {
1489            live_delay(READ_TRACK_DATA_BYTE);
1490            return;
1491         }
1492
1493         break;
1494      }
1495
1496      case READ_TRACK_DATA_BYTE:
1497         data = cur_live.data_reg;
1498         set_drq();
1499         cur_live.state = READ_TRACK_DATA;
1500         checkpoint();
1501         break;
1502
1503      case WRITE_TRACK_DATA:
1504         if(drq) {
1505            status |= S_LOST;
1506            data = 0;
1507         }
1508
1509         switch(data) {
1510         case 0xf5:
1511            live_write_raw(0x4489);
1512            cur_live.crc = 0x968b; // Ensures that the crc is cdb4 after writing the byte
1513            cur_live.previous_type = live_info::PT_NONE;
1514            break;
1515         case 0xf6:
1516            cur_live.previous_type = live_info::PT_NONE;
1517            live_write_raw(0x5224);
1518            break;
1519         case 0xf7:
1520            if(cur_live.previous_type == live_info::PT_CRC_2) {
1521               cur_live.previous_type = live_info::PT_NONE;
1522               live_write_mfm(0xf7);
1523            } else {
1524               cur_live.previous_type = live_info::PT_CRC_1;
1525               live_write_mfm(cur_live.crc >> 8);
1526            }
1527            break;
1528         default:
1529            cur_live.previous_type = live_info::PT_NONE;
1530            live_write_mfm(data);
1531            break;
1532         }
1533         set_drq();
1534         cur_live.state = WRITE_BYTE;
1535         cur_live.bit_counter = 16;
1536         checkpoint();
1537         break;
1538
1539      case WRITE_BYTE:
1540         if(write_one_bit(limit))
1541            return;
1542         if(cur_live.bit_counter == 0) {
1543            live_delay(WRITE_BYTE_DONE);
1544            return;
1545         }
1546         break;
1547
1548      case WRITE_BYTE_DONE:
1549         switch(sub_state) {
1550         case TRACK_DONE:
1551            if(cur_live.previous_type == live_info::PT_CRC_1) {
1552               cur_live.previous_type = live_info::PT_CRC_2;
1553               live_write_mfm(cur_live.crc >> 8);
1554               cur_live.state = WRITE_BYTE;
1555               cur_live.bit_counter = 16;
1556               checkpoint();
1557            } else
1558               cur_live.state = WRITE_TRACK_DATA;
1559            break;
1560
1561         case SECTOR_WRITE:
1562            cur_live.state = WRITE_BYTE;
1563            cur_live.bit_counter = 16;
1564            cur_live.byte_counter++;
1565            if(cur_live.byte_counter <= 11)
1566               live_write_mfm(0x00);
1567            else if(cur_live.byte_counter == 12) {
1568               cur_live.crc = 0xffff;
1569               live_write_raw(0x4489);
1570            } else if(cur_live.byte_counter <= 14)
1571               live_write_raw(0x4489);
1572            else if(cur_live.byte_counter == 15)
1573               live_write_mfm(command & 1 ? 0xf8 : 0xfb);
1574            else if(cur_live.byte_counter <= sector_size + 16-2) {
1575               if(drq) {
1576                  status |= S_LOST;
1577                  data = 0;
1578               }
1579               live_write_mfm(data);
1580               set_drq();
1581            } else if(cur_live.byte_counter == sector_size + 16-1) {
1582               if(drq) {
1583                  status |= S_LOST;
1584                  data = 0;
1585               }
1586               live_write_mfm(data);
1587            } else if(cur_live.byte_counter <= sector_size + 16+1)
1588               live_write_mfm(cur_live.crc >> 8);
1589            else if(cur_live.byte_counter == sector_size + 16+2)
1590               // Is that correct?  It seems required (try ST formatting)
1591               live_write_mfm(0xff);
1592            else {
1593               cur_live.pll.stop_writing(floppy, cur_live.tm);
1594               cur_live.state = IDLE;
1595               return;
1596            }
1597
1598            checkpoint();
1599            break;
1600
1601         default:
1602            logerror("%s: Unknown sub state %d in WRITE_BYTE_DONE\n", tts(cur_live.tm).cstr(), sub_state);
1603            live_abort();
1604            return;
1605         }
1606         break;
1607
1608      case WRITE_SECTOR_PRE:
1609         if(read_one_bit(limit))
1610            return;
1611         if(cur_live.bit_counter != 16)
1612            break;
1613         live_delay(WRITE_SECTOR_PRE_BYTE);
1614         return;
1615
1616      case WRITE_SECTOR_PRE_BYTE:
1617         cur_live.state = WRITE_SECTOR_PRE;
1618         cur_live.byte_counter++;
1619         cur_live.bit_counter = 0;
1620         switch(cur_live.byte_counter) {
1621         case 2:
1622            set_drq();
1623            checkpoint();
1624            break;
1625         case 11:
1626            if(drq) {
1627               status |= S_LOST;
1628               cur_live.state = IDLE;
1629               return;
1630            }
1631            break;
1632         case 22:
1633            cur_live.state = WRITE_BYTE;
1634            cur_live.bit_counter = 16;
1635            cur_live.byte_counter = 0;
1636            cur_live.data_bit_context = cur_live.data_reg & 1;
1637            cur_live.pll.start_writing(cur_live.tm);
1638            live_write_mfm(0x00);
1639            break;
1640         }
1641         break;
1642
1643      default:
1644         logerror("%s: Unknown live state %d\n", tts(cur_live.tm).cstr(), cur_live.state);
1645         return;
1646      }
1647   }
1648}
1649
1650void wd177x_t::set_drq()
1651{
1652   if(drq)
1653      status |= S_LOST;
1654   else {
1655      drq = true;
1656      if(!drq_cb.isnull())
1657         drq_cb(true);
1658   }
1659}
1660
1661void wd177x_t::drop_drq()
1662{
1663   if(drq) {
1664      drq = false;
1665      if(!drq_cb.isnull())
1666         drq_cb(false);
1667   }
1668}
1669
1670void wd177x_t::pll_t::set_clock(attotime period)
1671{
1672   for(int i=0; i<42; i++)
1673      delays[i] = period*(i+1);
1674}
1675
1676void wd177x_t::pll_t::reset(attotime when)
1677{
1678   counter = 0;
1679   increment = 128;
1680   transition_time = 0xffff;
1681   history = 0x80;
1682   slot = 0;
1683   ctime = when;
1684   phase_add = 0x00;
1685   phase_sub = 0x00;
1686   freq_add  = 0x00;
1687   freq_sub  = 0x00;
1688   write_position = 0;
1689   write_start_time = attotime::never;
1690}
1691
1692int wd177x_t::pll_t::get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit)
1693{
1694   attotime when = floppy ? floppy->get_next_transition(ctime) : attotime::never;
1695#if 0
1696   if(!when.is_never())
1697      fprintf(stderr, "transition_time=%s\n", tts(when).cstr());
1698#endif
1699
1700   for(;;) {
1701      //      fprintf(stderr, "slot=%2d, counter=%03x\n", slot, counter);
1702      attotime etime = ctime+delays[slot];
1703      //      fprintf(stderr, "etime=%s\n", tts(etime).cstr());
1704      if(etime > limit)
1705         return -1;
1706      if(transition_time == 0xffff && !when.is_never() && etime >= when)
1707         transition_time = counter;
1708      if(slot < 8) {
1709         UINT8 mask = 1 << slot;
1710         if(phase_add & mask)
1711            counter += 226;
1712         else if(phase_sub & mask)
1713            counter += 30;
1714         else
1715            counter += increment;
1716
1717         if((freq_add & mask) && increment < 140)
1718            increment++;
1719         else if((freq_sub & mask) && increment > 117)
1720            increment--;
1721      } else
1722         counter += increment;
1723
1724      slot++;
1725      tm = etime;
1726      if(counter & 0x800)
1727         break;
1728   }
1729   //  fprintf(stderr, "first transition, time=%03x, inc=%3d\n", transition_time, increment);
1730   int bit = transition_time != 0xffff;
1731
1732   if(transition_time != 0xffff) {
1733      static const UINT8 pha[8] = { 0xf, 0x7, 0x3, 0x1, 0, 0, 0, 0 };
1734      static const UINT8 phs[8] = { 0, 0, 0, 0, 0x1, 0x3, 0x7, 0xf };
1735      static const UINT8 freqa[4][8] = {
1736         { 0xf, 0x7, 0x3, 0x1, 0, 0, 0, 0 },
1737         { 0x7, 0x3, 0x1, 0, 0, 0, 0, 0 },
1738         { 0x7, 0x3, 0x1, 0, 0, 0, 0, 0 },
1739         { 0, 0, 0, 0, 0, 0, 0, 0 }
1740      };
1741      static const UINT8 freqs[4][8] = {
1742         { 0, 0, 0, 0, 0, 0, 0, 0 },
1743         { 0, 0, 0, 0, 0, 0x1, 0x3, 0x7 },
1744         { 0, 0, 0, 0, 0, 0x1, 0x3, 0x7 },
1745         { 0, 0, 0, 0, 0x1, 0x3, 0x7, 0xf },
1746      };
1747
1748      int cslot = transition_time >> 8;
1749      phase_add = pha[cslot];
1750      phase_sub = phs[cslot];
1751      int way = transition_time & 0x400 ? 1 : 0;
1752      if(history & 0x80)
1753         history = way ? 0x80 : 0x83;
1754      else if(history & 0x40)
1755         history = way ? history & 2 : (history & 2) | 1;
1756      freq_add = freqa[history & 3][cslot];
1757      freq_sub = freqs[history & 3][cslot];
1758      history = way ? (history >> 1) | 2 : history >> 1;
1759
1760   } else
1761      phase_add = phase_sub = freq_add = freq_sub = 0;
1762
1763   counter &= 0x7ff;
1764
1765   ctime = tm;
1766   transition_time = 0xffff;
1767   slot = 0;
1768
1769   return bit;
1770}
1771
1772void wd177x_t::pll_t::start_writing(attotime tm)
1773{
1774   write_start_time = tm;
1775   write_position = 0;
1776}
1777
1778void wd177x_t::pll_t::stop_writing(floppy_image_device *floppy, attotime tm)
1779{
1780   commit(floppy, tm);
1781   write_start_time = attotime::never;
1782}
1783
1784bool wd177x_t::pll_t::write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit)
1785{
1786   if(write_start_time.is_never()) {
1787      write_start_time = ctime;
1788      write_position = 0;
1789   }
1790
1791   for(;;) {
1792      attotime etime = ctime+delays[slot];
1793      if(etime > limit)
1794         return true;
1795      UINT16 pre_counter = counter;
1796      counter += increment;
1797      if(bit && !(pre_counter & 0x400) && (counter & 0x400))
1798         if(write_position < ARRAY_LENGTH(write_buffer))
1799            write_buffer[write_position++] = etime;
1800      slot++;
1801      tm = etime;
1802      if(counter & 0x800)
1803         break;
1804   }
1805
1806   counter &= 0x7ff;
1807
1808   ctime = tm;
1809   slot = 0;
1810
1811   return false;
1812}
1813
1814void wd177x_t::pll_t::commit(floppy_image_device *floppy, attotime tm)
1815{
1816   if(write_start_time.is_never() || tm == write_start_time)
1817      return;
1818
1819   if(floppy)
1820      floppy->write_flux(write_start_time, tm, write_position, write_buffer);
1821   write_start_time = tm;
1822   write_position = 0;
1823}
1824
1825int wd177x_t::step_time(int mode) const
1826{
1827   const static int step_times[4] = { 48000, 96000, 160000, 240000 };
1828   return step_times[mode];
1829}
1830
1831int wd177x_t::settle_time() const
1832{
1833   return 240000;
1834}
1835
1836bool wd177x_t::has_ready() const
1837{
1838   return false;
1839}
1840
1841bool wd177x_t::has_head_load() const
1842{
1843   return false;
1844}
1845
1846bool wd177x_t::has_side_check() const
1847{
1848   return false;
1849}
1850
1851bool wd177x_t::has_side_select() const
1852{
1853   return false;
1854}
1855
1856bool wd177x_t::has_sector_length_select() const
1857{
1858   return false;
1859}
1860
1861bool wd177x_t::has_precompensation() const
1862{
1863   return false;
1864}
1865
1866fd1771_t::fd1771_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd177x_t(mconfig, FD1771x, "FD1771", tag, owner, clock)
1867{
1868}
1869
1870fd1793_t::fd1793_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd177x_t(mconfig, FD1793x, "FD1793", tag, owner, clock)
1871{
1872}
1873
1874fd1797_t::fd1797_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd177x_t(mconfig, FD1797x, "FD1797", tag, owner, clock)
1875{
1876}
1877
1878wd2793_t::wd2793_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd177x_t(mconfig, WD2793x, "WD2793", tag, owner, clock)
1879{
1880}
1881
1882wd2797_t::wd2797_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd177x_t(mconfig, WD2797x, "WD2797", tag, owner, clock)
1883{
1884}
1885
1886wd1770_t::wd1770_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd177x_t(mconfig, WD1770x, "WD1770", tag, owner, clock)
1887{
1888}
1889
1890wd1772_t::wd1772_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd177x_t(mconfig, WD1772x, "WD1772", tag, owner, clock)
1891{
1892}
1893
1894int wd1772_t::step_time(int mode) const
1895{
1896   const static int step_times[4] = { 48000, 96000, 16000, 24000 };
1897   return step_times[mode];
1898}
1899
1900int wd1772_t::settle_time() const
1901{
1902   return 120000;
1903}
1904
1905wd1773_t::wd1773_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd177x_t(mconfig, WD1773x, "WD1773", tag, owner, clock)
1906{
1907}
trunk/src/mess/machine/wd1772.h
r19165r19166
1#ifndef WD1772_H
2#define WD1772_H
3
4#include "emu.h"
5#include "imagedev/floppy.h"
6
7#define MCFG_FD1771x_ADD(_tag, _clock)  \
8   MCFG_DEVICE_ADD(_tag, FD1771x, _clock)
9
10#define MCFG_FD1793x_ADD(_tag, _clock)  \
11   MCFG_DEVICE_ADD(_tag, FD1793x, _clock)
12
13#define MCFG_FD1797x_ADD(_tag, _clock)  \
14   MCFG_DEVICE_ADD(_tag, FD1797x, _clock)
15
16#define MCFG_WD2793x_ADD(_tag, _clock)  \
17   MCFG_DEVICE_ADD(_tag, WD2793x, _clock)
18
19#define MCFG_WD2797x_ADD(_tag, _clock)  \
20   MCFG_DEVICE_ADD(_tag, WD2797x, _clock)
21
22#define MCFG_WD1770x_ADD(_tag, _clock)  \
23   MCFG_DEVICE_ADD(_tag, WD1770x, _clock)
24
25#define MCFG_WD1772x_ADD(_tag, _clock)  \
26   MCFG_DEVICE_ADD(_tag, WD1772x, _clock)
27
28#define MCFG_WD1773x_ADD(_tag, _clock)  \
29   MCFG_DEVICE_ADD(_tag, WD1773x, _clock)
30
31class wd177x_t : public device_t {
32public:
33   typedef delegate<void (bool state)> line_cb;
34
35   wd177x_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
36
37   void dden_w(bool dden);
38   void set_floppy(floppy_image_device *floppy);
39   void setup_intrq_cb(line_cb cb);
40   void setup_drq_cb(line_cb cb);
41   void setup_hld_cb(line_cb cb);
42   void setup_enp_cb(line_cb cb);
43
44   void cmd_w(UINT8 val);
45   UINT8 status_r();
46   DECLARE_READ8_MEMBER( status_r ) { return status_r(); }
47   DECLARE_WRITE8_MEMBER( cmd_w ) { cmd_w(data); }
48
49   void track_w(UINT8 val);
50   UINT8 track_r();
51   DECLARE_READ8_MEMBER( track_r ) { return track_r(); }
52   DECLARE_WRITE8_MEMBER( track_w ) { track_w(data); }
53
54   void sector_w(UINT8 val);
55   UINT8 sector_r();
56   DECLARE_READ8_MEMBER( sector_r ) { return sector_r(); }
57   DECLARE_WRITE8_MEMBER( sector_w ) { sector_w(data); }
58
59   void data_w(UINT8 val);
60   UINT8 data_r();
61   DECLARE_READ8_MEMBER( data_r ) { return data_r(); }
62   DECLARE_WRITE8_MEMBER( data_w ) { data_w(data); }
63
64   void gen_w(int reg, UINT8 val);
65   UINT8 gen_r(int reg);
66   DECLARE_READ8_MEMBER( read ) { return gen_r(offset);}
67   DECLARE_WRITE8_MEMBER( write ) { gen_w(offset,data); }
68
69   bool intrq_r();
70   bool drq_r();
71
72   bool hld_r();
73   void hlt_w(bool state);
74
75   bool enp_r();
76
77protected:
78   virtual void device_start();
79   virtual void device_reset();
80   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
81
82   virtual bool has_ready() const;
83   virtual bool has_motor() const = 0;
84   virtual bool has_head_load() const;
85   virtual bool has_side_check() const;
86   virtual bool has_side_select() const;
87   virtual bool has_sector_length_select() const;
88   virtual bool has_precompensation() const;
89   virtual int step_time(int mode) const;
90   virtual int settle_time() const;
91
92private:
93   enum { TM_GEN, TM_CMD, TM_TRACK, TM_SECTOR };
94
95   //  State machine general behaviour:
96   //
97   //  There are three levels of state.
98   //
99   //  Main state is associated to (groups of) commands.  They're set
100   //  by a *_start() function below, and the associated _continue()
101   //  function can then be called at pretty much any time.
102   //
103   //  Sub state is the state of execution within a command.  The
104   //  principle is that the *_start() function selects the initial
105   //  substate, then the *_continue() function decides what to do,
106   //  possibly changing state.  Eventually it can:
107   //  - decide to wait for an event (timer, index)
108   //  - end the command with command_end()
109   //  - start a live state (see below)
110   //
111   //  In the first case, it must first switch to a waiting
112   //  sub-state, then return.  The waiting sub-state must just
113   //  return immediatly when *_continue is called.  Eventually the
114   //  event handler function will advance the state machine to
115   //  another sub-state, and things will continue synchronously.
116   //
117   //  On command end it's also supposed to return immediatly.
118   //
119   //  The last option is to switch to the next sub-state, start a
120   //  live state with live_start() then return.  The next sub-state
121   //  will only be called once the live state is finished.
122   //
123   //  Live states change continually depending on the disk contents
124   //  until the next externally discernable event is found.  They
125   //  are checkpointing, run until an event is found, then they wait
126   //  for it.  When an event eventually happen the the changes are
127   //  either committed or replayed until the sync event time.
128   //
129   //  The transition to IDLE is only done on a synced event.  Some
130   //  other transitions, such as activating drq, are also done after
131   //  syncing without exiting live mode.  Syncing in live mode is
132   //  done by calling live_delay() with the state to change to after
133   //  syncing.
134
135   enum {
136      // General "doing nothing" state
137      IDLE,
138
139      // Main states - the commands
140      RESTORE,
141      SEEK,
142      STEP,
143      READ_SECTOR,
144      READ_TRACK,
145      READ_ID,
146      WRITE_TRACK,
147      WRITE_SECTOR,
148
149      // Sub states
150
151      SPINUP,
152      SPINUP_WAIT,
153      SPINUP_DONE,
154
155      SETTLE_WAIT,
156      SETTLE_DONE,
157
158      DATA_LOAD_WAIT,
159      DATA_LOAD_WAIT_DONE,
160
161      SEEK_MOVE,
162      SEEK_WAIT_STEP_TIME,
163      SEEK_WAIT_STEP_TIME_DONE,
164      SEEK_WAIT_STABILIZATION_TIME,
165      SEEK_WAIT_STABILIZATION_TIME_DONE,
166      SEEK_DONE,
167
168      WAIT_INDEX,
169      WAIT_INDEX_DONE,
170
171      SCAN_ID,
172      SCAN_ID_FAILED,
173
174      SECTOR_READ,
175      SECTOR_WRITE,
176      TRACK_DONE,
177
178      // Live states
179
180      SEARCH_ADDRESS_MARK_HEADER,
181      READ_HEADER_BLOCK_HEADER,
182      READ_DATA_BLOCK_HEADER,
183      READ_ID_BLOCK_TO_LOCAL,
184      READ_ID_BLOCK_TO_DMA,
185      READ_ID_BLOCK_TO_DMA_BYTE,
186      SEARCH_ADDRESS_MARK_DATA,
187      SEARCH_ADDRESS_MARK_DATA_FAILED,
188      READ_SECTOR_DATA,
189      READ_SECTOR_DATA_BYTE,
190      READ_TRACK_DATA,
191      READ_TRACK_DATA_BYTE,
192      WRITE_TRACK_DATA,
193      WRITE_BYTE,
194      WRITE_BYTE_DONE,
195      WRITE_SECTOR_PRE,
196      WRITE_SECTOR_PRE_BYTE,
197   };
198
199   struct pll_t {
200      UINT16 counter;
201      UINT16 increment;
202      UINT16 transition_time;
203      UINT8 history;
204      UINT8 slot;
205      UINT8 phase_add, phase_sub, freq_add, freq_sub;
206      attotime ctime;
207
208      attotime delays[42];
209
210      attotime write_start_time;
211      attotime write_buffer[32];
212      int write_position;
213
214      void set_clock(attotime period);
215      void reset(attotime when);
216      int get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit);
217      bool write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit);
218      void start_writing(attotime tm);
219      void commit(floppy_image_device *floppy, attotime tm);
220      void stop_writing(floppy_image_device *floppy, attotime tm);
221   };
222
223   struct live_info {
224      enum { PT_NONE, PT_CRC_1, PT_CRC_2 };
225
226      attotime tm;
227      int state, next_state;
228      UINT16 shift_reg;
229      UINT16 crc;
230      int bit_counter, byte_counter, previous_type;
231      bool data_separator_phase, data_bit_context;
232      UINT8 data_reg;
233      UINT8 idbuf[6];
234      pll_t pll;
235   };
236
237   enum {
238      S_BUSY = 0x01,
239      S_DRQ  = 0x02,
240      S_IP   = 0x02,
241      S_TR00 = 0x04,
242      S_LOST = 0x04,
243      S_CRC  = 0x08,
244      S_RNF  = 0x10,
245      S_HLD  = 0x20,
246      S_SPIN = 0x20, // WD1770, WD1772
247      S_DDM  = 0x20,
248      S_WF   = 0x20, // WD1773
249      S_WP   = 0x40,
250      S_NRDY = 0x80,
251      S_MON  = 0x80  // WD1770, WD1772
252   };
253
254   enum {
255      I_RDY = 0x01,
256      I_NRDY = 0x02,
257      I_IDX = 0x04,
258      I_IMM = 0x08
259   };
260
261   floppy_image_device *floppy;
262
263   emu_timer *t_gen, *t_cmd, *t_track, *t_sector;
264
265   bool dden, status_type_1, intrq, drq, hld, hlt, enp;
266   int main_state, sub_state;
267   UINT8 command, track, sector, data, status, intrq_cond;
268   int last_dir;
269
270   int counter, motor_timeout, sector_size;
271
272   int cmd_buffer, track_buffer, sector_buffer;
273
274   live_info cur_live, checkpoint_live;
275   line_cb intrq_cb, drq_cb, hld_cb, enp_cb;
276
277   static astring tts(attotime t);
278   astring ttsn();
279
280   void delay_cycles(emu_timer *tm, int cycles);
281
282   // Device timer subfunctions
283   void do_cmd_w();
284   void do_track_w();
285   void do_sector_w();
286   void do_generic();
287
288
289   // Main-state handling functions
290   void seek_start(int state);
291   void seek_continue();
292
293   void read_sector_start();
294   void read_sector_continue();
295
296   void read_track_start();
297   void read_track_continue();
298
299   void read_id_start();
300   void read_id_continue();
301
302   void write_track_start();
303   void write_track_continue();
304
305   void write_sector_start();
306   void write_sector_continue();
307
308   void interrupt_start();
309
310   void general_continue();
311   void command_end();
312
313   void spinup();
314   void index_callback(floppy_image_device *floppy, int state);
315   bool sector_matches() const;
316   bool is_ready();
317
318   void live_start(int live_state);
319   void live_abort();
320   void checkpoint();
321   void rollback();
322   void live_delay(int state);
323   void live_sync();
324   void live_run(attotime limit = attotime::never);
325   bool read_one_bit(attotime limit);
326   bool write_one_bit(attotime limit);
327
328   void live_write_raw(UINT16 raw);
329   void live_write_mfm(UINT8 mfm);
330
331   void drop_drq();
332   void set_drq();
333};
334
335class fd1771_t : public wd177x_t {
336public:
337   fd1771_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
338
339protected:
340   virtual bool has_ready() const { return true; }
341   virtual bool has_motor() const { return false; }
342   virtual bool has_head_load() const { return true; }
343   virtual bool has_side_check() const { return true; }
344};
345
346class fd1793_t : public wd177x_t {
347public:
348   fd1793_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
349
350protected:
351   virtual bool has_ready() const { return true; }
352   virtual bool has_motor() const { return false; }
353   virtual bool has_head_load() const { return true; }
354   virtual bool has_side_check() const { return true; }
355};
356
357class fd1797_t : public wd177x_t {
358public:
359   fd1797_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
360
361protected:
362   virtual bool has_ready() const { return true; }
363   virtual bool has_motor() const { return false; }
364   virtual bool has_head_load() const { return true; }
365   virtual bool has_side_select() const { return true; }
366   virtual bool has_sector_length_select() const { return true; }
367};
368
369class wd2793_t : public wd177x_t {
370public:
371   wd2793_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
372
373protected:
374   virtual bool has_ready() const { return true; }
375   virtual bool has_motor() const { return false; }
376   virtual bool has_head_load() const { return true; }
377   virtual bool has_side_check() const { return true; }
378};
379
380class wd2797_t : public wd177x_t {
381public:
382   wd2797_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
383
384protected:
385   virtual bool has_ready() const { return true; }
386   virtual bool has_motor() const { return false; }
387   virtual bool has_head_load() const { return true; }
388   virtual bool has_side_select() const { return true; }
389   virtual bool has_sector_length_select() const { return true; }
390};
391
392class wd1770_t : public wd177x_t {
393public:
394   wd1770_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
395
396protected:
397   virtual bool has_motor() const { return true; }
398   virtual bool has_precompensation() const { return true; }
399};
400
401class wd1772_t : public wd177x_t {
402public:
403   wd1772_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
404
405protected:
406   virtual bool has_motor() const { return true; }
407   virtual bool has_precompensation() const { return true; }
408   virtual int step_time(int mode) const;
409   virtual int settle_time() const;
410};
411
412class wd1773_t : public wd177x_t {
413public:
414   wd1773_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
415
416protected:
417   virtual bool has_motor() const { return false; }
418   virtual bool has_head_load() const { return true; }
419   virtual bool has_side_check() const { return true; }
420};
421
422extern const device_type FD1771x;
423extern const device_type FD1793x;
424extern const device_type FD1797x;
425extern const device_type WD2793x;
426extern const device_type WD2797x;
427extern const device_type WD1770x;
428extern const device_type WD1772x;
429extern const device_type WD1773x;
430
431#endif
trunk/src/mess/machine/pc_fdc.h
r19165r19166
99
1010#include "emu.h"
1111#include "imagedev/floppy.h"
12#include "upd765.h"
12#include "machine/upd765.h"
1313
1414#define MCFG_PC_FDC_XT_ADD(_tag) \
1515   MCFG_DEVICE_ADD(_tag, PC_FDC_XT, 0)

Previous 199869 Revisions Next


© 1997-2024 The MAME Team