Previous 199869 Revisions Next

r19414 Saturday 8th December, 2012 at 18:35:12 UTC by O. Galibert
cleanups (nw)
[src/mess/drivers]mikromik.c pc88va.c
[src/mess/machine]pc_fdc.c

trunk/src/mess/machine/pc_fdc.c
r19413r19414
195195{
196196   m_shortname = "pc_fdc_at";
197197}
198
199#if 0
200
201
202/* if not 1, DACK and TC inputs to FDC are disabled, and DRQ and IRQ are held
203 * at high impedance i.e they are not affective */
204#define PC_FDC_FLAGS_DOR_DMA_ENABLED   (1<<3)
205#define PC_FDC_FLAGS_DOR_FDC_ENABLED   (1<<2)
206#define PC_FDC_FLAGS_DOR_MOTOR_ON      (1<<4)
207
208#define LOG_FDC      0
209
210/* registers etc */
211struct pc_fdc
212{
213   int status_register_a;
214   int status_register_b;
215   int digital_output_register;
216   int tape_drive_register;
217   int data_rate_register;
218   int digital_input_register;
219   int configuration_control_register;
220
221   /* stored tc state - state present at pins */
222   int tc_state;
223   /* stored dma drq state */
224   int dma_state;
225   /* stored int state */
226   int int_state;
227
228   /* PCJR watchdog timer */
229   emu_timer   *watchdog;
230
231   struct pc_fdc_interface fdc_interface;
232};
233
234static struct pc_fdc *fdc;
235
236/* Prototypes */
237
238static TIMER_CALLBACK( watchdog_timeout );
239
240static WRITE_LINE_DEVICE_HANDLER(  pc_fdc_hw_interrupt );
241static WRITE_LINE_DEVICE_HANDLER( pc_fdc_hw_dma_drq );
242static UPD765_GET_IMAGE ( pc_fdc_get_image );
243static UPD765_GET_IMAGE ( pcjr_fdc_get_image );
244
245const upd765_interface pc_fdc_upd765_connected_interface =
246{
247   DEVCB_LINE(pc_fdc_hw_interrupt),
248   DEVCB_LINE(pc_fdc_hw_dma_drq),
249   pc_fdc_get_image,
250   UPD765_RDY_PIN_CONNECTED,
251   {FLOPPY_0, FLOPPY_1, NULL, NULL}
252};
253
254const upd765_interface pc_fdc_upd765_connected_1_drive_interface =
255{
256   DEVCB_LINE(pc_fdc_hw_interrupt),
257   DEVCB_LINE(pc_fdc_hw_dma_drq),
258   pc_fdc_get_image,
259   UPD765_RDY_PIN_CONNECTED,
260   {FLOPPY_0, NULL, NULL, NULL}
261};
262
263
264const upd765_interface pc_fdc_upd765_not_connected_interface =
265{
266   DEVCB_LINE(pc_fdc_hw_interrupt),
267   DEVCB_LINE(pc_fdc_hw_dma_drq),
268   pc_fdc_get_image,
269   UPD765_RDY_PIN_NOT_CONNECTED,
270   {FLOPPY_0, FLOPPY_1, NULL, NULL}
271};
272
273const upd765_interface pcjr_fdc_upd765_interface =
274{
275   DEVCB_LINE(pc_fdc_hw_interrupt),
276   DEVCB_NULL,
277   pcjr_fdc_get_image,
278   UPD765_RDY_PIN_NOT_CONNECTED,
279   {FLOPPY_0, NULL, NULL, NULL}
280};
281
282
283static device_t* pc_get_device(running_machine &machine)
284{
285   return (*fdc->fdc_interface.get_device)(machine);
286}
287
288void pc_fdc_reset(running_machine &machine)
289{
290   /* setup reset condition */
291   fdc->data_rate_register = 2;
292   fdc->digital_output_register = 0;
293
294   /* bit 7 is disk change */
295   fdc->digital_input_register = 0x07f;
296
297   upd765_reset(pc_get_device(machine),0);
298
299   /* set FDC at reset */
300   upd765_reset_w(pc_get_device(machine), 1);
301}
302
303
304
305void pc_fdc_init(running_machine &machine, const struct pc_fdc_interface *iface)
306{
307   /* initialize fdc structure */
308   fdc = auto_alloc_clear(machine, struct pc_fdc);
309
310   /* copy specified interface */
311   if (iface)
312      memcpy(&fdc->fdc_interface, iface, sizeof(fdc->fdc_interface));
313
314   fdc->watchdog = machine.scheduler().timer_alloc(FUNC(watchdog_timeout));
315
316   pc_fdc_reset(machine);
317}
318
319
320
321static UPD765_GET_IMAGE ( pc_fdc_get_image )
322{
323   device_t *image = NULL;
324
325   if (!fdc->fdc_interface.get_image)
326   {
327      image = floppy_get_device(device->machine(), (fdc->digital_output_register & 0x03));
328   }
329   else
330   {
331      image = fdc->fdc_interface.get_image(device->machine(), (fdc->digital_output_register & 0x03));
332   }
333   return image;
334}
335
336static UPD765_GET_IMAGE ( pcjr_fdc_get_image )
337{
338   device_t *image = NULL;
339
340   if (!fdc->fdc_interface.get_image)
341   {
342      image = floppy_get_device(device->machine(), 0);
343   }
344   else
345   {
346      image = fdc->fdc_interface.get_image(device->machine(), 0);
347   }
348   return image;
349}
350
351void pc_fdc_set_tc_state(running_machine &machine, int state)
352{
353   /* store state */
354   fdc->tc_state = state;
355
356   /* if dma is not enabled, tc's are not acknowledged */
357   if ((fdc->digital_output_register & PC_FDC_FLAGS_DOR_DMA_ENABLED)!=0)
358   {
359      upd765_tc_w(pc_get_device(machine), state);
360   }
361}
362
363
364
365static WRITE_LINE_DEVICE_HANDLER(  pc_fdc_hw_interrupt )
366{
367   fdc->int_state = state;
368
369   /* if dma is not enabled, irq's are masked */
370   if ((fdc->digital_output_register & PC_FDC_FLAGS_DOR_DMA_ENABLED)==0)
371      return;
372
373   /* send irq */
374   if (fdc->fdc_interface.pc_fdc_interrupt)
375      fdc->fdc_interface.pc_fdc_interrupt(device->machine(), state);
376}
377
378
379
380int   pc_fdc_dack_r(running_machine &machine, address_space &space)
381{
382   int data;
383
384   /* what is output if dack is not acknowledged? */
385   data = 0x0ff;
386
387   /* if dma is not enabled, dacks are not acknowledged */
388   if ((fdc->digital_output_register & PC_FDC_FLAGS_DOR_DMA_ENABLED)!=0)
389   {
390      data = upd765_dack_r(pc_get_device(machine), space, 0);
391   }
392
393   return data;
394}
395
396
397
398void pc_fdc_dack_w(running_machine &machine, address_space &space, int data)
399{
400   /* if dma is not enabled, dacks are not issued */
401   if ((fdc->digital_output_register & PC_FDC_FLAGS_DOR_DMA_ENABLED)!=0)
402   {
403      /* dma acknowledge - and send byte to fdc */
404      upd765_dack_w(pc_get_device(machine), space, 0,data);
405   }
406}
407
408
409
410static WRITE_LINE_DEVICE_HANDLER( pc_fdc_hw_dma_drq )
411{
412   fdc->dma_state = state;
413
414   /* if dma is not enabled, drqs are masked */
415   if ((fdc->digital_output_register & PC_FDC_FLAGS_DOR_DMA_ENABLED)==0)
416      return;
417
418   if (fdc->fdc_interface.pc_fdc_dma_drq)
419      fdc->fdc_interface.pc_fdc_dma_drq(device->machine(), state);
420}
421
422
423
424static void pc_fdc_data_rate_w(running_machine &machine, UINT8 data)
425{
426   if ((data & 0x080)!=0)
427   {
428      /* set ready state */
429      upd765_ready_w(pc_get_device(machine),1);
430
431      /* toggle reset state */
432      upd765_reset_w(pc_get_device(machine), 1);
433      upd765_reset_w(pc_get_device(machine), 0);
434
435      /* bit is self-clearing */
436      data &= ~0x080;
437   }
438
439   fdc->data_rate_register = data;
440}
441
442
443
444/*  FDC Digitial Output Register (DOR)
445
446    |7|6|5|4|3|2|1|0|
447     | | | | | | `------ floppy drive select (0=A, 1=B, 2=floppy C, ...)
448     | | | | | `-------- 1 = FDC enable, 0 = hold FDC at reset
449     | | | | `---------- 1 = DMA & I/O interface enabled
450     | | | `------------ 1 = turn floppy drive A motor on
451     | | `-------------- 1 = turn floppy drive B motor on
452     | `---------------- 1 = turn floppy drive C motor on
453     `------------------ 1 = turn floppy drive D motor on
454 */
455
456static WRITE8_HANDLER( pc_fdc_dor_w )
457{
458   int selected_drive;
459   int floppy_count;
460
461   floppy_count = floppy_get_count(space.machine());
462
463   if (floppy_count > (fdc->digital_output_register & 0x03))
464      floppy_drive_set_ready_state(floppy_get_device(space.machine(), fdc->digital_output_register & 0x03), 1, 0);
465
466   fdc->digital_output_register = data;
467
468   selected_drive = data & 0x03;
469
470   /* set floppy drive motor state */
471   if (floppy_count > 0)
472      floppy_mon_w(floppy_get_device(space.machine(), 0), !BIT(data, 4));
473   if (floppy_count > 1)
474      floppy_mon_w(floppy_get_device(space.machine(), 1), !BIT(data, 5));
475   if (floppy_count > 2)
476      floppy_mon_w(floppy_get_device(space.machine(), 2), !BIT(data, 6));
477   if (floppy_count > 3)
478      floppy_mon_w(floppy_get_device(space.machine(), 3), !BIT(data, 7));
479
480   if ((data>>4) & (1<<selected_drive))
481   {
482      if (floppy_count > selected_drive)
483         floppy_drive_set_ready_state(floppy_get_device(space.machine(), selected_drive), 1, 0);
484   }
485
486   /* changing the DMA enable bit, will affect the terminal count state
487    from reaching the fdc - if dma is enabled this will send it through
488    otherwise it will be ignored */
489   pc_fdc_set_tc_state(space.machine(), fdc->tc_state);
490
491   /* changing the DMA enable bit, will affect the dma drq state
492    from reaching us - if dma is enabled this will send it through
493    otherwise it will be ignored */
494   pc_fdc_hw_dma_drq(pc_get_device(space.machine()), fdc->dma_state);
495
496   /* changing the DMA enable bit, will affect the irq state
497    from reaching us - if dma is enabled this will send it through
498    otherwise it will be ignored */
499   pc_fdc_hw_interrupt(pc_get_device(space.machine()), fdc->int_state);
500
501   /* reset? */
502   if ((fdc->digital_output_register & PC_FDC_FLAGS_DOR_FDC_ENABLED)==0)
503   {
504      /* yes */
505
506         /* pc-xt expects a interrupt to be generated
507            when the fdc is reset.
508            In the FDC docs, it states that a INT will
509            be generated if READY input is true when the
510            fdc is reset.
511
512                It also states, that outputs to drive are set to 0.
513                Maybe this causes the drive motor to go on, and therefore
514                the ready line is set.
515
516            This in return causes a int?? ---
517
518
519        what is not yet clear is if this is a result of the drives ready state
520        changing...
521        */
522         upd765_ready_w(pc_get_device(space.machine()),1);
523
524      /* set FDC at reset */
525      upd765_reset_w(pc_get_device(space.machine()), 1);
526   }
527   else
528   {
529      pc_fdc_set_tc_state(space.machine(), 0);
530
531      /* release reset on fdc */
532      upd765_reset_w(pc_get_device(space.machine()), 0);
533   }
534}
535
536/*  PCJr FDC Digitial Output Register (DOR)
537
538    On a PC Jr the DOR is wired up a bit differently:
539    |7|6|5|4|3|2|1|0|
540     | | | | | | | `--- Drive enable ( 0 = off, 1 = on )
541     | | | | | | `----- Reserved
542     | | | | | `------- Reserved
543     | | | | `--------- Reserved
544     | | | `----------- Reserved
545     | | `------------- Watchdog Timer Enable ( 0 = watchdog disabled, 1 = watchdog enabled )
546     | `--------------- Watchdog Timer Trigger ( on a 1->0 transition to strobe the trigger )
547     `----------------- FDC Reset ( 0 = hold reset, 1 = release reset )
548 */
549
550static TIMER_CALLBACK( watchdog_timeout )
551{
552   /* Trigger a watchdog timeout signal */
553   if ( fdc->fdc_interface.pc_fdc_interrupt && ( fdc->digital_output_register & 0x20 )  )
554   {
555      fdc->fdc_interface.pc_fdc_interrupt(machine, 1 );
556   }
557   else
558   {
559      fdc->fdc_interface.pc_fdc_interrupt(machine, 0 );
560   }
561}
562
563static WRITE8_HANDLER( pcjr_fdc_dor_w )
564{
565   int floppy_count;
566
567   floppy_count = floppy_get_count(space.machine());
568
569   /* set floppy drive motor state */
570   if (floppy_count > 0)
571      floppy_mon_w(floppy_get_device(space.machine(), 0), BIT(data, 0) ? CLEAR_LINE : ASSERT_LINE);
572
573   if ( data & 0x01 )
574   {
575      if ( floppy_count )
576         floppy_drive_set_ready_state(floppy_get_device(space.machine(), 0), 1, 0);
577   }
578
579   /* Is the watchdog timer disabled */
580   if ( ! ( data & 0x20 ) )
581   {
582      fdc->watchdog->adjust( attotime::never );
583      if ( fdc->fdc_interface.pc_fdc_interrupt )
584      {
585         fdc->fdc_interface.pc_fdc_interrupt(space.machine(), 0 );
586      }
587   } else {
588      /* Check for 1->0 watchdog trigger */
589      if ( ( fdc->digital_output_register & 0x40 ) && ! ( data & 0x40 ) )
590      {
591         /* Start watchdog timer here */
592         fdc->watchdog->adjust( attotime::from_seconds(3) );
593      }
594   }
595
596   /* reset? */
597   if ( ! (data & 0x80) )
598   {
599      /* yes */
600
601         /* pc-xt expects a interrupt to be generated
602            when the fdc is reset.
603            In the FDC docs, it states that a INT will
604            be generated if READY input is true when the
605            fdc is reset.
606
607                It also states, that outputs to drive are set to 0.
608                Maybe this causes the drive motor to go on, and therefore
609                the ready line is set.
610
611            This in return causes a int?? ---
612
613
614        what is not yet clear is if this is a result of the drives ready state
615        changing...
616        */
617         upd765_ready_w(pc_get_device(space.machine()),1);
618
619      /* set FDC at reset */
620      upd765_reset_w(pc_get_device(space.machine()), 1);
621   }
622   else
623   {
624      pc_fdc_set_tc_state(space.machine(), 0);
625
626      /* release reset on fdc */
627      upd765_reset_w(pc_get_device(space.machine()), 0);
628   }
629
630   logerror("pcjr_fdc_dor_w: changing dor from %02x to %02x\n", fdc->digital_output_register, data);
631
632   fdc->digital_output_register = data;
633}
634
635#define RATE_250  2
636#define RATE_300  1
637#define RATE_500  0
638#define RATE_1000 3
639
640static void pc_fdc_check_data_rate(running_machine &machine)
641{
642   device_t *device = floppy_get_device(machine, fdc->digital_output_register & 0x03);
643   floppy_image_legacy *image;
644   int tracks, sectors, rate;
645
646   upd765_set_bad(pc_get_device(machine), 0); // unset in case format is unknown
647   if (!device) return;
648   image = flopimg_get_image(device);
649   if (!image) return;
650   tracks = floppy_get_tracks_per_disk(image);
651   tracks -= (tracks % 10); // ignore extra tracks
652   floppy_get_sector_count(image, 0, 0, &sectors);
653
654   if (tracks == 40) {
655      if ((fdc->data_rate_register != RATE_250) && (fdc->data_rate_register != RATE_300))
656         upd765_set_bad(pc_get_device(machine), 1);
657      return;
658   } else if (tracks == 80) {
659      if (sectors <= 14)      rate = RATE_250;    // 720KB 5 1/4 and 3 1/2
660      else if (sectors <= 24) rate = RATE_500;    // 1.2MB 5 1/4 and 1.44MB 3 1/2
661      else                    rate = RATE_1000;   // 2.88MB 3 1/2
662   } else return;
663
664   if (rate != (fdc->data_rate_register & 3))
665      upd765_set_bad(pc_get_device(machine), 1);
666}
667
668READ8_HANDLER ( pc_fdc_r )
669{
670   UINT8 data = 0xff;
671
672   switch(offset)
673   {
674      case 0: /* status register a */
675      case 1: /* status register b */
676         data = 0x00;
677         break;
678      case 2:
679         data = fdc->digital_output_register;
680         break;
681      case 3: /* tape drive select? */
682         break;
683      case 4:
684         data = upd765_status_r(pc_get_device(space.machine()), space, 0);
685         break;
686      case 5:
687         data = upd765_data_r(pc_get_device(space.machine()), space, offset);
688         break;
689      case 6: /* FDC reserved */
690         break;
691      case 7:
692         device_t *dev = floppy_get_device(space.machine(), fdc->digital_output_register & 0x03);
693         data = fdc->digital_input_register;
694         if(dev) data |= (!floppy_dskchg_r(dev)<<7);
695         break;
696    }
697
698   if (LOG_FDC)
699      logerror("pc_fdc_r(): pc=0x%08x offset=%d result=0x%02X\n", (unsigned) space.machine().firstcpu->pc(), offset, data);
700   return data;
701}
702
703
704
705WRITE8_HANDLER ( pc_fdc_w )
706{
707   if (LOG_FDC)
708      logerror("pc_fdc_w(): pc=0x%08x offset=%d data=0x%02X\n", (unsigned) space.machine().firstcpu->pc(), offset, data);
709
710   pc_fdc_check_data_rate(space.machine());  // check every time a command may start
711   switch(offset)
712   {
713      case 0:   /* n/a */
714      case 1:   /* n/a */
715         break;
716      case 2:
717         pc_fdc_dor_w(space, 0, data, mem_mask);
718         break;
719      case 3:
720         /* tape drive select? */
721         break;
722      case 4:
723         pc_fdc_data_rate_w(space.machine(), data);
724         break;
725      case 5:
726         upd765_data_w(pc_get_device(space.machine()), space, 0, data);
727         break;
728      case 6:
729         /* FDC reserved */
730         break;
731      case 7:
732         /* Configuration Control Register
733             *
734             * Currently unimplemented; bits 1-0 are supposed to control data
735             * flow rates:
736             *      0 0      500 kbps
737             *      0 1      300 kbps
738             *      1 0      250 kbps
739             *      1 1     1000 kbps
740             */
741         pc_fdc_data_rate_w(space.machine(), data & 3);
742         break;
743   }
744}
745
746WRITE8_HANDLER ( pcjr_fdc_w )
747{
748   if (LOG_FDC)
749      logerror("pcjr_fdc_w(): pc=0x%08x offset=%d data=0x%02X\n", (unsigned) space.machine().firstcpu->pc(), offset, data);
750
751   switch(offset)
752   {
753      case 2:
754         pcjr_fdc_dor_w( space, 0, data, mem_mask );
755         break;
756      case 4:
757      case 7:
758         break;
759      default:
760         pc_fdc_w( space, offset, data );
761         break;
762   }
763}
764
765#endif
trunk/src/mess/drivers/pc88va.c
r19413r19414
10241024   m_fdc_motor_status[1] = 1;
10251025}
10261026
1027/* TODO: double check schematics */
10281027void pc88va_state::pc88va_fdc_update_ready(floppy_image_device *, int)
10291028{
1030   bool ready_0 = m_fdc_ctrl_2 & 0x20;
1031   bool ready_1 = m_fdc_ctrl_2 & 0x40;
1029   bool ready = m_fdc_ctrl_2 & 0x40;
10321030
10331031   floppy_image_device *floppy;
10341032   floppy = machine().device<floppy_connector>("upd765:0")->get_device();
1035   if(floppy && ready_0)
1036      ready_0 = floppy->ready_r();
1033   if(floppy && ready)
1034      ready = floppy->ready_r();
10371035   floppy = machine().device<floppy_connector>("upd765:1")->get_device();
1038   if(floppy && ready_1)
1039      ready_1 = floppy->ready_r();
1036   if(floppy && ready)
1037      ready = floppy->ready_r();
10401038
1041   m_fdc->ready_w(ready_0 && ready_1);
1039   m_fdc->ready_w(ready);
10421040}
10431041
10441042WRITE8_MEMBER(pc88va_state::pc88va_fdc_w)
trunk/src/mess/drivers/mikromik.c
r19413r19414
250250      if (LOG) logerror("MOTOR %u\n", d);
251251      m_floppy0->mon_w(!d);
252252      m_floppy1->mon_w(!d);
253
254      if (ioport("T5")->read()) m_fdc->ready_w(d);
255253      break;
256254   }
257255}
r19413r19414
745743   // reset LS259
746744   for (i = 0; i < 8; i++) ls259_w(program, i, 0);
747745
748   // set FDC ready
749   if (!ioport("T5")->read()) m_fdc->ready_w(true);
750
751746   // reset FDC
752747   m_fdc->reset();
753748}

Previous 199869 Revisions Next


© 1997-2024 The MAME Team