26
26
*/
27
27
28
28
/*
29
-
30
- TODO:
31
-
32
- - write protect
33
- - separate read/write methods
34
- - communication error with SCP after loading boot sector
35
- - bp ff1a8
36
- - patch ff1ab=c3
37
- - 8048 spindle speed control
38
-
29
+ TODO: write protect
39
30
*/
40
31
41
32
#include " emu.h"
42
33
#include " victor9k_fdc.h"
43
34
44
-
45
35
// **************************************************************************
46
36
// LOGGING
47
37
// **************************************************************************
82
72
// Tandon TM-100 spindle @ 300RPM, measured TACH 12VAC 256Hz
83
73
// TACH = RPM / 60 * SPINDLE RATIO * MOTOR POLES
84
74
// 256 = 300 / 60 * 6.4 * 8
85
- #define SPINDLE_RATIO 6.4
75
+ #define SPINDLE_RATIO 6.4 // Motor RPM divided by Disk RPM
86
76
#define MOTOR_POLES 8.0
87
77
88
- // TODO wrong values here! motor speed is controlled by an LM2917, with help from the spindle TACH and a DAC0808 whose value is set by the SCP 8048
89
- const int victor_9000_fdc_device::rpm[] = { 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 254, 255, 257, 259, 260, 262, 264, 266, 267, 269, 271, 273, 275, 276, 278, 280, 282, 284, 286, 288, 290, 291, 293, 295, 297, 299, 301, 303, 305, 307, 309, 311, 313, 315, 318, 320, 322, 324, 326, 328, 330, 333, 335, 337, 339, 342, 344, 346, 348, 351, 353, 355, 358, 360, 362, 365, 367, 370, 372, 375, 377, 380, 382, 385, 387, 390, 392, 395, 398, 400, 403, 406, 408, 411, 414, 416, 419, 422, 425, 428, 430, 433, 436, 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472, 475, 478, 482, 485, 488, 491, 494, 498, 501, 504, 508, 511, 514, 518, 521, 525, 528, 532, 535, 539, 542, 546, 550, 553, 557, 561, 564, 568, 572, 576, 579, 583, 587, 591, 595, 599, 603, 607, 611, 615, 619, 623, 627, 631, 636, 640, 644, 648, 653, 657, 661, 666, 670, 674, 679, 683, 688, 693, 697, 702, 706, 711, 716, 721, 725, 730, 735, 740, 745, 750, 755, 760, 765, 770, 775, 780, 785, 790, 796, 801, 806, 812, 817, 822, 828, 833, 839, 844, 850, 856, 861, 867, 873, 878, 884 };
90
-
91
-
92
78
93
79
// **************************************************************************
94
80
// DEVICE DEFINITIONS
@@ -193,6 +179,7 @@ void victor_9000_fdc_device::device_add_mconfig(machine_config &config)
193
179
connector->option_add (" 525qd" , FLOPPY_525_QD); // Tandon TM100-4 with custom electronics
194
180
connector->set_default_option (" 525qd" );
195
181
connector->set_formats (floppy_formats);
182
+ connector->enable_sound (true );
196
183
}
197
184
}
198
185
@@ -217,13 +204,12 @@ victor_9000_fdc_device::victor_9000_fdc_device(const machine_config &mconfig, co
217
204
m_floppy(*this , I8048_TAG" :%u" , 0U ),
218
205
m_gcr_rom(*this , " gcr" ),
219
206
m_leds(*this , " led%u" , 0U ),
220
- m_data(0 ),
221
207
m_da{0 , 0 },
222
208
m_start{1 , 1 },
223
209
m_stop{1 , 1 },
224
210
m_sel{0 , 0 },
225
211
m_tach{0 , 0 },
226
- m_rdy {0 , 0 },
212
+ m_tach_hz {0 , 0 },
227
213
m_scp_rdy0 (0 ),
228
214
m_scp_rdy1(0 ),
229
215
m_via_rdy0(1 ),
@@ -261,13 +247,12 @@ void victor_9000_fdc_device::device_start()
261
247
t_tach[1 ] = timer_alloc (FUNC (victor_9000_fdc_device::tach1_tick), this );
262
248
263
249
// state saving
264
- save_item (NAME (m_data));
265
250
save_item (NAME (m_da));
266
251
save_item (NAME (m_start));
267
252
save_item (NAME (m_stop));
268
253
save_item (NAME (m_sel));
269
254
save_item (NAME (m_tach));
270
- save_item (NAME (m_rdy ));
255
+ save_item (NAME (m_tach_hz ));
271
256
save_item (NAME (m_scp_rdy0));
272
257
save_item (NAME (m_scp_rdy1));
273
258
save_item (NAME (m_via_rdy0));
@@ -294,6 +279,8 @@ void victor_9000_fdc_device::device_start()
294
279
295
280
void victor_9000_fdc_device::device_reset ()
296
281
{
282
+ m_maincpu->set_input_line (INPUT_LINE_RESET, ASSERT_LINE);
283
+
297
284
live_abort ();
298
285
299
286
// reset devices
@@ -330,12 +317,16 @@ TIMER_CALLBACK_MEMBER(victor_9000_fdc_device::tach0_tick)
330
317
{
331
318
m_tach[0 ] = !m_tach[0 ];
332
319
LOGSCP (" %s TACH0 %u\n " , machine ().time ().as_string (), m_tach[0 ]);
320
+
321
+ t_tach[0 ]->adjust (attotime::from_hz (m_tach_hz[0 ]*2 ));
333
322
}
334
323
335
324
TIMER_CALLBACK_MEMBER (victor_9000_fdc_device::tach1_tick)
336
325
{
337
326
m_tach[1 ] = !m_tach[1 ];
338
327
LOGSCP (" %s TACH1 %u\n " , machine ().time ().as_string (), m_tach[1 ]);
328
+
329
+ t_tach[1 ]->adjust (attotime::from_hz (m_tach_hz[1 ]*2 ));
339
330
}
340
331
341
332
@@ -467,7 +458,7 @@ void victor_9000_fdc_device::floppy_p2_w(uint8_t data)
467
458
m_scp_rdy1 = BIT (data, 7 );
468
459
update_rdy ();
469
460
470
- LOGSCP (" %s %s START0/STOP0/SEL0/RDY0 %u/%u/%u/%u START1/STOP1/SEL1/RDY1 %u/%u/%u/%u\n " , machine ().time ().as_string (), machine ().describe_context (), start0, stop0, sel0, m_rdy[ 0 ] , start1, stop1, sel1, m_rdy[ 1 ] );
461
+ LOGSCP (" %s %s START0/STOP0/SEL0/RDY0 %u/%u/%u/%u START1/STOP1/SEL1/RDY1 %u/%u/%u/%u\n " , machine ().time ().as_string (), machine ().describe_context (), start0, stop0, sel0, m_scp_rdy0 , start1, stop1, sel1, m_scp_rdy1 );
471
462
472
463
if (sync)
473
464
{
@@ -476,14 +467,14 @@ void victor_9000_fdc_device::floppy_p2_w(uint8_t data)
476
467
m_start[0 ] = start0;
477
468
m_stop[0 ] = stop0;
478
469
m_sel[0 ] = sel0;
479
- update_spindle_motor (m_floppy[0 ]->get_device (), t_tach[0 ], m_start [0 ], m_stop [0 ], m_sel[ 0 ], m_da [0 ]);
480
- update_rpm (m_floppy[0 ]->get_device (), t_tach[0 ], m_sel[0 ], m_da [0 ]);
470
+ update_rpm (m_floppy[0 ]->get_device (), t_tach[0 ], m_sel [0 ], m_da [0 ], m_tach_hz [0 ]);
471
+ update_spindle_motor (m_floppy[0 ]->get_device (), t_tach[0 ], m_start[ 0 ], m_stop[ 0 ], m_sel[0 ], m_tach_hz [0 ]);
481
472
482
473
m_start[1 ] = start1;
483
474
m_stop[1 ] = stop1;
484
475
m_sel[1 ] = sel1;
485
- update_spindle_motor (m_floppy[1 ]->get_device (), t_tach[1 ], m_start [1 ], m_stop [1 ], m_sel[ 1 ], m_da [1 ]);
486
- update_rpm (m_floppy[1 ]->get_device (), t_tach[1 ], m_sel[1 ], m_da [1 ]);
476
+ update_rpm (m_floppy[1 ]->get_device (), t_tach[1 ], m_sel [1 ], m_da [1 ], m_tach_hz [1 ]);
477
+ update_spindle_motor (m_floppy[1 ]->get_device (), t_tach[1 ], m_start[ 1 ], m_stop[ 1 ], m_sel[1 ], m_tach_hz [1 ]);
487
478
488
479
checkpoint ();
489
480
@@ -556,13 +547,13 @@ void victor_9000_fdc_device::update_stepper_motor(floppy_image_device *floppy, i
556
547
floppy->set_rpm (victor9k_format::get_rpm (m_side, floppy->get_cyl ()));
557
548
}
558
549
559
- void victor_9000_fdc_device::update_spindle_motor (floppy_image_device *floppy, emu_timer *t_tach, bool start, bool stop, bool sel, uint8_t &da )
550
+ void victor_9000_fdc_device::update_spindle_motor (floppy_image_device *floppy, emu_timer *t_tach, bool start, bool stop, bool sel, float tach_hz )
560
551
{
561
- #ifdef USE_SCP
562
552
if (start && !stop && floppy->mon_r ())
563
553
{
564
554
LOGSCP (" %s: motor start\n " , floppy->tag ());
565
555
floppy->mon_w (0 );
556
+ t_tach->adjust (attotime::from_hz (tach_hz));
566
557
t_tach->enable (true );
567
558
}
568
559
else if (stop && !floppy->mon_r ())
@@ -571,33 +562,34 @@ void victor_9000_fdc_device::update_spindle_motor(floppy_image_device *floppy, e
571
562
floppy->mon_w (1 );
572
563
t_tach->enable (false );
573
564
}
574
- #endif
575
565
}
576
566
577
- void victor_9000_fdc_device::update_rpm (floppy_image_device *floppy, emu_timer *t_tach, bool sel, uint8_t &da )
567
+ void victor_9000_fdc_device::update_rpm (floppy_image_device *floppy, emu_timer *t_tach, bool sel, uint8_t dacval, float &tach_hz )
578
568
{
579
- #ifdef USE_SCP
580
569
if (sel)
581
570
{
582
- da = m_data;
583
-
584
- float tach = rpm[da] / 60.0 * SPINDLE_RATIO * MOTOR_POLES;
571
+ // Map DAC value to RPM, using the range of RPMs for zones 0 to 8,
572
+ // and adding some margin. The SCP will adjust the DAC value
573
+ // until it measures the desired frequency at the tach inputs.
574
+ const float rpm_min = 240 , rpm_max = 430 ;
575
+ float rpm = rpm_min + ((255 -dacval)/255 .0f ) * (rpm_max-rpm_min);
585
576
586
- LOGSCP ( " %s: motor speed %u rpm / tach %0.1f hz %0.9f s (DA %02x) \n " , floppy-> tag (), rpm[da], ( double ) tach, 1.0 /( double )tach, da) ;
577
+ tach_hz = rpm / 60.0 * SPINDLE_RATIO * MOTOR_POLES ;
587
578
588
- floppy->set_rpm ( rpm[da] );
579
+ LOGSCP ( " %s: motor speed %u rpm / tach %0.1f hz %0.9f s (DAC %02x) \n " , floppy->tag (), rpm, ( double )tach_hz, 1.0 /( double )tach_hz, dacval );
589
580
590
- bool enabled = t_tach->enabled ();
591
- t_tach->adjust (attotime::from_hz (tach*2 ), 0 , attotime::from_hz (tach*2 ));
592
- t_tach->enable (enabled);
581
+ floppy->set_rpm (rpm);
593
582
}
594
- #endif
595
583
}
596
584
597
585
void victor_9000_fdc_device::update_rdy ()
598
586
{
599
- m_via5->write_ca2 ((m_via_rdy0 && m_via_rdy1) ? m_rdy[0 ] : m_scp_rdy0);
600
- m_via5->write_cb2 ((m_via_rdy0 && m_via_rdy1) ? m_rdy[1 ] : m_scp_rdy1);
587
+ uint8_t output_mask = m_via6->read (via6522_device::VIA_DDRB);
588
+
589
+ // The SCP and VIA chips can both output the RDY0/RDY1 (and L0MS/L1MS)
590
+ // signals. When the VIA chip is configured to output the signal, it wins.
591
+ m_via5->write_ca2 ((output_mask & 1 ) ? m_via_rdy0 : m_scp_rdy0);
592
+ m_via5->write_cb2 ((output_mask & 2 ) ? m_via_rdy1 : m_scp_rdy1);
601
593
}
602
594
603
595
@@ -610,9 +602,16 @@ void victor_9000_fdc_device::da_w(uint8_t data)
610
602
LOGSCP (" %s %s DA %02x SEL0 %u SEL1 %u\n " , machine ().time ().as_string (), machine ().describe_context (), data, m_sel[0 ], m_sel[1 ]);
611
603
612
604
live_sync ();
613
- m_data = data;
614
- if (m_floppy[0 ]->get_device ()) update_rpm (m_floppy[0 ]->get_device (), t_tach[0 ], m_sel[0 ], m_da[0 ]);
615
- if (m_floppy[1 ]->get_device ()) update_rpm (m_floppy[1 ]->get_device (), t_tach[1 ], m_sel[1 ], m_da[1 ]);
605
+ if (m_sel[0 ])
606
+ {
607
+ m_da[0 ] = data;
608
+ }
609
+ if (m_sel[1 ])
610
+ {
611
+ m_da[1 ] = data;
612
+ }
613
+ if (m_floppy[0 ]->get_device ()) update_rpm (m_floppy[0 ]->get_device (), t_tach[0 ], m_sel[0 ], m_da[0 ], m_tach_hz[0 ]);
614
+ if (m_floppy[1 ]->get_device ()) update_rpm (m_floppy[1 ]->get_device (), t_tach[1 ], m_sel[1 ], m_da[1 ], m_tach_hz[1 ]);
616
615
checkpoint ();
617
616
live_run ();
618
617
}
@@ -634,7 +633,9 @@ uint8_t victor_9000_fdc_device::via4_pa_r()
634
633
635
634
*/
636
635
637
- return m_scp_l0ms;
636
+ uint8_t output_mask = m_via4->read (via6522_device::VIA_DDRA);
637
+
638
+ return (m_via_l0ms & output_mask) | (m_scp_l0ms & ~output_mask);
638
639
}
639
640
640
641
void victor_9000_fdc_device::via4_pa_w (uint8_t data)
@@ -656,17 +657,6 @@ void victor_9000_fdc_device::via4_pa_w(uint8_t data)
656
657
657
658
m_via_l0ms = data & 0x0f ;
658
659
659
- #ifndef USE_SCP
660
- // HACK to bypass SCP
661
- if (m_floppy[0 ]->get_device ())
662
- {
663
- m_floppy[0 ]->get_device ()->mon_w ((m_via_l0ms == 0xf ) ? 1 : 0 );
664
- m_floppy[0 ]->get_device ()->set_rpm (victor9k_format::get_rpm (m_side, m_floppy[0 ]->get_device ()->get_cyl ()));
665
- }
666
- m_rdy[0 ] = (m_via_l0ms == 0xf ) ? 0 : 1 ;
667
- update_rdy ();
668
- #endif
669
-
670
660
uint8_t st0 = data >> 4 ;
671
661
672
662
LOGVIA (" %s %s L0MS %01x ST0 %01x\n " , machine ().time ().as_string (), machine ().describe_context (), m_via_l0ms, st0);
@@ -698,7 +688,9 @@ uint8_t victor_9000_fdc_device::via4_pb_r()
698
688
699
689
*/
700
690
701
- return m_scp_l1ms;
691
+ uint8_t output_mask = m_via4->read (via6522_device::VIA_DDRB);
692
+
693
+ return (m_via_l1ms & output_mask) | (m_scp_l1ms & ~output_mask);
702
694
}
703
695
704
696
void victor_9000_fdc_device::via4_pb_w (uint8_t data)
@@ -720,17 +712,6 @@ void victor_9000_fdc_device::via4_pb_w(uint8_t data)
720
712
721
713
m_via_l1ms = data & 0x0f ;
722
714
723
- #ifndef USE_SCP
724
- // HACK to bypass SCP
725
- if (m_floppy[1 ]->get_device ())
726
- {
727
- m_floppy[1 ]->get_device ()->mon_w ((m_via_l1ms == 0xf ) ? 1 : 0 );
728
- m_floppy[1 ]->get_device ()->set_rpm (victor9k_format::get_rpm (m_side, m_floppy[1 ]->get_device ()->get_cyl ()));
729
- }
730
- m_rdy[1 ] = (m_via_l1ms == 0xf ) ? 0 : 1 ;
731
- update_rdy ();
732
- #endif
733
-
734
715
uint8_t st1 = data >> 4 ;
735
716
736
717
LOGVIA (" %s %s L1MS %01x ST1 %01x\n " , machine ().time ().as_string (), machine ().describe_context (), m_via_l1ms, st1);
@@ -934,11 +915,13 @@ uint8_t victor_9000_fdc_device::via6_pb_r()
934
915
935
916
uint8_t data = 0 ;
936
917
918
+ uint8_t output_mask = m_via6->read (via6522_device::VIA_DDRB);
919
+
937
920
// motor speed status, drive A
938
- data |= (m_via_rdy0 && m_via_rdy1 ) ? m_rdy[ 0 ] : m_scp_rdy0;
921
+ data |= (output_mask & 1 ) ? m_via_rdy0 : m_scp_rdy0;
939
922
940
923
// motor speed status, drive B
941
- data |= ((m_via_rdy0 && m_via_rdy1 ) ? m_rdy[ 1 ] : m_scp_rdy1) << 1 ;
924
+ data |= ((output_mask & 2 ) ? m_via_rdy1 : m_scp_rdy1) << 1 ;
942
925
943
926
// door B sense
944
927
data |= ((m_floppy[1 ]->get_device () && m_floppy[1 ]->get_device ()->exists ()) ? 0 : 1 ) << 3 ;
@@ -958,8 +941,11 @@ void victor_9000_fdc_device::via6_pb_w(uint8_t data)
958
941
959
942
bit description
960
943
961
- PB0 RDY0 to SCP Motor speed status, drive A
962
- PB1 RDY1 to SCP Motor speed status, drive B
944
+ PB0 Data Ready Handshake signal during speed table download
945
+ PB1 Data Ack Handshake signal during speed table download
946
+
947
+ PB0 RDY0 from SCP In Normal Operation: drive A speed converged
948
+ PB1 RDY1 from SCP In Normal Operation: drive B speed converged
963
949
PB2 _SCRESET Motor speed controller (8048) reset, output
964
950
PB3 DS1 Door B sense, input ->order is correct, leads with B
965
951
PB4 DSO Door A sense, input
@@ -969,13 +955,25 @@ void victor_9000_fdc_device::via6_pb_w(uint8_t data)
969
955
970
956
*/
971
957
958
+ uint8_t output_mask = m_via6->read (via6522_device::VIA_DDRB);
959
+
972
960
m_via_rdy0 = BIT (data, 0 );
973
961
m_via_rdy1 = BIT (data, 1 );
974
962
update_rdy ();
975
963
976
- // motor speed controller reset
977
- if (!BIT (data, 2 ))
978
- m_maincpu->reset ();
964
+ // _SCRESET in the schematic is misnamed. There's an inverter between this
965
+ // signal and the _RESET pin of the 8048, so the reset signal is actually
966
+ // active high.
967
+ //
968
+ // Hold the 8048 in reset, unless the reset signal is actively driven low.
969
+ if (BIT (output_mask, 2 ) && !BIT (data, 2 ))
970
+ {
971
+ m_maincpu->set_input_line (INPUT_LINE_RESET, CLEAR_LINE);
972
+ }
973
+ else
974
+ {
975
+ m_maincpu->set_input_line (INPUT_LINE_RESET, ASSERT_LINE);
976
+ }
979
977
980
978
bool sync = false ;
981
979
0 commit comments