mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
wd_fdc: Add a MON callback so that drives, which are unselected early, do not spin forever.
This commit is contained in:
parent
207da844b8
commit
f62ad5e394
@ -4,21 +4,19 @@
|
||||
Myarc Floppy Disk Controller (DDCC-1)
|
||||
Double Density, Double-sided
|
||||
May be used with a 1770 or 1772 controller
|
||||
|
||||
|
||||
EPROM 2764A (8Kx8) in two banks (2x 4000-4fff)
|
||||
SRAM HM6116 (2Kx8) (5000-57ff)
|
||||
|
||||
|
||||
DIP switches (SW1) set the head step rate. For the 1770 controller, closed
|
||||
switches mean 20ms, open switches mean 6ms. For the 1772 controller, closed
|
||||
means 2ms, open means 6 ms. There is an alternative ROM for the 1772 which
|
||||
allows for slower step rates (6ms-12ms).
|
||||
|
||||
|
||||
Another switch is included (SW2) labeled "Turbo" on schematics, but which
|
||||
is not present on all boards. It may require a different ROM.
|
||||
|
||||
Known issue: On error, the drive may continue spinning.
|
||||
|
||||
Michael Zapf
|
||||
|
||||
Michael Zapf
|
||||
March 2020
|
||||
|
||||
*******************************************************************************/
|
||||
@ -63,13 +61,13 @@ myarc_fdc_device::myarc_fdc_device(const machine_config &mconfig, const char *ta
|
||||
m_wd1770(*this, WD1770_TAG),
|
||||
m_wd1772(*this, WD1772_TAG),
|
||||
m_drivelatch(*this, LATCH_TAG),
|
||||
m_buffer_ram(*this, BUFFER_TAG),
|
||||
m_pal(*this, PAL_TAG),
|
||||
m_dsrrom(nullptr),
|
||||
m_banksel(false),
|
||||
m_cardsel(false),
|
||||
m_selected_drive(0),
|
||||
m_address(0)
|
||||
m_buffer_ram(*this, BUFFER_TAG),
|
||||
m_pal(*this, PAL_TAG),
|
||||
m_dsrrom(nullptr),
|
||||
m_banksel(false),
|
||||
m_cardsel(false),
|
||||
m_selected_drive(0),
|
||||
m_address(0)
|
||||
{ }
|
||||
|
||||
SETADDRESS_DBIN_MEMBER( myarc_fdc_device::setaddress_dbin )
|
||||
@ -84,7 +82,7 @@ bool myarc_fdc_device::card_selected()
|
||||
return m_cardsel;
|
||||
}
|
||||
/*
|
||||
Provides the current address to the PAL.
|
||||
Provides the current address to the PAL.
|
||||
*/
|
||||
uint16_t myarc_fdc_device::get_address()
|
||||
{
|
||||
@ -92,7 +90,7 @@ uint16_t myarc_fdc_device::get_address()
|
||||
}
|
||||
|
||||
/*
|
||||
Debugger access.
|
||||
Debugger access.
|
||||
*/
|
||||
void myarc_fdc_device::debug_read(offs_t offset, uint8_t* value)
|
||||
{
|
||||
@ -102,7 +100,7 @@ void myarc_fdc_device::debug_read(offs_t offset, uint8_t* value)
|
||||
{
|
||||
*value = m_buffer_ram->pointer()[m_address & 0x07ff];
|
||||
}
|
||||
|
||||
|
||||
if (m_pal->romen())
|
||||
{
|
||||
// EPROM selected
|
||||
@ -113,7 +111,7 @@ void myarc_fdc_device::debug_read(offs_t offset, uint8_t* value)
|
||||
}
|
||||
|
||||
/*
|
||||
Debugger access.
|
||||
Debugger access.
|
||||
*/
|
||||
void myarc_fdc_device::debug_write(offs_t offset, uint8_t data)
|
||||
{
|
||||
@ -127,7 +125,7 @@ void myarc_fdc_device::debug_write(offs_t offset, uint8_t data)
|
||||
}
|
||||
|
||||
/*
|
||||
Read access to the RAM, EPROM, and controller chip.
|
||||
Read access to the RAM, EPROM, and controller chip.
|
||||
*/
|
||||
READ8Z_MEMBER(myarc_fdc_device::readz)
|
||||
{
|
||||
@ -136,38 +134,38 @@ READ8Z_MEMBER(myarc_fdc_device::readz)
|
||||
debug_read(offset, value);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (m_pal->ramsel())
|
||||
{
|
||||
// SRAM selected
|
||||
*value = m_buffer_ram->pointer()[m_address & 0x07ff];
|
||||
LOGMASKED(LOG_RAM, "Read RAM: %04x -> %02x\n", m_address & 0xffff, *value);
|
||||
}
|
||||
|
||||
|
||||
if (m_pal->romen())
|
||||
{
|
||||
// EPROM selected
|
||||
uint16_t base = m_banksel? 0x1000 : 0;
|
||||
uint8_t* rom = &m_dsrrom[base | (m_address & 0x0fff)];
|
||||
*value = *rom;
|
||||
|
||||
|
||||
if (WORD_ALIGNED(m_address))
|
||||
{
|
||||
uint16_t val = (*rom << 8) | (*(rom+1));
|
||||
uint16_t val = (*rom << 8) | (*(rom+1));
|
||||
LOGMASKED(LOG_EPROM, "Read DSR: %04x (page %d)-> %04x\n", m_address & 0xffff, base>>12, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (m_pal->fdcsel())
|
||||
{
|
||||
// WDC selected
|
||||
*value = m_wdc->read((m_address >> 1)&0x03);
|
||||
LOGMASKED(LOG_CONTR, "Read FDC: %04x -> %02x\n", m_address & 0xffff, *value);
|
||||
LOGMASKED(LOG_CONTR, "Read FDC: %04x -> %02x\n", m_address & 0xffff, *value);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Write access to RAM and the controller chip.
|
||||
Write access to RAM and the controller chip.
|
||||
*/
|
||||
void myarc_fdc_device::write(offs_t offset, uint8_t data)
|
||||
{
|
||||
@ -176,14 +174,14 @@ void myarc_fdc_device::write(offs_t offset, uint8_t data)
|
||||
debug_write(offset, data);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (m_pal->ramsel())
|
||||
{
|
||||
// SRAM selected
|
||||
LOGMASKED(LOG_RAM, "Write RAM: %04x <- %02x\n", m_address & 0xffff, data);
|
||||
m_buffer_ram->pointer()[m_address & 0x07ff] = data;
|
||||
}
|
||||
|
||||
|
||||
if (m_pal->fdcsel())
|
||||
{
|
||||
// WDC selected
|
||||
@ -193,7 +191,7 @@ void myarc_fdc_device::write(offs_t offset, uint8_t data)
|
||||
}
|
||||
|
||||
/*
|
||||
CRU read access to the LS251 multiplexer.
|
||||
CRU read access to the LS251 multiplexer.
|
||||
*/
|
||||
READ8Z_MEMBER( myarc_fdc_device::crureadz )
|
||||
{
|
||||
@ -227,7 +225,7 @@ READ8Z_MEMBER( myarc_fdc_device::crureadz )
|
||||
}
|
||||
|
||||
/*
|
||||
CRU write access to the LS259 latch.
|
||||
CRU write access to the LS259 latch.
|
||||
*/
|
||||
void myarc_fdc_device::cruwrite(offs_t offset, uint8_t data)
|
||||
{
|
||||
@ -243,7 +241,7 @@ void myarc_fdc_device::cruwrite(offs_t offset, uint8_t data)
|
||||
}
|
||||
|
||||
/*
|
||||
Callbacks from the WDC chip
|
||||
Callbacks from the WDC chip
|
||||
*/
|
||||
WRITE_LINE_MEMBER( myarc_fdc_device::fdc_irq_w )
|
||||
{
|
||||
@ -255,8 +253,19 @@ WRITE_LINE_MEMBER( myarc_fdc_device::fdc_drq_w )
|
||||
LOGMASKED(LOG_DRQ, "DRQ callback = %d\n", state);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( myarc_fdc_device::fdc_mon_w )
|
||||
{
|
||||
LOGMASKED(LOG_DRIVE, "MON callback = %d\n", state);
|
||||
// All MON lines are connected
|
||||
// Do not start the motors when no drive is selected. However, motors
|
||||
// can always be stopped.
|
||||
if (m_selected_drive != 0 || state==1)
|
||||
for (int i=0; i < 3; i++)
|
||||
if (m_floppy[i] != nullptr) m_floppy[i]->mon_w(state);
|
||||
}
|
||||
|
||||
/*
|
||||
Callbacks from the 74LS259 latch
|
||||
Callbacks from the 74LS259 latch
|
||||
*/
|
||||
WRITE_LINE_MEMBER( myarc_fdc_device::den_w )
|
||||
{
|
||||
@ -277,7 +286,7 @@ WRITE_LINE_MEMBER( myarc_fdc_device::sidsel_w )
|
||||
{
|
||||
LOGMASKED(LOG_DRIVE, "Set side = %d on DSK%d\n", state, m_selected_drive);
|
||||
m_floppy[m_selected_drive-1]->ss_w(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Selects the EPROM bank, and also controls the DDEN line
|
||||
@ -291,13 +300,13 @@ WRITE_LINE_MEMBER( myarc_fdc_device::bankdden_w )
|
||||
WRITE_LINE_MEMBER( myarc_fdc_device::drivesel_w )
|
||||
{
|
||||
int driveno = 0;
|
||||
|
||||
// We do not know what happens when two drives are selected
|
||||
|
||||
// We do not know what happens when two drives are selected
|
||||
if (m_drivelatch->q7_r() != 0) driveno = 4;
|
||||
if (m_drivelatch->q6_r() != 0) driveno = 3;
|
||||
if (m_drivelatch->q5_r() != 0) driveno = 2;
|
||||
if (m_drivelatch->q4_r() != 0) driveno = 1;
|
||||
|
||||
|
||||
if (state == CLEAR_LINE)
|
||||
{
|
||||
// Only when no bit is set, unselect all drives.
|
||||
@ -322,7 +331,6 @@ WRITE_LINE_MEMBER( myarc_fdc_device::drivesel_w )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void myarc_fdc_device::device_start()
|
||||
{
|
||||
m_dsrrom = memregion(TI99_DSRROM)->base();
|
||||
@ -397,15 +405,20 @@ ROM_END
|
||||
|
||||
void myarc_fdc_device::device_add_mconfig(machine_config& config)
|
||||
{
|
||||
// Cards appeared with one of those controllers
|
||||
// Cards appeared with one of those controllers
|
||||
WD1770(config, m_wd1770, 8_MHz_XTAL);
|
||||
WD1772(config, m_wd1772, 8_MHz_XTAL);
|
||||
|
||||
m_wd1770->intrq_wr_callback().set(FUNC(myarc_fdc_device::fdc_irq_w));
|
||||
m_wd1770->drq_wr_callback().set(FUNC(myarc_fdc_device::fdc_drq_w));
|
||||
m_wd1770->mon_wr_callback().set(FUNC(myarc_fdc_device::fdc_mon_w));
|
||||
m_wd1770->set_disable_motor_control(true);
|
||||
|
||||
m_wd1772->intrq_wr_callback().set(FUNC(myarc_fdc_device::fdc_irq_w));
|
||||
m_wd1772->drq_wr_callback().set(FUNC(myarc_fdc_device::fdc_drq_w));
|
||||
|
||||
m_wd1772->mon_wr_callback().set(FUNC(myarc_fdc_device::fdc_mon_w));
|
||||
m_wd1772->set_disable_motor_control(true);
|
||||
|
||||
LS259(config, m_drivelatch); // U10
|
||||
m_drivelatch->q_out_cb<0>().set(FUNC(myarc_fdc_device::den_w));
|
||||
m_drivelatch->q_out_cb<1>().set(FUNC(myarc_fdc_device::wdreset_w));
|
||||
@ -415,13 +428,13 @@ void myarc_fdc_device::device_add_mconfig(machine_config& config)
|
||||
m_drivelatch->q_out_cb<5>().set(FUNC(myarc_fdc_device::drivesel_w));
|
||||
m_drivelatch->q_out_cb<6>().set(FUNC(myarc_fdc_device::drivesel_w));
|
||||
m_drivelatch->q_out_cb<7>().set(FUNC(myarc_fdc_device::drivesel_w));
|
||||
|
||||
|
||||
// SRAM 6114 2Kx8
|
||||
RAM(config, BUFFER_TAG).set_default_size("2k").set_default_value(0);
|
||||
|
||||
RAM(config, BUFFER_TAG).set_default_size("2k").set_default_value(0);
|
||||
|
||||
// PAL circuit
|
||||
DDCC1_PAL(config, PAL_TAG, 0);
|
||||
|
||||
|
||||
// Floppy drives
|
||||
FLOPPY_CONNECTOR(config, "0", ccfdc_floppies, "525dd", myarc_fdc_device::floppy_formats).enable_sound(true);
|
||||
FLOPPY_CONNECTOR(config, "1", ccfdc_floppies, "525dd", myarc_fdc_device::floppy_formats).enable_sound(true);
|
||||
@ -440,8 +453,8 @@ const tiny_rom_entry *myarc_fdc_device::device_rom_region() const
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// PAL circuit on the DDCC-1 board
|
||||
// ========================================================================
|
||||
// PAL circuit on the DDCC-1 board
|
||||
// ========================================================================
|
||||
|
||||
ddcc1_pal_device::ddcc1_pal_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, DDCC1_PAL, tag, owner, clock),
|
||||
@ -462,7 +475,7 @@ bool ddcc1_pal_device::romen()
|
||||
bool ddcc1_pal_device::fdcsel()
|
||||
{
|
||||
// The memory mapping of the DDCC-1 differs from the usual scheme, using
|
||||
// addresses 5F01, 5F03, 5F05, 5F07
|
||||
// addresses 5F01, 5F03, 5F05, 5F07
|
||||
return (((m_board->get_address() & 0xff01)==0x5f01) && (m_board->card_selected()));
|
||||
}
|
||||
|
||||
|
@ -23,11 +23,11 @@
|
||||
namespace bus { namespace ti99 { namespace peb {
|
||||
|
||||
class ddcc1_pal_device;
|
||||
|
||||
|
||||
class myarc_fdc_device : public device_t, public device_ti99_peribox_card_interface
|
||||
{
|
||||
friend class ddcc1_pal_device;
|
||||
|
||||
|
||||
public:
|
||||
myarc_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
@ -48,10 +48,12 @@ private:
|
||||
ioport_constructor device_input_ports() const override;
|
||||
|
||||
DECLARE_FLOPPY_FORMATS( floppy_formats );
|
||||
|
||||
|
||||
// Callback methods
|
||||
DECLARE_WRITE_LINE_MEMBER( fdc_irq_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( fdc_drq_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( fdc_mon_w );
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER( den_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( wdreset_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( sidsel_w );
|
||||
@ -67,22 +69,22 @@ private:
|
||||
// Link to the WD controller on the board.
|
||||
wd_fdc_digital_device_base* m_wdc;
|
||||
|
||||
// Two options for the controller chip. Can be selected by the configuration switch.
|
||||
// Two options for the controller chip. Can be selected by the configuration switch.
|
||||
required_device<wd1770_device> m_wd1770;
|
||||
required_device<wd1772_device> m_wd1772;
|
||||
|
||||
|
||||
// Latch
|
||||
required_device<ls259_device> m_drivelatch;
|
||||
|
||||
|
||||
// Buffer RAM
|
||||
required_device<ram_device> m_buffer_ram;
|
||||
|
||||
|
||||
// Decoder PAL
|
||||
required_device<ddcc1_pal_device> m_pal;
|
||||
|
||||
// DSR ROM
|
||||
uint8_t* m_dsrrom;
|
||||
|
||||
|
||||
// Link to the attached floppy drives
|
||||
floppy_image_device* m_floppy[4];
|
||||
|
||||
@ -92,13 +94,13 @@ private:
|
||||
|
||||
// Upper bank selected
|
||||
bool m_banksel;
|
||||
|
||||
|
||||
// Card enabled
|
||||
bool m_cardsel;
|
||||
|
||||
|
||||
// Selected drive
|
||||
int m_selected_drive;
|
||||
|
||||
|
||||
// Recent address
|
||||
int m_address;
|
||||
};
|
||||
@ -115,7 +117,7 @@ public:
|
||||
bool fdcsel();
|
||||
bool cs251();
|
||||
bool cs259();
|
||||
|
||||
|
||||
private:
|
||||
void device_start() override { };
|
||||
void device_config_complete() override;
|
||||
|
@ -87,7 +87,8 @@ wd_fdc_device_base::wd_fdc_device_base(const machine_config &mconfig, device_typ
|
||||
enp_cb(*this),
|
||||
sso_cb(*this),
|
||||
ready_cb(*this), // actually output by the drive, not by the FDC
|
||||
enmf_cb(*this)
|
||||
enmf_cb(*this),
|
||||
mon_cb(*this)
|
||||
{
|
||||
force_ready = false;
|
||||
disable_motor_control = false;
|
||||
@ -113,6 +114,7 @@ void wd_fdc_device_base::device_start()
|
||||
sso_cb.resolve();
|
||||
ready_cb.resolve();
|
||||
enmf_cb.resolve();
|
||||
mon_cb.resolve_safe();
|
||||
|
||||
if (!has_enmf && !enmf_cb.isnull())
|
||||
logerror("Warning, this chip doesn't have an ENMF line.\n");
|
||||
@ -217,6 +219,9 @@ void wd_fdc_device_base::set_floppy(floppy_image_device *_floppy)
|
||||
|
||||
int next_ready = floppy ? floppy->ready_r() : 1;
|
||||
|
||||
if (motor_control)
|
||||
mon_cb(status & S_MON ? 0 : 1);
|
||||
|
||||
if(floppy) {
|
||||
if(motor_control && !disable_motor_control)
|
||||
floppy->mon_w(status & S_MON ? 0 : 1);
|
||||
@ -1296,6 +1301,8 @@ void wd_fdc_device_base::spinup()
|
||||
}
|
||||
|
||||
status |= S_MON|S_SPIN;
|
||||
|
||||
mon_cb(0);
|
||||
if(floppy && !disable_motor_control)
|
||||
floppy->mon_w(0);
|
||||
}
|
||||
@ -1335,6 +1342,7 @@ void wd_fdc_device_base::index_callback(floppy_image_device *floppy, int state)
|
||||
motor_timeout ++;
|
||||
if(motor_control && motor_timeout >= 5) {
|
||||
status &= ~S_MON;
|
||||
mon_cb(1);
|
||||
if(floppy && !disable_motor_control)
|
||||
floppy->mon_w(1);
|
||||
}
|
||||
|
@ -57,6 +57,8 @@ public:
|
||||
auto ready_wr_callback() { return ready_cb.bind(); }
|
||||
auto enmf_rd_callback() { return enmf_cb.bind(); }
|
||||
|
||||
auto mon_wr_callback() { return mon_cb.bind(); }
|
||||
|
||||
void soft_reset();
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(dden_w);
|
||||
@ -295,6 +297,7 @@ private:
|
||||
|
||||
devcb_write_line intrq_cb, drq_cb, hld_cb, enp_cb, sso_cb, ready_cb;
|
||||
devcb_read_line enmf_cb;
|
||||
devcb_write_line mon_cb;
|
||||
|
||||
uint8_t format_last_byte;
|
||||
int format_last_byte_count;
|
||||
|
Loading…
Reference in New Issue
Block a user