diff options
Diffstat (limited to 'src/devices/bus/ss50/dc5.cpp')
-rw-r--r-- | src/devices/bus/ss50/dc5.cpp | 326 |
1 files changed, 207 insertions, 119 deletions
diff --git a/src/devices/bus/ss50/dc5.cpp b/src/devices/bus/ss50/dc5.cpp index 52bf89a9976..2229e896add 100644 --- a/src/devices/bus/ss50/dc5.cpp +++ b/src/devices/bus/ss50/dc5.cpp @@ -31,7 +31,11 @@ #include "dc5.h" #include "machine/wd_fdc.h" #include "imagedev/floppy.h" +#include "formats/cp68_dsk.h" +#include "formats/fdos_dsk.h" #include "formats/flex_dsk.h" +#include "formats/os9_dsk.h" +#include "formats/uniflex_dsk.h" class ss50_dc5_device : public device_t, public ss50_card_interface { @@ -40,43 +44,46 @@ public: : device_t(mconfig, SS50_DC5, tag, owner, clock) , ss50_card_interface(mconfig, *this) , m_fdc(*this, "fdc") - , m_floppy0(*this, "fdc:0") - , m_floppy1(*this, "fdc:1") - , m_floppy2(*this, "fdc:2") - , m_floppy3(*this, "fdc:3") - , m_interrupt_select(*this, "interrupt_select") - , m_address_mode(*this, "address_mode") - , m_two_control_regs(*this, "two_control_regs") - , m_ctrl_reg_bit7_side_select(*this, "ctrl_reg_bit7_side_select") - , m_expected_clock(*this, "expected_clock") - , m_expected_density(*this, "expected_density") - , m_expected_sectors(*this, "expected_sectors") - , m_track_zero_expected_sectors(*this, "track_zero_expected_sectors") + , m_floppy(*this, "fdc:%u", 0U) + , m_interrupt_select(*this, "INTERRUPT_SELECT") + , m_address_mode(*this, "ADDRESS_MODE") + , m_two_control_regs(*this, "TWO_CONTROL_REGS") + , m_force_ready(*this, "FORCE_READY") + , m_ctrl_reg_bit7_side_select(*this, "CTRL_REG_BIT7_SIDE_SELECT") + , m_expected_clock(*this, "EXPECTED_CLOCK") + , m_expected_density(*this, "EXPECTED_DENSITY") + , m_expected_sectors(*this, "EXPECTED_SECTORS") + , m_track_zero_expected_sectors(*this, "TRACK_ZERO_EXPECTED_SECTORS") { } + DECLARE_INPUT_CHANGED_MEMBER(force_ready_change); + DECLARE_INPUT_CHANGED_MEMBER(ctrl_reg_bit7_side_select_change); + DECLARE_INPUT_CHANGED_MEMBER(expected_clock_change); + protected: - virtual ioport_constructor device_input_ports() const override; - virtual void device_add_mconfig(machine_config &config) override; - virtual void device_start() override; - virtual void device_reset() override; + virtual ioport_constructor device_input_ports() const override ATTR_COLD; + virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; + virtual void device_start() override ATTR_COLD; + virtual void device_reset() override ATTR_COLD; virtual uint8_t register_read(offs_t offset) override; virtual void register_write(offs_t offset, uint8_t data) override; private: - DECLARE_WRITE_LINE_MEMBER( fdc_intrq_w ); - DECLARE_WRITE_LINE_MEMBER( fdc_drq_w ); - DECLARE_WRITE_LINE_MEMBER( fdc_sso_w ); + void fdc_intrq_w(int state); + void fdc_drq_w(int state); + void fdc_sso_w(int state); - DECLARE_FLOPPY_FORMATS(floppy_formats); + static void floppy_formats(format_registration &fr); uint8_t m_fdc_status; // for floppy controller uint8_t m_control_register; uint8_t m_motor_timer_out; emu_timer *m_floppy_motor_timer; floppy_image_device *m_fdc_selected_floppy; // Current selected floppy. - uint8_t m_fdc_side; // Current floppy side. - uint32_t m_fdc_clock; // Current clock frequency. + uint8_t m_fdc_side; // Current floppy side. + uint8_t m_fdc_clock_div; // Current clock frequency divisor. + uint8_t m_fdc_prog_clock_div; // Programmed clock frequency divisor. TIMER_CALLBACK_MEMBER(floppy_motor_callback); @@ -88,13 +95,11 @@ private: uint8_t validate_fdc_sector_size(uint8_t cmd); required_device<wd2797_device> m_fdc; - required_device<floppy_connector> m_floppy0; - required_device<floppy_connector> m_floppy1; - required_device<floppy_connector> m_floppy2; - required_device<floppy_connector> m_floppy3; + required_device_array<floppy_connector, 4> m_floppy; required_ioport m_interrupt_select; required_ioport m_address_mode; required_ioport m_two_control_regs; + required_ioport m_force_ready; required_ioport m_ctrl_reg_bit7_side_select; required_ioport m_expected_clock; required_ioport m_expected_density; @@ -104,22 +109,33 @@ private: static INPUT_PORTS_START( dc5 ) - PORT_START("interrupt_select") - PORT_DIPNAME(0xf, 0, "Interrupt select") + PORT_START("INTERRUPT_SELECT") + PORT_DIPNAME(0x3, 0, "Interrupt select") PORT_DIPSETTING(0, "N/C") PORT_DIPSETTING(1, "IRQ") PORT_DIPSETTING(2, "NMI/FIRQ") - PORT_START("address_mode") - PORT_DIPNAME(0xf, 1, "Address mode") + PORT_START("ADDRESS_MODE") + PORT_DIPNAME(0x1, 1, "Address mode") PORT_DIPSETTING(0, "4 address") PORT_DIPSETTING(1, "16 address") - PORT_START("two_control_regs") - PORT_DIPNAME(0xf, 0, "Two control registers") + PORT_START("TWO_CONTROL_REGS") + PORT_DIPNAME(0x1, 0, "Two control registers") PORT_DIPSETTING(0, "No, DC4 compatible") PORT_DIPSETTING(1, "Yes, DC5 extension") + // The DC5 has two modes for controlling the FDC 'ready' input. One + // mode forces the 'ready' line for a period triggered by the chip + // select, along with the motors. The other mode detects index pulses + // from the disk to control the 'ready' line. Flex2 for the 6800 + // generally needs the 'ready' line forced and Flex9 can use the index + // pulse detection to determine if disks are present. + PORT_START("FORCE_READY") + PORT_CONFNAME(0x1, 0, "Force ready") PORT_CHANGED_MEMBER(DEVICE_SELF, FUNC(ss50_dc5_device::force_ready_change), 0) + PORT_CONFSETTING(0, DEF_STR(No)) + PORT_CONFSETTING(1, DEF_STR(Yes)) + // This config setting allows checking of the FDC clock rate and // overriding it to assist driver development. The DC5 supports // programming of the clock rate via the second control register, and @@ -131,53 +147,57 @@ static INPUT_PORTS_START( dc5 ) // 3.5" 'standard' - 1.2MHz // 3.5" HD - 2.0MHz // 8" 360rpm - 2.4MHz - PORT_START("expected_clock") - PORT_CONFNAME(0xffffff, 0, "FDC expected clock rate") + PORT_START("EXPECTED_CLOCK") + PORT_CONFNAME(0xf, 0, "FDC expected clock rate") PORT_CHANGED_MEMBER(DEVICE_SELF, FUNC(ss50_dc5_device::expected_clock_change), 0) PORT_CONFSETTING(0, "-") - PORT_CONFSETTING(1000000, "1.0 MHz") - PORT_CONFSETTING(1200000, "1.2 MHz") - PORT_CONFSETTING(2000000, "2.0 MHz") - PORT_CONFSETTING(2400000, "2.4 MHz") + PORT_CONFSETTING(12, "1.0 MHz") + PORT_CONFSETTING(10, "1.2 MHz") + PORT_CONFSETTING(6, "2.0 MHz") + PORT_CONFSETTING(5, "2.4 MHz") // It is not uncommon to see drivers using bit 7 of the control // register as a side selection. This conflicts with the DC5, and // earlier controllers in this series, which use bit 7 to inhibit // drive selection. These drivers need to be corrected, but this // option helps identify this issue and work around it. - PORT_START("ctrl_reg_bit7_side_select") - PORT_CONFNAME(0x01, 0, "Control register bit 7") + PORT_START("CTRL_REG_BIT7_SIDE_SELECT") + PORT_CONFNAME(0x1, 0, "Control register bit 7") PORT_CHANGED_MEMBER(DEVICE_SELF, FUNC(ss50_dc5_device::ctrl_reg_bit7_side_select_change), 0) PORT_CONFSETTING(0, "Inhibits drive selection") PORT_CONFSETTING(1, "Erroneous side select") - // Debug aid to hard code the density. The FLEX format uses single - // density for track zero. Many virtual disks 'fix' the format to be - // purely double density and often without properly implement driver - // support for that. This setting is an aid to report unexpected - // usage, and it attempts to correct that. - PORT_START("expected_density") - PORT_CONFNAME(0xff, 0, "Expected density") + // Debug aid to hard code the density. The OS9 format can use single + // density for track zero head zero. The FLEX format can use single + // density for track zero on all heads, and many virtual disks 'fix' + // the format to be purely double density and often without properly + // implementing driver support for that. This setting is an aid to + // report unexpected usage, and it attempts to correct that. + PORT_START("EXPECTED_DENSITY") + PORT_CONFNAME(0x7, 0, "Expected density") PORT_CONFSETTING(0, "-") PORT_CONFSETTING(1, "single density") // Purely single density. - PORT_CONFSETTING(2, "double density, with single density track zero") // The default FLEX double density format. - PORT_CONFSETTING(3, "double density") // Purely double density. + PORT_CONFSETTING(2, "double density, with single density track zero head zero") // OS9 format + PORT_CONFSETTING(3, "double density, with single density track zero all heads") // The default FLEX double density format. + PORT_CONFSETTING(4, "double density") // Purely double density. // Debug aid, to check that the sector head or side is set as expected // for the sector ID being read for the FLEX floppy disk format. Many // FLEX disk images were developed for vitural machines that have - // little regard for the actual head and can work off the sector ID - // and their drivers can set the head incorrectly. E.g. a disk with 18 - // sectors per side might have a drive set to switch heads for sectors - // above 10. Another issue is that double density disk images are - // often 'fixed' so that they are pure double density without being - // single density onthe first track, and the drivers might still set - // the head based track zero being single density. This aid is not - // intended to be a substitute for fixing the drivers but it does help - // work through the issues while patching the disks. - PORT_START("expected_sectors") - PORT_CONFNAME(0xff, 0, "Expected sectors per side") + // little regard for the actual number of heads and can work off the + // sector ID and their drivers can set the head incorrectly. E.g. a + // disk with 18 sectors per side might have a driver incorrectly switch + // heads for sectors above 10. Another issue is that double density + // disk images are often 'fixed' so that they are pure double density + // without being single density on the first track, and the drivers + // might still set the head based on track zero being single + // density. This aid is not intended to be a substitute for fixing the + // drivers but it does help work through the issues while patching the + // disks. + PORT_START("EXPECTED_SECTORS") + PORT_CONFNAME(0xff, 0, "FLEX expected sectors per side") PORT_CONFSETTING(0, "-") PORT_CONFSETTING(10, "10") // 5 1/4" single density 256B PORT_CONFSETTING(15, "15") // 8" single density 256B + PORT_CONFSETTING(16, "16") // 5 1/4" double density 256B PORT_CONFSETTING(18, "18") // 5 1/4" double density 256B PORT_CONFSETTING(26, "26") // 8" double density 256B PORT_CONFSETTING(36, "36") // 3.5" 1.4M QD 256B @@ -185,11 +205,12 @@ static INPUT_PORTS_START( dc5 ) // 6800 disks did format track zero in single density and if the // driver sticks to that and if using a double density disk then set a // single density size here. - PORT_START("track_zero_expected_sectors") - PORT_CONFNAME(0xff, 0, "Track zero expected sectors per side") + PORT_START("TRACK_ZERO_EXPECTED_SECTORS") + PORT_CONFNAME(0xff, 0, "FLEX track zero expected sectors per side") PORT_CONFSETTING(0, "-") PORT_CONFSETTING(10, "10") // 5 1/4" single density 256B PORT_CONFSETTING(15, "15") // 8" single density 256B + PORT_CONFSETTING(16, "16") // 5 1/4" double density 256B PORT_CONFSETTING(18, "18") // 5 1/4" double density 256B PORT_CONFSETTING(26, "26") // 8" double density 256B PORT_CONFSETTING(36, "36") // 3.5" 1.4M QD 256B @@ -211,11 +232,16 @@ ioport_constructor ss50_dc5_device::device_input_ports() const // machine configuration //------------------------------------------------- -FLOPPY_FORMATS_MEMBER( ss50_dc5_device::floppy_formats ) - FLOPPY_FLEX_FORMAT -FLOPPY_FORMATS_END +void ss50_dc5_device::floppy_formats(format_registration &fr) +{ + fr.add_mfm_containers(); + fr.add(FLOPPY_FLEX_FORMAT); + fr.add(FLOPPY_CP68_FORMAT); + fr.add(FLOPPY_FDOS_FORMAT); + fr.add(FLOPPY_OS9_FORMAT); + fr.add(FLOPPY_UNIFLEX_FORMAT); +} -// todo: implement floppy controller cards as slot devices and do this properly static void flex_floppies(device_slot_interface &device) { device.option_add("sssd35", FLOPPY_525_SSSD_35T); // 35 trks ss sd 5.25 @@ -235,11 +261,9 @@ static void flex_floppies(device_slot_interface &device) void ss50_dc5_device::device_add_mconfig(machine_config &config) { - WD2797(config, m_fdc, 1_MHz_XTAL); - FLOPPY_CONNECTOR(config, "fdc:0", flex_floppies, "sssd35", ss50_dc5_device::floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "fdc:1", flex_floppies, "sssd35", ss50_dc5_device::floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "fdc:2", flex_floppies, "sssd35", ss50_dc5_device::floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "fdc:3", flex_floppies, "sssd35", ss50_dc5_device::floppy_formats).enable_sound(true); + WD2797(config, m_fdc, 12_MHz_XTAL / 12); // divider is selectable + for (auto &floppy : m_floppy) + FLOPPY_CONNECTOR(config, floppy, flex_floppies, "sssd35", ss50_dc5_device::floppy_formats).enable_sound(true); m_fdc->intrq_wr_callback().set(FUNC(ss50_dc5_device::fdc_intrq_w)); m_fdc->drq_wr_callback().set(FUNC(ss50_dc5_device::fdc_drq_w)); @@ -249,10 +273,11 @@ void ss50_dc5_device::device_add_mconfig(machine_config &config) void ss50_dc5_device::device_reset() { // Initialize to the expected rate if any, otherwise to 1MHz. - uint32_t clock = m_expected_clock->read(); - clock = clock ? clock : 1000000; - m_fdc->set_unscaled_clock(clock); - m_fdc_clock = clock; + m_fdc_prog_clock_div = 12; + uint8_t expected_clock_div = m_expected_clock->read(); + uint8_t clock_div = expected_clock_div ? expected_clock_div : m_fdc_prog_clock_div; + m_fdc->set_unscaled_clock(12_MHz_XTAL / clock_div); + m_fdc_clock_div = clock_div; // The reset state of DDEN for the DC5 is one, so selecting single density. m_fdc->dden_w(1); @@ -263,11 +288,37 @@ void ss50_dc5_device::device_start() m_fdc_status = 0; m_control_register = 0; m_fdc_side = 0; - m_floppy_motor_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ss50_dc5_device::floppy_motor_callback),this)); + m_floppy_motor_timer = timer_alloc(FUNC(ss50_dc5_device::floppy_motor_callback), this); m_motor_timer_out = 0; + m_fdc->set_force_ready(0); + m_fdc_prog_clock_div = 12; + + save_item(NAME(m_fdc_status)); + save_item(NAME(m_control_register)); + save_item(NAME(m_motor_timer_out)); + save_item(NAME(m_fdc_side)); + save_item(NAME(m_fdc_clock_div)); + save_item(NAME(m_fdc_prog_clock_div)); } +INPUT_CHANGED_MEMBER(ss50_dc5_device::force_ready_change) +{ + control_register_update(); +} + +INPUT_CHANGED_MEMBER(ss50_dc5_device::ctrl_reg_bit7_side_select_change) +{ + control_register_update(); +} + +INPUT_CHANGED_MEMBER(ss50_dc5_device::expected_clock_change) +{ + uint8_t clock_div = newval ? newval : m_fdc_prog_clock_div; + m_fdc->set_unscaled_clock(12_MHz_XTAL / clock_div); + m_fdc_clock_div = clock_div; +} + /* Shared floppy support. */ void ss50_dc5_device::floppy_motor_trigger() @@ -309,7 +360,7 @@ void ss50_dc5_device::validate_floppy_side(uint8_t cmd) if (m_fdc_side != expected_side) { - logerror("%s Unexpected size %d for track %d sector %d expected side %d\n", machine().describe_context(), m_fdc_side, track, sector, expected_side); + logerror("%s Unexpected side %d for track %d sector %d expected side %d\n", machine().describe_context(), m_fdc_side, track, sector, expected_side); if (m_fdc_selected_floppy) { m_fdc_selected_floppy->ss_w(expected_side); @@ -317,8 +368,7 @@ void ss50_dc5_device::validate_floppy_side(uint8_t cmd) } } } - - if (expected_sectors) + else if (expected_sectors) { uint8_t expected_side = sector > expected_sectors ? 1 : 0; @@ -348,17 +398,17 @@ uint8_t ss50_dc5_device::validate_fdc_dden(uint8_t dden) return 1; case 2: { - // Double density with track zero single density. + // Double density with track zero head zero single density. uint8_t track = m_fdc->track_r(); - if (track == 0) + if (track == 0 && m_fdc_side == 0) { - // If this path is call on an update of the + // If this path is called on an update of the // second control register then the track need // not be accurate so this message might not // be accurate. if (!dden) - logerror("%s Unexpected DDEN %d for single density trak 0\n", machine().describe_context(), dden); + logerror("%s Unexpected DDEN %d for single density track 0 head 0\n", machine().describe_context(), dden); return 1; } if (dden) @@ -366,6 +416,25 @@ uint8_t ss50_dc5_device::validate_fdc_dden(uint8_t dden) return 0; } case 3: + { + // Double density with track zero all heads single density. + uint8_t track = m_fdc->track_r(); + + if (track == 0) + { + // If this path is called on an update of the + // second control register then the track need + // not be accurate so this message might not + // be accurate. + if (!dden) + logerror("%s Unexpected DDEN %d for single density track 0\n", machine().describe_context(), dden); + return 1; + } + if (dden) + logerror("%s Unexpected DDEN %d for double density\n", machine().describe_context(), dden); + return 0; + } + case 4: // Pure double density. if (dden) logerror("%s Unexpected DDEN %d for double density\n", machine().describe_context(), dden); @@ -384,7 +453,7 @@ uint8_t ss50_dc5_device::validate_fdc_sso(uint8_t cmd) uint32_t two_regs = m_two_control_regs->read(); if (two_regs) { - // How if drivers are attempting to use SSO to control the + // If drivers are attempting to use SSO to control the // density then that might need correcting so report such // usage. logerror("%s Unexpected SSO flag set in two control registers mode\n", machine().describe_context()); @@ -426,7 +495,7 @@ uint8_t ss50_dc5_device::validate_fdc_sector_size(uint8_t cmd) return cmd; } -WRITE_LINE_MEMBER( ss50_dc5_device::fdc_intrq_w ) +void ss50_dc5_device::fdc_intrq_w(int state) { if (state) m_fdc_status |= 0x40; @@ -436,16 +505,12 @@ WRITE_LINE_MEMBER( ss50_dc5_device::fdc_intrq_w ) uint8_t selection = m_interrupt_select->read(); if (selection == 1) - { write_irq(state); - } else if (selection == 2) - { write_firq(state); - } } -WRITE_LINE_MEMBER( ss50_dc5_device::fdc_drq_w ) +void ss50_dc5_device::fdc_drq_w(int state) { if (state) m_fdc_status |= 0x80; @@ -453,7 +518,7 @@ WRITE_LINE_MEMBER( ss50_dc5_device::fdc_drq_w ) m_fdc_status &= 0x7f; } -WRITE_LINE_MEMBER( ss50_dc5_device::fdc_sso_w ) +void ss50_dc5_device::fdc_sso_w(int state) { // The DC4 and DC5 invert the SSO output and wire it to the DDEN input // to allow selection of single or double density. @@ -477,13 +542,13 @@ WRITE_LINE_MEMBER( ss50_dc5_device::fdc_sso_w ) break; case 2: { - // Double density with track zero single density. + // Double density with track zero head zero single density. uint8_t track = m_fdc->track_r(); - if (track == 0) + if (track == 0 && m_fdc_side == 0) { if (state) - logerror("Unexpected SSO %d for single density trak 0\n", state); + logerror("Unexpected SSO %d for single density track 0 head 0\n", state); m_fdc->dden_w(1); } else @@ -495,6 +560,25 @@ WRITE_LINE_MEMBER( ss50_dc5_device::fdc_sso_w ) break; } case 3: + { + // Double density with track zero all heads single density. + uint8_t track = m_fdc->track_r(); + + if (track == 0) + { + if (state) + logerror("Unexpected SSO %d for single density track 0\n", state); + m_fdc->dden_w(1); + } + else + { + if (!state) + logerror("Unexpected SSO %d for double density\n", state); + m_fdc->dden_w(0); + } + break; + } + case 4: // Pure double density. if (!state) logerror("Unexpected SSO %d for double density\n", state); @@ -513,10 +597,12 @@ void ss50_dc5_device::control_register_update() // The floppy drives do not gate the motor based on the select input, // so the motors run, or not, irrespective of the drive selection. uint8_t motor = m_motor_timer_out ? CLEAR_LINE : ASSERT_LINE; - m_floppy0->get_device()->mon_w(motor); - m_floppy1->get_device()->mon_w(motor); - m_floppy2->get_device()->mon_w(motor); - m_floppy3->get_device()->mon_w(motor); + for (auto &floppy : m_floppy) + { + floppy_image_device *fd = floppy->get_device(); + if (fd) + fd->mon_w(motor); + } // The DC2, DC3, DC4, DC5 have a drive inhibit feature controlled by // bit 7, and the drives are de-selected if the motor timer has timed @@ -530,13 +616,7 @@ void ss50_dc5_device::control_register_update() floppy_image_device *floppy = nullptr; if ((bit7_side_select || !inhibit) && m_motor_timer_out) - { - uint8_t drive = m_control_register & 3; - if (drive == 0) floppy = m_floppy0->get_device(); - if (drive == 1) floppy = m_floppy1->get_device(); - if (drive == 2) floppy = m_floppy2->get_device(); - if (drive == 3) floppy = m_floppy3->get_device(); - } + floppy = m_floppy[m_control_register & 3]->get_device(); if (floppy != m_fdc_selected_floppy) { @@ -560,13 +640,17 @@ void ss50_dc5_device::control_register_update() // the most useful choice because drivers in error are // most likely just writing to the wrong bit rather // than inconsistently to both bits. This allows - // incremental correction of driver while spotting + // incremental correction of drivers while spotting // remaining uses of bit 7 for side selection. side |= bit7; } floppy->ss_w(side); m_fdc_side = side; } + + // Force the FDC 'ready' line on if the motor line is asserted, but + // only when this forced mode is enabled. + m_fdc->set_force_ready(m_motor_timer_out && m_force_ready->read()); } @@ -594,7 +678,7 @@ uint8_t ss50_dc5_device::register_read(offs_t offset) uint32_t two_regs = m_two_control_regs->read(); // Note: access to this control register does not trigger the - // motor on and and does not reset the motor timer. + // motor on and does not reset the motor timer. if (!two_regs || (offset & 2) == 0) { @@ -661,7 +745,7 @@ void ss50_dc5_device::register_write(offs_t offset, uint8_t data) // Osc20 and osc12 control a clock divider. uint8_t osc12 = BIT(data, 2); uint8_t osc20 = BIT(data, 3); - uint32_t clock = 1000000; + uint8_t clock_div = 12; // Note: supporting 2.4MHz is here is an extension to // the published DC5 design, and appears necessary to @@ -676,24 +760,28 @@ void ss50_dc5_device::register_write(offs_t offset, uint8_t data) // 8" drives run at 300rpm; is there an error in the // rates elsewhere? if (osc20 && osc12) - clock = 2400000; + clock_div = 5; else if (osc20) - clock = 2000000; + clock_div = 6; else if (osc12) - clock = 1200000; + clock_div = 10; + + // Note the programmed clock divisor, in case the + // expected changes. + m_fdc_prog_clock_div = clock_div; - // Compare to the expected clock rate if any. - uint32_t expected_clock = m_expected_clock->read(); - if (expected_clock && clock != expected_clock) + // Compare to the expected clock divisor if any. + uint32_t expected_clock_div = m_expected_clock->read(); + if (expected_clock_div && clock_div != expected_clock_div) { - logerror("%s Unexpected clock rate of %dHz expected %dHz.\n", machine().describe_context(), clock, expected_clock); - clock = expected_clock; + logerror("%s Unexpected clock rate of %dHz expected %dHz.\n", machine().describe_context(), 12'000'000 / clock_div, 12'000'000 / expected_clock_div); + clock_div = expected_clock_div; } - if (clock != m_fdc_clock) + if (clock_div != m_fdc_clock_div) { - m_fdc->set_unscaled_clock(clock); - m_fdc_clock = clock; + m_fdc->set_unscaled_clock(12_MHz_XTAL / clock_div); + m_fdc_clock_div = clock_div; } #if 0 |