mirror of
https://github.com/holub/mame
synced 2025-10-06 17:08:28 +03:00
Defining variants 9224 and 9234 (WIP)
This commit is contained in:
parent
471907963b
commit
1784a89ee4
@ -2550,13 +2550,13 @@ end
|
|||||||
|
|
||||||
---------------------------------------------------
|
---------------------------------------------------
|
||||||
--
|
--
|
||||||
--@src/emu/machine/hdc9234.h,MACHINES["HDC9234"] = true
|
--@src/emu/machine/hdc92x4.h,MACHINES["HDC9234"] = true
|
||||||
---------------------------------------------------
|
---------------------------------------------------
|
||||||
|
|
||||||
if (MACHINES["HDC9234"]~=null) then
|
if (MACHINES["HDC9234"]~=null) then
|
||||||
files {
|
files {
|
||||||
MAME_DIR .. "src/emu/machine/hdc9234.c",
|
MAME_DIR .. "src/emu/machine/hdc92x4.c",
|
||||||
MAME_DIR .. "src/emu/machine/hdc9234.h",
|
MAME_DIR .. "src/emu/machine/hdc92x4.h",
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1019,12 +1019,12 @@ SLOT_INTERFACE_END
|
|||||||
|
|
||||||
MACHINE_CONFIG_FRAGMENT( ti99_hfdc )
|
MACHINE_CONFIG_FRAGMENT( ti99_hfdc )
|
||||||
MCFG_DEVICE_ADD(FDC_TAG, HDC9234, 0)
|
MCFG_DEVICE_ADD(FDC_TAG, HDC9234, 0)
|
||||||
MCFG_HDC9234_INTRQ_CALLBACK(WRITELINE(myarc_hfdc_device, intrq_w))
|
MCFG_HDC92X4_INTRQ_CALLBACK(WRITELINE(myarc_hfdc_device, intrq_w))
|
||||||
MCFG_HDC9234_DIP_CALLBACK(WRITELINE(myarc_hfdc_device, dip_w))
|
MCFG_HDC92X4_DIP_CALLBACK(WRITELINE(myarc_hfdc_device, dip_w))
|
||||||
MCFG_HDC9234_AUXBUS_OUT_CALLBACK(WRITE8(myarc_hfdc_device, auxbus_out))
|
MCFG_HDC92X4_AUXBUS_OUT_CALLBACK(WRITE8(myarc_hfdc_device, auxbus_out))
|
||||||
MCFG_HDC9234_DMARQ_CALLBACK(WRITELINE(myarc_hfdc_device, dmarq_w))
|
MCFG_HDC92X4_DMARQ_CALLBACK(WRITELINE(myarc_hfdc_device, dmarq_w))
|
||||||
MCFG_HDC9234_DMA_IN_CALLBACK(READ8(myarc_hfdc_device, read_buffer))
|
MCFG_HDC92X4_DMA_IN_CALLBACK(READ8(myarc_hfdc_device, read_buffer))
|
||||||
MCFG_HDC9234_DMA_OUT_CALLBACK(WRITE8(myarc_hfdc_device, write_buffer))
|
MCFG_HDC92X4_DMA_OUT_CALLBACK(WRITE8(myarc_hfdc_device, write_buffer))
|
||||||
|
|
||||||
MCFG_FLOPPY_DRIVE_ADD("f1", hfdc_floppies, "525dd", myarc_hfdc_device::floppy_formats)
|
MCFG_FLOPPY_DRIVE_ADD("f1", hfdc_floppies, "525dd", myarc_hfdc_device::floppy_formats)
|
||||||
MCFG_FLOPPY_DRIVE_ADD("f2", hfdc_floppies, "525dd", myarc_hfdc_device::floppy_formats)
|
MCFG_FLOPPY_DRIVE_ADD("f2", hfdc_floppies, "525dd", myarc_hfdc_device::floppy_formats)
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
#include "imagedev/mfmhd.h"
|
#include "imagedev/mfmhd.h"
|
||||||
|
|
||||||
#include "machine/mm58274c.h"
|
#include "machine/mm58274c.h"
|
||||||
#include "machine/hdc9234.h"
|
#include "machine/hdc92x4.h"
|
||||||
|
|
||||||
extern const device_type TI99_HFDC;
|
extern const device_type TI99_HFDC;
|
||||||
|
|
||||||
|
@ -2,26 +2,24 @@
|
|||||||
// copyright-holders:Michael Zapf
|
// copyright-holders:Michael Zapf
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
|
||||||
HDC9234 Hard and Floppy Disk Controller
|
HDC 9224 and HDC 9234 Hard and Floppy Disk Controller
|
||||||
Standard Microsystems Corporation (SMC)
|
Standard Microsystems Corporation (SMC)
|
||||||
|
|
||||||
This controller handles MFM and FM encoded floppy disks and hard disks.
|
This controller handles MFM and FM encoded floppy disks and hard disks.
|
||||||
A variant, the HDC9224, is used in some DEC systems.
|
|
||||||
|
|
||||||
The HDC9234 is used in the Myarc HFDC card for the TI99/4A.
|
|
||||||
|
|
||||||
References:
|
References:
|
||||||
[1] SMC HDC9234 preliminary data book (1988)
|
[1] SMC HDC9234 preliminary data book (1988)
|
||||||
|
[2] SMC HDC9224 data book
|
||||||
|
|
||||||
The HDC9234 controller is also referred to as the "Universal Disk Controller" (UDC)
|
The HDC 9224 / 9234 controller is also referred to as the "Universal Disk Controller" (UDC)
|
||||||
by the data book
|
by the data book
|
||||||
|
|
||||||
Michael Zapf, July 2015
|
Michael Zapf, August 2015
|
||||||
|
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
#include "hdc9234.h"
|
#include "hdc92x4.h"
|
||||||
#include "formats/imageutl.h"
|
#include "formats/imageutl.h"
|
||||||
|
|
||||||
// Per-command debugging
|
// Per-command debugging
|
||||||
@ -410,30 +408,30 @@ enum
|
|||||||
SUCCESS
|
SUCCESS
|
||||||
};
|
};
|
||||||
|
|
||||||
const hdc9234_device::cmddef hdc9234_device::s_command[] =
|
const hdc92x4_device::cmddef hdc92x4_device::s_command[] =
|
||||||
{
|
{
|
||||||
{ 0x00, 0xff, &hdc9234_device::reset_controller },
|
{ 0x00, 0xff, &hdc92x4_device::reset_controller },
|
||||||
{ 0x01, 0xff, &hdc9234_device::drive_deselect },
|
{ 0x01, 0xff, &hdc92x4_device::drive_deselect },
|
||||||
{ 0x02, 0xfe, &hdc9234_device::restore_drive },
|
{ 0x02, 0xfe, &hdc92x4_device::restore_drive },
|
||||||
{ 0x04, 0xfc, &hdc9234_device::step_drive },
|
{ 0x04, 0xfc, &hdc92x4_device::step_drive },
|
||||||
{ 0x08, 0xf8, &hdc9234_device::tape_backup },
|
{ 0x08, 0xf8, &hdc92x4_device::tape_backup },
|
||||||
{ 0x10, 0xf0, &hdc9234_device::poll_drives },
|
{ 0x10, 0xf0, &hdc92x4_device::poll_drives },
|
||||||
{ 0x20, 0xe0, &hdc9234_device::drive_select },
|
{ 0x20, 0xe0, &hdc92x4_device::drive_select },
|
||||||
{ 0x40, 0xf0, &hdc9234_device::set_register_pointer },
|
{ 0x40, 0xf0, &hdc92x4_device::set_register_pointer },
|
||||||
{ 0x50, 0xf8, &hdc9234_device::seek_read_id },
|
{ 0x50, 0xf8, &hdc92x4_device::seek_read_id },
|
||||||
{ 0x58, 0xfe, &hdc9234_device::read_sectors },
|
{ 0x58, 0xfe, &hdc92x4_device::read_sectors },
|
||||||
{ 0x5a, 0xfe, &hdc9234_device::read_track },
|
{ 0x5a, 0xfe, &hdc92x4_device::read_track },
|
||||||
{ 0x5c, 0xfc, &hdc9234_device::read_sectors },
|
{ 0x5c, 0xfc, &hdc92x4_device::read_sectors },
|
||||||
{ 0x60, 0xe0, &hdc9234_device::format_track },
|
{ 0x60, 0xe0, &hdc92x4_device::format_track },
|
||||||
{ 0x80, 0x80, &hdc9234_device::write_sectors },
|
{ 0x80, 0x80, &hdc92x4_device::write_sectors },
|
||||||
{ 0, 0, 0 }
|
{ 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Standard constructor.
|
Standard constructor for the base class and the two variants
|
||||||
*/
|
*/
|
||||||
hdc9234_device::hdc9234_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
hdc92x4_device::hdc92x4_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)
|
||||||
: device_t(mconfig, HDC9234, "SMC HDC9234 Universal Disk Controller", tag, owner, clock, "hdc9234", __FILE__),
|
: device_t(mconfig, type, name, tag, owner, clock, shortname, source),
|
||||||
m_out_intrq(*this),
|
m_out_intrq(*this),
|
||||||
m_out_dmarq(*this),
|
m_out_dmarq(*this),
|
||||||
m_out_dip(*this),
|
m_out_dip(*this),
|
||||||
@ -444,10 +442,23 @@ hdc9234_device::hdc9234_device(const machine_config &mconfig, const char *tag, d
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hdc9224_device::hdc9224_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: hdc92x4_device(mconfig, HDC9224, "SMC HDC9224 Universal Disk Controller", tag, owner, clock, "hdc9224", __FILE__)
|
||||||
|
{
|
||||||
|
m_is_hdc9234 = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdc9234_device::hdc9234_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: hdc92x4_device(mconfig, HDC9234, "SMC HDC9234 Universal Disk Controller", tag, owner, clock, "hdc9234", __FILE__)
|
||||||
|
{
|
||||||
|
m_is_hdc9234 = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Set or reset some bits.
|
Set or reset some bits.
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::set_bits(UINT8& byte, int mask, bool set)
|
void hdc92x4_device::set_bits(UINT8& byte, int mask, bool set)
|
||||||
{
|
{
|
||||||
if (set) byte |= mask;
|
if (set) byte |= mask;
|
||||||
else byte &= ~mask;
|
else byte &= ~mask;
|
||||||
@ -456,7 +467,7 @@ void hdc9234_device::set_bits(UINT8& byte, int mask, bool set)
|
|||||||
/*
|
/*
|
||||||
Tell whether the controller is in FM mode.
|
Tell whether the controller is in FM mode.
|
||||||
*/
|
*/
|
||||||
bool hdc9234_device::fm_mode()
|
bool hdc92x4_device::fm_mode()
|
||||||
{
|
{
|
||||||
return ((m_register_w[MODE]&MO_DENSITY)!=0);
|
return ((m_register_w[MODE]&MO_DENSITY)!=0);
|
||||||
}
|
}
|
||||||
@ -464,7 +475,7 @@ bool hdc9234_device::fm_mode()
|
|||||||
/*
|
/*
|
||||||
Are we back on track 0?
|
Are we back on track 0?
|
||||||
*/
|
*/
|
||||||
bool hdc9234_device::on_track00()
|
bool hdc92x4_device::on_track00()
|
||||||
{
|
{
|
||||||
return (m_register_r[DRIVE_STATUS] & HDC_DS_TRK00)!=0;
|
return (m_register_r[DRIVE_STATUS] & HDC_DS_TRK00)!=0;
|
||||||
}
|
}
|
||||||
@ -472,7 +483,7 @@ bool hdc9234_device::on_track00()
|
|||||||
/*
|
/*
|
||||||
Seek completed?
|
Seek completed?
|
||||||
*/
|
*/
|
||||||
bool hdc9234_device::seek_complete()
|
bool hdc92x4_device::seek_complete()
|
||||||
{
|
{
|
||||||
return (m_register_r[DRIVE_STATUS] & HDC_DS_SKCOM)!=0;
|
return (m_register_r[DRIVE_STATUS] & HDC_DS_SKCOM)!=0;
|
||||||
}
|
}
|
||||||
@ -480,7 +491,7 @@ bool hdc9234_device::seek_complete()
|
|||||||
/*
|
/*
|
||||||
Index hole?
|
Index hole?
|
||||||
*/
|
*/
|
||||||
bool hdc9234_device::index_hole()
|
bool hdc92x4_device::index_hole()
|
||||||
{
|
{
|
||||||
return (m_register_r[DRIVE_STATUS] & HDC_DS_INDEX)!=0;
|
return (m_register_r[DRIVE_STATUS] & HDC_DS_INDEX)!=0;
|
||||||
}
|
}
|
||||||
@ -488,7 +499,7 @@ bool hdc9234_device::index_hole()
|
|||||||
/*
|
/*
|
||||||
Drive ready?
|
Drive ready?
|
||||||
*/
|
*/
|
||||||
bool hdc9234_device::drive_ready()
|
bool hdc92x4_device::drive_ready()
|
||||||
{
|
{
|
||||||
return (m_register_r[DRIVE_STATUS] & HDC_DS_READY)!=0;
|
return (m_register_r[DRIVE_STATUS] & HDC_DS_READY)!=0;
|
||||||
}
|
}
|
||||||
@ -496,7 +507,7 @@ bool hdc9234_device::drive_ready()
|
|||||||
/*
|
/*
|
||||||
Doing a track read?
|
Doing a track read?
|
||||||
*/
|
*/
|
||||||
bool hdc9234_device::reading_track()
|
bool hdc92x4_device::reading_track()
|
||||||
{
|
{
|
||||||
return (current_command() & 0xfe) == 0x5a;
|
return (current_command() & 0xfe) == 0x5a;
|
||||||
}
|
}
|
||||||
@ -511,42 +522,42 @@ bool hdc9234_device::reading_track()
|
|||||||
This is true for the desired cyl/head, current cyl/head, and the header
|
This is true for the desired cyl/head, current cyl/head, and the header
|
||||||
fields on the track.
|
fields on the track.
|
||||||
*/
|
*/
|
||||||
int hdc9234_device::desired_head()
|
int hdc92x4_device::desired_head()
|
||||||
{
|
{
|
||||||
return m_register_w[DESIRED_HEAD] & 0x0f;
|
return m_register_w[DESIRED_HEAD] & 0x0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hdc9234_device::desired_cylinder()
|
int hdc92x4_device::desired_cylinder()
|
||||||
{
|
{
|
||||||
return (m_register_w[DESIRED_CYLINDER] & 0xff) | ((m_register_w[DESIRED_HEAD] & 0x70) << 4);
|
return (m_register_w[DESIRED_CYLINDER] & 0xff) | ((m_register_w[DESIRED_HEAD] & 0x70) << 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
int hdc9234_device::desired_sector()
|
int hdc92x4_device::desired_sector()
|
||||||
{
|
{
|
||||||
return m_register_w[DESIRED_SECTOR] & 0xff;
|
return m_register_w[DESIRED_SECTOR] & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hdc9234_device::current_head()
|
int hdc92x4_device::current_head()
|
||||||
{
|
{
|
||||||
return m_register_r[CURRENT_HEAD] & 0x0f;
|
return m_register_r[CURRENT_HEAD] & 0x0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hdc9234_device::current_cylinder()
|
int hdc92x4_device::current_cylinder()
|
||||||
{
|
{
|
||||||
return (m_register_r[CURRENT_CYLINDER] & 0xff) | ((m_register_r[CURRENT_HEAD] & 0x70) << 4);
|
return (m_register_r[CURRENT_CYLINDER] & 0xff) | ((m_register_r[CURRENT_HEAD] & 0x70) << 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
int hdc9234_device::current_sector()
|
int hdc92x4_device::current_sector()
|
||||||
{
|
{
|
||||||
return m_register_r[CURRENT_SECTOR] & 0xff;
|
return m_register_r[CURRENT_SECTOR] & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT8 hdc9234_device::current_command()
|
UINT8 hdc92x4_device::current_command()
|
||||||
{
|
{
|
||||||
return m_register_w[COMMAND];
|
return m_register_w[COMMAND];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hdc9234_device::using_floppy()
|
bool hdc92x4_device::using_floppy()
|
||||||
{
|
{
|
||||||
return (m_selected_drive_type == TYPE_FLOPPY5 || m_selected_drive_type == TYPE_FLOPPY8);
|
return (m_selected_drive_type == TYPE_FLOPPY5 || m_selected_drive_type == TYPE_FLOPPY8);
|
||||||
}
|
}
|
||||||
@ -554,7 +565,7 @@ bool hdc9234_device::using_floppy()
|
|||||||
/*
|
/*
|
||||||
Delivers the step time (in microseconds) minus the pulse width
|
Delivers the step time (in microseconds) minus the pulse width
|
||||||
*/
|
*/
|
||||||
int hdc9234_device::step_time()
|
int hdc92x4_device::step_time()
|
||||||
{
|
{
|
||||||
int time = 0;
|
int time = 0;
|
||||||
int index = m_register_w[MODE] & MO_STEPRATE;
|
int index = m_register_w[MODE] & MO_STEPRATE;
|
||||||
@ -574,7 +585,7 @@ int hdc9234_device::step_time()
|
|||||||
/*
|
/*
|
||||||
Delivers the pulse width time (in microseconds)
|
Delivers the pulse width time (in microseconds)
|
||||||
*/
|
*/
|
||||||
int hdc9234_device::pulse_width()
|
int hdc92x4_device::pulse_width()
|
||||||
{
|
{
|
||||||
int time = 0;
|
int time = 0;
|
||||||
// Get seek time.
|
// Get seek time.
|
||||||
@ -593,7 +604,7 @@ int hdc9234_device::pulse_width()
|
|||||||
/*
|
/*
|
||||||
Delivers the sector size
|
Delivers the sector size
|
||||||
*/
|
*/
|
||||||
int hdc9234_device::calc_sector_size()
|
int hdc92x4_device::calc_sector_size()
|
||||||
{
|
{
|
||||||
return 128 << (m_register_r[CURRENT_SIZE] & 3);
|
return 128 << (m_register_r[CURRENT_SIZE] & 3);
|
||||||
}
|
}
|
||||||
@ -603,12 +614,12 @@ int hdc9234_device::calc_sector_size()
|
|||||||
// We can wait for a given time period or for a line to be set or cleared
|
// We can wait for a given time period or for a line to be set or cleared
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
|
|
||||||
void hdc9234_device::wait_time(emu_timer *tm, int microsec, int next_substate)
|
void hdc92x4_device::wait_time(emu_timer *tm, int microsec, int next_substate)
|
||||||
{
|
{
|
||||||
wait_time(tm, attotime::from_usec(microsec), next_substate);
|
wait_time(tm, attotime::from_usec(microsec), next_substate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hdc9234_device::wait_time(emu_timer *tm, const attotime &delay, int param)
|
void hdc92x4_device::wait_time(emu_timer *tm, const attotime &delay, int param)
|
||||||
{
|
{
|
||||||
if (TRACE_DELAY) logerror("%s: [%s] Delaying by %4.2f microsecs\n", tag(), ttsn().c_str(), delay.as_double()*1000000);
|
if (TRACE_DELAY) logerror("%s: [%s] Delaying by %4.2f microsecs\n", tag(), ttsn().c_str(), delay.as_double()*1000000);
|
||||||
tm->adjust(delay);
|
tm->adjust(delay);
|
||||||
@ -620,7 +631,7 @@ void hdc9234_device::wait_time(emu_timer *tm, const attotime &delay, int param)
|
|||||||
/*
|
/*
|
||||||
Set the hook for line level handling
|
Set the hook for line level handling
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::wait_line(int line, line_state level, int substate, bool stopwrite)
|
void hdc92x4_device::wait_line(int line, line_state level, int substate, bool stopwrite)
|
||||||
{
|
{
|
||||||
bool line_at_level = true;
|
bool line_at_level = true;
|
||||||
m_timed_wait = false;
|
m_timed_wait = false;
|
||||||
@ -676,7 +687,7 @@ void hdc9234_device::wait_line(int line, line_state level, int substate, bool st
|
|||||||
(must have saved that value before!)
|
(must have saved that value before!)
|
||||||
- steps to that location during OUTPUT2 times
|
- steps to that location during OUTPUT2 times
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::read_id(int& cont, bool implied_seek, bool wait_seek_complete)
|
void hdc92x4_device::read_id(int& cont, bool implied_seek, bool wait_seek_complete)
|
||||||
{
|
{
|
||||||
cont = CONTINUE;
|
cont = CONTINUE;
|
||||||
|
|
||||||
@ -796,7 +807,7 @@ void hdc9234_device::read_id(int& cont, bool implied_seek, bool wait_seek_comple
|
|||||||
contents of the DESIRED_HEAD/CYLINDER/SECTOR registers
|
contents of the DESIRED_HEAD/CYLINDER/SECTOR registers
|
||||||
- checks the CRC
|
- checks the CRC
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::verify(int& cont)
|
void hdc92x4_device::verify(int& cont)
|
||||||
{
|
{
|
||||||
cont = CONTINUE;
|
cont = CONTINUE;
|
||||||
|
|
||||||
@ -910,7 +921,7 @@ void hdc9234_device::verify(int& cont)
|
|||||||
- transfers the contents of the current sector into memory via DMA (read) or
|
- transfers the contents of the current sector into memory via DMA (read) or
|
||||||
via DMA to the sector (write)
|
via DMA to the sector (write)
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::data_transfer(int& cont)
|
void hdc92x4_device::data_transfer(int& cont)
|
||||||
{
|
{
|
||||||
cont = CONTINUE;
|
cont = CONTINUE;
|
||||||
|
|
||||||
@ -1091,7 +1102,7 @@ void hdc9234_device::data_transfer(int& cont)
|
|||||||
+-----+-----+-----+-----+-----+-----+-----+-----+
|
+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
|
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::reset_controller()
|
void hdc92x4_device::reset_controller()
|
||||||
{
|
{
|
||||||
logerror("%s: RESET command\n", tag());
|
logerror("%s: RESET command\n", tag());
|
||||||
device_reset();
|
device_reset();
|
||||||
@ -1108,7 +1119,7 @@ void hdc9234_device::reset_controller()
|
|||||||
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
|
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
|
||||||
+-----+-----+-----+-----+-----+-----+-----+-----+
|
+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::drive_deselect()
|
void hdc92x4_device::drive_deselect()
|
||||||
{
|
{
|
||||||
if (TRACE_SELECT) logerror("%s: DESELECT command\n", tag());
|
if (TRACE_SELECT) logerror("%s: DESELECT command\n", tag());
|
||||||
m_selected_drive_number = NODRIVE;
|
m_selected_drive_number = NODRIVE;
|
||||||
@ -1128,7 +1139,7 @@ void hdc9234_device::drive_deselect()
|
|||||||
| 0 | 0 | 0 | 0 | 0 | 0 | 1 |skcom|
|
| 0 | 0 | 0 | 0 | 0 | 0 | 1 |skcom|
|
||||||
+-----+-----+-----+-----+-----+-----+-----+-----+
|
+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::restore_drive()
|
void hdc92x4_device::restore_drive()
|
||||||
{
|
{
|
||||||
int cont = CONTINUE;
|
int cont = CONTINUE;
|
||||||
bool buffered_step = current_command() & 1;
|
bool buffered_step = current_command() & 1;
|
||||||
@ -1232,7 +1243,7 @@ void hdc9234_device::restore_drive()
|
|||||||
+-----+-----+-----+-----+-----+-----+-----+-----+
|
+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
|
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::step_drive()
|
void hdc92x4_device::step_drive()
|
||||||
{
|
{
|
||||||
int cont = CONTINUE;
|
int cont = CONTINUE;
|
||||||
|
|
||||||
@ -1282,7 +1293,7 @@ void hdc9234_device::step_drive()
|
|||||||
TAPE BACKUP
|
TAPE BACKUP
|
||||||
Not implemented
|
Not implemented
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::tape_backup()
|
void hdc92x4_device::tape_backup()
|
||||||
{
|
{
|
||||||
logerror("%s: TAPE BACKUP command %02x not implemented\n", tag(), current_command());
|
logerror("%s: TAPE BACKUP command %02x not implemented\n", tag(), current_command());
|
||||||
set_command_done(TC_SUCCESS);
|
set_command_done(TC_SUCCESS);
|
||||||
@ -1305,7 +1316,7 @@ void hdc9234_device::tape_backup()
|
|||||||
This command only sets the select lines but does not process parameters
|
This command only sets the select lines but does not process parameters
|
||||||
like head load times or drive types.
|
like head load times or drive types.
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::poll_drives()
|
void hdc92x4_device::poll_drives()
|
||||||
{
|
{
|
||||||
UINT8 drivebit = 0;
|
UINT8 drivebit = 0;
|
||||||
if (m_substate == UNDEF)
|
if (m_substate == UNDEF)
|
||||||
@ -1388,7 +1399,7 @@ void hdc9234_device::poll_drives()
|
|||||||
+-----+-----+-----+-----+-----+-----+-----+-----+
|
+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void hdc9234_device::drive_select()
|
void hdc92x4_device::drive_select()
|
||||||
{
|
{
|
||||||
int cont = CONTINUE;
|
int cont = CONTINUE;
|
||||||
int head_load_delay = 0;
|
int head_load_delay = 0;
|
||||||
@ -1449,7 +1460,7 @@ void hdc9234_device::drive_select()
|
|||||||
Sets the pointer to the read and write registers. On read or write accesses,
|
Sets the pointer to the read and write registers. On read or write accesses,
|
||||||
the pointer is increased until it reaches the DATA register.
|
the pointer is increased until it reaches the DATA register.
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::set_register_pointer()
|
void hdc92x4_device::set_register_pointer()
|
||||||
{
|
{
|
||||||
m_register_pointer = current_command() & 0xf;
|
m_register_pointer = current_command() & 0xf;
|
||||||
if (TRACE_SETPTR) logerror("%s: SET REGISTER POINTER command; start reg=%d\n", tag(), m_register_pointer);
|
if (TRACE_SETPTR) logerror("%s: SET REGISTER POINTER command; start reg=%d\n", tag(), m_register_pointer);
|
||||||
@ -1478,7 +1489,7 @@ void hdc9234_device::set_register_pointer()
|
|||||||
|
|
||||||
All combinations of flags are legal ([1], p.12).
|
All combinations of flags are legal ([1], p.12).
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::seek_read_id()
|
void hdc92x4_device::seek_read_id()
|
||||||
{
|
{
|
||||||
if (m_substate == UNDEF)
|
if (m_substate == UNDEF)
|
||||||
{
|
{
|
||||||
@ -1540,7 +1551,7 @@ void hdc9234_device::seek_read_id()
|
|||||||
+-----+-----+-----+-----+-----+--------+------+------+
|
+-----+-----+-----+-----+-----+--------+------+------+
|
||||||
|
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::read_sectors()
|
void hdc92x4_device::read_sectors()
|
||||||
{
|
{
|
||||||
m_logical = (current_command() & 0x04)!=0;
|
m_logical = (current_command() & 0x04)!=0;
|
||||||
|
|
||||||
@ -1594,7 +1605,7 @@ void hdc9234_device::read_sectors()
|
|||||||
+-----+-----+-----+-----+-----+-----+-----+------+
|
+-----+-----+-----+-----+-----+-----+-----+------+
|
||||||
|
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::read_track()
|
void hdc92x4_device::read_track()
|
||||||
{
|
{
|
||||||
if (m_substate == UNDEF)
|
if (m_substate == UNDEF)
|
||||||
{
|
{
|
||||||
@ -1702,7 +1713,7 @@ void hdc9234_device::read_track()
|
|||||||
| 0 | 1 | 1 |DelMrk|RedWC| Precompensation |
|
| 0 | 1 | 1 |DelMrk|RedWC| Precompensation |
|
||||||
+-----+-----+-----+------+-----+-----+-----+------+
|
+-----+-----+-----+------+-----+-----+-----+------+
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::format_track()
|
void hdc92x4_device::format_track()
|
||||||
{
|
{
|
||||||
if (m_substate == UNDEF)
|
if (m_substate == UNDEF)
|
||||||
{
|
{
|
||||||
@ -1797,7 +1808,7 @@ void hdc9234_device::format_track()
|
|||||||
| 1 |NoSeek|Logical|DelMrk|RedWC| Precompensation |
|
| 1 |NoSeek|Logical|DelMrk|RedWC| Precompensation |
|
||||||
+-----+------+-------+------+-----+-----+-----+------+
|
+-----+------+-------+------+-----+-----+-----+------+
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::write_sectors()
|
void hdc92x4_device::write_sectors()
|
||||||
{
|
{
|
||||||
m_logical = (current_command() & 0x20)!=0;
|
m_logical = (current_command() & 0x20)!=0;
|
||||||
|
|
||||||
@ -1878,7 +1889,7 @@ void hdc9234_device::write_sectors()
|
|||||||
===========================================================================
|
===========================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
std::string hdc9234_device::tts(const attotime &t)
|
std::string hdc92x4_device::tts(const attotime &t)
|
||||||
{
|
{
|
||||||
char buf[256];
|
char buf[256];
|
||||||
int nsec = t.attoseconds / ATTOSECONDS_PER_NANOSECOND;
|
int nsec = t.attoseconds / ATTOSECONDS_PER_NANOSECOND;
|
||||||
@ -1886,12 +1897,12 @@ std::string hdc9234_device::tts(const attotime &t)
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string hdc9234_device::ttsn()
|
std::string hdc92x4_device::ttsn()
|
||||||
{
|
{
|
||||||
return tts(machine().time());
|
return tts(machine().time());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hdc9234_device::found_mark(int state)
|
bool hdc92x4_device::found_mark(int state)
|
||||||
{
|
{
|
||||||
bool ismark = false;
|
bool ismark = false;
|
||||||
if (using_floppy())
|
if (using_floppy())
|
||||||
@ -1928,7 +1939,7 @@ bool hdc9234_device::found_mark(int state)
|
|||||||
The controller starts to read bits from the disk. This method takes an
|
The controller starts to read bits from the disk. This method takes an
|
||||||
argument for the state machine called at the end.
|
argument for the state machine called at the end.
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::live_start(int state)
|
void hdc92x4_device::live_start(int state)
|
||||||
{
|
{
|
||||||
if (TRACE_LIVE) logerror("%s: [%s] Live start substate=%02x\n", tag(), ttsn().c_str(), state);
|
if (TRACE_LIVE) logerror("%s: [%s] Live start substate=%02x\n", tag(), ttsn().c_str(), state);
|
||||||
m_live_state.time = machine().time();
|
m_live_state.time = machine().time();
|
||||||
@ -1954,7 +1965,7 @@ void hdc9234_device::live_start(int state)
|
|||||||
if (TRACE_LIVE) logerror("%s: [%s] Live start end\n", tag(), ttsn().c_str()); // delete
|
if (TRACE_LIVE) logerror("%s: [%s] Live start end\n", tag(), ttsn().c_str()); // delete
|
||||||
}
|
}
|
||||||
|
|
||||||
void hdc9234_device::live_run()
|
void hdc92x4_device::live_run()
|
||||||
{
|
{
|
||||||
if (using_floppy()) live_run_until(attotime::never);
|
if (using_floppy()) live_run_until(attotime::never);
|
||||||
else live_run_hd_until(attotime::never);
|
else live_run_hd_until(attotime::never);
|
||||||
@ -1968,7 +1979,7 @@ void hdc9234_device::live_run()
|
|||||||
|
|
||||||
THIS IS THE FLOPPY-ONLY LIVE_RUN
|
THIS IS THE FLOPPY-ONLY LIVE_RUN
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::live_run_until(attotime limit)
|
void hdc92x4_device::live_run_until(attotime limit)
|
||||||
{
|
{
|
||||||
int slot = 0;
|
int slot = 0;
|
||||||
|
|
||||||
@ -2799,7 +2810,7 @@ void hdc9234_device::live_run_until(attotime limit)
|
|||||||
[1], section "Drive select", table
|
[1], section "Drive select", table
|
||||||
This is currently unsupported; hard disks are forced to MFM
|
This is currently unsupported; hard disks are forced to MFM
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::live_run_hd_until(attotime limit)
|
void hdc92x4_device::live_run_hd_until(attotime limit)
|
||||||
{
|
{
|
||||||
int slot = 0;
|
int slot = 0;
|
||||||
if (TRACE_LIVE) logerror("%s: live_run_hd\n", tag());
|
if (TRACE_LIVE) logerror("%s: live_run_hd\n", tag());
|
||||||
@ -3400,7 +3411,7 @@ void hdc9234_device::live_run_hd_until(attotime limit)
|
|||||||
Results in a new checkpoint and a live position at machine time or behind.
|
Results in a new checkpoint and a live position at machine time or behind.
|
||||||
As a side effect, portions of the track may be re-read
|
As a side effect, portions of the track may be re-read
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::live_sync()
|
void hdc92x4_device::live_sync()
|
||||||
{
|
{
|
||||||
// Do we have some time set?
|
// Do we have some time set?
|
||||||
if (!m_live_state.time.is_never())
|
if (!m_live_state.time.is_never())
|
||||||
@ -3452,7 +3463,7 @@ void hdc9234_device::live_sync()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hdc9234_device::live_abort()
|
void hdc92x4_device::live_abort()
|
||||||
{
|
{
|
||||||
if (!m_live_state.time.is_never() && m_live_state.time > machine().time())
|
if (!m_live_state.time.is_never() && m_live_state.time > machine().time())
|
||||||
{
|
{
|
||||||
@ -3473,7 +3484,7 @@ void hdc9234_device::live_abort()
|
|||||||
comprised by WRITE_TRACK_(NEXT_)BYTE
|
comprised by WRITE_TRACK_(NEXT_)BYTE
|
||||||
Arguments: byte to be written, number, state on return
|
Arguments: byte to be written, number, state on return
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::write_on_track(UINT16 encoded, int repeat, int next_state)
|
void hdc92x4_device::write_on_track(UINT16 encoded, int repeat, int next_state)
|
||||||
{
|
{
|
||||||
m_live_state.repeat = repeat;
|
m_live_state.repeat = repeat;
|
||||||
m_live_state.state = WRITE_TRACK_BYTE;
|
m_live_state.state = WRITE_TRACK_BYTE;
|
||||||
@ -3486,7 +3497,7 @@ void hdc9234_device::write_on_track(UINT16 encoded, int repeat, int next_state)
|
|||||||
only intended for skipping bytes.
|
only intended for skipping bytes.
|
||||||
Arguments: number, state on return
|
Arguments: number, state on return
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::skip_on_track(int repeat, int next_state)
|
void hdc92x4_device::skip_on_track(int repeat, int next_state)
|
||||||
{
|
{
|
||||||
m_live_state.bit_counter = 0;
|
m_live_state.bit_counter = 0;
|
||||||
m_live_state.repeat = repeat;
|
m_live_state.repeat = repeat;
|
||||||
@ -3494,7 +3505,7 @@ void hdc9234_device::skip_on_track(int repeat, int next_state)
|
|||||||
m_live_state.return_state = next_state;
|
m_live_state.return_state = next_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT8 hdc9234_device::get_data_from_encoding(UINT16 raw)
|
UINT8 hdc92x4_device::get_data_from_encoding(UINT16 raw)
|
||||||
{
|
{
|
||||||
unsigned int value = 0;
|
unsigned int value = 0;
|
||||||
|
|
||||||
@ -3509,7 +3520,7 @@ UINT8 hdc9234_device::get_data_from_encoding(UINT16 raw)
|
|||||||
return (value >> 14) & 0xff;
|
return (value >> 14) & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hdc9234_device::rollback()
|
void hdc92x4_device::rollback()
|
||||||
{
|
{
|
||||||
m_live_state = m_checkpoint_state;
|
m_live_state = m_checkpoint_state;
|
||||||
m_pll = m_checkpoint_pll;
|
m_pll = m_checkpoint_pll;
|
||||||
@ -3519,7 +3530,7 @@ void hdc9234_device::rollback()
|
|||||||
Wait for real time to catch up. This way we pretend that the last
|
Wait for real time to catch up. This way we pretend that the last
|
||||||
operation actually needed the real time.
|
operation actually needed the real time.
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::wait_for_realtime(int state)
|
void hdc92x4_device::wait_for_realtime(int state)
|
||||||
{
|
{
|
||||||
m_live_state.next_state = state;
|
m_live_state.next_state = state;
|
||||||
m_timer->adjust(m_live_state.time - machine().time());
|
m_timer->adjust(m_live_state.time - machine().time());
|
||||||
@ -3533,7 +3544,7 @@ void hdc9234_device::wait_for_realtime(int state)
|
|||||||
rightmost bit; the shift register is a member of m_live_state. Also,
|
rightmost bit; the shift register is a member of m_live_state. Also,
|
||||||
the CRC is updated.
|
the CRC is updated.
|
||||||
*/
|
*/
|
||||||
bool hdc9234_device::read_one_bit(const attotime &limit)
|
bool hdc92x4_device::read_one_bit(const attotime &limit)
|
||||||
{
|
{
|
||||||
// Get the next bit from the phase-locked loop.
|
// Get the next bit from the phase-locked loop.
|
||||||
int bit = m_pll.get_next_bit(m_live_state.time, m_floppy, limit);
|
int bit = m_pll.get_next_bit(m_live_state.time, m_floppy, limit);
|
||||||
@ -3572,7 +3583,7 @@ bool hdc9234_device::read_one_bit(const attotime &limit)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hdc9234_device::write_one_bit(const attotime &limit)
|
bool hdc92x4_device::write_one_bit(const attotime &limit)
|
||||||
{
|
{
|
||||||
bool bit = (m_live_state.shift_reg & 0x8000)!=0;
|
bool bit = (m_live_state.shift_reg & 0x8000)!=0;
|
||||||
|
|
||||||
@ -3592,7 +3603,7 @@ bool hdc9234_device::write_one_bit(const attotime &limit)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT16 hdc9234_device::encode(UINT8 byte)
|
UINT16 hdc92x4_device::encode(UINT8 byte)
|
||||||
{
|
{
|
||||||
UINT16 raw;
|
UINT16 raw;
|
||||||
UINT8 check_pos;
|
UINT8 check_pos;
|
||||||
@ -3638,12 +3649,12 @@ UINT16 hdc9234_device::encode(UINT8 byte)
|
|||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hdc9234_device::encode_again()
|
void hdc92x4_device::encode_again()
|
||||||
{
|
{
|
||||||
encode_raw(m_live_state.shift_reg_save);
|
encode_raw(m_live_state.shift_reg_save);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hdc9234_device::encode_raw(UINT16 raw)
|
void hdc92x4_device::encode_raw(UINT16 raw)
|
||||||
{
|
{
|
||||||
m_live_state.bit_counter = 16;
|
m_live_state.bit_counter = 16;
|
||||||
m_live_state.shift_reg = m_live_state.shift_reg_save = raw;
|
m_live_state.shift_reg = m_live_state.shift_reg_save = raw;
|
||||||
@ -3660,7 +3671,7 @@ void hdc9234_device::encode_raw(UINT16 raw)
|
|||||||
When writing, the controller generates the proper output bitstream, so we
|
When writing, the controller generates the proper output bitstream, so we
|
||||||
have to set it from its own state (fm/mfm and device type).
|
have to set it from its own state (fm/mfm and device type).
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::pll_reset(const attotime &when, bool output)
|
void hdc92x4_device::pll_reset(const attotime &when, bool output)
|
||||||
{
|
{
|
||||||
m_pll.reset(when);
|
m_pll.reset(when);
|
||||||
|
|
||||||
@ -3675,7 +3686,7 @@ void hdc9234_device::pll_reset(const attotime &when, bool output)
|
|||||||
m_pll.set_clock(attotime::from_nsec(8000 >> (~m_clock_divider & 0x03)));
|
m_pll.set_clock(attotime::from_nsec(8000 >> (~m_clock_divider & 0x03)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void hdc9234_device::checkpoint()
|
void hdc92x4_device::checkpoint()
|
||||||
{
|
{
|
||||||
// Commit bits from pll buffer to disk until live time (if there is something to write)
|
// Commit bits from pll buffer to disk until live time (if there is something to write)
|
||||||
// For HD we do not use a PLL in this implementation
|
// For HD we do not use a PLL in this implementation
|
||||||
@ -3698,7 +3709,7 @@ void hdc9234_device::checkpoint()
|
|||||||
|
|
||||||
Updates the CRC and the shift register. Also, the time is updated.
|
Updates the CRC and the shift register. Also, the time is updated.
|
||||||
*/
|
*/
|
||||||
bool hdc9234_device::read_from_mfmhd(const attotime &limit)
|
bool hdc92x4_device::read_from_mfmhd(const attotime &limit)
|
||||||
{
|
{
|
||||||
UINT16 data = 0;
|
UINT16 data = 0;
|
||||||
bool offlimit = m_harddisk->read(m_live_state.time, limit, data);
|
bool offlimit = m_harddisk->read(m_live_state.time, limit, data);
|
||||||
@ -3766,7 +3777,7 @@ bool hdc9234_device::read_from_mfmhd(const attotime &limit)
|
|||||||
Return false: valid return
|
Return false: valid return
|
||||||
Updates the CRC and the shift register. Also, the time is updated.
|
Updates the CRC and the shift register. Also, the time is updated.
|
||||||
*/
|
*/
|
||||||
bool hdc9234_device::write_to_mfmhd(const attotime &limit)
|
bool hdc92x4_device::write_to_mfmhd(const attotime &limit)
|
||||||
{
|
{
|
||||||
UINT16 data = 0;
|
UINT16 data = 0;
|
||||||
int count;
|
int count;
|
||||||
@ -3809,7 +3820,7 @@ bool hdc9234_device::write_to_mfmhd(const attotime &limit)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT16 hdc9234_device::encode_hd(UINT8 byte)
|
UINT16 hdc92x4_device::encode_hd(UINT8 byte)
|
||||||
{
|
{
|
||||||
UINT16 cells;
|
UINT16 cells;
|
||||||
UINT8 check_pos;
|
UINT8 check_pos;
|
||||||
@ -3853,7 +3864,7 @@ UINT16 hdc9234_device::encode_hd(UINT8 byte)
|
|||||||
return cells;
|
return cells;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT16 hdc9234_device::encode_a1_hd()
|
UINT16 hdc92x4_device::encode_a1_hd()
|
||||||
{
|
{
|
||||||
UINT16 cells = 0;
|
UINT16 cells = 0;
|
||||||
|
|
||||||
@ -3884,7 +3895,7 @@ UINT16 hdc9234_device::encode_a1_hd()
|
|||||||
Read a byte of data from the controller
|
Read a byte of data from the controller
|
||||||
The address (offset) encodes the C/D* line (command and /data)
|
The address (offset) encodes the C/D* line (command and /data)
|
||||||
*/
|
*/
|
||||||
READ8_MEMBER( hdc9234_device::read )
|
READ8_MEMBER( hdc92x4_device::read )
|
||||||
{
|
{
|
||||||
UINT8 reply = 0;
|
UINT8 reply = 0;
|
||||||
|
|
||||||
@ -3920,7 +3931,7 @@ READ8_MEMBER( hdc9234_device::read )
|
|||||||
The operation terminates immediately, and the controller picks up the
|
The operation terminates immediately, and the controller picks up the
|
||||||
values stored in this phase at a later time.
|
values stored in this phase at a later time.
|
||||||
*/
|
*/
|
||||||
WRITE8_MEMBER( hdc9234_device::write )
|
WRITE8_MEMBER( hdc92x4_device::write )
|
||||||
{
|
{
|
||||||
if ((offset & 1) == 0)
|
if ((offset & 1) == 0)
|
||||||
{
|
{
|
||||||
@ -3944,7 +3955,7 @@ WRITE8_MEMBER( hdc9234_device::write )
|
|||||||
/*
|
/*
|
||||||
When the commit period has passed, process the command or register access
|
When the commit period has passed, process the command or register access
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::process_command()
|
void hdc92x4_device::process_command()
|
||||||
{
|
{
|
||||||
if (m_substate == REGISTER_ACCESS)
|
if (m_substate == REGISTER_ACCESS)
|
||||||
{
|
{
|
||||||
@ -4004,7 +4015,7 @@ void hdc9234_device::process_command()
|
|||||||
auxbus_out();
|
auxbus_out();
|
||||||
}
|
}
|
||||||
|
|
||||||
void hdc9234_device::reenter_command_processing()
|
void hdc92x4_device::reenter_command_processing()
|
||||||
{
|
{
|
||||||
if (TRACE_DELAY) logerror("%s: Re-enter command processing; live state = %02x\n", tag(), m_live_state.state);
|
if (TRACE_DELAY) logerror("%s: Re-enter command processing; live state = %02x\n", tag(), m_live_state.state);
|
||||||
// Do we have a live run on the track?
|
// Do we have a live run on the track?
|
||||||
@ -4026,7 +4037,7 @@ void hdc9234_device::reenter_command_processing()
|
|||||||
/*
|
/*
|
||||||
Assert Command Done status bit, triggering interrupts as needed
|
Assert Command Done status bit, triggering interrupts as needed
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::set_command_done(int flags)
|
void hdc92x4_device::set_command_done(int flags)
|
||||||
{
|
{
|
||||||
// Do another output, then set the flag
|
// Do another output, then set the flag
|
||||||
auxbus_out();
|
auxbus_out();
|
||||||
@ -4055,7 +4066,7 @@ void hdc9234_device::set_command_done(int flags)
|
|||||||
/*
|
/*
|
||||||
Preserve previously set termination code
|
Preserve previously set termination code
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::set_command_done()
|
void hdc92x4_device::set_command_done()
|
||||||
{
|
{
|
||||||
set_command_done(-1);
|
set_command_done(-1);
|
||||||
}
|
}
|
||||||
@ -4063,7 +4074,7 @@ void hdc9234_device::set_command_done()
|
|||||||
/*
|
/*
|
||||||
Auxiliary bus operation.
|
Auxiliary bus operation.
|
||||||
|
|
||||||
The auxbus of the HDC9234 is used to poll the drive status of the cur-
|
The auxbus of the HDC92x4 is used to poll the drive status of the cur-
|
||||||
rently selected drive, to transmit DMA address bytes, to output the
|
rently selected drive, to transmit DMA address bytes, to output the
|
||||||
OUTPUT1 register, and to output the OUTPUT2 register.
|
OUTPUT1 register, and to output the OUTPUT2 register.
|
||||||
|
|
||||||
@ -4106,7 +4117,7 @@ void hdc9234_device::set_command_done()
|
|||||||
Read the drive status over the auxbus
|
Read the drive status over the auxbus
|
||||||
(as said, let the controller board push the values into the controller)
|
(as said, let the controller board push the values into the controller)
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::auxbus_in(UINT8 data)
|
void hdc92x4_device::auxbus_in(UINT8 data)
|
||||||
{
|
{
|
||||||
// Kill unwanted input via auxbus until we are initialized.
|
// Kill unwanted input via auxbus until we are initialized.
|
||||||
if (!m_initialized)
|
if (!m_initialized)
|
||||||
@ -4131,12 +4142,12 @@ void hdc9234_device::auxbus_in(UINT8 data)
|
|||||||
if (prevskcom != seek_complete()) seek_complete_handler();
|
if (prevskcom != seek_complete()) seek_complete_handler();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hdc9234_device::waiting_for_line(int line, int level)
|
bool hdc92x4_device::waiting_for_line(int line, int level)
|
||||||
{
|
{
|
||||||
return (m_event_line == line && m_state_after_line != UNDEF && m_line_level == level);
|
return (m_event_line == line && m_state_after_line != UNDEF && m_line_level == level);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hdc9234_device::waiting_for_other_line(int line)
|
bool hdc92x4_device::waiting_for_other_line(int line)
|
||||||
{
|
{
|
||||||
return (m_state_after_line != UNDEF && m_event_line != line);
|
return (m_state_after_line != UNDEF && m_event_line != line);
|
||||||
}
|
}
|
||||||
@ -4144,7 +4155,7 @@ bool hdc9234_device::waiting_for_other_line(int line)
|
|||||||
/*
|
/*
|
||||||
Handlers for incoming signal lines.
|
Handlers for incoming signal lines.
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::index_handler()
|
void hdc92x4_device::index_handler()
|
||||||
{
|
{
|
||||||
int level = index_hole()? ASSERT_LINE : CLEAR_LINE;
|
int level = index_hole()? ASSERT_LINE : CLEAR_LINE;
|
||||||
if (TRACE_LINES) logerror("%s: [%s] Index handler; level=%d\n", tag(), ttsn().c_str(), level);
|
if (TRACE_LINES) logerror("%s: [%s] Index handler; level=%d\n", tag(), ttsn().c_str(), level);
|
||||||
@ -4179,7 +4190,7 @@ void hdc9234_device::index_handler()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hdc9234_device::ready_handler()
|
void hdc92x4_device::ready_handler()
|
||||||
{
|
{
|
||||||
int level = drive_ready()? ASSERT_LINE : CLEAR_LINE;
|
int level = drive_ready()? ASSERT_LINE : CLEAR_LINE;
|
||||||
if (TRACE_LINES) logerror("%s: [%s] Ready handler; level=%d\n", tag(), ttsn().c_str(), level);
|
if (TRACE_LINES) logerror("%s: [%s] Ready handler; level=%d\n", tag(), ttsn().c_str(), level);
|
||||||
@ -4206,7 +4217,7 @@ void hdc9234_device::ready_handler()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hdc9234_device::seek_complete_handler()
|
void hdc92x4_device::seek_complete_handler()
|
||||||
{
|
{
|
||||||
int level = seek_complete()? ASSERT_LINE : CLEAR_LINE;
|
int level = seek_complete()? ASSERT_LINE : CLEAR_LINE;
|
||||||
if (TRACE_LINES) logerror("%s: [%s] Seek complete handler; level=%d\n", tag(), ttsn().c_str(), level);
|
if (TRACE_LINES) logerror("%s: [%s] Seek complete handler; level=%d\n", tag(), ttsn().c_str(), level);
|
||||||
@ -4248,7 +4259,7 @@ void hdc9234_device::seek_complete_handler()
|
|||||||
Step = Step pulse
|
Step = Step pulse
|
||||||
Head = desired head
|
Head = desired head
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::auxbus_out()
|
void hdc92x4_device::auxbus_out()
|
||||||
{
|
{
|
||||||
// prepare output2
|
// prepare output2
|
||||||
set_bits(m_output2, OUT2_DRVSEL3I, (m_output1 & OUT1_DRVSEL3)==0);
|
set_bits(m_output2, OUT2_DRVSEL3I, (m_output1 & OUT1_DRVSEL3)==0);
|
||||||
@ -4268,7 +4279,7 @@ void hdc9234_device::auxbus_out()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hdc9234_device::dma_address_out(UINT8 addrub, UINT8 addrhb, UINT8 addrlb)
|
void hdc92x4_device::dma_address_out(UINT8 addrub, UINT8 addrhb, UINT8 addrlb)
|
||||||
{
|
{
|
||||||
if (TRACE_DMA) logerror("%s: Setting DMA address %06x\n", tag(), (addrub<<16 | addrhb<<8 | addrlb)&0xffffff);
|
if (TRACE_DMA) logerror("%s: Setting DMA address %06x\n", tag(), (addrub<<16 | addrhb<<8 | addrlb)&0xffffff);
|
||||||
m_out_auxbus((offs_t)HDC_OUTPUT_DMA_ADDR, addrub);
|
m_out_auxbus((offs_t)HDC_OUTPUT_DMA_ADDR, addrub);
|
||||||
@ -4284,7 +4295,7 @@ void hdc9234_device::dma_address_out(UINT8 addrub, UINT8 addrhb, UINT8 addrlb)
|
|||||||
- when the READY_CHANGE bit is set to 1 in the ISR and ST_RDYCHNG is set to 1
|
- when the READY_CHANGE bit is set to 1 in the ISR and ST_RDYCHNG is set to 1
|
||||||
(ready change: 1->0 or 0->1)
|
(ready change: 1->0 or 0->1)
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::set_interrupt(line_state intr)
|
void hdc92x4_device::set_interrupt(line_state intr)
|
||||||
{
|
{
|
||||||
if (intr == ASSERT_LINE)
|
if (intr == ASSERT_LINE)
|
||||||
{
|
{
|
||||||
@ -4306,7 +4317,7 @@ void hdc9234_device::set_interrupt(line_state intr)
|
|||||||
/*
|
/*
|
||||||
DMA acknowledge line.
|
DMA acknowledge line.
|
||||||
*/
|
*/
|
||||||
WRITE_LINE_MEMBER( hdc9234_device::dmaack )
|
WRITE_LINE_MEMBER( hdc92x4_device::dmaack )
|
||||||
{
|
{
|
||||||
if (state==ASSERT_LINE)
|
if (state==ASSERT_LINE)
|
||||||
{
|
{
|
||||||
@ -4319,7 +4330,7 @@ WRITE_LINE_MEMBER( hdc9234_device::dmaack )
|
|||||||
This is pretty simple here, compared to wd17xx, because index and ready
|
This is pretty simple here, compared to wd17xx, because index and ready
|
||||||
callbacks have to be tied to the controller board outside the chip.
|
callbacks have to be tied to the controller board outside the chip.
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::connect_floppy_drive(floppy_image_device* floppy)
|
void hdc92x4_device::connect_floppy_drive(floppy_image_device* floppy)
|
||||||
{
|
{
|
||||||
m_floppy = floppy;
|
m_floppy = floppy;
|
||||||
}
|
}
|
||||||
@ -4327,7 +4338,7 @@ void hdc9234_device::connect_floppy_drive(floppy_image_device* floppy)
|
|||||||
/*
|
/*
|
||||||
Connect the current hard drive.
|
Connect the current hard drive.
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::connect_hard_drive(mfm_harddisk_device* harddisk)
|
void hdc92x4_device::connect_hard_drive(mfm_harddisk_device* harddisk)
|
||||||
{
|
{
|
||||||
m_harddisk = harddisk;
|
m_harddisk = harddisk;
|
||||||
m_hd_encoding = m_harddisk->get_encoding();
|
m_hd_encoding = m_harddisk->get_encoding();
|
||||||
@ -4340,7 +4351,7 @@ void hdc9234_device::connect_hard_drive(mfm_harddisk_device* harddisk)
|
|||||||
at some time and make it a device of its own.
|
at some time and make it a device of its own.
|
||||||
line: CD0 (0) and CD1(1), value 0 or 1
|
line: CD0 (0) and CD1(1), value 0 or 1
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::set_clock_divider(int line, int value)
|
void hdc92x4_device::set_clock_divider(int line, int value)
|
||||||
{
|
{
|
||||||
set_bits(m_clock_divider, (line==0)? 1 : 2, value&1);
|
set_bits(m_clock_divider, (line==0)? 1 : 2, value&1);
|
||||||
}
|
}
|
||||||
@ -4348,7 +4359,7 @@ void hdc9234_device::set_clock_divider(int line, int value)
|
|||||||
/*
|
/*
|
||||||
This is reached when a timer has expired
|
This is reached when a timer has expired
|
||||||
*/
|
*/
|
||||||
void hdc9234_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
void hdc92x4_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||||
{
|
{
|
||||||
live_sync();
|
live_sync();
|
||||||
m_timed_wait = false;
|
m_timed_wait = false;
|
||||||
@ -4367,7 +4378,7 @@ void hdc9234_device::device_timer(emu_timer &timer, device_timer_id id, int para
|
|||||||
/*
|
/*
|
||||||
Reset the controller. Negative logic, but we use ASSERT_LINE.
|
Reset the controller. Negative logic, but we use ASSERT_LINE.
|
||||||
*/
|
*/
|
||||||
WRITE_LINE_MEMBER( hdc9234_device::reset )
|
WRITE_LINE_MEMBER( hdc92x4_device::reset )
|
||||||
{
|
{
|
||||||
if (state == ASSERT_LINE)
|
if (state == ASSERT_LINE)
|
||||||
{
|
{
|
||||||
@ -4376,7 +4387,7 @@ WRITE_LINE_MEMBER( hdc9234_device::reset )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hdc9234_device::device_start()
|
void hdc92x4_device::device_start()
|
||||||
{
|
{
|
||||||
m_out_intrq.resolve_safe();
|
m_out_intrq.resolve_safe();
|
||||||
m_out_dip.resolve_safe();
|
m_out_dip.resolve_safe();
|
||||||
@ -4393,7 +4404,7 @@ void hdc9234_device::device_start()
|
|||||||
m_live_state.state = IDLE;
|
m_live_state.state = IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hdc9234_device::device_reset()
|
void hdc92x4_device::device_reset()
|
||||||
{
|
{
|
||||||
m_clock_divider = 0;
|
m_clock_divider = 0;
|
||||||
m_deleted = false;
|
m_deleted = false;
|
||||||
@ -4435,4 +4446,5 @@ void hdc9234_device::device_reset()
|
|||||||
m_out_dmarq(CLEAR_LINE);
|
m_out_dmarq(CLEAR_LINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const device_type HDC9224 = &device_creator<hdc9224_device>;
|
||||||
const device_type HDC9234 = &device_creator<hdc9234_device>;
|
const device_type HDC9234 = &device_creator<hdc9234_device>;
|
@ -1,17 +1,18 @@
|
|||||||
// license:BSD-3-Clause
|
// license:BSD-3-Clause
|
||||||
// copyright-holders:Michael Zapf
|
// copyright-holders:Michael Zapf
|
||||||
/*
|
/*
|
||||||
HDC9234 Hard and Floppy Disk Controller
|
HDC9224 / HDC9234 Hard and Floppy Disk Controller
|
||||||
For details see hdc9234.c
|
For details see hdc92x4.c
|
||||||
*/
|
*/
|
||||||
#ifndef __HDC9234_H__
|
#ifndef __HDC92X4_H__
|
||||||
#define __HDC9234_H__
|
#define __HDC92X4_H__
|
||||||
|
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
#include "imagedev/floppy.h"
|
#include "imagedev/floppy.h"
|
||||||
#include "imagedev/mfmhd.h"
|
#include "imagedev/mfmhd.h"
|
||||||
#include "fdc_pll.h"
|
#include "fdc_pll.h"
|
||||||
|
|
||||||
|
extern const device_type HDC9224;
|
||||||
extern const device_type HDC9234;
|
extern const device_type HDC9234;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -44,41 +45,41 @@ enum
|
|||||||
//===================================================================
|
//===================================================================
|
||||||
|
|
||||||
/* Interrupt line. To be connected with the controller PCB. */
|
/* Interrupt line. To be connected with the controller PCB. */
|
||||||
#define MCFG_HDC9234_INTRQ_CALLBACK(_write) \
|
#define MCFG_HDC92X4_INTRQ_CALLBACK(_write) \
|
||||||
devcb = &hdc9234_device::set_intrq_wr_callback(*device, DEVCB_##_write);
|
devcb = &hdc92x4_device::set_intrq_wr_callback(*device, DEVCB_##_write);
|
||||||
|
|
||||||
/* DMA request line. To be connected with the controller PCB. */
|
/* DMA request line. To be connected with the controller PCB. */
|
||||||
#define MCFG_HDC9234_DMARQ_CALLBACK(_write) \
|
#define MCFG_HDC92X4_DMARQ_CALLBACK(_write) \
|
||||||
devcb = &hdc9234_device::set_dmarq_wr_callback(*device, DEVCB_##_write);
|
devcb = &hdc92x4_device::set_dmarq_wr_callback(*device, DEVCB_##_write);
|
||||||
|
|
||||||
/* DMA in progress line. To be connected with the controller PCB. */
|
/* DMA in progress line. To be connected with the controller PCB. */
|
||||||
#define MCFG_HDC9234_DIP_CALLBACK(_write) \
|
#define MCFG_HDC92X4_DIP_CALLBACK(_write) \
|
||||||
devcb = &hdc9234_device::set_dip_wr_callback(*device, DEVCB_##_write);
|
devcb = &hdc92x4_device::set_dip_wr_callback(*device, DEVCB_##_write);
|
||||||
|
|
||||||
/* Auxiliary Bus. These 8 lines need to be connected to external latches
|
/* Auxiliary Bus. These 8 lines need to be connected to external latches
|
||||||
and to a counter circuitry which works together with the external RAM.
|
and to a counter circuitry which works together with the external RAM.
|
||||||
We use the S0/S1 lines as address lines. */
|
We use the S0/S1 lines as address lines. */
|
||||||
#define MCFG_HDC9234_AUXBUS_OUT_CALLBACK(_write) \
|
#define MCFG_HDC92X4_AUXBUS_OUT_CALLBACK(_write) \
|
||||||
devcb = &hdc9234_device::set_auxbus_wr_callback(*device, DEVCB_##_write);
|
devcb = &hdc92x4_device::set_auxbus_wr_callback(*device, DEVCB_##_write);
|
||||||
|
|
||||||
/* Callback to read the contents of the external RAM via the data bus.
|
/* Callback to read the contents of the external RAM via the data bus.
|
||||||
Note that the address must be set and automatically increased
|
Note that the address must be set and automatically increased
|
||||||
by external circuitry. */
|
by external circuitry. */
|
||||||
#define MCFG_HDC9234_DMA_IN_CALLBACK(_read) \
|
#define MCFG_HDC92X4_DMA_IN_CALLBACK(_read) \
|
||||||
devcb = &hdc9234_device::set_dma_rd_callback(*device, DEVCB_##_read);
|
devcb = &hdc92x4_device::set_dma_rd_callback(*device, DEVCB_##_read);
|
||||||
|
|
||||||
/* Callback to write the contents of the external RAM via the data bus.
|
/* Callback to write the contents of the external RAM via the data bus.
|
||||||
Note that the address must be set and automatically increased
|
Note that the address must be set and automatically increased
|
||||||
by external circuitry. */
|
by external circuitry. */
|
||||||
#define MCFG_HDC9234_DMA_OUT_CALLBACK(_write) \
|
#define MCFG_HDC92X4_DMA_OUT_CALLBACK(_write) \
|
||||||
devcb = &hdc9234_device::set_dma_wr_callback(*device, DEVCB_##_write);
|
devcb = &hdc92x4_device::set_dma_wr_callback(*device, DEVCB_##_write);
|
||||||
|
|
||||||
//===================================================================
|
//===================================================================
|
||||||
|
|
||||||
class hdc9234_device : public device_t
|
class hdc92x4_device : public device_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
hdc9234_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
hdc92x4_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);
|
||||||
|
|
||||||
// Accesors from the CPU side
|
// Accesors from the CPU side
|
||||||
DECLARE_READ8_MEMBER( read );
|
DECLARE_READ8_MEMBER( read );
|
||||||
@ -87,12 +88,12 @@ public:
|
|||||||
DECLARE_WRITE_LINE_MEMBER( dmaack );
|
DECLARE_WRITE_LINE_MEMBER( dmaack );
|
||||||
|
|
||||||
// Callbacks
|
// Callbacks
|
||||||
template<class _Object> static devcb_base &set_intrq_wr_callback(device_t &device, _Object object) { return downcast<hdc9234_device &>(device).m_out_intrq.set_callback(object); }
|
template<class _Object> static devcb_base &set_intrq_wr_callback(device_t &device, _Object object) { return downcast<hdc92x4_device &>(device).m_out_intrq.set_callback(object); }
|
||||||
template<class _Object> static devcb_base &set_dmarq_wr_callback(device_t &device, _Object object) { return downcast<hdc9234_device &>(device).m_out_dmarq.set_callback(object); }
|
template<class _Object> static devcb_base &set_dmarq_wr_callback(device_t &device, _Object object) { return downcast<hdc92x4_device &>(device).m_out_dmarq.set_callback(object); }
|
||||||
template<class _Object> static devcb_base &set_dip_wr_callback(device_t &device, _Object object) { return downcast<hdc9234_device &>(device).m_out_dip.set_callback(object); }
|
template<class _Object> static devcb_base &set_dip_wr_callback(device_t &device, _Object object) { return downcast<hdc92x4_device &>(device).m_out_dip.set_callback(object); }
|
||||||
template<class _Object> static devcb_base &set_auxbus_wr_callback(device_t &device, _Object object) { return downcast<hdc9234_device &>(device).m_out_auxbus.set_callback(object); }
|
template<class _Object> static devcb_base &set_auxbus_wr_callback(device_t &device, _Object object) { return downcast<hdc92x4_device &>(device).m_out_auxbus.set_callback(object); }
|
||||||
template<class _Object> static devcb_base &set_dma_rd_callback(device_t &device, _Object object) { return downcast<hdc9234_device &>(device).m_in_dma.set_callback(object); }
|
template<class _Object> static devcb_base &set_dma_rd_callback(device_t &device, _Object object) { return downcast<hdc92x4_device &>(device).m_in_dma.set_callback(object); }
|
||||||
template<class _Object> static devcb_base &set_dma_wr_callback(device_t &device, _Object object) { return downcast<hdc9234_device &>(device).m_out_dma.set_callback(object); }
|
template<class _Object> static devcb_base &set_dma_wr_callback(device_t &device, _Object object) { return downcast<hdc92x4_device &>(device).m_out_dma.set_callback(object); }
|
||||||
|
|
||||||
// auxbus_in is intended to read events from the drives
|
// auxbus_in is intended to read events from the drives
|
||||||
// In the real chip the status is polled; to avoid unnecessary load
|
// In the real chip the status is polled; to avoid unnecessary load
|
||||||
@ -117,7 +118,8 @@ protected:
|
|||||||
void device_start();
|
void device_start();
|
||||||
void device_reset();
|
void device_reset();
|
||||||
|
|
||||||
private:
|
bool m_is_hdc9234;
|
||||||
|
|
||||||
devcb_write_line m_out_intrq; // INT line
|
devcb_write_line m_out_intrq; // INT line
|
||||||
devcb_write_line m_out_dmarq; // DMA request line
|
devcb_write_line m_out_dmarq; // DMA request line
|
||||||
devcb_write_line m_out_dip; // DMA in progress line
|
devcb_write_line m_out_dip; // DMA in progress line
|
||||||
@ -309,7 +311,7 @@ private:
|
|||||||
|
|
||||||
int m_substate;
|
int m_substate;
|
||||||
|
|
||||||
typedef void (hdc9234_device::*cmdfunc)(void);
|
typedef void (hdc92x4_device::*cmdfunc)(void);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -466,4 +468,20 @@ private:
|
|||||||
void write_sectors();
|
void write_sectors();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// =====================================================
|
||||||
|
// Subclasses: the two variants
|
||||||
|
// =====================================================
|
||||||
|
|
||||||
|
class hdc9224_device : public hdc92x4_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
hdc9224_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
};
|
||||||
|
|
||||||
|
class hdc9234_device : public hdc92x4_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
hdc9234_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue
Block a user