Previous 199869 Revisions Next

r37084 Friday 10th April, 2015 at 08:29:29 UTC by Vasantha Crabb
Merge branch 'master' of https://github.com/mamedev/mame
[src/emu/bus/ieee488]c2040fdc.c c8050.c c8050.h c8050fdc.c c8050fdc.h
[src/emu/machine]64h156.c 6522via.c mos6530n.c
[src/lib/formats]d64_dsk.c d64_dsk.h d80_dsk.c d82_dsk.c
[src/mess/machine]victor9k_fdc.c

trunk/src/emu/bus/ieee488/c2040fdc.c
r245595r245596
99
1010**********************************************************************/
1111
12/*
13
14   TODO:
15
16    - write protect
17    - separate read/write methods
18
19*/
20
1221#include "c2040fdc.h"
1322
1423
r245595r245596
310319               !(BIT(cur_live.cell_counter, 3) || BIT(cur_live.cell_counter, 2)), cur_live.shift_reg, cur_live.rw_sel, cur_live.mode_sel);
311320
312321            // write bit
313            if (!cur_live.rw_sel) {
322            if (!cur_live.rw_sel) { // TODO WPS
314323               write_next_bit(BIT(cur_live.shift_reg_write, 9), limit);
315324            }
316325
trunk/src/emu/bus/ieee488/c8050.c
r245595r245596
3636#define M6502_TAG       "un1"
3737#define M6532_0_TAG     "uc1"
3838#define M6532_1_TAG     "ue1"
39
4039#define M6504_TAG       "uh3"
4140#define M6522_TAG       "um3"
4241#define M6530_TAG       "uk3"
42#define FDC_TAG         "fdc"
4343
4444
4545enum
r245595r245596
5151};
5252
5353
54#define SYNC \
55   (!(((m_sr & G64_SYNC_MARK) == G64_SYNC_MARK) & m_rw))
5654
57#define ERROR \
58   (!(m_ready | BIT(m_e, 3)))
59
60
61
6255//**************************************************************************
6356//  DEVICE DEFINITIONS
6457//**************************************************************************
r245595r245596
10497   ROMX_LOAD( "901887-01.ul1", 0x0000, 0x2000, CRC(0073b8b2) SHA1(b10603195f240118fe5fb6c6dfe5c5097463d890), ROM_BIOS(4) )
10598   ROMX_LOAD( "901888-01.uh1", 0x2000, 0x2000, CRC(de9b6132) SHA1(2e6c2d7ca934e5c550ad14bd5e9e7749686b7af4), ROM_BIOS(4) )
10699
107   ROM_REGION( 0x400, M6504_TAG, 0 )
100   ROM_REGION( 0x400, M6530_TAG, 0 )
108101   ROM_LOAD_OPTIONAL( "901483-02.uk3", 0x000, 0x400, CRC(d7277f95) SHA1(7607f9357f3a08f2a9f20931058d60d9e3c17d39) ) // 6530-036
109102   ROM_LOAD_OPTIONAL( "901483-03.uk3", 0x000, 0x400, CRC(9e83fa70) SHA1(e367ea8a5ddbd47f13570088427293138a10784b) ) // 6530-038 RIOT DOS 2.5 Micropolis
110103   ROM_LOAD_OPTIONAL( "901483-04.uk3", 0x000, 0x400, CRC(ae1c7866) SHA1(13bdf0bb387159167534c07a4554964734373f11) ) // 6530-039 RIOT DOS 2.5 Tandon
r245595r245596
112105   ROM_LOAD_OPTIONAL( "901885-01.uk3", 0x000, 0x400, NO_DUMP ) // 6530-044
113106   ROM_LOAD_OPTIONAL( "901885-04.uk3", 0x000, 0x400, CRC(bab998c9) SHA1(0dc9a3b60f1b866c63eebd882403532fc59fe57f) ) // 6530-47 RIOT DOS 2.7 Micropolis
114107   ROM_LOAD( "901869-01.uk3", 0x000, 0x400, CRC(2915327a) SHA1(3a9a80f72ce76e5f5c72513f8ef7553212912ae3) ) // 6530-48 RIOT DOS 2.7 MPI
115
116   ROM_REGION( 0x800, "gcr", 0)
117   ROM_LOAD( "901467.uk6", 0x000, 0x800, CRC(a23337eb) SHA1(97df576397608455616331f8e837cb3404363fa2) )
118108ROM_END
119109
120110
r245595r245596
149139   ROMX_LOAD( "251474-01b", 0x000, 0x400, CRC(9e9a9f90) SHA1(39498d7369a31ea7527b5044071acf35a84ea2ac), ROM_BIOS(1) ) // Matsushita
150140   ROMX_LOAD( "fdc-2.7b.bin", 0x000, 0x800, CRC(13a24482) SHA1(1cfa52d2ed245a95e6369b46a36c6c7aa3929931), ROM_BIOS(2) ) // CBM DOS 2.7B FDC ROM from the 8250LP inside 8296D
151141   ROMX_LOAD( "speeddos-fdc-f800.bin", 0x000, 0x800, CRC(253e760f) SHA1(3f7892a9bab84b633f45686bbbbe66bc2948c8e5), ROM_BIOS(3) )
152
153   ROM_REGION( 0x800, "gcr", 0)
154   ROM_LOAD( "251167-01.uc1", 0x000, 0x800, BAD_DUMP CRC(a23337eb) SHA1(97df576397608455616331f8e837cb3404363fa2) )
155142ROM_END
156143
157144
r245595r245596
174161   ROM_LOAD( "901887-01.1j",  0x0000, 0x2000, CRC(0073b8b2) SHA1(b10603195f240118fe5fb6c6dfe5c5097463d890) )
175162   ROM_LOAD( "901888-01.3j",  0x2000, 0x2000, CRC(de9b6132) SHA1(2e6c2d7ca934e5c550ad14bd5e9e7749686b7af4) )
176163
177   ROM_REGION( 0x800, M6504_TAG, 0 )
164   ROM_REGION( 0x400, M6530_TAG, 0 )
178165   ROM_LOAD( "901885-04.u1", 0x000, 0x400, CRC(bab998c9) SHA1(0dc9a3b60f1b866c63eebd882403532fc59fe57f) )
166
167   ROM_REGION( 0x800, M6504_TAG, 0 )
179168   ROM_LOAD( "251257-02a.u2", 0x000, 0x800, CRC(b51150de) SHA1(3b954eb34f7ea088eed1d33ebc6d6e83a3e9be15) )
180169
181170   ROM_REGION( 0x800, "gcr", 0)
r245595r245596
216205
217206static ADDRESS_MAP_START( c8050_fdc_mem, AS_PROGRAM, 8, c8050_device )
218207   ADDRESS_MAP_GLOBAL_MASK(0x1fff)
219   AM_RANGE(0x0000, 0x003f) AM_MIRROR(0x0300) AM_RAM // 6530
220   AM_RANGE(0x0040, 0x004f) AM_MIRROR(0x0330) AM_DEVREADWRITE(M6522_TAG, via6522_device, read, write)
221   AM_RANGE(0x0080, 0x008f) AM_MIRROR(0x0330) AM_DEVREADWRITE(M6530_TAG, mos6530_device, read, write)
208   AM_RANGE(0x0000, 0x003f) AM_MIRROR(0x0300) AM_DEVICE(M6530_TAG, mos6530_t, ram_map)
209   AM_RANGE(0x0040, 0x004f) AM_MIRROR(0x0330) AM_DEVICE(M6522_TAG, via6522_device, map)
210   AM_RANGE(0x0080, 0x008f) AM_MIRROR(0x0330) AM_DEVICE(M6530_TAG, mos6530_t, io_map)
222211   AM_RANGE(0x0400, 0x07ff) AM_RAM AM_SHARE("share1")
223212   AM_RANGE(0x0800, 0x0bff) AM_RAM AM_SHARE("share2")
224213   AM_RANGE(0x0c00, 0x0fff) AM_RAM AM_SHARE("share3")
225214   AM_RANGE(0x1000, 0x13ff) AM_RAM AM_SHARE("share4")
226   AM_RANGE(0x1c00, 0x1fff) AM_ROM AM_REGION(M6504_TAG, 0)
215   AM_RANGE(0x1c00, 0x1fff) AM_DEVICE(M6530_TAG, mos6530_t, rom_map)
227216ADDRESS_MAP_END
228217
229218
r245595r245596
233222
234223static ADDRESS_MAP_START( c8250lp_fdc_mem, AS_PROGRAM, 8, c8050_device )
235224   ADDRESS_MAP_GLOBAL_MASK(0x1fff)
236   AM_RANGE(0x0000, 0x003f) AM_MIRROR(0x0300) AM_RAM // 6530
237   AM_RANGE(0x0040, 0x004f) AM_MIRROR(0x0330) AM_DEVREADWRITE(M6522_TAG, via6522_device, read, write)
238   AM_RANGE(0x0080, 0x008f) AM_MIRROR(0x0330) AM_DEVREADWRITE(M6530_TAG, mos6530_device, read, write)
225   AM_RANGE(0x0000, 0x003f) AM_MIRROR(0x0300) AM_DEVICE(M6530_TAG, mos6530_t, ram_map)
226   AM_RANGE(0x0040, 0x004f) AM_MIRROR(0x0330) AM_DEVICE(M6522_TAG, via6522_device, map)
227   AM_RANGE(0x0080, 0x008f) AM_MIRROR(0x0330) AM_DEVICE(M6530_TAG, mos6530_t, io_map)
239228   AM_RANGE(0x0400, 0x07ff) AM_RAM AM_SHARE("share1")
240229   AM_RANGE(0x0800, 0x0bff) AM_RAM AM_SHARE("share2")
241230   AM_RANGE(0x0c00, 0x0fff) AM_RAM AM_SHARE("share3")
r245595r245596
250239
251240static ADDRESS_MAP_START( sfd1001_fdc_mem, AS_PROGRAM, 8, c8050_device )
252241   ADDRESS_MAP_GLOBAL_MASK(0x1fff)
253   AM_RANGE(0x0000, 0x003f) AM_MIRROR(0x0300) AM_RAM // 6530
254   AM_RANGE(0x0040, 0x004f) AM_MIRROR(0x0330) AM_DEVREADWRITE(M6522_TAG, via6522_device, read, write)
255   AM_RANGE(0x0080, 0x008f) AM_MIRROR(0x0330) AM_DEVREADWRITE(M6530_TAG, mos6530_device, read, write)
242   AM_RANGE(0x0000, 0x003f) AM_MIRROR(0x0300) AM_DEVICE(M6530_TAG, mos6530_t, ram_map)
243   AM_RANGE(0x0040, 0x004f) AM_MIRROR(0x0330) AM_DEVICE(M6522_TAG, via6522_device, map)
244   AM_RANGE(0x0080, 0x008f) AM_MIRROR(0x0330) AM_DEVICE(M6530_TAG, mos6530_t, io_map)
256245   AM_RANGE(0x0400, 0x07ff) AM_RAM AM_SHARE("share1")
257246   AM_RANGE(0x0800, 0x0bff) AM_RAM AM_SHARE("share2")
258247   AM_RANGE(0x0c00, 0x0fff) AM_RAM AM_SHARE("share3")
r245595r245596
433422   output_set_led_value(LED_ERR, BIT(data, 5));
434423}
435424
436
437READ8_MEMBER( c8050_device::via_pa_r )
438{
439   /*
440
441       bit     description
442
443       PA0     E0
444       PA1     E1
445       PA2     I2
446       PA3     E2
447       PA4     E4
448       PA5     E5
449       PA6     I7
450       PA7     E6
451
452   */
453
454   return (BIT(m_e, 6) << 7) | (BIT(m_i, 7) << 6) | (m_e & 0x33) | (BIT(m_e, 2) << 3) | (m_i & 0x04);
455}
456
457WRITE_LINE_MEMBER( c8050_device::mode_sel_w )
458{
459   // mode select
460   m_mode = state;
461
462   update_gcr_data();
463   m_via->write_cb1(ERROR);
464}
465
466WRITE_LINE_MEMBER( c8050_device::rw_sel_w )
467{
468   // read/write select
469   m_rw = state;
470
471   update_gcr_data();
472   m_via->write_cb1(ERROR);
473}
474
475
476READ8_MEMBER( c8050_device::via_pb_r )
477{
478   /*
479
480       bit     description
481
482       PB0     S1A
483       PB1     S1B
484       PB2     S0A
485       PB3     S0B
486       PB4     MTR1
487       PB5     MTR0
488       PB6     PULL SYNC
489       PB7     SYNC
490
491   */
492
493   UINT8 data = 0;
494
495   // SYNC detected
496   data |= SYNC << 7;
497
498   return data;
499}
500
501425WRITE8_MEMBER( c8050_device::via_pb_w )
502426{
503427   /*
r245595r245596
511435       PB4     MTR1
512436       PB5     MTR0
513437       PB6     PULL SYNC
514       PB7     SYNC
438       PB7
515439
516440   */
517441
518442   // spindle motor 1
519   int mtr1 = BIT(data, 4);
520   spindle_motor(1, mtr1);
443   m_fdc->mtr1_w(BIT(data, 4));
521444
522445   // spindle motor 0
523   int mtr0 = BIT(data, 5);
524   spindle_motor(0, mtr0);
446   m_fdc->mtr0_w(BIT(data, 5));
525447
526448   // stepper motor 1
527   int s1 = data & 0x03;
528   mpi_step_motor(1, s1);
449   m_fdc->stp1_w(data & 0x03);
529450
530451   // stepper motor 0
531   int s0 = (data >> 2) & 0x03;
532   mpi_step_motor(0, s0);
452   m_fdc->stp0_w((data >> 2) & 0x03);
533453
534   m_bit_timer->enable(!mtr1 || !mtr0);
454   // PLL sync
455   m_fdc->pull_sync_w(!BIT(data, 6));
535456}
536457
537458
538459//-------------------------------------------------
539//  mos6530 uk3
460//  SLOT_INTERFACE( c8050_floppies )
540461//-------------------------------------------------
541462
542READ8_MEMBER( c8050_device::pi_r )
543{
544   /*
463static SLOT_INTERFACE_START( c8050_floppies )
464   SLOT_INTERFACE( "525ssqd", FLOPPY_525_SSQD )
465SLOT_INTERFACE_END
545466
546       bit     description
547467
548       PA0     PI0
549       PA1     PI1
550       PA2     PI2
551       PA3     PI3
552       PA4     PI4
553       PA5     PI5
554       PA6     PI6
555       PA7     PI7
468//-------------------------------------------------
469//  FLOPPY_FORMATS( floppy_formats )
470//-------------------------------------------------
556471
557   */
472FLOPPY_FORMATS_MEMBER( c8050_device::floppy_formats )
473   FLOPPY_D80_FORMAT
474FLOPPY_FORMATS_END
558475
559   return m_pi;
560}
561476
562WRITE8_MEMBER( c8050_device::pi_w )
563{
564   /*
565
566       bit     description
567
568       PA0     PI0
569       PA1     PI1
570       PA2     PI2
571       PA3     PI3
572       PA4     PI4
573       PA5     PI5
574       PA6     PI6
575       PA7     PI7
576
577   */
578
579   m_pi = data;
580}
581
582READ8_MEMBER( c8050_device::miot_pb_r )
583{
584   /*
585
586       bit     description
587
588       PB0     DRV SEL
589       PB1     DS0
590       PB2     DS1
591       PB3     WPS
592       PB4     DRIVE TYPE (0=2A, 1=2C)
593       PB5
594       PB6     (0=DS, 1=SS)
595       PB7     M6504 IRQ
596
597   */
598
599   UINT8 data = 0;
600
601   // write protect sense
602   data |= m_unit[m_drive].m_image->floppy_wpt_r() << 3;
603
604   // drive type
605   data |= 0x10;
606
607   // single/dual sided
608   if (!m_double_sided)
609   {
610      data |= 0x40;
611   }
612
613   return data;
614}
615
616WRITE8_MEMBER( c8050_device::miot_pb_w )
617{
618   /*
619
620       bit     description
621
622       PB0     DRV SEL
623       PB1     DS0
624       PB2     DS1
625       PB3     WPS
626       PB4     ODD HD (0=78-154, 1=1-77)
627       PB5
628       PB6     (0=DS, 1=SS)
629       PB7     M6504 IRQ
630
631   */
632
633   // drive select
634   if (m_image1)
635   {
636      m_drive = BIT(data, 0);
637   }
638
639   // density select
640   int ds = (data >> 1) & 0x03;
641
642   if (m_ds != ds)
643   {
644      m_bit_timer->adjust(attotime::zero, 0, attotime::from_hz(C8050_BITRATE[ds]));
645      m_ds = ds;
646   }
647
648   // side select
649   if (m_double_sided)
650   {
651      m_side = !BIT(data, 4);
652   }
653
654   // interrupt
655   if (m_miot_irq != BIT(data, 7))
656   {
657      m_fdccpu->set_input_line(M6502_IRQ_LINE, BIT(data, 7) ? CLEAR_LINE : ASSERT_LINE);
658      m_miot_irq = BIT(data, 7);
659   }
660}
661
662477//-------------------------------------------------
663//  LEGACY_FLOPPY_OPTIONS( c8050 )
478//  SLOT_INTERFACE( c8250_floppies )
664479//-------------------------------------------------
665480
666static LEGACY_FLOPPY_OPTIONS_START( c8050 )
667   LEGACY_FLOPPY_OPTION( c8050, "d80", "Commodore 8050 Disk Image", d80_dsk_identify, d64_dsk_construct, NULL, NULL )
668LEGACY_FLOPPY_OPTIONS_END
481static SLOT_INTERFACE_START( c8250_floppies )
482   SLOT_INTERFACE( "525qd", FLOPPY_525_QD )
483SLOT_INTERFACE_END
669484
670485
671486//-------------------------------------------------
672//  LEGACY_FLOPPY_OPTIONS( c8250 )
487//  FLOPPY_FORMATS( floppy_formats )
673488//-------------------------------------------------
674489
675static LEGACY_FLOPPY_OPTIONS_START( c8250 )
676   LEGACY_FLOPPY_OPTION( c8250, "d80", "Commodore 8050 Disk Image", d80_dsk_identify, d64_dsk_construct, NULL, NULL )
677   LEGACY_FLOPPY_OPTION( c8250, "d82", "Commodore 8250/SFD1001 Disk Image", d82_dsk_identify, d64_dsk_construct, NULL, NULL )
678LEGACY_FLOPPY_OPTIONS_END
490FLOPPY_FORMATS_MEMBER( c8250_device::floppy_formats )
491   FLOPPY_D80_FORMAT,
492   FLOPPY_D82_FORMAT
493FLOPPY_FORMATS_END
679494
680495
681496//-------------------------------------------------
682//  floppy_interface c8050_floppy_interface
497//  FLOPPY_FORMATS( floppy_formats )
683498//-------------------------------------------------
684499
685static const floppy_interface c8050_floppy_interface =
686{
687   FLOPPY_STANDARD_5_25_SSDD,
688   LEGACY_FLOPPY_OPTIONS_NAME(c8050),
689   "floppy_5_25"
690};
500FLOPPY_FORMATS_MEMBER( c8250lp_device::floppy_formats )
501   FLOPPY_D80_FORMAT,
502   FLOPPY_D82_FORMAT
503FLOPPY_FORMATS_END
691504
692505
693506//-------------------------------------------------
694//  floppy_interface c8250_floppy_interface
507//  FLOPPY_FORMATS( floppy_formats )
695508//-------------------------------------------------
696509
697static const floppy_interface c8250_floppy_interface =
698{
699   FLOPPY_STANDARD_5_25_DSQD,
700   LEGACY_FLOPPY_OPTIONS_NAME(c8250),
701   "floppy_5_25"
702};
510FLOPPY_FORMATS_MEMBER( sfd1001_device::floppy_formats )
511   FLOPPY_D80_FORMAT,
512   FLOPPY_D82_FORMAT
513FLOPPY_FORMATS_END
703514
704515
705516//-------------------------------------------------
r245595r245596
727538   MCFG_CPU_PROGRAM_MAP(c8050_fdc_mem)
728539
729540   MCFG_DEVICE_ADD(M6522_TAG, VIA6522, XTAL_12MHz/12)
730   MCFG_VIA6522_READPA_HANDLER(READ8(c8050_device, via_pa_r))
731   MCFG_VIA6522_READPB_HANDLER(READ8(c8050_device, via_pb_r))
541   MCFG_VIA6522_READPA_HANDLER(DEVREAD8(FDC_TAG, c8050_fdc_t, read))
732542   MCFG_VIA6522_WRITEPB_HANDLER(WRITE8(c8050_device, via_pb_w))
733   MCFG_VIA6522_CA2_HANDLER(WRITELINE(c8050_device, mode_sel_w))
734   MCFG_VIA6522_CB2_HANDLER(WRITELINE(c8050_device, rw_sel_w))
543   MCFG_VIA6522_CA2_HANDLER(DEVWRITELINE(FDC_TAG, c8050_fdc_t, mode_sel_w))
544   MCFG_VIA6522_CB2_HANDLER(DEVWRITELINE(FDC_TAG, c8050_fdc_t, rw_sel_w))
735545
736   MCFG_DEVICE_ADD(M6530_TAG, MOS6530, XTAL_12MHz/12)
737   MCFG_MOS6530_IN_PA_CB(READ8(c8050_device, pi_r))
738   MCFG_MOS6530_OUT_PA_CB(WRITE8(c8050_device, pi_w))
739   MCFG_MOS6530_IN_PB_CB(READ8(c8050_device, miot_pb_r))
740   MCFG_MOS6530_OUT_PB_CB(WRITE8(c8050_device, miot_pb_w))
546   MCFG_DEVICE_ADD(M6530_TAG, MOS6530n, XTAL_12MHz/12)
547   MCFG_MOS6530n_IRQ_CB(INPUTLINE(M6504_TAG, M6502_IRQ_LINE))
548   MCFG_MOS6530n_OUT_PA_CB(DEVWRITE8(FDC_TAG, c8050_fdc_t, write))
549   MCFG_MOS6530n_OUT_PB0_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, drv_sel_w))
550   MCFG_MOS6530n_OUT_PB1_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, ds0_w))
551   MCFG_MOS6530n_OUT_PB2_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, ds1_w))
552   MCFG_MOS6530n_IN_PB6_CB(VCC) // SINGLE SIDED
741553
742   MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(c8050_floppy_interface)
554   MCFG_DEVICE_ADD(FDC_TAG, C8050_FDC, XTAL_12MHz/2)
555   MCFG_C8050_SYNC_CALLBACK(DEVWRITELINE(M6522_TAG, via6522_device, write_pb7))
556   MCFG_C8050_READY_CALLBACK(DEVWRITELINE(M6522_TAG, via6522_device, write_ca1))
557   MCFG_C8050_BRDY_CALLBACK(INPUTLINE(M6504_TAG, M6502_SET_OVERFLOW)) MCFG_DEVCB_XOR(1)
558   MCFG_C8050_ERROR_CALLBACK(DEVWRITELINE(M6522_TAG, via6522_device, write_cb1))
559   MCFG_C8050_WPS_CALLBACK(DEVWRITELINE(M6530_TAG, mos6530_t, pb3_w))
560   MCFG_FLOPPY_DRIVE_ADD(FDC_TAG ":0", c8050_floppies, "525ssqd", c8050_device::floppy_formats)
561   MCFG_FLOPPY_DRIVE_ADD(FDC_TAG ":1", c8050_floppies, "525ssqd", c8050_device::floppy_formats)
743562MACHINE_CONFIG_END
744563
745564
r245595r245596
779598   MCFG_CPU_PROGRAM_MAP(c8050_fdc_mem)
780599
781600   MCFG_DEVICE_ADD(M6522_TAG, VIA6522, XTAL_12MHz/12)
782   MCFG_VIA6522_READPA_HANDLER(READ8(c8050_device, via_pa_r))
783   MCFG_VIA6522_READPB_HANDLER(READ8(c8050_device, via_pb_r))
601   MCFG_VIA6522_READPA_HANDLER(DEVREAD8(FDC_TAG, c8050_fdc_t, read))
784602   MCFG_VIA6522_WRITEPB_HANDLER(WRITE8(c8050_device, via_pb_w))
785   MCFG_VIA6522_CA2_HANDLER(WRITELINE(c8050_device, mode_sel_w))
786   MCFG_VIA6522_CB2_HANDLER(WRITELINE(c8050_device, rw_sel_w))
603   MCFG_VIA6522_CA2_HANDLER(DEVWRITELINE(FDC_TAG, c8050_fdc_t, mode_sel_w))
604   MCFG_VIA6522_CB2_HANDLER(DEVWRITELINE(FDC_TAG, c8050_fdc_t, rw_sel_w))
787605
788   MCFG_DEVICE_ADD(M6530_TAG, MOS6530, XTAL_12MHz/12)
789   MCFG_MOS6530_IN_PA_CB(READ8(c8050_device, pi_r))
790   MCFG_MOS6530_OUT_PA_CB(WRITE8(c8050_device, pi_w))
791   MCFG_MOS6530_IN_PB_CB(READ8(c8050_device, miot_pb_r))
792   MCFG_MOS6530_OUT_PB_CB(WRITE8(c8050_device, miot_pb_w))
606   MCFG_DEVICE_ADD(M6530_TAG, MOS6530n, XTAL_12MHz/12)
607   MCFG_MOS6530n_IRQ_CB(INPUTLINE(M6504_TAG, M6502_IRQ_LINE))
608   MCFG_MOS6530n_OUT_PA_CB(DEVWRITE8(FDC_TAG, c8050_fdc_t, write))
609   MCFG_MOS6530n_OUT_PB0_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, drv_sel_w))
610   MCFG_MOS6530n_OUT_PB1_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, ds0_w))
611   MCFG_MOS6530n_OUT_PB2_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, ds1_w))
612   MCFG_MOS6530n_OUT_PB4_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, odd_hd_w))
613   MCFG_MOS6530n_IN_PB6_CB(GND) // DOUBLE SIDED
793614
794   MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(c8250_floppy_interface)
615   MCFG_DEVICE_ADD(FDC_TAG, C8050_FDC, XTAL_12MHz/2)
616   MCFG_C8050_SYNC_CALLBACK(DEVWRITELINE(M6522_TAG, via6522_device, write_pb7))
617   MCFG_C8050_READY_CALLBACK(DEVWRITELINE(M6522_TAG, via6522_device, write_ca1))
618   MCFG_C8050_BRDY_CALLBACK(INPUTLINE(M6504_TAG, M6502_SET_OVERFLOW)) MCFG_DEVCB_XOR(1)
619   MCFG_C8050_ERROR_CALLBACK(DEVWRITELINE(M6522_TAG, via6522_device, write_cb1))
620   MCFG_C8050_WPS_CALLBACK(DEVWRITELINE(M6530_TAG, mos6530_t, pb3_w))
621   MCFG_FLOPPY_DRIVE_ADD(FDC_TAG ":0", c8250_floppies, "525qd", c8250_device::floppy_formats)
622   MCFG_FLOPPY_DRIVE_ADD(FDC_TAG ":1", c8250_floppies, "525qd", c8250_device::floppy_formats)
795623MACHINE_CONFIG_END
796624
797625
r245595r245596
831659   MCFG_CPU_PROGRAM_MAP(c8250lp_fdc_mem)
832660
833661   MCFG_DEVICE_ADD(M6522_TAG, VIA6522, XTAL_12MHz/12)
834   MCFG_VIA6522_READPA_HANDLER(READ8(c8050_device, via_pa_r))
835   MCFG_VIA6522_READPB_HANDLER(READ8(c8050_device, via_pb_r))
662   MCFG_VIA6522_READPA_HANDLER(DEVREAD8(FDC_TAG, c8050_fdc_t, read))
836663   MCFG_VIA6522_WRITEPB_HANDLER(WRITE8(c8050_device, via_pb_w))
837   MCFG_VIA6522_CA2_HANDLER(WRITELINE(c8050_device, mode_sel_w))
838   MCFG_VIA6522_CB2_HANDLER(WRITELINE(c8050_device, rw_sel_w))
664   MCFG_VIA6522_CA2_HANDLER(DEVWRITELINE(FDC_TAG, c8050_fdc_t, mode_sel_w))
665   MCFG_VIA6522_CB2_HANDLER(DEVWRITELINE(FDC_TAG, c8050_fdc_t, rw_sel_w))
839666
840   MCFG_DEVICE_ADD(M6530_TAG, MOS6530, XTAL_12MHz/12)
841   MCFG_MOS6530_IN_PA_CB(READ8(c8050_device, pi_r))
842   MCFG_MOS6530_OUT_PA_CB(WRITE8(c8050_device, pi_w))
843   MCFG_MOS6530_IN_PB_CB(READ8(c8050_device, miot_pb_r))
844   MCFG_MOS6530_OUT_PB_CB(WRITE8(c8050_device, miot_pb_w))
667   MCFG_DEVICE_ADD(M6530_TAG, MOS6530n, XTAL_12MHz/12)
668   MCFG_MOS6530n_IRQ_CB(INPUTLINE(M6504_TAG, M6502_IRQ_LINE))
669   MCFG_MOS6530n_OUT_PA_CB(DEVWRITE8(FDC_TAG, c8050_fdc_t, write))
670   MCFG_MOS6530n_OUT_PB0_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, drv_sel_w))
671   MCFG_MOS6530n_OUT_PB1_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, ds0_w))
672   MCFG_MOS6530n_OUT_PB2_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, ds1_w))
673   MCFG_MOS6530n_OUT_PB4_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, odd_hd_w))
674   MCFG_MOS6530n_IN_PB6_CB(GND) // DOUBLE SIDED
845675
846   MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(c8250_floppy_interface)
676   MCFG_DEVICE_ADD(FDC_TAG, C8050_FDC, XTAL_12MHz/2)
677   MCFG_C8050_SYNC_CALLBACK(DEVWRITELINE(M6522_TAG, via6522_device, write_pb7))
678   MCFG_C8050_READY_CALLBACK(DEVWRITELINE(M6522_TAG, via6522_device, write_ca1))
679   MCFG_C8050_BRDY_CALLBACK(INPUTLINE(M6504_TAG, M6502_SET_OVERFLOW)) MCFG_DEVCB_XOR(1)
680   MCFG_C8050_ERROR_CALLBACK(DEVWRITELINE(M6522_TAG, via6522_device, write_cb1))
681   MCFG_C8050_WPS_CALLBACK(DEVWRITELINE(M6530_TAG, mos6530_t, pb3_w))
682   MCFG_FLOPPY_DRIVE_ADD(FDC_TAG ":0", c8250_floppies, "525qd", c8250lp_device::floppy_formats)
683   MCFG_FLOPPY_DRIVE_ADD(FDC_TAG ":1", c8250_floppies, "525qd", c8250lp_device::floppy_formats)
847684MACHINE_CONFIG_END
848685
849686
r245595r245596
883720   MCFG_CPU_PROGRAM_MAP(sfd1001_fdc_mem)
884721
885722   MCFG_DEVICE_ADD(M6522_TAG, VIA6522, XTAL_12MHz/12)
886   MCFG_VIA6522_READPA_HANDLER(READ8(c8050_device, via_pa_r))
887   MCFG_VIA6522_READPB_HANDLER(READ8(c8050_device, via_pb_r))
723   MCFG_VIA6522_READPA_HANDLER(DEVREAD8(FDC_TAG, c8050_fdc_t, read))
888724   MCFG_VIA6522_WRITEPB_HANDLER(WRITE8(c8050_device, via_pb_w))
889   MCFG_VIA6522_CA2_HANDLER(WRITELINE(c8050_device, mode_sel_w))
890   MCFG_VIA6522_CB2_HANDLER(WRITELINE(c8050_device, rw_sel_w))
725   MCFG_VIA6522_CA2_HANDLER(DEVWRITELINE(FDC_TAG, c8050_fdc_t, mode_sel_w))
726   MCFG_VIA6522_CB2_HANDLER(DEVWRITELINE(FDC_TAG, c8050_fdc_t, rw_sel_w))
891727
892   MCFG_DEVICE_ADD(M6530_TAG, MOS6530, XTAL_12MHz/12)
893   MCFG_MOS6530_IN_PA_CB(READ8(c8050_device, pi_r))
894   MCFG_MOS6530_OUT_PA_CB(WRITE8(c8050_device, pi_w))
895   MCFG_MOS6530_IN_PB_CB(READ8(c8050_device, miot_pb_r))
896   MCFG_MOS6530_OUT_PB_CB(WRITE8(c8050_device, miot_pb_w))
728   MCFG_DEVICE_ADD(M6530_TAG, MOS6530n, XTAL_12MHz/12)
729   MCFG_MOS6530n_IRQ_CB(INPUTLINE(M6504_TAG, M6502_IRQ_LINE))
730   MCFG_MOS6530n_OUT_PA_CB(DEVWRITE8(FDC_TAG, c8050_fdc_t, write))
731   MCFG_MOS6530n_OUT_PB0_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, drv_sel_w))
732   MCFG_MOS6530n_OUT_PB1_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, ds0_w))
733   MCFG_MOS6530n_OUT_PB2_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, ds1_w))
734   MCFG_MOS6530n_OUT_PB4_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, odd_hd_w))
735   MCFG_MOS6530n_IN_PB6_CB(GND) // DOUBLE SIDED
897736
898   MCFG_LEGACY_FLOPPY_DRIVE_ADD(FLOPPY_0, c8250_floppy_interface)
737   MCFG_DEVICE_ADD(FDC_TAG, C8050_FDC, XTAL_12MHz/2)
738   MCFG_C8050_SYNC_CALLBACK(DEVWRITELINE(M6522_TAG, via6522_device, write_pb7))
739   MCFG_C8050_READY_CALLBACK(DEVWRITELINE(M6522_TAG, via6522_device, write_ca1))
740   MCFG_C8050_BRDY_CALLBACK(INPUTLINE(M6504_TAG, M6502_SET_OVERFLOW)) MCFG_DEVCB_XOR(1)
741   MCFG_C8050_ERROR_CALLBACK(DEVWRITELINE(M6522_TAG, via6522_device, write_cb1))
742   MCFG_C8050_WPS_CALLBACK(DEVWRITELINE(M6530_TAG, mos6530_t, pb3_w))
743   MCFG_FLOPPY_DRIVE_ADD(FDC_TAG ":0", c8250_floppies, "525qd", sfd1001_device::floppy_formats)
744   MCFG_FLOPPY_DRIVE_ADD(FDC_TAG ":1", c8250_floppies, NULL,    sfd1001_device::floppy_formats)
899745MACHINE_CONFIG_END
900746
901747
r245595r245596
958804}
959805
960806
961//-------------------------------------------------
962//  update_gcr_data -
963//-------------------------------------------------
964807
965inline void c8050_device::update_gcr_data()
966{
967   if (m_rw)
968   {
969      /*
970
971          bit     description
972
973          I0      SR0
974          I1      SR1
975          I2      SR2
976          I3      SR3
977          I4      SR4
978          I5      SR5
979          I6      SR6
980          I7      SR7
981          I8      SR8
982          I9      SR9
983          I10     R/_W SEL
984
985      */
986
987      m_i = (m_rw << 10) | (m_sr & 0x3ff);
988   }
989   else
990   {
991      /*
992
993          bit     description
994
995          I0      PI0
996          I1      PI1
997          I2      PI2
998          I3      PI3
999          I4      MODE SEL
1000          I5      PI4
1001          I6      PI5
1002          I7      PI6
1003          I8      PI7
1004          I9      0
1005          I10     R/_W SEL
1006
1007      */
1008
1009      m_i = (m_rw << 10) | ((m_pi & 0xf0) << 1) | (m_mode << 4) | (m_pi & 0x0f);
1010   }
1011
1012   m_e = m_gcr->base()[m_i];
1013}
1014
1015
1016//-------------------------------------------------
1017//  read_current_track -
1018//-------------------------------------------------
1019
1020inline void c8050_device::read_current_track(int unit)
1021{
1022   m_unit[unit].m_track_len = G64_BUFFER_SIZE;
1023   m_unit[unit].m_buffer_pos = 0;
1024   m_unit[unit].m_bit_pos = 7;
1025   m_bit_count = 0;
1026
1027   // read track data
1028   m_unit[unit].m_image->floppy_drive_read_track_data_info_buffer(m_side, m_unit[unit].m_track_buffer, &m_unit[unit].m_track_len);
1029
1030   // extract track length
1031   m_unit[unit].m_track_len = m_unit[unit].m_image->floppy_drive_get_current_track_size(m_side);
1032}
1033
1034
1035//-------------------------------------------------
1036//  spindle_motor -
1037//-------------------------------------------------
1038
1039inline void c8050_device::spindle_motor(int unit, int mtr)
1040{
1041   if (m_unit[unit].m_mtr != mtr)
1042   {
1043      if (!mtr)
1044      {
1045         // read track data
1046         read_current_track(unit);
1047      }
1048
1049      m_unit[unit].m_image->floppy_mon_w(mtr);
1050
1051      m_unit[unit].m_mtr = mtr;
1052   }
1053}
1054
1055
1056//-------------------------------------------------
1057//  mpi_step_motor -
1058//-------------------------------------------------
1059
1060inline void c8050_device::mpi_step_motor(int unit, int stp)
1061{
1062   if (!m_unit[unit].m_mtr && (m_unit[unit].m_stp != stp))
1063   {
1064      int tracks = 0;
1065
1066      switch (m_unit[unit].m_stp)
1067      {
1068      case 0: if (stp == 1) tracks++; else if (stp == 2) tracks--; break;
1069      case 1: if (stp == 3) tracks++; else if (stp == 0) tracks--; break;
1070      case 2: if (stp == 0) tracks++; else if (stp == 3) tracks--; break;
1071      case 3: if (stp == 2) tracks++; else if (stp == 1) tracks--; break;
1072      }
1073
1074      if (tracks != 0)
1075      {
1076         // step read/write head
1077         m_unit[unit].m_image->floppy_drive_seek(tracks);
1078
1079         // read new track data
1080         read_current_track(unit);
1081      }
1082
1083      m_unit[unit].m_stp = stp;
1084   }
1085}
1086
1087
1088
1089808//**************************************************************************
1090809//  LIVE DEVICE
1091810//**************************************************************************
r245595r245596
1094813//  c8050_device - constructor
1095814//-------------------------------------------------
1096815
1097c8050_device::c8050_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, bool double_sided, const char *shortname, const char *source)
1098   : device_t(mconfig, type, name, tag, owner, clock, shortname, source),
1099      device_ieee488_interface(mconfig, *this),
1100      m_maincpu(*this, M6502_TAG),
1101      m_fdccpu(*this, M6504_TAG),
1102      m_riot0(*this, M6532_0_TAG),
1103      m_riot1(*this, M6532_1_TAG),
1104      m_miot(*this, M6530_TAG),
1105      m_via(*this, M6522_TAG),
1106      m_image0(*this, FLOPPY_0),
1107      m_image1(*this, FLOPPY_1),
1108      m_gcr(*this, "gcr"),
1109      m_address(*this, "ADDRESS"),
1110      m_drive(0),
1111      m_side(0),
1112      m_double_sided(double_sided),
1113      m_rfdo(1),
1114      m_daco(1),
1115      m_atna(1),
1116      m_ifc(0),
1117      m_ds(-1),
1118      m_bit_count(0),
1119      m_sr(0),
1120      m_pi(0),
1121      m_ready(0),
1122      m_mode(0),
1123      m_rw(0),
1124      m_miot_irq(CLEAR_LINE)
816c8050_device::c8050_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) :
817   device_t(mconfig, type, name, tag, owner, clock, shortname, source),
818   device_ieee488_interface(mconfig, *this),
819   m_maincpu(*this, M6502_TAG),
820   m_fdccpu(*this, M6504_TAG),
821   m_riot0(*this, M6532_0_TAG),
822   m_riot1(*this, M6532_1_TAG),
823   m_miot(*this, M6530_TAG),
824   m_via(*this, M6522_TAG),
825   m_floppy0(*this, FDC_TAG ":0"),
826   m_floppy1(*this, FDC_TAG ":1"),
827   m_fdc(*this, FDC_TAG),
828   m_address(*this, "ADDRESS"),
829   m_rfdo(1),
830   m_daco(1),
831   m_atna(1)
1125832{
1126   for (int i = 0; i < 2; i++)
1127   {
1128      m_unit[i].m_stp = 0;
1129      m_unit[i].m_mtr = 1;
1130      m_unit[i].m_track_len = 0;
1131      m_unit[i].m_buffer_pos = 0;
1132      m_unit[i].m_bit_pos = 0;
1133      memset(m_unit[i].m_track_buffer, 0, sizeof(m_unit[i].m_track_buffer));
1134   }
1135833}
1136834
1137c8050_device::c8050_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
1138   : device_t(mconfig, C8050, "C8050", tag, owner, clock, "c8050", __FILE__),
1139      device_ieee488_interface(mconfig, *this),
1140      m_maincpu(*this, M6502_TAG),
1141      m_fdccpu(*this, M6504_TAG),
1142      m_riot0(*this, M6532_0_TAG),
1143      m_riot1(*this, M6532_1_TAG),
1144      m_miot(*this, M6530_TAG),
1145      m_via(*this, M6522_TAG),
1146      m_image0(*this, FLOPPY_0),
1147      m_image1(*this, FLOPPY_1),
1148      m_gcr(*this, "gcr"),
1149      m_address(*this, "ADDRESS"),
1150      m_drive(0),
1151      m_side(0),
1152      m_double_sided(false),
1153      m_rfdo(1),
1154      m_daco(1),
1155      m_atna(1),
1156      m_ifc(0),
1157      m_ds(-1),
1158      m_bit_count(0),
1159      m_sr(0),
1160      m_pi(0),
1161      m_ready(0),
1162      m_mode(0),
1163      m_rw(0),
1164      m_miot_irq(CLEAR_LINE)
835c8050_device::c8050_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
836   device_t(mconfig, C8050, "C8050", tag, owner, clock, "c8050", __FILE__),
837   device_ieee488_interface(mconfig, *this),
838   m_maincpu(*this, M6502_TAG),
839   m_fdccpu(*this, M6504_TAG),
840   m_riot0(*this, M6532_0_TAG),
841   m_riot1(*this, M6532_1_TAG),
842   m_miot(*this, M6530_TAG),
843   m_via(*this, M6522_TAG),
844   m_floppy0(*this, FDC_TAG ":0"),
845   m_floppy1(*this, FDC_TAG ":1"),
846   m_fdc(*this, FDC_TAG),
847   m_address(*this, "ADDRESS"),
848   m_rfdo(1),
849   m_daco(1),
850   m_atna(1)
1165851{
1166   for (int i = 0; i < 2; i++)
1167   {
1168      m_unit[i].m_stp = 0;
1169      m_unit[i].m_mtr = 1;
1170      m_unit[i].m_track_len = 0;
1171      m_unit[i].m_buffer_pos = 0;
1172      m_unit[i].m_bit_pos = 0;
1173   }
1174852}
1175853
1176854
r245595r245596
1178856//  c8250_device - constructor
1179857//-------------------------------------------------
1180858
1181c8250_device::c8250_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
1182   : c8050_device(mconfig, C8250, "C8250", tag, owner, clock, true, "c8250", __FILE__) { }
859c8250_device::c8250_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
860   c8050_device(mconfig, C8250, "C8250", tag, owner, clock, "c8250", __FILE__) { }
1183861
1184862
1185863//-------------------------------------------------
1186864//  c8250lp_device - constructor
1187865//-------------------------------------------------
1188866
1189c8250lp_device::c8250lp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
1190   : c8050_device(mconfig, C8250LP, "C8250LP", tag, owner, clock, true, "c8250lp", __FILE__) { }
867c8250lp_device::c8250lp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
868   c8050_device(mconfig, C8250LP, "C8250LP", tag, owner, clock, "c8250lp", __FILE__) { }
1191869
1192870
1193871//-------------------------------------------------
1194872//  sfd1001_device - constructor
1195873//-------------------------------------------------
1196874
1197sfd1001_device::sfd1001_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
1198   : c8050_device(mconfig, SFD1001, "SFD1001", tag, owner, clock, true, "sfd1001", __FILE__) { }
875sfd1001_device::sfd1001_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
876   c8050_device(mconfig, SFD1001, "SFD1001", tag, owner, clock, "sfd1001", __FILE__) { }
1199877
1200878
1201879//-------------------------------------------------
r245595r245596
1204882
1205883void c8050_device::device_start()
1206884{
1207   m_bit_timer = timer_alloc();
1208
1209885   // install image callbacks
1210   m_unit[0].m_image = m_image0;
886   m_fdc->set_floppy(m_floppy0->get_device(), m_floppy1->get_device());
1211887
1212   m_image0->floppy_install_load_proc(c8050_device::on_disk0_change);
1213
1214   if (m_image1)
1215   {
1216      m_unit[1].m_image = m_image1;
1217
1218      m_image1->floppy_install_load_proc(c8050_device::on_disk1_change);
1219   }
1220
1221888   // register for state saving
1222   save_item(NAME(m_drive));
1223   save_item(NAME(m_side));
1224889   save_item(NAME(m_rfdo));
1225890   save_item(NAME(m_daco));
1226891   save_item(NAME(m_atna));
1227   save_item(NAME(m_ds));
1228   save_item(NAME(m_bit_count));
1229   save_item(NAME(m_sr));
1230   save_item(NAME(m_pi));
1231   save_item(NAME(m_i));
1232   save_item(NAME(m_e));
1233   save_item(NAME(m_ready));
1234   save_item(NAME(m_mode));
1235   save_item(NAME(m_rw));
1236   save_item(NAME(m_miot_irq));
1237   save_item(NAME(m_unit[0].m_stp));
1238   save_item(NAME(m_unit[0].m_mtr));
1239   save_item(NAME(m_unit[0].m_track_len));
1240   save_item(NAME(m_unit[0].m_buffer_pos));
1241   save_item(NAME(m_unit[0].m_bit_pos));
1242
1243   if (m_image1)
1244   {
1245      save_item(NAME(m_unit[1].m_stp));
1246      save_item(NAME(m_unit[1].m_mtr));
1247      save_item(NAME(m_unit[1].m_track_len));
1248      save_item(NAME(m_unit[1].m_buffer_pos));
1249      save_item(NAME(m_unit[1].m_bit_pos));
1250   }
1251892}
1252893
1253894
r245595r245596
1271912   m_via->reset();
1272913
1273914   // turn off spindle motors
1274   m_unit[0].m_mtr = m_unit[1].m_mtr = 1;
915   m_fdc->mtr0_w(1);
916   m_fdc->mtr1_w(1);
1275917}
1276918
1277919
1278920//-------------------------------------------------
1279//  device_timer - handler timer events
1280//-------------------------------------------------
1281
1282void c8050_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
1283{
1284   int ready = 1;
1285
1286   // shift in data from the read head
1287   m_sr <<= 1;
1288   m_sr |= BIT(m_unit[m_drive].m_track_buffer[m_unit[m_drive].m_buffer_pos], m_unit[m_drive].m_bit_pos);
1289
1290   // update GCR data
1291   update_gcr_data();
1292
1293   // update bit counters
1294   m_unit[m_drive].m_bit_pos--;
1295   m_bit_count++;
1296
1297   if (m_unit[m_drive].m_bit_pos < 0)
1298   {
1299      m_unit[m_drive].m_bit_pos = 7;
1300      m_unit[m_drive].m_buffer_pos++;
1301
1302      if (m_unit[m_drive].m_buffer_pos >= m_unit[m_drive].m_track_len)
1303      {
1304         // loop to the start of the track
1305         m_unit[m_drive].m_buffer_pos = 0;
1306      }
1307   }
1308
1309   if (!SYNC)
1310   {
1311      // SYNC detected
1312      m_bit_count = 0;
1313   }
1314
1315   if (m_bit_count == 10)
1316   {
1317      // byte ready
1318      m_bit_count = 0;
1319      ready = 0;
1320   }
1321
1322   if (m_ready != ready)
1323   {
1324      // set byte ready flag
1325      m_ready = ready;
1326
1327      m_via->write_ca1(ready);
1328      m_via->write_cb1(ERROR);
1329
1330      this->byte_ready(ready);
1331   }
1332}
1333
1334inline void c8050_device::byte_ready(int state)
1335{
1336   m_fdccpu->set_input_line(M6502_SET_OVERFLOW, state ? CLEAR_LINE : ASSERT_LINE);
1337}
1338
1339
1340
1341//-------------------------------------------------
1342921//  ieee488_atn -
1343922//-------------------------------------------------
1344923
r245595r245596
1364943
1365944   m_ifc = state;
1366945}
1367
1368
1369//-------------------------------------------------
1370//  on_disk0_change -
1371//-------------------------------------------------
1372
1373void c8050_device::on_disk0_change(device_image_interface &image)
1374{
1375   c8050_device *c8050 = static_cast<c8050_device *>(image.device().owner());
1376
1377   c8050->read_current_track(0);
1378}
1379
1380
1381//-------------------------------------------------
1382//  on_disk1_change -
1383//-------------------------------------------------
1384
1385void c8050_device::on_disk1_change(device_image_interface &image)
1386{
1387   c8050_device *c8050 = static_cast<c8050_device *>(image.device().owner());
1388
1389   c8050->read_current_track(1);
1390}
trunk/src/emu/bus/ieee488/c8050.h
r245595r245596
1616
1717#include "emu.h"
1818#include "ieee488.h"
19#include "c8050fdc.h"
1920#include "cpu/m6502/m6502.h"
2021#include "cpu/m6502/m6504.h"
21#include "imagedev/flopdrv.h"
22#include "formats/d64_dsk.h"
23#include "formats/g64_dsk.h"
2422#include "machine/6522via.h"
2523#include "machine/6532riot.h"
26#include "machine/mos6530.h"
24#include "machine/mos6530n.h"
2725
2826
2927
3028//**************************************************************************
31//  MACROS / CONSTANTS
32//**************************************************************************
33
34#define G64_BUFFER_SIZE         32768
35#define G64_SYNC_MARK           0x3ff
36
37
38const int C8050_BITRATE[] =
39{
40   XTAL_12MHz/2/16,    /* tracks  1-39 */
41   XTAL_12MHz/2/15,    /* tracks 40-53 */
42   XTAL_12MHz/2/14,    /* tracks 54-65 */
43   XTAL_12MHz/2/13     /* tracks 65-84 */
44};
45
46
47
48//**************************************************************************
4929//  TYPE DEFINITIONS
5030//**************************************************************************
5131
5232// ======================> c8050_device
5333
5434class c8050_device :  public device_t,
55                  public device_ieee488_interface
35                 public device_ieee488_interface
5636{
5737public:
5838   // construction/destruction
59   c8050_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, bool double_sided, const char *shortname, const char *source);
39   c8050_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
6040   c8050_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
6141
6242   // optional information overrides
r245595r245596
6444   virtual machine_config_constructor device_mconfig_additions() const;
6545   virtual ioport_constructor device_input_ports() const;
6646
67   // not really public
68   static void on_disk0_change(device_image_interface &image);
69   static void on_disk1_change(device_image_interface &image);
70
7147   DECLARE_READ8_MEMBER( dio_r );
7248   DECLARE_WRITE8_MEMBER( dio_w );
7349   DECLARE_READ8_MEMBER( riot1_pa_r );
7450   DECLARE_WRITE8_MEMBER( riot1_pa_w );
7551   DECLARE_READ8_MEMBER( riot1_pb_r );
7652   DECLARE_WRITE8_MEMBER( riot1_pb_w );
77   DECLARE_READ8_MEMBER( via_pa_r );
78   DECLARE_READ8_MEMBER( via_pb_r );
7953   DECLARE_WRITE8_MEMBER( via_pb_w );
80   DECLARE_WRITE_LINE_MEMBER( mode_sel_w );
81   DECLARE_WRITE_LINE_MEMBER( rw_sel_w );
8254   DECLARE_READ8_MEMBER( pi_r );
8355   DECLARE_WRITE8_MEMBER( pi_w );
84   DECLARE_READ8_MEMBER( miot_pb_r );
85   DECLARE_WRITE8_MEMBER( miot_pb_w );
56   
57   DECLARE_FLOPPY_FORMATS( floppy_formats );
8658
8759protected:
8860   // device-level overrides
8961   virtual void device_start();
9062   virtual void device_reset();
91   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
9263
9364   // device_ieee488_interface overrides
9465   virtual void ieee488_atn(int state);
9566   virtual void ieee488_ifc(int state);
9667
97   inline void byte_ready(int state);
9868   inline void update_ieee_signals();
99   inline void update_gcr_data();
100   inline void read_current_track(int unit);
101   inline void spindle_motor(int unit, int mtr);
102   inline void micropolis_step_motor(int unit, int stp);
103   inline void mpi_step_motor(int unit, int stp);
10469
10570   required_device<m6502_device> m_maincpu;
10671   required_device<m6504_device> m_fdccpu;
10772   required_device<riot6532_device> m_riot0;
10873   required_device<riot6532_device> m_riot1;
109   required_device<mos6530_device> m_miot;
74   required_device<mos6530_t> m_miot;
11075   required_device<via6522_device> m_via;
111   required_device<legacy_floppy_image_device> m_image0;
112   optional_device<legacy_floppy_image_device> m_image1;
113   required_memory_region m_gcr;
76   required_device<floppy_connector> m_floppy0;
77   optional_device<floppy_connector> m_floppy1;
78   required_device<c8050_fdc_t> m_fdc;
11479   required_ioport m_address;
11580
116   struct {
117      // motors
118      int m_stp;                              // stepper motor phase
119      int m_mtr;                              // spindle motor on
120
121      // track
122      UINT8 m_track_buffer[G64_BUFFER_SIZE];  // track data buffer
123      int m_track_len;                        // track length
124      int m_buffer_pos;                       // byte position within track buffer
125      int m_bit_pos;                          // bit position within track buffer byte
126
127      // devices
128      legacy_floppy_image_device *m_image;
129   } m_unit[2];
130
131   int m_drive;                        // selected drive
132   int m_side;                         // selected side
133   bool m_double_sided;
134
13581   // IEEE-488 bus
13682   int m_rfdo;                         // not ready for data output
13783   int m_daco;                         // not data accepted output
13884   int m_atna;                         // attention acknowledge
13985   int m_ifc;
140
141   // track
142   int m_ds;                           // density select
143   int m_bit_count;                    // GCR bit counter
144   UINT16 m_sr;                        // GCR data shift register
145   UINT8 m_pi;                         // parallel data input
146   UINT16 m_i;                         // GCR encoder/decoded ROM address
147   UINT8 m_e;                          // GCR encoder/decoded ROM data
148
149   // signals
150   int m_ready;                        // byte ready
151   int m_mode;                         // mode select
152   int m_rw;                           // read/write select
153   int m_miot_irq;                     // MIOT interrupt
154
155   // timers
156   emu_timer *m_bit_timer;
15786};
15887
15988
r245595r245596
16796
16897   // optional information overrides
16998   virtual machine_config_constructor device_mconfig_additions() const;
99
100   DECLARE_FLOPPY_FORMATS( floppy_formats );
170101};
171102
172103
r245595r245596
181112   // optional information overrides
182113   virtual const rom_entry *device_rom_region() const;
183114   virtual machine_config_constructor device_mconfig_additions() const;
115
116   DECLARE_FLOPPY_FORMATS( floppy_formats );
184117};
185118
186119
r245595r245596
195128   // optional information overrides
196129   virtual const rom_entry *device_rom_region() const;
197130   virtual machine_config_constructor device_mconfig_additions() const;
131
132   DECLARE_FLOPPY_FORMATS( floppy_formats );
198133};
199134
200135
trunk/src/emu/bus/ieee488/c8050fdc.c
r245595r245596
99
1010**********************************************************************/
1111
12/*
13
14   TODO:
15
16   - write mode
17    - write protect
18    - separate read/write methods
19
20*/
21
1222#include "c8050fdc.h"
1323
1424
r245595r245596
1727//  MACROS / CONSTANTS
1828//**************************************************************************
1929
20#define LOG 1
30#define LOG 0
2131
2232#define GCR_DECODE(_e, _i) \
2333   ((BIT(_e, 6) << 7) | (BIT(_i, 7) << 6) | (_e & 0x33) | (BIT(_e, 2) << 3) | (_i & 0x04))
r245595r245596
6777   device_t(mconfig, C8050_FDC, "C8050 FDC", tag, owner, clock, "c8050fdc", __FILE__),
6878   m_write_sync(*this),
6979   m_write_ready(*this),
80   m_write_brdy(*this),
7081   m_write_error(*this),
82   m_write_wps(*this),
7183   m_gcr_rom(*this, "gcr"),
7284   m_floppy0(NULL),
7385   m_floppy1(NULL),
r245595r245596
7890   m_ds(0),
7991   m_drv_sel(0),
8092   m_mode_sel(0),
81   m_rw_sel(0)
93   m_rw_sel(0),
94   m_wps(0),
95   m_wps0(0),
96   m_wps1(0)
8297{
8398   cur_live.tm = attotime::never;
8499   cur_live.state = IDLE;
r245595r245596
87102}
88103
89104
90
91105//-------------------------------------------------
92106//  device_start - device-specific startup
93107//-------------------------------------------------
r245595r245596
97111   // resolve callbacks
98112   m_write_sync.resolve_safe();
99113   m_write_ready.resolve_safe();
114   m_write_brdy.resolve_safe();
100115   m_write_error.resolve_safe();
116   m_write_wps.resolve_safe();
101117
102118   // allocate timer
103119   t_gen = timer_alloc(0);
r245595r245596
206222void c8050_fdc_t::set_floppy(floppy_image_device *floppy0, floppy_image_device *floppy1)
207223{
208224   m_floppy0 = floppy0;
209   m_floppy1 = floppy1;
225   m_floppy0->setup_wpt_cb(floppy_image_device::wpt_cb(FUNC(c8050_fdc_t::wps0_w), this));
226
227   if (floppy1) {
228      m_floppy1 = floppy1;
229      m_floppy1->setup_wpt_cb(floppy_image_device::wpt_cb(FUNC(c8050_fdc_t::wps1_w), this));
230   }
210231}
211232
233void c8050_fdc_t::update_wps()
234{
235   int state = m_drv_sel ? m_wps1 : m_wps0;
236
237   if (m_wps != state)
238   {
239      m_wps = state;
240      m_write_wps(m_wps);
241   }
242}
243
244void c8050_fdc_t::wps0_w(floppy_image_device *floppy, int state)
245{
246   if (m_wps0 != state)
247   {
248      live_sync();
249      m_wps0 = state;
250      update_wps();
251      checkpoint();
252      live_run();
253   }
254}
255
256void c8050_fdc_t::wps1_w(floppy_image_device *floppy, int state)
257{
258   if (m_wps1 != state)
259   {
260      live_sync();
261      m_wps0 = state;
262      update_wps();
263      checkpoint();
264      live_run();
265   }
266}
267
212268void c8050_fdc_t::live_start()
213269{
214270   cur_live.tm = machine().time();
r245595r245596
225281   cur_live.mode_sel = m_mode_sel;
226282   cur_live.rw_sel = m_rw_sel;
227283   cur_live.pi = m_pi;
284   cur_live.wps = m_wps;
228285
229286   pll_reset(cur_live.tm, attotime::from_hz(clock() / (16 - m_ds)));
230287   checkpoint_live = cur_live;
r245595r245596
333390   cur_live.next_state = -1;
334391
335392   cur_live.ready = 1;
393   cur_live.brdy = 1;
336394   cur_live.sync = 1;
337395   cur_live.error = 1;
338396}
r245595r245596
390448         if (LOG) logerror("%s cyl %u bit %u sync %u bc %u sr %03x i %03x e %02x\n",cur_live.tm.as_string(),get_floppy()->get_cyl(),bit,sync,cur_live.bit_counter,cur_live.shift_reg,cur_live.i,cur_live.e);
391449
392450         // byte ready
393         int ready = !(cur_live.bit_counter == 9);
451         int ready = !(cur_live.bit_counter == 9); // 74190 _RC, should be triggered on the falling edge of the clock
452         int brdy = ready; // 74190 TC
394453
395454         // GCR error
396455         int error = !(ready || BIT(cur_live.e, 3));
r245595r245596
419478            syncpoint = true;
420479         }
421480
481         if (brdy != cur_live.brdy) {
482            if (LOG) logerror("%s BRDY %u\n", cur_live.tm.as_string(), brdy);
483            cur_live.brdy = brdy;
484            syncpoint = true;
485         }
486
422487         if (sync != cur_live.sync) {
423            if (LOG) logerror("%s SYNC %u\n", cur_live.tm.as_string(),sync);
488            if (LOG) logerror("%s SYNC %u\n", cur_live.tm.as_string(), sync);
424489            cur_live.sync = sync;
425490            syncpoint = true;
426491         }
427492
428493         if (error != cur_live.error) {
429            if (LOG) logerror("%s ERROR %u\n", cur_live.tm.as_string(),error);
494            if (LOG) logerror("%s ERROR %u\n", cur_live.tm.as_string(), error);
430495            cur_live.error = error;
431496            syncpoint = true;
432497         }
r245595r245596
439504      }
440505
441506      case RUNNING_SYNCPOINT: {
507         if (LOG) {
508            if (!cur_live.sync) logerror("%s SYNC\n",cur_live.tm.as_string());
509            if (!cur_live.ready && cur_live.bit_counter == 9) logerror("%s DATA %02x\n",cur_live.tm.as_string(),GCR_DECODE(cur_live.e,cur_live.i));
510         }
442511         m_write_ready(cur_live.ready);
512         m_write_brdy(cur_live.brdy);
443513         m_write_sync(cur_live.sync);
444514         m_write_error(cur_live.error);
445515
r245595r245596
456526   UINT8 e = checkpoint_live.e;
457527   offs_t i = checkpoint_live.i;
458528
459   UINT8 data = (BIT(e, 6) << 7) | (BIT(i, 7) << 6) | (e & 0x33) | (BIT(e, 2) << 3) | (i & 0x04);
529   UINT8 data = GCR_DECODE(e, i);
460530
461   if (LOG) logerror("%s %s VIA reads data %02x (%03x)\n", machine().time().as_string(), machine().describe_context(), data, checkpoint_live.shift_reg);
531   if (LOG)logerror("%s %s VIA reads data %02x (%03x)\n", machine().time().as_string(), machine().describe_context(), data, checkpoint_live.shift_reg);
462532
463533   return data;
464534}
r245595r245596
475545   }
476546}
477547
548WRITE_LINE_MEMBER( c8050_fdc_t::ds0_w )
549{
550   m_ds0 = state;
551}
552
553WRITE_LINE_MEMBER( c8050_fdc_t::ds1_w )
554{
555   m_ds1 = state;
556
557   ds_w(m_ds1 << 1 | m_ds0);
558}
559
478560WRITE_LINE_MEMBER( c8050_fdc_t::drv_sel_w )
479561{
480562   if (m_drv_sel != state)
481563   {
482564      live_sync();
483565      m_drv_sel = cur_live.drv_sel = state;
566      update_wps();
484567      checkpoint();
485568      if (LOG) logerror("%s %s DRV SEL %u\n", machine().time().as_string(), machine().describe_context(), state);
486569      live_run();
r245595r245596
576659
577660WRITE_LINE_MEMBER( c8050_fdc_t::pull_sync_w )
578661{
579   // TODO
580662   if (LOG) logerror("%s %s PULL SYNC %u\n", machine().time().as_string(), machine().describe_context(), state);
581663}
trunk/src/emu/bus/ieee488/c8050fdc.h
r245595r245596
3232#define MCFG_C8050_READY_CALLBACK(_write) \
3333   devcb = &c8050_fdc_t::set_ready_wr_callback(*device, DEVCB_##_write);
3434
35#define MCFG_C8050_BRDY_CALLBACK(_write) \
36   devcb = &c8050_fdc_t::set_brdy_wr_callback(*device, DEVCB_##_write);
37
3538#define MCFG_C8050_ERROR_CALLBACK(_write) \
3639   devcb = &c8050_fdc_t::set_error_wr_callback(*device, DEVCB_##_write);
3740
41#define MCFG_C8050_WPS_CALLBACK(_write) \
42   devcb = &c8050_fdc_t::set_wps_wr_callback(*device, DEVCB_##_write);
3843
3944
45
4046//**************************************************************************
4147//  TYPE DEFINITIONS
4248//**************************************************************************
r245595r245596
5157
5258   template<class _Object> static devcb_base &set_sync_wr_callback(device_t &device, _Object object) { return downcast<c8050_fdc_t &>(device).m_write_sync.set_callback(object); }
5359   template<class _Object> static devcb_base &set_ready_wr_callback(device_t &device, _Object object) { return downcast<c8050_fdc_t &>(device).m_write_ready.set_callback(object); }
60   template<class _Object> static devcb_base &set_brdy_wr_callback(device_t &device, _Object object) { return downcast<c8050_fdc_t &>(device).m_write_brdy.set_callback(object); }
5461   template<class _Object> static devcb_base &set_error_wr_callback(device_t &device, _Object object) { return downcast<c8050_fdc_t &>(device).m_write_error.set_callback(object); }
62   template<class _Object> static devcb_base &set_wps_wr_callback(device_t &device, _Object object) { return downcast<c8050_fdc_t &>(device).m_write_wps.set_callback(object); }
5563
5664   DECLARE_READ8_MEMBER( read );
5765   DECLARE_WRITE8_MEMBER( write );
5866
67   DECLARE_WRITE_LINE_MEMBER( ds0_w );
68   DECLARE_WRITE_LINE_MEMBER( ds1_w );
5969   DECLARE_WRITE_LINE_MEMBER( drv_sel_w );
6070   DECLARE_WRITE_LINE_MEMBER( mode_sel_w );
6171   DECLARE_WRITE_LINE_MEMBER( rw_sel_w );
r245595r245596
6474   DECLARE_WRITE_LINE_MEMBER( odd_hd_w );
6575   DECLARE_WRITE_LINE_MEMBER( pull_sync_w );
6676
67   DECLARE_READ_LINE_MEMBER( wps_r ) { return checkpoint_live.drv_sel ? m_floppy1->wpt_r() : m_floppy0->wpt_r(); }
68
6977   void stp0_w(int stp);
7078   void stp1_w(int stp);
7179   void ds_w(int ds);
7280
7381   void set_floppy(floppy_image_device *floppy0, floppy_image_device *floppy1);
82   void wps0_w(floppy_image_device *floppy, int state);
83   void wps1_w(floppy_image_device *floppy, int state);
7484
7585protected:
7686   // device-level overrides
r245595r245596
8292   virtual const rom_entry *device_rom_region() const;
8393
8494   void stp_w(floppy_image_device *floppy, int mtr, int &old_stp, int stp);
95   void update_wps();
8596
8697   enum {
8798      IDLE,
r245595r245596
94105      int state, next_state;
95106      int sync;
96107      int ready;
108      int brdy;
97109      int error;
98110      int ds;
99111      int drv_sel;
r245595r245596
111123
112124      UINT8 pi;
113125      UINT16 shift_reg_write;
126      int wps;
114127   };
115128
116129   devcb_write_line m_write_sync;
117130   devcb_write_line m_write_ready;
131   devcb_write_line m_write_brdy;
118132   devcb_write_line m_write_error;
133   devcb_write_line m_write_wps;
119134
120135   required_memory_region m_gcr_rom;
121136
r245595r245596
127142   int m_stp0;
128143   int m_stp1;
129144   int m_ds;
145   int m_ds0;
146   int m_ds1;
130147   int m_drv_sel;
131148   int m_mode_sel;
132149   int m_rw_sel;
133150   int m_odd_hd;
134151   UINT8 m_pi;
152   int m_wps;
153   int m_wps0;
154   int m_wps1;
135155
136156   live_info cur_live, checkpoint_live;
137157   fdc_pll_t cur_pll, checkpoint_pll;
trunk/src/emu/machine/64h156.c
r245595r245596
1515
1616    http://personalpages.tds.net/~rcarlsen/cbm/1541/1541%20EARLY/1540-2.GIF
1717
18    - write
18    - write protect
19    - separate read/write methods
1920    - cycle exact VIA
20
2121    - get these running and we're golden
2222        - Bounty Bob Strikes Back (aligned halftracks)
2323        - Quiwi (speed change within track)
r245595r245596
306306            syncpoint = true;
307307         }
308308
309         if (BIT(cell_counter, 1) && !BIT(cur_live.cell_counter, 1) && !cur_live.oe) {
309         if (BIT(cell_counter, 1) && !BIT(cur_live.cell_counter, 1) && !cur_live.oe) { // TODO WPS
310310            write_next_bit(BIT(cur_live.shift_reg_write, 7), limit);
311311         }
312312
trunk/src/emu/machine/6522via.c
r245595r245596
493493READ8_MEMBER( via6522_device::read )
494494{
495495   int val = 0;
496   if (space.debugger_access())
497      return 0;
496498
497499   offset &= 0xf;
498500
trunk/src/emu/machine/mos6530n.c
r245595r245596
391391{
392392   UINT8 data = 0;
393393
394   if (space.debugger_access())
395      return 0;
396
394397   if (offset & 0x01)
395398   {
396399      data = m_irq ? 0x80 : 0x00;
r245595r245596
565568      }
566569
567570      case RUNNING_SYNCPOINT: {
568         logerror("%s MOS6530 '%s' IRQ\n", machine().time().as_string(), tag());
571         if (LOG) logerror("%s MOS6530 '%s' IRQ\n", machine().time().as_string(), tag());
569572
570573         m_irq = true;
571574         update_pb();
trunk/src/lib/formats/d64_dsk.c
r245595r245596
245245}
246246
247247const floppy_format_type FLOPPY_D64_FORMAT = &floppy_image_format_creator<d64_format>;
248
249
250// ------ LEGACY -----
251
252
253/*********************************************************************
254
255    formats/d64_dsk.c
256
257    Floppy format code for Commodore 1541/2040/8050 disk images
258
259*********************************************************************/
260
261/*
262
263    TODO:
264
265    - write to disk
266    - disk errors 24, 25, 26, 28, 74
267    - variable gaps
268
269*/
270
271#define XTAL_16MHz      16000000
272#define XTAL_12MHz      12000000
273#include "g64_dsk.h"
274#include "flopimg.h"
275#include "d64_dsk.h"
276
277/***************************************************************************
278    PARAMETERS
279***************************************************************************/
280
281#define MAX_HEADS           2
282#define MAX_TRACKS          84
283#define MAX_ERROR_SECTORS   4166
284#define SECTOR_SIZE         256
285#define SECTOR_SIZE_GCR     368
286
287#define INVALID_OFFSET      0xbadbad
288
289#define D64_SIZE_35_TRACKS               174848
290#define D64_SIZE_35_TRACKS_WITH_ERRORS   175531
291#define D64_SIZE_40_TRACKS               196608
292#define D64_SIZE_40_TRACKS_WITH_ERRORS   197376
293#define D64_SIZE_42_TRACKS               205312
294#define D64_SIZE_42_TRACKS_WITH_ERRORS   206114
295#define D67_SIZE_35_TRACKS               176640
296#define D71_SIZE_70_TRACKS               349696
297#define D71_SIZE_70_TRACKS_WITH_ERRORS   351062
298#define D80_SIZE_77_TRACKS               533248
299#define D80_SIZE_77_TRACKS_WITH_ERRORS   535331
300#define D82_SIZE_154_TRACKS             1066496
301#define D82_SIZE_154_TRACKS_WITH_ERRORS 1070662
302
303#define G64_SPEED_BLOCK_SIZE    1982
304
305enum
306{
307   DOS1,
308   DOS2,
309   DOS25
310};
311
312static const char *const DOS_VERSION[] = { "1.0", "2.0", "2.5" };
313
314enum
315{
316   ERROR_00 = 1,
317   ERROR_20,       /* header block not found */
318   ERROR_21,       /* no sync character */
319   ERROR_22,       /* data block not present */
320   ERROR_23,       /* checksum error in data block */
321   ERROR_24,       /* write verify (on format) UNIMPLEMENTED */
322   ERROR_25,       /* write verify error UNIMPLEMENTED */
323   ERROR_26,       /* write protect on UNIMPLEMENTED */
324   ERROR_27,       /* checksum error in header block */
325   ERROR_28,       /* write error UNIMPLEMENTED */
326   ERROR_29,       /* disk ID mismatch */
327   ERROR_74,       /* disk not ready (no device 1) UNIMPLEMENTED */
328};
329
330static const char *const ERROR_CODE[] = { "00", "00", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "74" };
331
332static const UINT8 bin_2_gcr[] =
333{
334   0x0a, 0x0b, 0x12, 0x13, 0x0e, 0x0f, 0x16, 0x17,
335   0x09, 0x19, 0x1a, 0x1b, 0x0d, 0x1d, 0x1e, 0x15
336};
337
338/* This could be of use if we ever implement saving in .d64 format, to convert back GCR -> d64 */
339/*
340static const int gcr_2_bin[] =
341{
342    -1, -1,   -1,   -1,
343    -1, -1,   -1,   -1,
344    -1, 0x08, 0x00, 0x01,
345    -1, 0x0c, 0x04, 0x05,
346    -1, -1,   0x02, 0x03,
347    -1, 0x0f, 0x06, 0x07,
348    -1, 0x09, 0x0a, 0x0b,
349    -1, 0x0d, 0x0e, -1
350};
351*/
352
353static const int DOS1_SECTORS_PER_TRACK[] =
354{
355   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
356   20, 20, 20, 20, 20, 20, 20,
357   18, 18, 18, 18, 18, 18,
358   17, 17, 17, 17, 17,
359   17, 17, 17, 17, 17,
360   17, 17
361};
362
363static const int DOS1_SPEED_ZONE[] =
364{
365   3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
366   2, 2, 2, 2, 2, 2, 2,
367   1, 1, 1, 1, 1, 1,
368   0, 0, 0, 0, 0,
369   0, 0, 0, 0, 0,
370   0, 0
371};
372
373static const int DOS2_SECTORS_PER_TRACK[] =
374{
375   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
376   19, 19, 19, 19, 19, 19, 19,
377   18, 18, 18, 18, 18, 18,
378   17, 17, 17, 17, 17,
379   17, 17, 17, 17, 17,
380   17, 17
381};
382
383static const int DOS25_SECTORS_PER_TRACK[] =
384{
385   29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
386   29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,     /* 1-39 */
387   27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,                         /* 40-53 */
388   25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,                                     /* 54-64 */
389   23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,                             /* 65-77 */
390   23, 23, 23, 23, 23, 23, 23                                                      /* 78-84 */
391};
392
393static const int DOS25_SPEED_ZONE[] =
394{
395   3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
396   3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,    /* 1-39 */
397   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,                   /* 40-53 */
398   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,                            /* 54-64 */
399   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                      /* 65-77 */
400   0, 0, 0, 0, 0, 0, 0                                         /* 78-84 */
401};
402
403/***************************************************************************
404    TYPE DEFINITIONS
405***************************************************************************/
406
407struct d64dsk_tag
408{
409   int dos;                                    /* CBM DOS version */
410   int heads;                                  /* number of physical heads */
411   int tracks;                                 /* number of physical tracks */
412   int dos_tracks;                             /* number of logical tracks */
413   int track_offset[MAX_HEADS][MAX_TRACKS];    /* offset within image for each physical track */
414   UINT32 speed_zone[MAX_TRACKS];              /* speed zone for each physical track */
415   bool has_errors;                            /* flag to check for available error codes */
416   UINT8 error[MAX_ERROR_SECTORS];             /* error code for each logical sector */
417   int error_offset[MAX_HEADS][MAX_TRACKS];    /* offset within error array for sector 0 of each logical track */
418
419   UINT8 id1, id2;                             /* DOS disk format ID */
420};
421
422/***************************************************************************
423    INLINE FUNCTIONS
424***************************************************************************/
425
426INLINE struct d64dsk_tag *get_tag(floppy_image_legacy *floppy)
427{
428   return (d64dsk_tag *)floppy_tag(floppy);
429}
430
431INLINE float get_dos_track(int track)
432{
433   return ((float)track / 2) + 1;
434}
435
436/***************************************************************************
437    IMPLEMENTATION
438***************************************************************************/
439
440/*-------------------------------------------------
441    d64_get_heads_per_disk - returns the number
442    of heads in the disk image
443-------------------------------------------------*/
444
445static int d64_get_heads_per_disk(floppy_image_legacy *floppy)
446{
447   return get_tag(floppy)->heads;
448}
449
450/*-------------------------------------------------
451    d64_get_tracks_per_disk - returns the number
452    of DOS tracks in the disk image
453-------------------------------------------------*/
454
455static int d64_get_tracks_per_disk(floppy_image_legacy *floppy)
456{
457   return get_tag(floppy)->tracks;
458}
459
460/*-------------------------------------------------
461    d64_get_sectors_per_track - returns the number
462    of sectors per given track
463-------------------------------------------------*/
464
465static int d64_get_sectors_per_track(floppy_image_legacy *floppy, int head, int track)
466{
467   int sectors_per_track = 0;
468
469   switch (get_tag(floppy)->dos)
470   {
471   case DOS1:  sectors_per_track = DOS1_SECTORS_PER_TRACK[track / 2]; break;
472   case DOS2:  sectors_per_track = DOS2_SECTORS_PER_TRACK[track / 2]; break;
473   case DOS25: sectors_per_track = DOS25_SECTORS_PER_TRACK[track];    break;
474   }
475
476   return sectors_per_track;
477}
478
479/*-------------------------------------------------
480    get_track_offset - returns the offset within
481    the disk image for a given track
482-------------------------------------------------*/
483
484static floperr_t get_track_offset(floppy_image_legacy *floppy, int head, int track, UINT64 *offset)
485{
486   struct d64dsk_tag *tag = get_tag(floppy);
487   UINT64 offs = 0;
488
489   if ((track < 0) || (track >= tag->tracks))
490      return FLOPPY_ERROR_SEEKERROR;
491
492   offs = tag->track_offset[head][track];
493
494   if (offset)
495      *offset = offs;
496
497   return FLOPPY_ERROR_SUCCESS;
498}
499
500/*-------------------------------------------------
501    d64_get_track_size - returns the track size
502-------------------------------------------------*/
503
504static UINT32 d64_get_track_size(floppy_image_legacy *floppy, int head, int track)
505{
506   struct d64dsk_tag *tag = get_tag(floppy);
507
508   if (tag->track_offset[head][track] == INVALID_OFFSET)
509      return 0;
510
511   /* determine number of sectors per track */
512   int sectors_per_track = d64_get_sectors_per_track(floppy, head, track);
513
514   /* allocate temporary GCR track data buffer */
515   UINT32 track_length = sectors_per_track * SECTOR_SIZE_GCR;
516
517   return track_length;
518}
519
520/*-------------------------------------------------
521    get_sector_error_code - returns the error
522    code for the given sector
523-------------------------------------------------*/
524
525static int get_sector_error_code(floppy_image_legacy *floppy, int head, int dos_track, int sector)
526{
527   struct d64dsk_tag *tag = get_tag(floppy);
528
529   if (!tag->has_errors)
530      return ERROR_00;
531
532   int sector_error = tag->error[tag->error_offset[head][dos_track] + sector]; // TODO index out of bounds!!!
533
534   if (sector_error != ERROR_00)
535   {
536      LOG_FORMATS("D64 error %s head %d track %d sector %d\n", ERROR_CODE[sector_error], head, dos_track, sector);
537   }
538
539   return sector_error;
540}
541
542/*-------------------------------------------------
543    gcr_double_2_gcr - GCR decodes given data
544-------------------------------------------------*/
545
546/* gcr_double_2_gcr takes 4 bytes (a, b, c, d) and shuffles their nibbles to obtain 5 bytes in dest */
547/* The result is basically res = (enc(a) << 15) | (enc(b) << 10) | (enc(c) << 5) | enc(d)
548 * with res being 5 bytes long and enc(x) being the GCR encode of x.
549 * In fact, we store the result as five separate bytes in the dest argument
550 */
551
552/*
553
554 Commodore GCR format
555
556Original    Encoded
5574 bits      5 bits
558
5590000    ->  01010 = 0x0a
5600001    ->  01011 = 0x0b
5610010    ->  10010 = 0x12
5620011    ->  10011 = 0x13
5630100    ->  01110 = 0x0e
5640101    ->  01111 = 0x0f
5650110    ->  10110 = 0x16
5660111    ->  10111 = 0x17
5671000    ->  01001 = 0x09
5681001    ->  11001 = 0x19
5691010    ->  11010 = 0x1a
5701011    ->  11011 = 0x1b
5711100    ->  01101 = 0x0d
5721101    ->  11101 = 0x1d
5731110    ->  11110 = 0x1e
5741111    ->  10101 = 0x15
575
576We use the encoded values in bytes because we use them to encode
577groups of 4 bytes into groups of 5 bytes, below.
578
579*/
580
581static void gcr_double_2_gcr(UINT8 a, UINT8 b, UINT8 c, UINT8 d, UINT8 *dest)
582{
583   UINT8 gcr[8];
584
585   /* Encode each nibble to 5 bits */
586   gcr[0] = bin_2_gcr[a >> 4];
587   gcr[1] = bin_2_gcr[a & 0x0f];
588   gcr[2] = bin_2_gcr[b >> 4];
589   gcr[3] = bin_2_gcr[b & 0x0f];
590   gcr[4] = bin_2_gcr[c >> 4];
591   gcr[5] = bin_2_gcr[c & 0x0f];
592   gcr[6] = bin_2_gcr[d >> 4];
593   gcr[7] = bin_2_gcr[d & 0x0f];
594
595   /* Re-order the encoded data to only keep the 5 lower bits of each byte */
596   dest[0] = (gcr[0] << 3) | (gcr[1] >> 2);
597   dest[1] = (gcr[1] << 6) | (gcr[2] << 1) | (gcr[3] >> 4);
598   dest[2] = (gcr[3] << 4) | (gcr[4] >> 1);
599   dest[3] = (gcr[4] << 7) | (gcr[5] << 2) | (gcr[6] >> 3);
600   dest[4] = (gcr[6] << 5) | gcr[7];
601}
602
603/*-------------------------------------------------
604    d64_read_track - reads a full track from the
605    disk image
606-------------------------------------------------*/
607
608/*
609
610    Commodore sector format
611
612    SYNC                        FF * 5
613    08
614    CHECKSUM                    sector ^ track ^ id2 ^ id1
615    SECTOR                      0..20 (2040), 0..28 (8050)
616    TRACK                       1..35 (2040), 1..77 (8050), 1..70 (1571)
617    ID2
618    ID1
619    GAP 1                       55 * 9 (2040), 55 * 8 (1541)
620
621    SYNC                        FF * 5
622    07
623    NEXT TRACK
624    NEXT SECTOR
625    254 BYTES OF DATA
626    CHECKSUM
627    GAP 2                       55 * 8..19
628
629*/
630
631static floperr_t d64_read_track(floppy_image_legacy *floppy, int head, int track, UINT64 offset, void *buffer, size_t buflen)
632{
633   struct d64dsk_tag *tag = get_tag(floppy);
634   floperr_t err;
635   UINT64 track_offset;
636
637   /* get track offset */
638   err = get_track_offset(floppy, head, track, &track_offset);
639
640   if (err)
641      return err;
642
643   if (track_offset != INVALID_OFFSET)
644   {
645      UINT8 id1 = tag->id1;
646      UINT8 id2 = tag->id2;
647      int sectors_per_track;
648      UINT16 d64_track_size;
649      UINT8 *d64_track_data;
650      UINT16 gcr_track_size;
651      UINT8 *gcr_track_data;
652      UINT64 gcr_pos = 0;
653
654      /* determine logical track number */
655      int dos_track = get_dos_track(track);
656
657      if (tag->dos == DOS25)
658      {
659         dos_track = track + 1;
660      }
661
662      /* logical track numbers continue on the flip side */
663      if (head == 1) dos_track += tag->dos_tracks;
664
665      /* determine number of sectors per track */
666      sectors_per_track = d64_get_sectors_per_track(floppy, head, track);
667
668      /* allocate D64 track data buffer */
669      d64_track_size = sectors_per_track * SECTOR_SIZE;
670      d64_track_data = (UINT8 *)alloca(d64_track_size);
671
672      /* allocate temporary GCR track data buffer */
673      gcr_track_size = sectors_per_track * SECTOR_SIZE_GCR;
674      gcr_track_data = (UINT8 *)alloca(gcr_track_size);
675
676      if (buflen < gcr_track_size) { fatalerror("D64 track buffer too small: %u!\n", (UINT32)buflen); }
677
678      /* read D64 track data */
679      floppy_image_read(floppy, d64_track_data, track_offset, d64_track_size);
680
681      /* GCR encode D64 sector data */
682      for (int sector = 0; sector < sectors_per_track; sector++)
683      {
684         // here we convert the sector data to gcr directly!
685         // IMPORTANT: errors in reading sectors can modify e.g. header info $01 & $05
686         int sector_error = get_sector_error_code(floppy, head, track, sector);
687
688         /* first we set the position at which sector data starts in the image */
689         UINT64 d64_pos = sector * SECTOR_SIZE;
690         int i;
691
692         /*
693             1. Header sync       FF FF FF FF FF (40 'on' bits, not GCR encoded)
694             2. Header info       52 54 B5 29 4B 7A 5E 95 55 55 (10 GCR bytes)
695             3. Header gap        55 55 55 55 55 55 55 55 55 (9 bytes, never read)
696             4. Data sync         FF FF FF FF FF (40 'on' bits, not GCR encoded)
697             5. Data block        55...4A (325 GCR bytes)
698             6. Inter-sector gap  55 55 55 55...55 55 (4 to 19 bytes, never read)
699         */
700
701         if (sector_error == ERROR_29)
702            id1 ^= 0xff;
703
704         /* Header sync */
705         if (sector_error != ERROR_21)
706         {
707            for (i = 0; i < 5; i++)
708               gcr_track_data[gcr_pos + i] = 0xff;
709            gcr_pos += 5;
710         }
711
712         /* Header info */
713         /* These are 8 bytes unencoded, which become 10 bytes encoded */
714         // $00 - header block ID ($08)                      // this byte can be modified by error code 20 -> 0xff
715         // $01 - header block checksum (EOR of $02-$05)     // this byte can be modified by error code 27 -> ^ 0xff
716         // $02 - Sector# of data block
717         // $03 - Track# of data block
718         UINT8 header_block_id = (sector_error == ERROR_20) ? 0xff : 0x08;
719         UINT8 header_block_checksum = sector ^ dos_track ^ id2 ^ id1;
720
721         if (sector_error == ERROR_27)
722            header_block_checksum ^= 0xff;
723
724         gcr_double_2_gcr(header_block_id, header_block_checksum, sector, dos_track, gcr_track_data + gcr_pos);
725         gcr_pos += 5;
726
727         // $04 - Format ID byte #2
728         // $05 - Format ID byte #1
729         // $06 - $0F ("off" byte)
730         // $07 - $0F ("off" byte)
731         gcr_double_2_gcr(id2, id1, 0x0f, 0x0f, gcr_track_data + gcr_pos);
732         gcr_pos += 5;
733
734         /* Header gap */
735         for (i = 0; i < 9; i++)
736            gcr_track_data[gcr_pos + i] = 0x55;
737         gcr_pos += 9;
738
739         /* Data sync */
740         for (i = 0; i < 5; i++)
741            gcr_track_data[gcr_pos + i] = 0xff;
742         gcr_pos += 5;
743
744         /* Data block */
745         UINT8 data_block_id = (sector_error == ERROR_22) ? 0xff : 0x07;
746
747         // we first need to calculate the checksum of the 256 bytes of the sector
748         UINT8 sector_checksum = d64_track_data[d64_pos];
749         for (i = 1; i < 256; i++)
750            sector_checksum ^= d64_track_data[d64_pos + i];
751
752         if (sector_error == ERROR_23)
753            sector_checksum ^= 0xff;
754
755         /*
756             $00      - data block ID ($07)
757             $01-100  - 256 bytes sector data
758             $101     - data block checksum (EOR of $01-100)
759             $102-103 - $00 ("off" bytes, to make the sector size a multiple of 5)
760         */
761         gcr_double_2_gcr(data_block_id, d64_track_data[d64_pos], d64_track_data[d64_pos + 1], d64_track_data[d64_pos + 2], gcr_track_data + gcr_pos);
762         gcr_pos += 5;
763
764         for (i = 1; i < 64; i++)
765         {
766            gcr_double_2_gcr(d64_track_data[d64_pos + 4 * i - 1], d64_track_data[d64_pos + 4 * i],
767                           d64_track_data[d64_pos + 4 * i + 1], d64_track_data[d64_pos + 4 * i + 2], gcr_track_data + gcr_pos);
768            gcr_pos += 5;
769         }
770
771         gcr_double_2_gcr(d64_track_data[d64_pos + 255], sector_checksum, 0x00, 0x00, gcr_track_data + gcr_pos);
772         gcr_pos += 5;
773
774         /* Inter-sector gap */
775         // "In tests that the author conducted on a real 1541 disk, gap sizes of 8 to 19 bytes were seen."
776         // Here we put 14 as an average...
777         for (i = 0; i < 14; i++)
778            gcr_track_data[gcr_pos + i] = 0x55;
779         gcr_pos += 14;
780      }
781
782      /* copy GCR track data to buffer */
783      memcpy((UINT8*)buffer, gcr_track_data, gcr_track_size);
784
785      // create a speed block with the same speed zone for the whole track
786      UINT8 speed = tag->speed_zone[track] & 0x03;
787      UINT8 speed_byte = (speed << 6) | (speed << 4) | (speed << 2) | speed;
788
789      memset(((UINT8*)buffer) + gcr_track_size, speed_byte, G64_SPEED_BLOCK_SIZE);
790
791      LOG_FORMATS("D64 side %u track %.1f length %u\n", head, get_dos_track(track), gcr_track_size);
792   }
793   else    /* half tracks */
794   {
795      /* set track length to 0 */
796      memset(buffer, 0, buflen);
797
798      LOG_FORMATS("D64 side %u track %.1f length %u\n", head, get_dos_track(track), 0);
799   }
800
801   return FLOPPY_ERROR_SUCCESS;
802}
803
804/*-------------------------------------------------
805    d64_write_track - writes a full track to the
806    disk image
807-------------------------------------------------*/
808
809static floperr_t d64_write_track(floppy_image_legacy *floppy, int head, int track, UINT64 offset, const void *buffer, size_t buflen)
810{
811   return FLOPPY_ERROR_UNSUPPORTED;
812}
813
814/*-------------------------------------------------
815    d64_identify - identifies the disk image
816-------------------------------------------------*/
817
818static void d64_identify(floppy_image_legacy *floppy, int *dos, int *heads, int *tracks, bool *has_errors)
819{
820   switch (floppy_image_size(floppy))
821   {
822   /* 2040/3040 */
823   case D67_SIZE_35_TRACKS:                *dos = DOS1;  *heads = 1; *tracks = 35; *has_errors = false; break;
824
825   /* 4040/2031/1541/1551 */
826   case D64_SIZE_35_TRACKS:                *dos = DOS2;  *heads = 1; *tracks = 35; *has_errors = false; break;
827   case D64_SIZE_35_TRACKS_WITH_ERRORS:    *dos = DOS2;  *heads = 1; *tracks = 35; *has_errors = true;  break;
828   case D64_SIZE_40_TRACKS:                *dos = DOS2;  *heads = 1; *tracks = 40; *has_errors = false; break;
829   case D64_SIZE_40_TRACKS_WITH_ERRORS:    *dos = DOS2;  *heads = 1; *tracks = 40; *has_errors = true;  break;
830   case D64_SIZE_42_TRACKS:                *dos = DOS2;  *heads = 1; *tracks = 42; *has_errors = false; break;
831   case D64_SIZE_42_TRACKS_WITH_ERRORS:    *dos = DOS2;  *heads = 1; *tracks = 42; *has_errors = true;  break;
832
833   /* 1571 */
834   case D71_SIZE_70_TRACKS:                *dos = DOS2;  *heads = 2; *tracks = 35; *has_errors = false; break;
835   case D71_SIZE_70_TRACKS_WITH_ERRORS:    *dos = DOS2;  *heads = 2; *tracks = 35; *has_errors = true;  break;
836
837   /* 8050 */
838   case D80_SIZE_77_TRACKS:                *dos = DOS25; *heads = 1; *tracks = 77; *has_errors = false; break;
839   case D80_SIZE_77_TRACKS_WITH_ERRORS:    *dos = DOS25; *heads = 1; *tracks = 77; *has_errors = true;  break;
840
841   /* 8250/SFD1001 */
842   case D82_SIZE_154_TRACKS:               *dos = DOS25; *heads = 2; *tracks = 77; *has_errors = false; break;
843   case D82_SIZE_154_TRACKS_WITH_ERRORS:   *dos = DOS25; *heads = 2; *tracks = 77; *has_errors = true;  break;
844   }
845}
846
847/*-------------------------------------------------
848    FLOPPY_IDENTIFY( d64_dsk_identify )
849-------------------------------------------------*/
850
851FLOPPY_IDENTIFY( d64_dsk_identify )
852{
853   int dos = 0, heads, tracks;
854   bool has_errors = false;
855
856   *vote = 0;
857
858   d64_identify(floppy, &dos, &heads, &tracks, &has_errors);
859
860   if (dos == DOS2 && heads == 1)
861   {
862      *vote = 100;
863   }
864
865   return FLOPPY_ERROR_SUCCESS;
866}
867
868/*-------------------------------------------------
869    FLOPPY_IDENTIFY( d67_dsk_identify )
870-------------------------------------------------*/
871
872FLOPPY_IDENTIFY( d67_dsk_identify )
873{
874   *vote = 0;
875
876   if (floppy_image_size(floppy) == D67_SIZE_35_TRACKS)
877   {
878      *vote = 100;
879   }
880
881   return FLOPPY_ERROR_SUCCESS;
882}
883
884/*-------------------------------------------------
885    FLOPPY_IDENTIFY( d71_dsk_identify )
886-------------------------------------------------*/
887
888FLOPPY_IDENTIFY( d71_dsk_identify )
889{
890   int heads = 0, tracks = 0, dos = -1;
891   bool has_errors = false;
892
893   *vote = 0;
894
895   d64_identify(floppy, &dos, &heads, &tracks, &has_errors);
896
897   if (dos == DOS2 && heads == 2)
898   {
899      *vote = 100;
900   }
901
902   return FLOPPY_ERROR_SUCCESS;
903}
904
905/*-------------------------------------------------
906    FLOPPY_IDENTIFY( d80_dsk_identify )
907-------------------------------------------------*/
908
909FLOPPY_IDENTIFY( d80_dsk_identify )
910{
911   int heads = 0, tracks = 0, dos = -1;
912   bool has_errors = false;
913   *vote = 0;
914
915   d64_identify(floppy, &dos, &heads, &tracks, &has_errors);
916
917   if (dos == DOS25 && heads == 1)
918   {
919      *vote = 100;
920   }
921
922   return FLOPPY_ERROR_SUCCESS;
923}
924
925/*-------------------------------------------------
926    FLOPPY_IDENTIFY( d82_dsk_identify )
927-------------------------------------------------*/
928
929FLOPPY_IDENTIFY( d82_dsk_identify )
930{
931   int heads = 0, tracks = 0, dos = -1;
932   bool has_errors = false;
933   *vote = 0;
934
935   d64_identify(floppy, &dos, &heads, &tracks, &has_errors);
936
937   if (dos == DOS25 && heads == 2)
938   {
939      *vote = 100;
940   }
941
942   return FLOPPY_ERROR_SUCCESS;
943}
944
945/*-------------------------------------------------
946    FLOPPY_CONSTRUCT( d64_dsk_construct )
947-------------------------------------------------*/
948
949FLOPPY_CONSTRUCT( d64_dsk_construct )
950{
951   struct FloppyCallbacks *callbacks;
952   struct d64dsk_tag *tag;
953   UINT8 id[2];
954
955   int track_offset = 0;
956   int head, track;
957
958   int heads = 0, dos_tracks = 0, dos = 0;
959   bool has_errors = 0;
960   int errors_size = 0;
961
962   if (params)
963   {
964      /* create not supported */
965      return FLOPPY_ERROR_UNSUPPORTED;
966   }
967
968   tag = (struct d64dsk_tag *) floppy_create_tag(floppy, sizeof(struct d64dsk_tag));
969
970   if (!tag) return FLOPPY_ERROR_OUTOFMEMORY;
971
972   /* identify image type */
973   d64_identify(floppy, &dos, &heads, &dos_tracks, &has_errors);
974
975   tag->dos = dos;
976   tag->heads = heads;
977   tag->tracks = MAX_TRACKS;
978   tag->dos_tracks = dos_tracks;
979   tag->has_errors = has_errors;
980
981   LOG_FORMATS("D64 size: %04x\n", (UINT32)floppy_image_size(floppy));
982   LOG_FORMATS("D64 heads: %d\n", heads);
983   LOG_FORMATS("D64 tracks: %d\n", dos_tracks);
984   LOG_FORMATS("D64 DOS version: %s\n", DOS_VERSION[dos]);
985   LOG_FORMATS("D64 error codes: %s\n", has_errors ? "yes" : "no");
986
987   /* clear track data offsets */
988   for (head = 0; head < MAX_HEADS; head++)
989   {
990      for (track = 0; track < MAX_TRACKS; track++)
991      {
992         tag->track_offset[head][track] = INVALID_OFFSET;
993      }
994   }
995
996   /* determine track data offsets */
997   for (head = 0; head < heads; head++)
998   {
999      for (track = 0; track < tag->tracks; track++)
1000      {
1001         if (dos == DOS25)
1002         {
1003            if (track >= dos_tracks)
1004            {
1005               /* track out of range */
1006               tag->track_offset[head][track] = INVALID_OFFSET;
1007            }
1008            else
1009            {
1010               tag->track_offset[head][track] = track_offset;
1011               tag->error_offset[head][track] = errors_size;
1012               tag->speed_zone[track] = DOS25_SPEED_ZONE[track];
1013
1014               track_offset += DOS25_SECTORS_PER_TRACK[track] * SECTOR_SIZE;
1015               /* also store an error entry for each sector */
1016               errors_size += DOS25_SECTORS_PER_TRACK[track];
1017
1018               LOG_FORMATS("D64 head %d track %d offset %05x", head, track + 1, tag->track_offset[head][track]);
1019               if (has_errors) LOG_FORMATS(" errors %05x", tag->error_offset[head][track]);
1020               LOG_FORMATS(" speed %u\n", tag->speed_zone[track]);
1021            }
1022         }
1023         else
1024         {
1025            if ((track % 2) || ((track / 2) >= dos_tracks))
1026            {
1027               /* half track or out of range */
1028               tag->track_offset[head][track] = INVALID_OFFSET;
1029            }
1030            else
1031            {
1032               /* full track */
1033               tag->track_offset[head][track] = track_offset;
1034               tag->error_offset[head][track] = errors_size;
1035               tag->speed_zone[track] = DOS1_SPEED_ZONE[track / 2];
1036
1037               if (dos == DOS1)
1038               {
1039                  track_offset += DOS1_SECTORS_PER_TRACK[track / 2] * SECTOR_SIZE;
1040                  /* also store an error entry for each sector */
1041                  errors_size += DOS1_SECTORS_PER_TRACK[track / 2];
1042               }
1043               else
1044               {
1045                  track_offset += DOS2_SECTORS_PER_TRACK[track / 2] * SECTOR_SIZE;
1046                  /* also store an error entry for each sector */
1047                  errors_size += DOS2_SECTORS_PER_TRACK[track / 2];
1048               }
1049
1050               LOG_FORMATS("D64 head %d track %.1f offset %05x", head, get_dos_track(track), tag->track_offset[head][track]);
1051               if (has_errors) LOG_FORMATS(" errors %05x", tag->error_offset[head][track]);
1052               LOG_FORMATS(" speed %u\n", tag->speed_zone[track]);
1053            }
1054         }
1055      }
1056   }
1057
1058   /* read format ID from directory */
1059   /*
1060   id1, id2 are the same for extended d64 (i.e. with error tables), for d67 and for d71
1061
1062   for d81 they are at track 40 bytes 0x17 & 0x18
1063   for d80 & d82 they are at track 39 bytes 0x18 & 0x19
1064   */
1065   if (dos == DOS25)
1066      floppy_image_read(floppy, id, tag->track_offset[0][38] + 0x18, 2);
1067   else
1068      floppy_image_read(floppy, id, tag->track_offset[0][34] + 0xa2, 2);
1069
1070   tag->id1 = id[0];
1071   tag->id2 = id[1];
1072
1073   LOG_FORMATS("D64 format ID: %02x%02x\n", id[0], id[1]);
1074
1075   /* read errors */
1076   if (tag->has_errors)
1077   {
1078      LOG_FORMATS("D64 error blocks: %d %d\n", errors_size, track_offset);
1079      floppy_image_read(floppy, tag->error, track_offset, errors_size);
1080   }
1081   else
1082   {
1083      memset(tag->error, ERROR_00, MAX_ERROR_SECTORS);
1084   }
1085
1086   /* set callbacks */
1087   callbacks = floppy_callbacks(floppy);
1088
1089   callbacks->read_track = d64_read_track;
1090   callbacks->write_track = d64_write_track;
1091   callbacks->get_heads_per_disk = d64_get_heads_per_disk;
1092   callbacks->get_tracks_per_disk = d64_get_tracks_per_disk;
1093   callbacks->get_track_size = d64_get_track_size;
1094
1095   return FLOPPY_ERROR_SUCCESS;
1096}
trunk/src/lib/formats/d64_dsk.h
r245595r245596
7676extern const floppy_format_type FLOPPY_D64_FORMAT;
7777
7878
79FLOPPY_IDENTIFY( d64_dsk_identify );
80FLOPPY_IDENTIFY( d67_dsk_identify );
81FLOPPY_IDENTIFY( d71_dsk_identify );
82FLOPPY_IDENTIFY( d80_dsk_identify );
83FLOPPY_IDENTIFY( d82_dsk_identify );
8479
85FLOPPY_CONSTRUCT( d64_dsk_construct );
86
8780#endif
trunk/src/lib/formats/d80_dsk.c
r245595r245596
3737
3838const d80_format::format d80_format::file_formats[] = {
3939   { // d80, dos 2.5, 77 tracks, head/stepper 100 tpi
40      floppy_image::FF_525, floppy_image::SSQD, 2083, 77, 1, 256, 9, 8
40      floppy_image::FF_525, floppy_image::SSQD, 2083, 77, 1, 256, 19, 19 // TODO verify gaps
4141   },
4242   {}
4343};
trunk/src/lib/formats/d82_dsk.c
r245595r245596
3333
3434const d82_format::format d82_format::file_formats[] = {
3535   { // d82, dos 2.5, 77 tracks, 2 heads, head/stepper 100 tpi
36      floppy_image::FF_525, floppy_image::DSQD, 2083, 77, 2, 256, 9, 8
36      floppy_image::FF_525, floppy_image::DSQD, 2083, 77, 2, 256, 19, 19 // TODO verify gaps
3737   },
3838   {}
3939};
trunk/src/mess/machine/victor9k_fdc.c
r245595r245596
3232
3333    TODO:
3434
35    - write protect
36    - separate read/write methods
3537    - communication error with SCP after loading boot sector
3638        - bp ff1a8
3739        - patch ff1ab=c3


Previous 199869 Revisions Next


© 1997-2024 The MAME Team