summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--scripts/src/machine.lua6
-rw-r--r--src/emu/bus/ti99_peb/hfdc.c12
-rw-r--r--src/emu/bus/ti99_peb/hfdc.h2
-rw-r--r--src/emu/machine/hdc92x4.c (renamed from src/emu/machine/hdc9234.c)234
-rw-r--r--src/emu/machine/hdc92x4.h (renamed from src/emu/machine/hdc9234.h)70
5 files changed, 177 insertions, 147 deletions
diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua
index e040fb0781a..6a3657129ef 100644
--- a/scripts/src/machine.lua
+++ b/scripts/src/machine.lua
@@ -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
files {
- MAME_DIR .. "src/emu/machine/hdc9234.c",
- MAME_DIR .. "src/emu/machine/hdc9234.h",
+ MAME_DIR .. "src/emu/machine/hdc92x4.c",
+ MAME_DIR .. "src/emu/machine/hdc92x4.h",
}
end
diff --git a/src/emu/bus/ti99_peb/hfdc.c b/src/emu/bus/ti99_peb/hfdc.c
index 3ade598a448..5bbac318b6c 100644
--- a/src/emu/bus/ti99_peb/hfdc.c
+++ b/src/emu/bus/ti99_peb/hfdc.c
@@ -1019,12 +1019,12 @@ SLOT_INTERFACE_END
MACHINE_CONFIG_FRAGMENT( ti99_hfdc )
MCFG_DEVICE_ADD(FDC_TAG, HDC9234, 0)
- MCFG_HDC9234_INTRQ_CALLBACK(WRITELINE(myarc_hfdc_device, intrq_w))
- MCFG_HDC9234_DIP_CALLBACK(WRITELINE(myarc_hfdc_device, dip_w))
- MCFG_HDC9234_AUXBUS_OUT_CALLBACK(WRITE8(myarc_hfdc_device, auxbus_out))
- MCFG_HDC9234_DMARQ_CALLBACK(WRITELINE(myarc_hfdc_device, dmarq_w))
- MCFG_HDC9234_DMA_IN_CALLBACK(READ8(myarc_hfdc_device, read_buffer))
- MCFG_HDC9234_DMA_OUT_CALLBACK(WRITE8(myarc_hfdc_device, write_buffer))
+ MCFG_HDC92X4_INTRQ_CALLBACK(WRITELINE(myarc_hfdc_device, intrq_w))
+ MCFG_HDC92X4_DIP_CALLBACK(WRITELINE(myarc_hfdc_device, dip_w))
+ MCFG_HDC92X4_AUXBUS_OUT_CALLBACK(WRITE8(myarc_hfdc_device, auxbus_out))
+ MCFG_HDC92X4_DMARQ_CALLBACK(WRITELINE(myarc_hfdc_device, dmarq_w))
+ MCFG_HDC92X4_DMA_IN_CALLBACK(READ8(myarc_hfdc_device, read_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("f2", hfdc_floppies, "525dd", myarc_hfdc_device::floppy_formats)
diff --git a/src/emu/bus/ti99_peb/hfdc.h b/src/emu/bus/ti99_peb/hfdc.h
index 062a2617070..e4e466a89d4 100644
--- a/src/emu/bus/ti99_peb/hfdc.h
+++ b/src/emu/bus/ti99_peb/hfdc.h
@@ -20,7 +20,7 @@
#include "imagedev/mfmhd.h"
#include "machine/mm58274c.h"
-#include "machine/hdc9234.h"
+#include "machine/hdc92x4.h"
extern const device_type TI99_HFDC;
diff --git a/src/emu/machine/hdc9234.c b/src/emu/machine/hdc92x4.c
index 1ff47f686f8..f9b77b63fb0 100644
--- a/src/emu/machine/hdc9234.c
+++ b/src/emu/machine/hdc92x4.c
@@ -2,26 +2,24 @@
// copyright-holders:Michael Zapf
/**************************************************************************
- HDC9234 Hard and Floppy Disk Controller
+ HDC 9224 and HDC 9234 Hard and Floppy Disk Controller
Standard Microsystems Corporation (SMC)
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:
[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
- Michael Zapf, July 2015
+ Michael Zapf, August 2015
***************************************************************************/
#include "emu.h"
-#include "hdc9234.h"
+#include "hdc92x4.h"
#include "formats/imageutl.h"
// Per-command debugging
@@ -410,30 +408,30 @@ enum
SUCCESS
};
-const hdc9234_device::cmddef hdc9234_device::s_command[] =
+const hdc92x4_device::cmddef hdc92x4_device::s_command[] =
{
- { 0x00, 0xff, &hdc9234_device::reset_controller },
- { 0x01, 0xff, &hdc9234_device::drive_deselect },
- { 0x02, 0xfe, &hdc9234_device::restore_drive },
- { 0x04, 0xfc, &hdc9234_device::step_drive },
- { 0x08, 0xf8, &hdc9234_device::tape_backup },
- { 0x10, 0xf0, &hdc9234_device::poll_drives },
- { 0x20, 0xe0, &hdc9234_device::drive_select },
- { 0x40, 0xf0, &hdc9234_device::set_register_pointer },
- { 0x50, 0xf8, &hdc9234_device::seek_read_id },
- { 0x58, 0xfe, &hdc9234_device::read_sectors },
- { 0x5a, 0xfe, &hdc9234_device::read_track },
- { 0x5c, 0xfc, &hdc9234_device::read_sectors },
- { 0x60, 0xe0, &hdc9234_device::format_track },
- { 0x80, 0x80, &hdc9234_device::write_sectors },
+ { 0x00, 0xff, &hdc92x4_device::reset_controller },
+ { 0x01, 0xff, &hdc92x4_device::drive_deselect },
+ { 0x02, 0xfe, &hdc92x4_device::restore_drive },
+ { 0x04, 0xfc, &hdc92x4_device::step_drive },
+ { 0x08, 0xf8, &hdc92x4_device::tape_backup },
+ { 0x10, 0xf0, &hdc92x4_device::poll_drives },
+ { 0x20, 0xe0, &hdc92x4_device::drive_select },
+ { 0x40, 0xf0, &hdc92x4_device::set_register_pointer },
+ { 0x50, 0xf8, &hdc92x4_device::seek_read_id },
+ { 0x58, 0xfe, &hdc92x4_device::read_sectors },
+ { 0x5a, 0xfe, &hdc92x4_device::read_track },
+ { 0x5c, 0xfc, &hdc92x4_device::read_sectors },
+ { 0x60, 0xe0, &hdc92x4_device::format_track },
+ { 0x80, 0x80, &hdc92x4_device::write_sectors },
{ 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)
- : device_t(mconfig, HDC9234, "SMC HDC9234 Universal Disk Controller", tag, owner, clock, "hdc9234", __FILE__),
+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, type, name, tag, owner, clock, shortname, source),
m_out_intrq(*this),
m_out_dmarq(*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.
*/
-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;
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.
*/
-bool hdc9234_device::fm_mode()
+bool hdc92x4_device::fm_mode()
{
return ((m_register_w[MODE]&MO_DENSITY)!=0);
}
@@ -464,7 +475,7 @@ bool hdc9234_device::fm_mode()
/*
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;
}
@@ -472,7 +483,7 @@ bool hdc9234_device::on_track00()
/*
Seek completed?
*/
-bool hdc9234_device::seek_complete()
+bool hdc92x4_device::seek_complete()
{
return (m_register_r[DRIVE_STATUS] & HDC_DS_SKCOM)!=0;
}
@@ -480,7 +491,7 @@ bool hdc9234_device::seek_complete()
/*
Index hole?
*/
-bool hdc9234_device::index_hole()
+bool hdc92x4_device::index_hole()
{
return (m_register_r[DRIVE_STATUS] & HDC_DS_INDEX)!=0;
}
@@ -488,7 +499,7 @@ bool hdc9234_device::index_hole()
/*
Drive ready?
*/
-bool hdc9234_device::drive_ready()
+bool hdc92x4_device::drive_ready()
{
return (m_register_r[DRIVE_STATUS] & HDC_DS_READY)!=0;
}
@@ -496,7 +507,7 @@ bool hdc9234_device::drive_ready()
/*
Doing a track read?
*/
-bool hdc9234_device::reading_track()
+bool hdc92x4_device::reading_track()
{
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
fields on the track.
*/
-int hdc9234_device::desired_head()
+int hdc92x4_device::desired_head()
{
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);
}
-int hdc9234_device::desired_sector()
+int hdc92x4_device::desired_sector()
{
return m_register_w[DESIRED_SECTOR] & 0xff;
}
-int hdc9234_device::current_head()
+int hdc92x4_device::current_head()
{
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);
}
-int hdc9234_device::current_sector()
+int hdc92x4_device::current_sector()
{
return m_register_r[CURRENT_SECTOR] & 0xff;
}
-UINT8 hdc9234_device::current_command()
+UINT8 hdc92x4_device::current_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);
}
@@ -554,7 +565,7 @@ bool hdc9234_device::using_floppy()
/*
Delivers the step time (in microseconds) minus the pulse width
*/
-int hdc9234_device::step_time()
+int hdc92x4_device::step_time()
{
int time = 0;
int index = m_register_w[MODE] & MO_STEPRATE;
@@ -574,7 +585,7 @@ int hdc9234_device::step_time()
/*
Delivers the pulse width time (in microseconds)
*/
-int hdc9234_device::pulse_width()
+int hdc92x4_device::pulse_width()
{
int time = 0;
// Get seek time.
@@ -593,7 +604,7 @@ int hdc9234_device::pulse_width()
/*
Delivers the sector size
*/
-int hdc9234_device::calc_sector_size()
+int hdc92x4_device::calc_sector_size()
{
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
// ===========================================================================
-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);
}
-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);
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
*/
-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;
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!)
- 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;
@@ -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
- checks the CRC
*/
-void hdc9234_device::verify(int& cont)
+void hdc92x4_device::verify(int& cont)
{
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
via DMA to the sector (write)
*/
-void hdc9234_device::data_transfer(int& cont)
+void hdc92x4_device::data_transfer(int& cont)
{
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());
device_reset();
@@ -1108,7 +1119,7 @@ void hdc9234_device::reset_controller()
| 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());
m_selected_drive_number = NODRIVE;
@@ -1128,7 +1139,7 @@ void hdc9234_device::drive_deselect()
| 0 | 0 | 0 | 0 | 0 | 0 | 1 |skcom|
+-----+-----+-----+-----+-----+-----+-----+-----+
*/
-void hdc9234_device::restore_drive()
+void hdc92x4_device::restore_drive()
{
int cont = CONTINUE;
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;
@@ -1282,7 +1293,7 @@ void hdc9234_device::step_drive()
TAPE BACKUP
Not implemented
*/
-void hdc9234_device::tape_backup()
+void hdc92x4_device::tape_backup()
{
logerror("%s: TAPE BACKUP command %02x not implemented\n", tag(), current_command());
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
like head load times or drive types.
*/
-void hdc9234_device::poll_drives()
+void hdc92x4_device::poll_drives()
{
UINT8 drivebit = 0;
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 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,
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;
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).
*/
-void hdc9234_device::seek_read_id()
+void hdc92x4_device::seek_read_id()
{
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;
@@ -1594,7 +1605,7 @@ void hdc9234_device::read_sectors()
+-----+-----+-----+-----+-----+-----+-----+------+
*/
-void hdc9234_device::read_track()
+void hdc92x4_device::read_track()
{
if (m_substate == UNDEF)
{
@@ -1702,7 +1713,7 @@ void hdc9234_device::read_track()
| 0 | 1 | 1 |DelMrk|RedWC| Precompensation |
+-----+-----+-----+------+-----+-----+-----+------+
*/
-void hdc9234_device::format_track()
+void hdc92x4_device::format_track()
{
if (m_substate == UNDEF)
{
@@ -1797,7 +1808,7 @@ void hdc9234_device::format_track()
| 1 |NoSeek|Logical|DelMrk|RedWC| Precompensation |
+-----+------+-------+------+-----+-----+-----+------+
*/
-void hdc9234_device::write_sectors()
+void hdc92x4_device::write_sectors()
{
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];
int nsec = t.attoseconds / ATTOSECONDS_PER_NANOSECOND;
@@ -1886,12 +1897,12 @@ std::string hdc9234_device::tts(const attotime &t)
return buf;
}
-std::string hdc9234_device::ttsn()
+std::string hdc92x4_device::ttsn()
{
return tts(machine().time());
}
-bool hdc9234_device::found_mark(int state)
+bool hdc92x4_device::found_mark(int state)
{
bool ismark = false;
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
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);
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
}
-void hdc9234_device::live_run()
+void hdc92x4_device::live_run()
{
if (using_floppy()) live_run_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
*/
-void hdc9234_device::live_run_until(attotime limit)
+void hdc92x4_device::live_run_until(attotime limit)
{
int slot = 0;
@@ -2799,7 +2810,7 @@ void hdc9234_device::live_run_until(attotime limit)
[1], section "Drive select", table
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;
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.
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?
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())
{
@@ -3473,7 +3484,7 @@ void hdc9234_device::live_abort()
comprised by WRITE_TRACK_(NEXT_)BYTE
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.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.
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.repeat = repeat;
@@ -3494,7 +3505,7 @@ void hdc9234_device::skip_on_track(int repeat, int 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;
@@ -3509,7 +3520,7 @@ UINT8 hdc9234_device::get_data_from_encoding(UINT16 raw)
return (value >> 14) & 0xff;
}
-void hdc9234_device::rollback()
+void hdc92x4_device::rollback()
{
m_live_state = m_checkpoint_state;
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
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_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,
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.
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;
}
-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;
@@ -3592,7 +3603,7 @@ bool hdc9234_device::write_one_bit(const attotime &limit)
return false;
}
-UINT16 hdc9234_device::encode(UINT8 byte)
+UINT16 hdc92x4_device::encode(UINT8 byte)
{
UINT16 raw;
UINT8 check_pos;
@@ -3638,12 +3649,12 @@ UINT16 hdc9234_device::encode(UINT8 byte)
return raw;
}
-void hdc9234_device::encode_again()
+void hdc92x4_device::encode_again()
{
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.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
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);
@@ -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)));
}
-void hdc9234_device::checkpoint()
+void hdc92x4_device::checkpoint()
{
// 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
@@ -3698,7 +3709,7 @@ void hdc9234_device::checkpoint()
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;
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
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;
int count;
@@ -3809,7 +3820,7 @@ bool hdc9234_device::write_to_mfmhd(const attotime &limit)
return false;
}
-UINT16 hdc9234_device::encode_hd(UINT8 byte)
+UINT16 hdc92x4_device::encode_hd(UINT8 byte)
{
UINT16 cells;
UINT8 check_pos;
@@ -3853,7 +3864,7 @@ UINT16 hdc9234_device::encode_hd(UINT8 byte)
return cells;
}
-UINT16 hdc9234_device::encode_a1_hd()
+UINT16 hdc92x4_device::encode_a1_hd()
{
UINT16 cells = 0;
@@ -3884,7 +3895,7 @@ UINT16 hdc9234_device::encode_a1_hd()
Read a byte of data from the controller
The address (offset) encodes the C/D* line (command and /data)
*/
-READ8_MEMBER( hdc9234_device::read )
+READ8_MEMBER( hdc92x4_device::read )
{
UINT8 reply = 0;
@@ -3920,7 +3931,7 @@ READ8_MEMBER( hdc9234_device::read )
The operation terminates immediately, and the controller picks up the
values stored in this phase at a later time.
*/
-WRITE8_MEMBER( hdc9234_device::write )
+WRITE8_MEMBER( hdc92x4_device::write )
{
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
*/
-void hdc9234_device::process_command()
+void hdc92x4_device::process_command()
{
if (m_substate == REGISTER_ACCESS)
{
@@ -4004,7 +4015,7 @@ void hdc9234_device::process_command()
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);
// 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
*/
-void hdc9234_device::set_command_done(int flags)
+void hdc92x4_device::set_command_done(int flags)
{
// Do another output, then set the flag
auxbus_out();
@@ -4055,7 +4066,7 @@ void hdc9234_device::set_command_done(int flags)
/*
Preserve previously set termination code
*/
-void hdc9234_device::set_command_done()
+void hdc92x4_device::set_command_done()
{
set_command_done(-1);
}
@@ -4063,7 +4074,7 @@ void hdc9234_device::set_command_done()
/*
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
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
(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.
if (!m_initialized)
@@ -4131,12 +4142,12 @@ void hdc9234_device::auxbus_in(UINT8 data)
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);
}
-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);
}
@@ -4144,7 +4155,7 @@ bool hdc9234_device::waiting_for_other_line(int line)
/*
Handlers for incoming signal lines.
*/
-void hdc9234_device::index_handler()
+void hdc92x4_device::index_handler()
{
int level = index_hole()? ASSERT_LINE : CLEAR_LINE;
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;
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;
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
Head = desired head
*/
-void hdc9234_device::auxbus_out()
+void hdc92x4_device::auxbus_out()
{
// prepare output2
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);
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
(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)
{
@@ -4306,7 +4317,7 @@ void hdc9234_device::set_interrupt(line_state intr)
/*
DMA acknowledge line.
*/
-WRITE_LINE_MEMBER( hdc9234_device::dmaack )
+WRITE_LINE_MEMBER( hdc92x4_device::dmaack )
{
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
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;
}
@@ -4327,7 +4338,7 @@ void hdc9234_device::connect_floppy_drive(floppy_image_device* floppy)
/*
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_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.
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);
}
@@ -4348,7 +4359,7 @@ void hdc9234_device::set_clock_divider(int line, int value)
/*
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();
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.
*/
-WRITE_LINE_MEMBER( hdc9234_device::reset )
+WRITE_LINE_MEMBER( hdc92x4_device::reset )
{
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_dip.resolve_safe();
@@ -4393,7 +4404,7 @@ void hdc9234_device::device_start()
m_live_state.state = IDLE;
}
-void hdc9234_device::device_reset()
+void hdc92x4_device::device_reset()
{
m_clock_divider = 0;
m_deleted = false;
@@ -4435,4 +4446,5 @@ void hdc9234_device::device_reset()
m_out_dmarq(CLEAR_LINE);
}
+const device_type HDC9224 = &device_creator<hdc9224_device>;
const device_type HDC9234 = &device_creator<hdc9234_device>;
diff --git a/src/emu/machine/hdc9234.h b/src/emu/machine/hdc92x4.h
index bedd98e3a9b..da3c5b6d954 100644
--- a/src/emu/machine/hdc9234.h
+++ b/src/emu/machine/hdc92x4.h
@@ -1,17 +1,18 @@
// license:BSD-3-Clause
// copyright-holders:Michael Zapf
/*
- HDC9234 Hard and Floppy Disk Controller
- For details see hdc9234.c
+ HDC9224 / HDC9234 Hard and Floppy Disk Controller
+ For details see hdc92x4.c
*/
-#ifndef __HDC9234_H__
-#define __HDC9234_H__
+#ifndef __HDC92X4_H__
+#define __HDC92X4_H__
#include "emu.h"
#include "imagedev/floppy.h"
#include "imagedev/mfmhd.h"
#include "fdc_pll.h"
+extern const device_type HDC9224;
extern const device_type HDC9234;
/*
@@ -44,41 +45,41 @@ enum
//===================================================================
/* Interrupt line. To be connected with the controller PCB. */
-#define MCFG_HDC9234_INTRQ_CALLBACK(_write) \
- devcb = &hdc9234_device::set_intrq_wr_callback(*device, DEVCB_##_write);
+#define MCFG_HDC92X4_INTRQ_CALLBACK(_write) \
+ devcb = &hdc92x4_device::set_intrq_wr_callback(*device, DEVCB_##_write);
/* DMA request line. To be connected with the controller PCB. */
-#define MCFG_HDC9234_DMARQ_CALLBACK(_write) \
- devcb = &hdc9234_device::set_dmarq_wr_callback(*device, DEVCB_##_write);
+#define MCFG_HDC92X4_DMARQ_CALLBACK(_write) \
+ devcb = &hdc92x4_device::set_dmarq_wr_callback(*device, DEVCB_##_write);
/* DMA in progress line. To be connected with the controller PCB. */
-#define MCFG_HDC9234_DIP_CALLBACK(_write) \
- devcb = &hdc9234_device::set_dip_wr_callback(*device, DEVCB_##_write);
+#define MCFG_HDC92X4_DIP_CALLBACK(_write) \
+ devcb = &hdc92x4_device::set_dip_wr_callback(*device, DEVCB_##_write);
/* Auxiliary Bus. These 8 lines need to be connected to external latches
and to a counter circuitry which works together with the external RAM.
We use the S0/S1 lines as address lines. */
-#define MCFG_HDC9234_AUXBUS_OUT_CALLBACK(_write) \
- devcb = &hdc9234_device::set_auxbus_wr_callback(*device, DEVCB_##_write);
+#define MCFG_HDC92X4_AUXBUS_OUT_CALLBACK(_write) \
+ devcb = &hdc92x4_device::set_auxbus_wr_callback(*device, DEVCB_##_write);
/* Callback to read the contents of the external RAM via the data bus.
Note that the address must be set and automatically increased
by external circuitry. */
-#define MCFG_HDC9234_DMA_IN_CALLBACK(_read) \
- devcb = &hdc9234_device::set_dma_rd_callback(*device, DEVCB_##_read);
+#define MCFG_HDC92X4_DMA_IN_CALLBACK(_read) \
+ devcb = &hdc92x4_device::set_dma_rd_callback(*device, DEVCB_##_read);
/* Callback to write the contents of the external RAM via the data bus.
Note that the address must be set and automatically increased
by external circuitry. */
-#define MCFG_HDC9234_DMA_OUT_CALLBACK(_write) \
- devcb = &hdc9234_device::set_dma_wr_callback(*device, DEVCB_##_write);
+#define MCFG_HDC92X4_DMA_OUT_CALLBACK(_write) \
+ devcb = &hdc92x4_device::set_dma_wr_callback(*device, DEVCB_##_write);
//===================================================================
-class hdc9234_device : public device_t
+class hdc92x4_device : public device_t
{
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
DECLARE_READ8_MEMBER( read );
@@ -87,12 +88,12 @@ public:
DECLARE_WRITE_LINE_MEMBER( dmaack );
// 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_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_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_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_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_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_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<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<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<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<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<hdc92x4_device &>(device).m_out_dma.set_callback(object); }
// auxbus_in is intended to read events from the drives
// In the real chip the status is polled; to avoid unnecessary load
@@ -117,7 +118,8 @@ protected:
void device_start();
void device_reset();
-private:
+ bool m_is_hdc9234;
+
devcb_write_line m_out_intrq; // INT line
devcb_write_line m_out_dmarq; // DMA request line
devcb_write_line m_out_dip; // DMA in progress line
@@ -309,7 +311,7 @@ private:
int m_substate;
- typedef void (hdc9234_device::*cmdfunc)(void);
+ typedef void (hdc92x4_device::*cmdfunc)(void);
typedef struct
{
@@ -466,4 +468,20 @@ private:
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