swtpc dc5: support a forced FDC 'ready' line.

Adds support for the DC5 configuration option of forcing the 'ready' line
input. This is need for Flex2 on the 6800.

With this option added the swtpc ROM patch to wait for drive to be ready is
not needed.
This commit is contained in:
68bit 2020-01-18 16:57:16 +11:00
parent 0efcf5ec2e
commit caaede75a9
3 changed files with 33 additions and 27 deletions

View File

@ -47,6 +47,7 @@ public:
, 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")
@ -55,6 +56,7 @@ public:
{
}
DECLARE_INPUT_CHANGED_MEMBER(force_ready_change);
DECLARE_INPUT_CHANGED_MEMBER(ctrl_reg_bit7_side_select_change);
DECLARE_INPUT_CHANGED_MEMBER(expected_clock_change);
@ -99,6 +101,7 @@ private:
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;
@ -109,21 +112,32 @@ private:
static INPUT_PORTS_START( dc5 )
PORT_START("INTERRUPT_SELECT")
PORT_DIPNAME(0xf, 0, "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_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_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, 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
@ -149,7 +163,7 @@ static INPUT_PORTS_START( dc5 )
// 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_CHANGED_MEMBER(DEVICE_SELF, ss50_dc5_device, ctrl_reg_bit7_side_select_change, 0)
PORT_CONFNAME(0x1, 0, "Control register bit 7") PORT_CHANGED_MEMBER(DEVICE_SELF, ss50_dc5_device, ctrl_reg_bit7_side_select_change, 0)
PORT_CONFSETTING(0, "Inhibits drive selection")
PORT_CONFSETTING(1, "Erroneous side select")
@ -159,7 +173,7 @@ static INPUT_PORTS_START( dc5 )
// 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")
PORT_CONFNAME(0x3, 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.
@ -270,6 +284,7 @@ void ss50_dc5_device::device_start()
m_fdc_side = 0;
m_floppy_motor_timer = machine().scheduler().timer_alloc(timer_expired_delegate(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));
@ -281,6 +296,11 @@ void ss50_dc5_device::device_start()
}
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();
@ -588,6 +608,10 @@ void ss50_dc5_device::control_register_update()
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());
}

View File

@ -110,7 +110,6 @@ public:
, m_ram(*this, "ram")
, m_brg(*this, "brg")
, m_maincpu_clock(*this, "MAINCPU_CLOCK")
, m_swtbug_ready_wait(*this, "SWTBUG_READY_WAIT")
, m_swtbug_load_at_a100(*this, "SWTBUG_LOAD_AT_A100")
{ }
@ -129,7 +128,6 @@ private:
required_device<ram_device> m_ram;
required_device<mc14411_device> m_brg;
required_ioport m_maincpu_clock;
required_ioport m_swtbug_ready_wait;
required_ioport m_swtbug_load_at_a100;
};
@ -168,17 +166,6 @@ static INPUT_PORTS_START( swtpc )
PORT_CONFSETTING(2000000, "2.0 MHz")
PORT_CONFSETTING(4000000, "4.0 MHz")
// Patch the SWTBUG to wait for the motor to start. The SWTBUG
// accesses the FDC control register and then waits a period for the
// motor to start. Unfortunately the DC series of FDCs do not trigger
// the motor when accessing the control register, the drive does not
// have time to become ready before commands are issued and the boot
// fails. This workaround is necessary in practice.
PORT_START("SWTBUG_READY_WAIT")
PORT_CONFNAME(0x1, 1, "SWTBUG ready wait patch")
PORT_CONFSETTING(0, "No")
PORT_CONFSETTING(1, "Yes - apply patch")
// Patch SWTBUG to load the disk boot code at 0xa100 rather than
// 0x2400. The disk boot code is typically position dependent and many
// disk images expect to have their boot code loaded at 0xa100. TODO
@ -194,7 +181,8 @@ static INPUT_PORTS_START( swtpc )
INPUT_PORTS_END
static DEVICE_INPUT_DEFAULTS_START( dc5 )
DEVICE_INPUT_DEFAULTS("address_mode", 0xf, 0)
DEVICE_INPUT_DEFAULTS("ADDRESS_MODE", 0x1, 0)
DEVICE_INPUT_DEFAULTS("FORCE_READY", 0x1, 1)
DEVICE_INPUT_DEFAULTS_END
INPUT_CHANGED_MEMBER(swtpc_state::maincpu_clock_change)
@ -210,13 +198,6 @@ void swtpc_state::machine_reset()
// TODO make these SWTBUG patches conditional on using SWTBUG!
if (m_swtbug_ready_wait->read())
{
// Patch SWTBUG to also wait until the drive is ready.
uint8_t* swtbug = memregion("mcm6830")->base();
swtbug[0x029b] = 0x81;
}
if (m_swtbug_load_at_a100->read())
{
// Patch SWTBUG to load the disk boot sector at 0xa100.

View File

@ -298,7 +298,8 @@ INPUT_PORTS_END
static DEVICE_INPUT_DEFAULTS_START( dc5 )
DEVICE_INPUT_DEFAULTS("address_mode", 0xf, 1)
DEVICE_INPUT_DEFAULTS("ADDRESS_MODE", 0x1, 1)
DEVICE_INPUT_DEFAULTS("FORCE_READY", 0x1, 0)
DEVICE_INPUT_DEFAULTS_END