summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2014-03-23 14:45:18 +0000
committer Miodrag Milanovic <mmicko@gmail.com>2014-03-23 14:45:18 +0000
commit72292ef70ad882d18aa22296500bc881ffea5727 (patch)
tree77755b59fc56616dd4a103c085fff72398937939
parent0a18895d99575ebaf54888a253b11793e9e62e53 (diff)
modernized 990_hd, moved some code into ti990_10.c, and simplified harddriv.c and remove some legacy leftovers (nw)
-rw-r--r--.gitattributes2
-rw-r--r--src/emu/diimage.h7
-rw-r--r--src/emu/driver.h1
-rw-r--r--src/emu/imagedev/harddriv.c10
-rw-r--r--src/emu/imagedev/harddriv.h15
-rw-r--r--src/emu/machine/corvushd.c2
-rw-r--r--src/emu/machine/nscsi_hd.c2
-rw-r--r--src/emu/machine/scsihd.c2
-rw-r--r--src/mess/drivers/ti990_10.c172
-rw-r--r--src/mess/includes/next.h1
-rw-r--r--src/mess/machine/ti99/990_hd.c550
-rw-r--r--src/mess/machine/ti99/990_hd.h70
-rw-r--r--src/mess/machine/ti99/ti990.c177
-rw-r--r--src/mess/machine/ti99/ti990.h23
-rw-r--r--src/mess/mess.mak1
15 files changed, 500 insertions, 535 deletions
diff --git a/.gitattributes b/.gitattributes
index a7d703ff457..f756c661270 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -8604,8 +8604,6 @@ src/mess/machine/ti99/mecmouse.c svneol=native#text/plain
src/mess/machine/ti99/mecmouse.h svneol=native#text/plain
src/mess/machine/ti99/speech8.c svneol=native#text/plain
src/mess/machine/ti99/speech8.h svneol=native#text/plain
-src/mess/machine/ti99/ti990.c svneol=native#text/plain
-src/mess/machine/ti99/ti990.h svneol=native#text/plain
src/mess/machine/ti99/ti99defs.h svneol=native#text/plain
src/mess/machine/ti99/videowrp.c svneol=native#text/plain
src/mess/machine/ti99/videowrp.h svneol=native#text/plain
diff --git a/src/emu/diimage.h b/src/emu/diimage.h
index adae6ee41b7..cfd9f85ef20 100644
--- a/src/emu/diimage.h
+++ b/src/emu/diimage.h
@@ -103,8 +103,6 @@ class software_info;
typedef delegate<int (device_image_interface &)> device_image_load_delegate;
typedef delegate<void (device_image_interface &)> device_image_func_delegate;
// legacy
-typedef int (*device_image_load_func)(device_image_interface &image);
-typedef void (*device_image_unload_func)(device_image_interface &image);
typedef void (*device_image_partialhash_func)(hash_collection &, const unsigned char *, unsigned long, const char *);
typedef void (*device_image_display_info_func)(device_image_interface &image);
@@ -117,14 +115,9 @@ typedef void (*device_image_display_info_func)(device_image_interface &image);
#define IMAGE_VERIFY_PASS FALSE
#define IMAGE_VERIFY_FAIL TRUE
-#define DEVICE_IMAGE_LOAD_NAME_LEGACY(name) device_load_##name
-#define DEVICE_IMAGE_LOAD_LEGACY(name) int DEVICE_IMAGE_LOAD_NAME_LEGACY(name)(device_image_interface &image)
-#define DEVICE_IMAGE_UNLOAD_NAME_LEGACY(name) device_unload_##name
-#define DEVICE_IMAGE_UNLOAD_LEGACY(name) void DEVICE_IMAGE_UNLOAD_NAME_LEGACY(name)(device_image_interface &image)
#define DEVICE_IMAGE_DISPLAY_INFO_NAME(name) device_image_display_info_func##name
#define DEVICE_IMAGE_DISPLAY_INFO(name) void DEVICE_IMAGE_DISPLAY_INFO_NAME(name)(device_image_interface &image)
-
#define DEVICE_IMAGE_LOAD_MEMBER_NAME(_name) device_image_load_##_name
#define DEVICE_IMAGE_LOAD_NAME(_class,_name) _class::DEVICE_IMAGE_LOAD_MEMBER_NAME(_name)
#define DECLARE_DEVICE_IMAGE_LOAD_MEMBER(_name) int DEVICE_IMAGE_LOAD_MEMBER_NAME(_name)(device_image_interface &image)
diff --git a/src/emu/driver.h b/src/emu/driver.h
index 8570402927c..80bd217bd25 100644
--- a/src/emu/driver.h
+++ b/src/emu/driver.h
@@ -79,7 +79,6 @@
#define VIDEO_START_NAME(name) video_start_##name
#define VIDEO_START(name) void VIDEO_START_NAME(name)(running_machine &machine) // legacy
#define VIDEO_START_CALL_MEMBER(name) VIDEO_START_NAME(name)()
-#define VIDEO_START_CALL_LEGACY(name) VIDEO_START_NAME(name)(machine())
#define DECLARE_VIDEO_START(name) void VIDEO_START_NAME(name)()
#define VIDEO_START_MEMBER(cls,name) void cls::VIDEO_START_NAME(name)()
diff --git a/src/emu/imagedev/harddriv.c b/src/emu/imagedev/harddriv.c
index 089d80518a1..03639711520 100644
--- a/src/emu/imagedev/harddriv.c
+++ b/src/emu/imagedev/harddriv.c
@@ -40,7 +40,9 @@ harddisk_image_device::harddisk_image_device(const machine_config &mconfig, cons
: device_t(mconfig, HARDDISK, "Harddisk", tag, owner, clock, "harddisk_image", __FILE__),
device_image_interface(mconfig, *this),
m_chd(NULL),
- m_hard_disk_handle(NULL)
+ m_hard_disk_handle(NULL),
+ m_device_image_load(device_image_load_delegate()),
+ m_device_image_unload(device_image_func_delegate())
{
}
@@ -68,8 +70,6 @@ void harddisk_image_device::device_config_complete()
// or initialize to defaults if none provided
else
{
- memset(&m_device_image_load, 0, sizeof(m_device_image_load));
- memset(&m_device_image_unload, 0, sizeof(m_device_image_unload));
memset(&m_interface, 0, sizeof(m_interface));
memset(&m_device_displayinfo, 0, sizeof(m_device_displayinfo));
}
@@ -118,7 +118,7 @@ bool harddisk_image_device::call_load()
our_result = internal_load_hd();
/* Check if there is an image_load callback defined */
- if ( m_device_image_load )
+ if (!m_device_image_load.isnull())
{
/* Let the override do some additional work/checks */
our_result = m_device_image_load(*this);
@@ -165,7 +165,7 @@ error:
void harddisk_image_device::call_unload()
{
/* Check if there is an image_unload callback defined */
- if ( m_device_image_unload )
+ if ( !m_device_image_unload.isnull() )
{
m_device_image_unload(*this);
}
diff --git a/src/emu/imagedev/harddriv.h b/src/emu/imagedev/harddriv.h
index c44e47bb802..1555caea912 100644
--- a/src/emu/imagedev/harddriv.h
+++ b/src/emu/imagedev/harddriv.h
@@ -19,8 +19,6 @@
struct harddisk_interface
{
- device_image_load_func m_device_image_load;
- device_image_unload_func m_device_image_unload;
const char * m_interface;
device_image_display_info_func m_device_displayinfo;
};
@@ -36,6 +34,9 @@ public:
harddisk_image_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
virtual ~harddisk_image_device();
+ void set_device_load(device_image_load_delegate _load) { m_device_image_load = _load; }
+ void set_device_unload(device_image_func_delegate _unload) { m_device_image_unload = _unload; }
+
// image-level overrides
virtual bool call_load();
virtual bool call_create(int create_format, option_resolution *create_args);
@@ -70,6 +71,9 @@ protected:
chd_file m_origchd; /* handle to the original CHD */
chd_file m_diffchd; /* handle to the diff CHD */
hard_disk_file *m_hard_disk_handle;
+
+ device_image_load_delegate m_device_image_load;
+ device_image_func_delegate m_device_image_unload;
};
// device type definition
@@ -84,4 +88,11 @@ extern const device_type HARDDISK;
#define MCFG_HARDDISK_CONFIG_ADD(_tag,_config) \
MCFG_DEVICE_ADD(_tag, HARDDISK, 0) \
MCFG_DEVICE_CONFIG(_config)
+
+#define MCFG_HARDDISK_LOAD(_class,_load) \
+ static_cast<harddisk_image_device *>(device)->set_device_load( DEVICE_IMAGE_LOAD_DELEGATE(_class,_load));
+
+#define MCFG_HARDDISK_UNLOAD(_class,_unload) \
+ static_cast<harddisk_image_device *>(device)->set_device_unload( DEVICE_IMAGE_UNLOAD_DELEGATE(_class,_unload));
+
#endif /* HARDDRIV_H */
diff --git a/src/emu/machine/corvushd.c b/src/emu/machine/corvushd.c
index 7bf5532c6f4..9884d963e20 100644
--- a/src/emu/machine/corvushd.c
+++ b/src/emu/machine/corvushd.c
@@ -70,7 +70,7 @@
const device_type CORVUS_HDC = &device_creator<corvus_hdc_t>;
-harddisk_interface corvus_hdc_t::hd_intf = { NULL, NULL, "corvus_hdd", NULL };
+harddisk_interface corvus_hdc_t::hd_intf = { "corvus_hdd", NULL };
corvus_hdc_t::corvus_hdc_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, CORVUS_HDC, "Corvus Flat Cable HDC", tag, owner, clock, "corvus_hdc", __FILE__),
diff --git a/src/emu/machine/nscsi_hd.c b/src/emu/machine/nscsi_hd.c
index 0ce6d6184f0..b13a624db55 100644
--- a/src/emu/machine/nscsi_hd.c
+++ b/src/emu/machine/nscsi_hd.c
@@ -33,7 +33,7 @@ void nscsi_harddisk_device::device_reset()
cur_lba = -1;
}
-harddisk_interface nscsi_harddisk_device::hd_intf = { NULL, NULL, "scsi_hdd", NULL };
+harddisk_interface nscsi_harddisk_device::hd_intf = { "scsi_hdd", NULL };
static MACHINE_CONFIG_FRAGMENT(scsi_harddisk)
MCFG_HARDDISK_CONFIG_ADD("image", nscsi_harddisk_device::hd_intf)
diff --git a/src/emu/machine/scsihd.c b/src/emu/machine/scsihd.c
index 29bdfc3dfd4..4454687ec27 100644
--- a/src/emu/machine/scsihd.c
+++ b/src/emu/machine/scsihd.c
@@ -28,7 +28,7 @@ void scsihd_device::device_start()
scsihle_device::device_start();
}
-harddisk_interface scsihd_device::hd_intf = { NULL, NULL, "scsi_hdd", NULL };
+harddisk_interface scsihd_device::hd_intf = { "scsi_hdd", NULL };
static MACHINE_CONFIG_FRAGMENT(scsi_harddisk)
MCFG_HARDDISK_CONFIG_ADD("image", scsihd_device::hd_intf)
diff --git a/src/mess/drivers/ti990_10.c b/src/mess/drivers/ti990_10.c
index d737f6de65c..6f9b90afaa0 100644
--- a/src/mess/drivers/ti990_10.c
+++ b/src/mess/drivers/ti990_10.c
@@ -71,7 +71,6 @@ TODO :
#include "cpu/tms9900/ti990_10.h"
#include "sound/beep.h"
-#include "machine/ti99/ti990.h"
#include "machine/ti99/990_hd.h"
#include "machine/ti99/990_tap.h"
#include "video/911_vdt.h"
@@ -82,46 +81,174 @@ class ti990_10_state : public driver_device
public:
ti990_10_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag) ,
- m_maincpu(*this, "maincpu") { }
+ m_maincpu(*this, "maincpu"),
+ m_intlines(0),
+ m_ckon_state(0) { }
device_t *m_terminal;
DECLARE_DRIVER_INIT(ti990_10);
- virtual void machine_start();
virtual void machine_reset();
virtual void video_start();
DECLARE_WRITE_LINE_MEMBER( key_interrupt );
DECLARE_WRITE_LINE_MEMBER( line_interrupt );
DECLARE_WRITE_LINE_MEMBER( tape_interrupt );
+ void ti990_set_int_line(int line, int state);
+ WRITE_LINE_MEMBER(ti990_set_int13);
+ TIMER_CALLBACK_MEMBER(clear_load);
+ void ti990_hold_load();
+ WRITE_LINE_MEMBER(ti990_ckon_ckof_callback);
+ READ8_MEMBER( ti990_panel_read );
+ WRITE8_MEMBER( ti990_panel_write );
required_device<cpu_device> m_maincpu;
+ UINT16 m_intlines;
+ int m_ckon_state;
};
-void ti990_10_state::machine_start()
+/*
+ Interrupt priority encoder. Actually part of the CPU board.
+*/
+
+void ti990_10_state::ti990_set_int_line(int line, int state)
+{
+ int level;
+
+
+ if (state)
+ m_intlines |= (1 << line);
+ else
+ m_intlines &= ~ (1 << line);
+
+ if (m_intlines)
+ {
+ for (level = 0; ! (m_intlines & (1 << level)); level++)
+ ;
+ m_maincpu->set_input_line_and_vector(0, ASSERT_LINE, level); /* interrupt it, baby */
+ }
+ else
+ m_maincpu->set_input_line(0, CLEAR_LINE);
+}
+
+
+WRITE_LINE_MEMBER(ti990_10_state::ti990_set_int13)
{
- MACHINE_START_CALL_LEGACY( ti990_hdc );
+ ti990_set_int_line(13, state);
}
+/*
+ hold and debounce load line (emulation is inaccurate)
+*/
+
+TIMER_CALLBACK_MEMBER(ti990_10_state::clear_load)
+{
+ m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
+}
+
+void ti990_10_state::ti990_hold_load()
+{
+ m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
+ machine().scheduler().timer_set(attotime::from_msec(100), timer_expired_delegate(FUNC(ti990_10_state::clear_load),this));
+}
+
+/*
+ line interrupt
+*/
+
+/* m_ckon_state: 1 if line clock active (RTCLR flip-flop on TI990/10 schematics -
+SMI sheet 4) */
+WRITE_LINE_MEMBER(ti990_10_state::line_interrupt)
+{
+ // set_int10(state);
+ if (m_ckon_state)
+ ti990_set_int_line(5, 1);
+}
+
+WRITE_LINE_MEMBER(ti990_10_state::ti990_ckon_ckof_callback)
+{
+ m_ckon_state = state;
+ if (! m_ckon_state)
+ ti990_set_int_line(5, 0);
+}
+
+
+
+/*
+ Control panel emulation
+
+ three panel types
+ * operator panel
+ * programmer panel
+ * MDU (external unit connected instead of the control panel, as seen in
+ 945401-9701 p. 2-5 though 2-15)
+
+ Operator panel:
+ * Power led
+ * Fault led
+ * Off/On/Load switch
+
+ Programmer panel:
+ * 16 status light, 32 switches, IDLE, RUN leds
+ * interface to a low-level debugger in ROMs
+
+ * MDU:
+ * includes a programmer panel, a tape unit, and a few parts
+ (diagnostic tape, diagnostic ROMs, etc.)
+
+ CRU output:
+ 0-7: lights 0-7
+ 8: increment scan
+ 9: clear scan (according to 990 handbook)
+ A: run light (additionally sets all data LEDs to 1s, the scan count to 0b10 and enables the HALT/SIE switch)
+ B: fault light
+ C: Memory Error Interrupt clear
+ D: Start panel timer
+ E: Set SIE function (interrupt after 2 instructions are executed)
+ F: flag (according to 990 handbook)
+
+ input :
+ 0-7: switches 0-7 (or data from MDU tape)
+ 8: scan count bit 1
+ 9: scan count bit 0
+ A: timer active
+ B: programmer panel not present or locked
+ C: char in MDU tape unit buffer?
+ D: unused?
+ E: if 0, MDU unit present
+ F: flag (according to 990 handbook)
+*/
+
+READ8_MEMBER( ti990_10_state::ti990_panel_read )
+{
+ if (offset == 1)
+ return 0x48;
+
+ return 0;
+}
+
+WRITE8_MEMBER( ti990_10_state::ti990_panel_write )
+{
+}
+
+
void ti990_10_state::machine_reset()
{
- ti990_hold_load(machine());
- ti990_reset_int();
- ti990_hdc_init(machine(), ti990_set_int13);
+ ti990_hold_load();
}
/*
-static void rset_callback(device_t *device)
+void ti990_10_state::rset_callback)
{
ti990_cpuboard_reset();
// clear controller panel and smi fault LEDs
}
-static void lrex_callback(device_t *device)
+void ti990_10_state::lrex_callback)
{
// right???
- ti990_hold_load(device->machine());
+ ti990_hold_load();
}
*/
@@ -141,12 +268,6 @@ WRITE_LINE_MEMBER(ti990_10_state::key_interrupt)
// set_int10(state);
}
-WRITE_LINE_MEMBER(ti990_10_state::line_interrupt)
-{
- // set_int10(state);
- ti990_line_interrupt(machine());
-}
-
/*
Memory map - see description above
*/
@@ -155,7 +276,7 @@ static ADDRESS_MAP_START(ti990_10_memmap, AS_PROGRAM, 16, ti990_10_state )
AM_RANGE(0x000000, 0x0fffff) AM_RAM /* let's say we have 1MB of RAM */
AM_RANGE(0x100000, 0x1ff7ff) AM_NOP /* free TILINE space */
- AM_RANGE(0x1ff800, 0x1ff81f) AM_READWRITE_LEGACY(ti990_hdc_r, ti990_hdc_w) /* disk controller TPCS */
+ AM_RANGE(0x1ff800, 0x1ff81f) AM_DEVREADWRITE("hdc", ti990_hdc_device, read, write) /* disk controller TPCS */
AM_RANGE(0x1ff820, 0x1ff87f) AM_NOP /* free TPCS */
AM_RANGE(0x1ff880, 0x1ff89f) AM_DEVREADWRITE("tpc", tap_990_device, read, write) /* tape controller TPCS */
AM_RANGE(0x1ff8a0, 0x1ffbff) AM_NOP /* free TPCS */
@@ -171,12 +292,12 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START(ti990_10_io, AS_IO, 8, ti990_10_state )
AM_RANGE(0x10, 0x11) AM_DEVREAD("vdt911", vdt911_device, cru_r)
AM_RANGE(0x80, 0x8f) AM_DEVWRITE("vdt911", vdt911_device, cru_w)
- AM_RANGE(0x1fa, 0x1fb) AM_NOP // AM_READ_LEGACY(ti990_10_mapper_cru_r)
- AM_RANGE(0x1fc, 0x1fd) AM_NOP // AM_READ_LEGACY(ti990_10_eir_cru_r)
- AM_RANGE(0x1fe, 0x1ff) AM_READ_LEGACY(ti990_panel_read)
- AM_RANGE(0xfd0, 0xfdf) AM_NOP // AM_WRITE_LEGACY(ti990_10_mapper_cru_w)
- AM_RANGE(0xfe0, 0xfef) AM_NOP // AM_WRITE_LEGACY(ti990_10_eir_cru_w)
- AM_RANGE(0xff0, 0xfff) AM_WRITE_LEGACY(ti990_panel_write)
+ AM_RANGE(0x1fa, 0x1fb) AM_NOP // AM_READ(ti990_10_mapper_cru_r)
+ AM_RANGE(0x1fc, 0x1fd) AM_NOP // AM_READ(ti990_10_eir_cru_r)
+ AM_RANGE(0x1fe, 0x1ff) AM_READ(ti990_panel_read)
+ AM_RANGE(0xfd0, 0xfdf) AM_NOP // AM_WRITE(ti990_10_mapper_cru_w)
+ AM_RANGE(0xfe0, 0xfef) AM_NOP // AM_WRITE(ti990_10_eir_cru_w)
+ AM_RANGE(0xff0, 0xfff) AM_WRITE(ti990_panel_write)
ADDRESS_MAP_END
@@ -199,7 +320,8 @@ static MACHINE_CONFIG_START( ti990_10, ti990_10_state )
MCFG_VDT911_LINEINT_HANDLER(WRITELINE(ti990_10_state, line_interrupt))
// Hard disk
- MCFG_FRAGMENT_ADD( ti990_hdc )
+ MCFG_DEVICE_ADD("hdc", TI990_HDC, 0)
+ MCFG_TI990_HDC_INT_CALLBACK(WRITELINE(ti990_10_state, ti990_set_int13))
// Tape controller
MCFG_DEVICE_ADD("tpc", TI990_TAPE_CTRL, 0)
diff --git a/src/mess/includes/next.h b/src/mess/includes/next.h
index 3b212a9aafb..911d906d53c 100644
--- a/src/mess/includes/next.h
+++ b/src/mess/includes/next.h
@@ -115,7 +115,6 @@ public:
DECLARE_FLOPPY_FORMATS( floppy_formats );
static const cdrom_interface cdrom_intf;
- static const harddisk_interface harddisk_intf;
protected:
struct dma_slot {
diff --git a/src/mess/machine/ti99/990_hd.c b/src/mess/machine/ti99/990_hd.c
index e88323f5395..86e319bf66d 100644
--- a/src/mess/machine/ti99/990_hd.c
+++ b/src/mess/machine/ti99/990_hd.c
@@ -23,12 +23,6 @@
#include "harddisk.h"
#include "imagedev/harddriv.h"
-static void update_interrupt(running_machine &machine);
-
-/* max disk units per controller: 4 is the protocol limit, but it may be
-overriden if more than one controller is used */
-#define MAX_DISK_UNIT 4
-
/* Max sector length is bytes. Generally 256, except for a few older disk
units which use 288-byte-long sectors, and SCSI units which generally use
standard 512-byte-long sectors. */
@@ -74,34 +68,6 @@ enum
header_len = sizeof(disk_image_header)
};
-enum format_t
-{
- format_mame,
- format_old
-};
-
-/* disk drive unit descriptor */
-struct hd_unit_t
-{
- device_image_interface *img; /* image descriptor */
- format_t format;
- hard_disk_file *hd_handle; /* mame hard disk descriptor - only if format == format_mame */
- unsigned int wp : 1; /* TRUE if disk is write-protected */
- unsigned int unsafe : 1; /* TRUE when a disk has just been connected */
-
- /* disk geometry */
- unsigned int cylinders, heads, sectors_per_track, bytes_per_sector;
-};
-
-/* disk controller */
-struct hdc_t
-{
- UINT16 w[8];
-
- void (*interrupt_callback)(running_machine &machine, int state);
-
- hd_unit_t d[MAX_DISK_UNIT];
-};
/* masks for individual bits controller registers */
enum
@@ -164,10 +130,8 @@ static const UINT16 w_mask[8] =
0xf7ff /* Don't overwrite reserved bits */
};
-static hdc_t hdc;
-
-static int get_id_from_device( device_t *device )
+int ti990_hdc_device::get_id_from_device( device_t *device )
{
int id = -1;
@@ -196,13 +160,13 @@ static int get_id_from_device( device_t *device )
/*
Initialize hard disk unit and open a hard disk image
*/
-static DEVICE_IMAGE_LOAD_LEGACY( ti990_hd )
+DEVICE_IMAGE_LOAD_MEMBER( ti990_hdc_device, ti990_hd )
{
int id = get_id_from_device( &image.device() );
hd_unit_t *d;
hard_disk_file *hd_file;
- d = &hdc.d[id];
+ d = &m_d[id];
d->img = &image;
hd_file = dynamic_cast<harddisk_image_device *>(&image)->get_hard_disk_file();
@@ -265,7 +229,7 @@ static DEVICE_IMAGE_LOAD_LEGACY( ti990_hd )
d->unsafe = 1;
/* set attention line */
- hdc.w[0] |= (0x80 >> id);
+ m_w[0] |= (0x80 >> id);
return IMAGE_INIT_PASS;
}
@@ -273,12 +237,12 @@ static DEVICE_IMAGE_LOAD_LEGACY( ti990_hd )
/*
close a hard disk image
*/
-static DEVICE_IMAGE_UNLOAD_LEGACY( ti990_hd )
+DEVICE_IMAGE_UNLOAD_MEMBER( ti990_hdc_device, ti990_hd )
{
int id = get_id_from_device( image );
hd_unit_t *d;
- d = &hdc.d[id];
+ d = &m_d[id];
d->format = format_mame; /* don't care */
d->hd_handle = NULL;
@@ -286,24 +250,24 @@ static DEVICE_IMAGE_UNLOAD_LEGACY( ti990_hd )
d->unsafe = 1;
/* clear attention line */
- hdc.w[0] &= ~ (0x80 >> id);
+ m_w[0] &= ~ (0x80 >> id);
}
/*
Return true if a HD image has been loaded
*/
-INLINE int is_unit_loaded(int unit)
+int ti990_hdc_device::is_unit_loaded(int unit)
{
int reply = 0;
- switch (hdc.d[unit].format)
+ switch (m_d[unit].format)
{
case format_mame:
- reply = (hdc.d[unit].hd_handle != NULL);
+ reply = (m_d[unit].hd_handle != NULL);
break;
case format_old:
- reply = (hdc.d[unit].img->exists() ? 1 : 0);
+ reply = (m_d[unit].img->exists() ? 1 : 0);
break;
}
@@ -311,57 +275,21 @@ INLINE int is_unit_loaded(int unit)
}
/*
- Init the hdc core
-*/
-MACHINE_START(ti990_hdc)
-{
- int i;
-
- /* initialize harddisk information */
- /* attention lines will be set by DEVICE_IMAGE_LOD */
- for (i=0; i<MAX_DISK_UNIT; i++)
- {
- hdc.d[i].format = format_mame;
- hdc.d[i].hd_handle = NULL;
- hdc.d[i].wp = 1;
- hdc.d[i].unsafe = 1;
- }
-}
-
-
-void ti990_hdc_init(running_machine &machine, void (*interrupt_callback)(running_machine &machine, int state))
-{
- memset(hdc.w, 0, sizeof(hdc.w));
- hdc.w[7] = w7_idle;
-
- /* get references to harddisk devices */
- hdc.d[0].img = dynamic_cast<device_image_interface *>(machine.device("harddisk1"));
- hdc.d[1].img = dynamic_cast<device_image_interface *>(machine.device("harddisk2"));
- hdc.d[2].img = dynamic_cast<device_image_interface *>(machine.device("harddisk3"));
- hdc.d[3].img = dynamic_cast<device_image_interface *>(machine.device("harddisk4"));
-
- hdc.interrupt_callback = interrupt_callback;
-
- update_interrupt(machine);
-}
-
-
-/*
Parse the disk select lines, and return the corresponding tape unit.
(-1 if none)
*/
-static int cur_disk_unit(void)
+int ti990_hdc_device::cur_disk_unit(void)
{
int reply;
- if (hdc.w[6] & w6_unit0_sel)
+ if (m_w[6] & w6_unit0_sel)
reply = 0;
- else if (hdc.w[6] & w6_unit1_sel)
+ else if (m_w[6] & w6_unit1_sel)
reply = 1;
- else if (hdc.w[6] & w6_unit2_sel)
+ else if (m_w[6] & w6_unit2_sel)
reply = 2;
- else if (hdc.w[6] & w6_unit3_sel)
+ else if (m_w[6] & w6_unit3_sel)
reply = 3;
else
reply = -1;
@@ -375,12 +303,12 @@ static int cur_disk_unit(void)
/*
Update interrupt state
*/
-static void update_interrupt(running_machine &machine)
+void ti990_hdc_device::update_interrupt()
{
- if (hdc.interrupt_callback)
- (*hdc.interrupt_callback)(machine, (hdc.w[7] & w7_idle)
- && (((hdc.w[7] & w7_int_enable) && (hdc.w[7] & (w7_complete | w7_error)))
- || ((hdc.w[0] & (hdc.w[0] >> 4)) & w0_attn_mask)));
+ if (!m_interrupt_callback.isnull())
+ m_interrupt_callback((m_w[7] & w7_idle)
+ && (((m_w[7] & w7_int_enable) && (m_w[7] & (w7_complete | w7_error)))
+ || ((m_w[0] & (m_w[0] >> 4)) & w0_attn_mask)));
}
/*
@@ -388,23 +316,23 @@ static void update_interrupt(running_machine &machine)
Terminate current command and return non-zero if the address is invalid.
*/
-static int check_sector_address(running_machine &machine, int unit, unsigned int cylinder, unsigned int head, unsigned int sector)
+int ti990_hdc_device::check_sector_address(int unit, unsigned int cylinder, unsigned int head, unsigned int sector)
{
- if ((cylinder > hdc.d[unit].cylinders) || (head > hdc.d[unit].heads) || (sector > hdc.d[unit].sectors_per_track))
+ if ((cylinder > m_d[unit].cylinders) || (head > m_d[unit].heads) || (sector > m_d[unit].sectors_per_track))
{ /* invalid address */
- if (cylinder > hdc.d[unit].cylinders)
+ if (cylinder > m_d[unit].cylinders)
{
- hdc.w[0] |= w0_seek_incomplete;
- hdc.w[7] |= w7_idle | w7_error | w7_unit_err;
+ m_w[0] |= w0_seek_incomplete;
+ m_w[7] |= w7_idle | w7_error | w7_unit_err;
}
- else if (head > hdc.d[unit].heads)
+ else if (head > m_d[unit].heads)
{
- hdc.w[0] |= w0_end_of_cylinder;
- hdc.w[7] |= w7_idle | w7_error | w7_unit_err;
+ m_w[0] |= w0_end_of_cylinder;
+ m_w[7] |= w7_idle | w7_error | w7_unit_err;
}
- else if (sector > hdc.d[unit].sectors_per_track)
- hdc.w[7] |= w7_idle | w7_error | w7_command_time_out_err;
- update_interrupt(machine);
+ else if (sector > m_d[unit].sectors_per_track)
+ m_w[7] |= w7_idle | w7_error | w7_command_time_out_err;
+ update_interrupt();
return 1;
}
@@ -414,12 +342,12 @@ static int check_sector_address(running_machine &machine, int unit, unsigned int
/*
Seek to sector whose address is given
*/
-static int sector_to_lba(running_machine &machine, int unit, unsigned int cylinder, unsigned int head, unsigned int sector, unsigned int *lba)
+int ti990_hdc_device::sector_to_lba(int unit, unsigned int cylinder, unsigned int head, unsigned int sector, unsigned int *lba)
{
- if (check_sector_address(machine, unit, cylinder, head, sector))
+ if (check_sector_address(unit, cylinder, head, sector))
return 1;
- * lba = (cylinder*hdc.d[unit].heads + head)*hdc.d[unit].sectors_per_track + sector;
+ * lba = (cylinder*m_d[unit].heads + head)*m_d[unit].sectors_per_track + sector;
return 0;
}
@@ -427,23 +355,23 @@ static int sector_to_lba(running_machine &machine, int unit, unsigned int cylind
/*
Read one given sector
*/
-static int read_sector(int unit, unsigned int lba, void *buffer, unsigned int bytes_to_read)
+int ti990_hdc_device::read_sector(int unit, unsigned int lba, void *buffer, unsigned int bytes_to_read)
{
unsigned long byte_position;
unsigned int bytes_read;
- switch (hdc.d[unit].format)
+ switch (m_d[unit].format)
{
case format_mame:
- bytes_read = hdc.d[unit].bytes_per_sector * hard_disk_read(hdc.d[unit].hd_handle, lba, buffer);
+ bytes_read = m_d[unit].bytes_per_sector * hard_disk_read(m_d[unit].hd_handle, lba, buffer);
if (bytes_read > bytes_to_read)
bytes_read = bytes_to_read;
break;
case format_old:
- byte_position = lba*hdc.d[unit].bytes_per_sector + header_len;
- hdc.d[unit].img->fseek(byte_position, SEEK_SET);
- bytes_read = hdc.d[unit].img->fread(buffer, bytes_to_read);
+ byte_position = lba*m_d[unit].bytes_per_sector + header_len;
+ m_d[unit].img->fseek(byte_position, SEEK_SET);
+ bytes_read = m_d[unit].img->fread(buffer, bytes_to_read);
break;
default:
@@ -457,23 +385,23 @@ static int read_sector(int unit, unsigned int lba, void *buffer, unsigned int by
/*
Write one given sector
*/
-static int write_sector(int unit, unsigned int lba, const void *buffer, unsigned int bytes_to_write)
+int ti990_hdc_device::write_sector(int unit, unsigned int lba, const void *buffer, unsigned int bytes_to_write)
{
unsigned long byte_position;
unsigned int bytes_written;
- switch (hdc.d[unit].format)
+ switch (m_d[unit].format)
{
case format_mame:
- bytes_written = hdc.d[unit].bytes_per_sector * hard_disk_write(hdc.d[unit].hd_handle, lba, buffer);
+ bytes_written = m_d[unit].bytes_per_sector * hard_disk_write(m_d[unit].hd_handle, lba, buffer);
if (bytes_written > bytes_to_write)
bytes_written = bytes_to_write;
break;
case format_old:
- byte_position = lba*hdc.d[unit].bytes_per_sector + header_len;
- hdc.d[unit].img->fseek(byte_position, SEEK_SET);
- bytes_written = hdc.d[unit].img->fwrite(buffer, bytes_to_write);
+ byte_position = lba*m_d[unit].bytes_per_sector + header_len;
+ m_d[unit].img->fseek(byte_position, SEEK_SET);
+ bytes_written = m_d[unit].img->fwrite(buffer, bytes_to_write);
break;
default:
@@ -487,7 +415,7 @@ static int write_sector(int unit, unsigned int lba, const void *buffer, unsigned
/*
Handle the store registers command: read the drive geometry.
*/
-static void store_registers(running_machine &machine)
+void ti990_hdc_device::store_registers()
{
int dma_address;
int byte_count;
@@ -501,44 +429,44 @@ static void store_registers(running_machine &machine)
if (dsk_sel == -1)
{
/* No idea what to report... */
- hdc.w[7] |= w7_idle | w7_error | w7_abnormal_completion;
- update_interrupt(machine);
+ m_w[7] |= w7_idle | w7_error | w7_abnormal_completion;
+ update_interrupt();
return;
}
else if (! is_unit_loaded(dsk_sel))
{ /* offline */
- hdc.w[0] |= w0_offline | w0_not_ready;
- hdc.w[7] |= w7_idle | w7_error | w7_unit_err;
- update_interrupt(machine);
+ m_w[0] |= w0_offline | w0_not_ready;
+ m_w[7] |= w7_idle | w7_error | w7_unit_err;
+ update_interrupt();
return;
}
- hdc.d[dsk_sel].unsafe = 0; /* I think */
+ m_d[dsk_sel].unsafe = 0; /* I think */
- dma_address = ((((int) hdc.w[6]) << 16) | hdc.w[5]) & 0x1ffffe;
- byte_count = hdc.w[4] & 0xfffe;
+ dma_address = ((((int) m_w[6]) << 16) | m_w[5]) & 0x1ffffe;
+ byte_count = m_w[4] & 0xfffe;
/* formatted words per track */
- buffer[0] = (hdc.d[dsk_sel].sectors_per_track*hdc.d[dsk_sel].bytes_per_sector) >> 1;
+ buffer[0] = (m_d[dsk_sel].sectors_per_track*m_d[dsk_sel].bytes_per_sector) >> 1;
/* MSByte: sectors per track; LSByte: bytes of overhead per sector */
- buffer[1] = (hdc.d[dsk_sel].sectors_per_track << 8) | 0;
+ buffer[1] = (m_d[dsk_sel].sectors_per_track << 8) | 0;
/* bits 0-4: heads; bits 5-15: cylinders */
- buffer[2] = (hdc.d[dsk_sel].heads << 11) | hdc.d[dsk_sel].cylinders;
+ buffer[2] = (m_d[dsk_sel].heads << 11) | m_d[dsk_sel].cylinders;
real_word_count = byte_count >> 1;
if (real_word_count > 3)
real_word_count = 3;
/* DMA */
- if (! (hdc.w[1] & w1_transfer_inhibit))
+ if (! (m_w[1] & w1_transfer_inhibit))
for (i=0; i<real_word_count; i++)
{
- machine.device("maincpu")->memory().space(AS_PROGRAM).write_word(dma_address, buffer[i]);
+ machine().device("maincpu")->memory().space(AS_PROGRAM).write_word(dma_address, buffer[i]);
dma_address = (dma_address + 2) & 0x1ffffe;
}
- hdc.w[7] |= w7_idle | w7_complete;
- update_interrupt(machine);
+ m_w[7] |= w7_idle | w7_complete;
+ update_interrupt();
}
/*
@@ -546,7 +474,7 @@ static void store_registers(running_machine &machine)
The emulation just clears the track data in the disk image.
*/
-static void write_format(running_machine &machine)
+void ti990_hdc_device::write_format()
{
unsigned int cylinder, head, sector;
unsigned int lba;
@@ -560,63 +488,63 @@ static void write_format(running_machine &machine)
if (dsk_sel == -1)
{
/* No idea what to report... */
- hdc.w[7] |= w7_idle | w7_error | w7_abnormal_completion;
- update_interrupt(machine);
+ m_w[7] |= w7_idle | w7_error | w7_abnormal_completion;
+ update_interrupt();
return;
}
else if (! is_unit_loaded(dsk_sel))
{ /* offline */
- hdc.w[0] |= w0_offline | w0_not_ready;
- hdc.w[7] |= w7_idle | w7_error | w7_unit_err;
- update_interrupt(machine);
+ m_w[0] |= w0_offline | w0_not_ready;
+ m_w[7] |= w7_idle | w7_error | w7_unit_err;
+ update_interrupt();
return;
}
- else if (hdc.d[dsk_sel].unsafe)
+ else if (m_d[dsk_sel].unsafe)
{ /* disk in unsafe condition */
- hdc.w[0] |= w0_unsafe | w0_pack_change;
- hdc.w[7] |= w7_idle | w7_error | w7_unit_err;
- update_interrupt(machine);
+ m_w[0] |= w0_unsafe | w0_pack_change;
+ m_w[7] |= w7_idle | w7_error | w7_unit_err;
+ update_interrupt();
return;
}
- else if (hdc.d[dsk_sel].wp)
+ else if (m_d[dsk_sel].wp)
{ /* disk write-protected */
- hdc.w[0] |= w0_write_protect;
- hdc.w[7] |= w7_idle | w7_error | w7_unit_err;
- update_interrupt(machine);
+ m_w[0] |= w0_write_protect;
+ m_w[7] |= w7_idle | w7_error | w7_unit_err;
+ update_interrupt();
return;
}
- cylinder = hdc.w[3];
- head = hdc.w[1] & w1_head_address;
+ cylinder = m_w[3];
+ head = m_w[1] & w1_head_address;
- if (sector_to_lba(machine, dsk_sel, cylinder, head, 0, &lba))
+ if (sector_to_lba(dsk_sel, cylinder, head, 0, &lba))
return;
- memset(buffer, 0, hdc.d[dsk_sel].bytes_per_sector);
+ memset(buffer, 0, m_d[dsk_sel].bytes_per_sector);
- for (sector=0; sector<hdc.d[dsk_sel].sectors_per_track; sector++)
+ for (sector=0; sector<m_d[dsk_sel].sectors_per_track; sector++)
{
- bytes_written = write_sector(dsk_sel, lba, buffer, hdc.d[dsk_sel].bytes_per_sector);
+ bytes_written = write_sector(dsk_sel, lba, buffer, m_d[dsk_sel].bytes_per_sector);
- if (bytes_written != hdc.d[dsk_sel].bytes_per_sector)
+ if (bytes_written != m_d[dsk_sel].bytes_per_sector)
{
- hdc.w[0] |= w0_offline | w0_not_ready;
- hdc.w[7] |= w7_idle | w7_error | w7_unit_err;
- update_interrupt(machine);
+ m_w[0] |= w0_offline | w0_not_ready;
+ m_w[7] |= w7_idle | w7_error | w7_unit_err;
+ update_interrupt();
return;
}
lba++;
}
- hdc.w[7] |= w7_idle | w7_complete;
- update_interrupt(machine);
+ m_w[7] |= w7_idle | w7_complete;
+ update_interrupt();
}
/*
Handle the read data command: read a variable number of sectors from disk.
*/
-static void read_data(running_machine &machine)
+void ti990_hdc_device::read_data()
{
int dma_address;
int byte_count;
@@ -635,60 +563,60 @@ static void read_data(running_machine &machine)
if (dsk_sel == -1)
{
/* No idea what to report... */
- hdc.w[7] |= w7_idle | w7_error | w7_abnormal_completion;
- update_interrupt(machine);
+ m_w[7] |= w7_idle | w7_error | w7_abnormal_completion;
+ update_interrupt();
return;
}
else if (! is_unit_loaded(dsk_sel))
{ /* offline */
- hdc.w[0] |= w0_offline | w0_not_ready;
- hdc.w[7] |= w7_idle | w7_error | w7_unit_err;
- update_interrupt(machine);
+ m_w[0] |= w0_offline | w0_not_ready;
+ m_w[7] |= w7_idle | w7_error | w7_unit_err;
+ update_interrupt();
return;
}
- else if (hdc.d[dsk_sel].unsafe)
+ else if (m_d[dsk_sel].unsafe)
{ /* disk in unsafe condition */
- hdc.w[0] |= w0_unsafe | w0_pack_change;
- hdc.w[7] |= w7_idle | w7_error | w7_unit_err;
- update_interrupt(machine);
+ m_w[0] |= w0_unsafe | w0_pack_change;
+ m_w[7] |= w7_idle | w7_error | w7_unit_err;
+ update_interrupt();
return;
}
- dma_address = ((((int) hdc.w[6]) << 16) | hdc.w[5]) & 0x1ffffe;
- byte_count = hdc.w[4] & 0xfffe;
+ dma_address = ((((int) m_w[6]) << 16) | m_w[5]) & 0x1ffffe;
+ byte_count = m_w[4] & 0xfffe;
- cylinder = hdc.w[3];
- head = hdc.w[1] & w1_head_address;
- sector = hdc.w[2] & 0xff;
+ cylinder = m_w[3];
+ head = m_w[1] & w1_head_address;
+ sector = m_w[2] & 0xff;
- if (sector_to_lba(machine, dsk_sel, cylinder, head, sector, &lba))
+ if (sector_to_lba(dsk_sel, cylinder, head, sector, &lba))
return;
while (byte_count)
{ /* read data sector per sector */
- if (cylinder > hdc.d[dsk_sel].cylinders)
+ if (cylinder > m_d[dsk_sel].cylinders)
{
- hdc.w[0] |= w0_seek_incomplete;
- hdc.w[7] |= w7_idle | w7_error | w7_unit_err;
- update_interrupt(machine);
+ m_w[0] |= w0_seek_incomplete;
+ m_w[7] |= w7_idle | w7_error | w7_unit_err;
+ update_interrupt();
return;
}
- bytes_to_read = (byte_count < hdc.d[dsk_sel].bytes_per_sector) ? byte_count : hdc.d[dsk_sel].bytes_per_sector;
+ bytes_to_read = (byte_count < m_d[dsk_sel].bytes_per_sector) ? byte_count : m_d[dsk_sel].bytes_per_sector;
bytes_read = read_sector(dsk_sel, lba, buffer, bytes_to_read);
if (bytes_read != bytes_to_read)
{ /* behave as if the controller could not found the sector ID mark */
- hdc.w[7] |= w7_idle | w7_error | w7_command_time_out_err;
- update_interrupt(machine);
+ m_w[7] |= w7_idle | w7_error | w7_command_time_out_err;
+ update_interrupt();
return;
}
/* DMA */
- if (! (hdc.w[1] & w1_transfer_inhibit))
+ if (! (m_w[1] & w1_transfer_inhibit))
for (i=0; i<bytes_read; i+=2)
{
- machine.device("maincpu")->memory().space(AS_PROGRAM).write_word(dma_address, (((int) buffer[i]) << 8) | buffer[i+1]);
+ machine().device("maincpu")->memory().space(AS_PROGRAM).write_word(dma_address, (((int) buffer[i]) << 8) | buffer[i+1]);
dma_address = (dma_address + 2) & 0x1ffffe;
}
@@ -697,11 +625,11 @@ static void read_data(running_machine &machine)
/* update sector address to point to next sector */
lba++;
sector++;
- if (sector == hdc.d[dsk_sel].sectors_per_track)
+ if (sector == m_d[dsk_sel].sectors_per_track)
{
sector = 0;
head++;
- if (head == hdc.d[dsk_sel].heads)
+ if (head == m_d[dsk_sel].heads)
{
head = 0;
cylinder++;
@@ -709,14 +637,14 @@ static void read_data(running_machine &machine)
}
}
- hdc.w[7] |= w7_idle | w7_complete;
- update_interrupt(machine);
+ m_w[7] |= w7_idle | w7_complete;
+ update_interrupt();
}
/*
Handle the write data command: write a variable number of sectors from disk.
*/
-static void write_data(running_machine &machine)
+void ti990_hdc_device::write_data()
{
int dma_address;
int byte_count;
@@ -735,72 +663,72 @@ static void write_data(running_machine &machine)
if (dsk_sel == -1)
{
/* No idea what to report... */
- hdc.w[7] |= w7_idle | w7_error | w7_abnormal_completion;
- update_interrupt(machine);
+ m_w[7] |= w7_idle | w7_error | w7_abnormal_completion;
+ update_interrupt();
return;
}
else if (! is_unit_loaded(dsk_sel))
{ /* offline */
- hdc.w[0] |= w0_offline | w0_not_ready;
- hdc.w[7] |= w7_idle | w7_error | w7_unit_err;
- update_interrupt(machine);
+ m_w[0] |= w0_offline | w0_not_ready;
+ m_w[7] |= w7_idle | w7_error | w7_unit_err;
+ update_interrupt();
return;
}
- else if (hdc.d[dsk_sel].unsafe)
+ else if (m_d[dsk_sel].unsafe)
{ /* disk in unsafe condition */
- hdc.w[0] |= w0_unsafe | w0_pack_change;
- hdc.w[7] |= w7_idle | w7_error | w7_unit_err;
- update_interrupt(machine);
+ m_w[0] |= w0_unsafe | w0_pack_change;
+ m_w[7] |= w7_idle | w7_error | w7_unit_err;
+ update_interrupt();
return;
}
- else if (hdc.d[dsk_sel].wp)
+ else if (m_d[dsk_sel].wp)
{ /* disk write-protected */
- hdc.w[0] |= w0_write_protect;
- hdc.w[7] |= w7_idle | w7_error | w7_unit_err;
- update_interrupt(machine);
+ m_w[0] |= w0_write_protect;
+ m_w[7] |= w7_idle | w7_error | w7_unit_err;
+ update_interrupt();
return;
}
- dma_address = ((((int) hdc.w[6]) << 16) | hdc.w[5]) & 0x1ffffe;
- byte_count = hdc.w[4] & 0xfffe;
+ dma_address = ((((int) m_w[6]) << 16) | m_w[5]) & 0x1ffffe;
+ byte_count = m_w[4] & 0xfffe;
- cylinder = hdc.w[3];
- head = hdc.w[1] & w1_head_address;
- sector = hdc.w[2] & 0xff;
+ cylinder = m_w[3];
+ head = m_w[1] & w1_head_address;
+ sector = m_w[2] & 0xff;
- if (sector_to_lba(machine, dsk_sel, cylinder, head, sector, &lba))
+ if (sector_to_lba(dsk_sel, cylinder, head, sector, &lba))
return;
while (byte_count > 0)
{ /* write data sector per sector */
- if (cylinder > hdc.d[dsk_sel].cylinders)
+ if (cylinder > m_d[dsk_sel].cylinders)
{
- hdc.w[0] |= w0_seek_incomplete;
- hdc.w[7] |= w7_idle | w7_error | w7_unit_err;
- update_interrupt(machine);
+ m_w[0] |= w0_seek_incomplete;
+ m_w[7] |= w7_idle | w7_error | w7_unit_err;
+ update_interrupt();
return;
}
/* DMA */
- for (i=0; (i<byte_count) && (i<hdc.d[dsk_sel].bytes_per_sector); i+=2)
+ for (i=0; (i<byte_count) && (i<m_d[dsk_sel].bytes_per_sector); i+=2)
{
- word = machine.device("maincpu")->memory().space(AS_PROGRAM).read_word(dma_address);
+ word = machine().device("maincpu")->memory().space(AS_PROGRAM).read_word(dma_address);
buffer[i] = word >> 8;
buffer[i+1] = word & 0xff;
dma_address = (dma_address + 2) & 0x1ffffe;
}
/* fill with 0s if we did not reach sector end */
- for (; i<hdc.d[dsk_sel].bytes_per_sector; i+=2)
+ for (; i<m_d[dsk_sel].bytes_per_sector; i+=2)
buffer[i] = buffer[i+1] = 0;
- bytes_written = write_sector(dsk_sel, lba, buffer, hdc.d[dsk_sel].bytes_per_sector);
+ bytes_written = write_sector(dsk_sel, lba, buffer, m_d[dsk_sel].bytes_per_sector);
- if (bytes_written != hdc.d[dsk_sel].bytes_per_sector)
+ if (bytes_written != m_d[dsk_sel].bytes_per_sector)
{
- hdc.w[0] |= w0_offline | w0_not_ready;
- hdc.w[7] |= w7_idle | w7_error | w7_unit_err;
- update_interrupt(machine);
+ m_w[0] |= w0_offline | w0_not_ready;
+ m_w[7] |= w7_idle | w7_error | w7_unit_err;
+ update_interrupt();
return;
}
@@ -809,11 +737,11 @@ static void write_data(running_machine &machine)
/* update sector address to point to next sector */
lba++;
sector++;
- if (sector == hdc.d[dsk_sel].sectors_per_track)
+ if (sector == m_d[dsk_sel].sectors_per_track)
{
sector = 0;
head++;
- if (head == hdc.d[dsk_sel].heads)
+ if (head == m_d[dsk_sel].heads)
{
head = 0;
cylinder++;
@@ -821,14 +749,14 @@ static void write_data(running_machine &machine)
}
}
- hdc.w[7] |= w7_idle | w7_complete;
- update_interrupt(machine);
+ m_w[7] |= w7_idle | w7_complete;
+ update_interrupt();
}
/*
Handle the unformatted read command: read drive geometry information.
*/
-static void unformatted_read(running_machine &machine)
+void ti990_hdc_device::unformatted_read()
{
int dma_address;
int byte_count;
@@ -844,65 +772,65 @@ static void unformatted_read(running_machine &machine)
if (dsk_sel == -1)
{
/* No idea what to report... */
- hdc.w[7] |= w7_idle | w7_error | w7_abnormal_completion;
- update_interrupt(machine);
+ m_w[7] |= w7_idle | w7_error | w7_abnormal_completion;
+ update_interrupt();
return;
}
else if (! is_unit_loaded(dsk_sel))
{ /* offline */
- hdc.w[0] |= w0_offline | w0_not_ready;
- hdc.w[7] |= w7_idle | w7_error | w7_unit_err;
- update_interrupt(machine);
+ m_w[0] |= w0_offline | w0_not_ready;
+ m_w[7] |= w7_idle | w7_error | w7_unit_err;
+ update_interrupt();
return;
}
- else if (hdc.d[dsk_sel].unsafe)
+ else if (m_d[dsk_sel].unsafe)
{ /* disk in unsafe condition */
- hdc.w[0] |= w0_unsafe | w0_pack_change;
- hdc.w[7] |= w7_idle | w7_error | w7_unit_err;
- update_interrupt(machine);
+ m_w[0] |= w0_unsafe | w0_pack_change;
+ m_w[7] |= w7_idle | w7_error | w7_unit_err;
+ update_interrupt();
return;
}
- dma_address = ((((int) hdc.w[6]) << 16) | hdc.w[5]) & 0x1ffffe;
- byte_count = hdc.w[4] & 0xfffe;
+ dma_address = ((((int) m_w[6]) << 16) | m_w[5]) & 0x1ffffe;
+ byte_count = m_w[4] & 0xfffe;
- cylinder = hdc.w[3];
- head = hdc.w[1] & w1_head_address;
- sector = hdc.w[2] & 0xff;
+ cylinder = m_w[3];
+ head = m_w[1] & w1_head_address;
+ sector = m_w[2] & 0xff;
- if (check_sector_address(machine, dsk_sel, cylinder, head, sector))
+ if (check_sector_address(dsk_sel, cylinder, head, sector))
return;
- dma_address = ((((int) hdc.w[6]) << 16) | hdc.w[5]) & 0x1ffffe;
- byte_count = hdc.w[4] & 0xfffe;
+ dma_address = ((((int) m_w[6]) << 16) | m_w[5]) & 0x1ffffe;
+ byte_count = m_w[4] & 0xfffe;
/* bits 0-4: head address; bits 5-15: cylinder address */
buffer[0] = (head << 11) | cylinder;
/* MSByte: sectors per record (1); LSByte: sector address */
buffer[1] = (1 << 8) | sector;
/* formatted words per record */
- buffer[2] = hdc.d[dsk_sel].bytes_per_sector >> 1;
+ buffer[2] = m_d[dsk_sel].bytes_per_sector >> 1;
real_word_count = byte_count >> 1;
if (real_word_count > 3)
real_word_count = 3;
/* DMA */
- if (! (hdc.w[1] & w1_transfer_inhibit))
+ if (! (m_w[1] & w1_transfer_inhibit))
for (i=0; i<real_word_count; i++)
{
- machine.device("maincpu")->memory().space(AS_PROGRAM).write_word(dma_address, buffer[i]);
+ machine().device("maincpu")->memory().space(AS_PROGRAM).write_word(dma_address, buffer[i]);
dma_address = (dma_address + 2) & 0x1ffffe;
}
- hdc.w[7] |= w7_idle | w7_complete;
- update_interrupt(machine);
+ m_w[7] |= w7_idle | w7_complete;
+ update_interrupt();
}
/*
Handle the restore command: return to track 0.
*/
-static void restore(running_machine &machine)
+void ti990_hdc_device::restore()
{
int dsk_sel = cur_disk_unit();
@@ -910,83 +838,83 @@ static void restore(running_machine &machine)
if (dsk_sel == -1)
{
/* No idea what to report... */
- hdc.w[7] |= w7_idle | w7_error | w7_abnormal_completion;
- update_interrupt(machine);
+ m_w[7] |= w7_idle | w7_error | w7_abnormal_completion;
+ update_interrupt();
return;
}
else if (! is_unit_loaded(dsk_sel))
{ /* offline */
- hdc.w[0] |= w0_offline | w0_not_ready;
- hdc.w[7] |= w7_idle | w7_error | w7_unit_err;
- update_interrupt(machine);
+ m_w[0] |= w0_offline | w0_not_ready;
+ m_w[7] |= w7_idle | w7_error | w7_unit_err;
+ update_interrupt();
return;
}
- hdc.d[dsk_sel].unsafe = 0; /* I think */
+ m_d[dsk_sel].unsafe = 0; /* I think */
/*if (seek_to_sector(dsk_sel, 0, 0, 0))
return;*/
- hdc.w[7] |= w7_idle | w7_complete;
- update_interrupt(machine);
+ m_w[7] |= w7_idle | w7_complete;
+ update_interrupt();
}
/*
Parse command code and execute the command.
*/
-static void execute_command(running_machine &machine)
+void ti990_hdc_device::execute_command()
{
/* hack */
- hdc.w[0] &= 0xff;
+ m_w[0] &= 0xff;
- if (hdc.w[1] & w1_extended_command)
+ if (m_w[1] & w1_extended_command)
logerror("extended commands not supported\n");
- switch (/*((hdc.w[1] & w1_extended_command) >> 11) |*/ ((hdc.w[1] & w1_command) >> 8))
+ switch (/*((m_w[1] & w1_extended_command) >> 11) |*/ ((m_w[1] & w1_command) >> 8))
{
case 0x00: //0b000:
/* store registers */
logerror("store registers\n");
- store_registers(machine);
+ store_registers();
break;
case 0x01: //0b001:
/* write format */
logerror("write format\n");
- write_format(machine);
+ write_format();
break;
case 0x02: //0b010:
/* read data */
logerror("read data\n");
- read_data(machine);
+ read_data();
break;
case 0x03: //0b011:
/* write data */
logerror("write data\n");
- write_data(machine);
+ write_data();
break;
case 0x04: //0b100:
/* unformatted read */
logerror("unformatted read\n");
- unformatted_read(machine);
+ unformatted_read();
break;
case 0x05: //0b101:
/* unformatted write */
logerror("unformatted write\n");
/* ... */
- hdc.w[7] |= w7_idle | w7_error | w7_abnormal_completion;
- update_interrupt(machine);
+ m_w[7] |= w7_idle | w7_error | w7_abnormal_completion;
+ update_interrupt();
break;
case 0x06: //0b110:
/* seek */
logerror("seek\n");
/* This command can (almost) safely be ignored */
- hdc.w[7] |= w7_idle | w7_complete;
- update_interrupt(machine);
+ m_w[7] |= w7_idle | w7_complete;
+ update_interrupt();
break;
case 0x07: //0b111:
/* restore */
logerror("restore\n");
- restore(machine);
+ restore();
break;
}
}
@@ -994,10 +922,10 @@ static void execute_command(running_machine &machine)
/*
Read one register in TPCS space
*/
-READ16_HANDLER(ti990_hdc_r)
+READ16_MEMBER(ti990_hdc_device::read)
{
if (offset < 8)
- return hdc.w[offset];
+ return m_w[offset];
else
return 0;
}
@@ -1005,24 +933,24 @@ READ16_HANDLER(ti990_hdc_r)
/*
Write one register in TPCS space. Execute command if w7_idle is cleared.
*/
-WRITE16_HANDLER(ti990_hdc_w)
+WRITE16_MEMBER(ti990_hdc_device::write)
{
if (offset < 8)
{
/* write protect if a command is in progress */
- if (hdc.w[7] & w7_idle)
+ if (m_w[7] & w7_idle)
{
- UINT16 old_data = hdc.w[offset];
+ UINT16 old_data = m_w[offset];
/* Only write writable bits AND honor byte accesses (ha!) */
- hdc.w[offset] = (hdc.w[offset] & ((~w_mask[offset]) | mem_mask)) | (data & w_mask[offset] & ~mem_mask);
+ m_w[offset] = (m_w[offset] & ((~w_mask[offset]) | mem_mask)) | (data & w_mask[offset] & ~mem_mask);
if ((offset == 0) || (offset == 7))
- update_interrupt(space.machine());
+ update_interrupt();
if ((offset == 7) && (old_data & w7_idle) && ! (data & w7_idle))
{ /* idle has been cleared: start command execution */
- execute_command(space.machine());
+ execute_command();
}
}
}
@@ -1031,15 +959,71 @@ WRITE16_HANDLER(ti990_hdc_w)
static const struct harddisk_interface ti990_harddisk_config =
{
- DEVICE_IMAGE_LOAD_NAME_LEGACY( ti990_hd ),
- DEVICE_IMAGE_UNLOAD_NAME_LEGACY( ti990_hd ),
NULL,
NULL
};
-MACHINE_CONFIG_FRAGMENT( ti990_hdc )
+static MACHINE_CONFIG_FRAGMENT( ti990_hdc )
MCFG_HARDDISK_CONFIG_ADD( "harddisk1", ti990_harddisk_config )
+ MCFG_HARDDISK_LOAD(ti990_hdc_device, ti990_hd)
+ MCFG_HARDDISK_UNLOAD(ti990_hdc_device, ti990_hd)
MCFG_HARDDISK_CONFIG_ADD( "harddisk2", ti990_harddisk_config )
+ MCFG_HARDDISK_LOAD(ti990_hdc_device, ti990_hd)
+ MCFG_HARDDISK_UNLOAD(ti990_hdc_device, ti990_hd)
MCFG_HARDDISK_CONFIG_ADD( "harddisk3", ti990_harddisk_config )
+ MCFG_HARDDISK_LOAD(ti990_hdc_device, ti990_hd)
+ MCFG_HARDDISK_UNLOAD(ti990_hdc_device, ti990_hd)
MCFG_HARDDISK_CONFIG_ADD( "harddisk4", ti990_harddisk_config )
+ MCFG_HARDDISK_LOAD(ti990_hdc_device, ti990_hd)
+ MCFG_HARDDISK_UNLOAD(ti990_hdc_device, ti990_hd)
MACHINE_CONFIG_END
+
+const device_type TI990_HDC = &device_creator<ti990_hdc_device>;
+
+ti990_hdc_device::ti990_hdc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, TI990_HDC, "Generic TI-990 Hard Disk Controller", tag, owner, clock, "hdc_990", __FILE__),
+ m_interrupt_callback(*this)
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void ti990_hdc_device::device_start()
+{
+ int i;
+
+ /* initialize harddisk information */
+ /* attention lines will be set by DEVICE_IMAGE_LOD */
+ for (i=0; i<MAX_DISK_UNIT; i++)
+ {
+ m_d[i].format = format_mame;
+ m_d[i].hd_handle = NULL;
+ m_d[i].wp = 1;
+ m_d[i].unsafe = 1;
+ }
+ memset(m_w, 0, sizeof(m_w));
+ m_w[7] = w7_idle;
+
+ /* get references to harddisk devices */
+ m_d[0].img = dynamic_cast<device_image_interface *>(subdevice("harddisk1"));
+ m_d[1].img = dynamic_cast<device_image_interface *>(subdevice("harddisk2"));
+ m_d[2].img = dynamic_cast<device_image_interface *>(subdevice("harddisk3"));
+ m_d[3].img = dynamic_cast<device_image_interface *>(subdevice("harddisk4"));
+
+ m_interrupt_callback.resolve_safe();
+
+ update_interrupt();
+}
+
+
+//-------------------------------------------------
+// device_mconfig_additions - return a pointer to
+// the device's machine fragment
+//-------------------------------------------------
+
+machine_config_constructor ti990_hdc_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( ti990_hdc );
+}
diff --git a/src/mess/machine/ti99/990_hd.h b/src/mess/machine/ti99/990_hd.h
index 892e90cc0f7..5445ea45a99 100644
--- a/src/mess/machine/ti99/990_hd.h
+++ b/src/mess/machine/ti99/990_hd.h
@@ -6,13 +6,73 @@
#include "imagedev/harddriv.h"
-MACHINE_START( ti990_hdc );
+/* max disk units per controller: 4 is the protocol limit, but it may be
+overriden if more than one controller is used */
+#define MAX_DISK_UNIT 4
-void ti990_hdc_init(running_machine &machine, void (*interrupt_callback)(running_machine &machine, int state));
+class ti990_hdc_device : public device_t
+{
+public:
+ ti990_hdc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ template<class _Object> static devcb2_base &static_set_int_callback(device_t &device, _Object object) { return downcast<ti990_hdc_device &>(device).m_interrupt_callback.set_callback(object); }
-DECLARE_READ16_HANDLER(ti990_hdc_r);
-DECLARE_WRITE16_HANDLER(ti990_hdc_w);
+ DECLARE_READ16_MEMBER(read);
+ DECLARE_WRITE16_MEMBER(write);
-MACHINE_CONFIG_EXTERN( ti990_hdc );
+ DECLARE_DEVICE_IMAGE_LOAD_MEMBER( ti990_hd );
+ DECLARE_DEVICE_IMAGE_UNLOAD_MEMBER( ti990_hd );
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual machine_config_constructor device_mconfig_additions() const;
+
+ int get_id_from_device( device_t *device );
+
+ inline int is_unit_loaded(int unit);
+ int cur_disk_unit(void);
+ void update_interrupt();
+ int check_sector_address(int unit, unsigned int cylinder, unsigned int head, unsigned int sector);
+ int sector_to_lba(int unit, unsigned int cylinder, unsigned int head, unsigned int sector, unsigned int *lba);
+ int read_sector(int unit, unsigned int lba, void *buffer, unsigned int bytes_to_read);
+ int write_sector(int unit, unsigned int lba, const void *buffer, unsigned int bytes_to_write);
+ void store_registers();
+ void write_format();
+ void read_data();
+ void write_data();
+ void unformatted_read();
+ void restore();
+ void execute_command();
+private:
+ enum format_t
+ {
+ format_mame,
+ format_old
+ };
+
+ /* disk drive unit descriptor */
+ struct hd_unit_t
+ {
+ device_image_interface *img; /* image descriptor */
+ format_t format;
+ hard_disk_file *hd_handle; /* mame hard disk descriptor - only if format == format_mame */
+ unsigned int wp : 1; /* TRUE if disk is write-protected */
+ unsigned int unsafe : 1; /* TRUE when a disk has just been connected */
+
+ /* disk geometry */
+ unsigned int cylinders, heads, sectors_per_track, bytes_per_sector;
+ };
+
+ UINT16 m_w[8];
+
+ devcb2_write_line m_interrupt_callback;
+
+ hd_unit_t m_d[MAX_DISK_UNIT];
+};
+
+#define MCFG_TI990_HDC_INT_CALLBACK( _write ) \
+ devcb = &ti990_hdc_device::static_set_int_callback( *device, DEVCB2_##_write );
+
+extern const device_type TI990_HDC;
#endif
diff --git a/src/mess/machine/ti99/ti990.c b/src/mess/machine/ti99/ti990.c
deleted file mode 100644
index e80fa6b548b..00000000000
--- a/src/mess/machine/ti99/ti990.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- machine/ti990.c
-
- Emulation for a few generic aspects of TI990
-*/
-
-#include "emu.h"
-#include "ti990.h"
-
-/*
- Interrupt priority encoder. Actually part of the CPU board.
-*/
-static UINT16 intlines;
-
-void ti990_reset_int(void)
-{
- intlines = 0;
-}
-
-void ti990_set_int_line(running_machine &machine, int line, int state)
-{
- int level;
-
-
- if (state)
- intlines |= (1 << line);
- else
- intlines &= ~ (1 << line);
-
- if (intlines)
- {
- for (level = 0; ! (intlines & (1 << level)); level++)
- ;
- machine.device("maincpu")->execute().set_input_line_and_vector(0, ASSERT_LINE, level); /* interrupt it, baby */
- }
- else
- machine.device("maincpu")->execute().set_input_line(0, CLEAR_LINE);
-}
-
-void ti990_set_int2(device_t *device, int state)
-{
- ti990_set_int_line(device->machine(), 2, state);
-}
-
-void ti990_set_int3(running_machine &machine, int state)
-{
- ti990_set_int_line(machine, 3, state);
-}
-
-void ti990_set_int6(running_machine &machine, int state)
-{
- ti990_set_int_line(machine, 6, state);
-}
-
-void ti990_set_int7(running_machine &machine, int state)
-{
- ti990_set_int_line(machine, 7, state);
-}
-
-void ti990_set_int9(running_machine &machine, int state)
-{
- ti990_set_int_line(machine, 9, state);
-}
-
-void ti990_set_int10(running_machine &machine, int state)
-{
- ti990_set_int_line(machine, 10, state);
-}
-
-void ti990_set_int13(running_machine &machine, int state)
-{
- ti990_set_int_line(machine, 13, state);
-}
-
-/*
- hold and debounce load line (emulation is inaccurate)
-*/
-
-static TIMER_CALLBACK(clear_load)
-{
- machine.device("maincpu")->execute().set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
-}
-
-void ti990_hold_load(running_machine &machine)
-{
- machine.device("maincpu")->execute().set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
- machine.scheduler().timer_set(attotime::from_msec(100), FUNC(clear_load));
-}
-
-/*
- line interrupt
-*/
-
-/* ckon_state: 1 if line clock active (RTCLR flip-flop on TI990/10 schematics -
-SMI sheet 4) */
-static char ckon_state;
-
-void ti990_line_interrupt(running_machine &machine)
-{
- if (ckon_state)
- ti990_set_int_line(machine, 5, 1);
-}
-
-void ti990_ckon_ckof_callback(device_t *device, int state)
-{
- ckon_state = state;
- if (! ckon_state)
- ti990_set_int_line(device->machine(), 5, 0);
-}
-
-
-
-/*
- Control panel emulation
-
- three panel types
- * operator panel
- * programmer panel
- * MDU (external unit connected instead of the control panel, as seen in
- 945401-9701 p. 2-5 though 2-15)
-
- Operator panel:
- * Power led
- * Fault led
- * Off/On/Load switch
-
- Programmer panel:
- * 16 status light, 32 switches, IDLE, RUN leds
- * interface to a low-level debugger in ROMs
-
- * MDU:
- * includes a programmer panel, a tape unit, and a few parts
- (diagnostic tape, diagnostic ROMs, etc.)
-
- CRU output:
- 0-7: lights 0-7
- 8: increment scan
- 9: clear scan (according to 990 handbook)
- A: run light (additionally sets all data LEDs to 1s, the scan count to 0b10 and enables the HALT/SIE switch)
- B: fault light
- C: Memory Error Interrupt clear
- D: Start panel timer
- E: Set SIE function (interrupt after 2 instructions are executed)
- F: flag (according to 990 handbook)
-
- input :
- 0-7: switches 0-7 (or data from MDU tape)
- 8: scan count bit 1
- 9: scan count bit 0
- A: timer active
- B: programmer panel not present or locked
- C: char in MDU tape unit buffer?
- D: unused?
- E: if 0, MDU unit present
- F: flag (according to 990 handbook)
-*/
-
- READ8_HANDLER ( ti990_panel_read )
-{
- if (offset == 1)
- return 0x48;
-
- return 0;
-}
-
-WRITE8_HANDLER ( ti990_panel_write )
-{
-}
-
-
-/*
- CPU board soft reset (RSET instruction)
-*/
-void ti990_cpuboard_reset(void)
-{
- ckon_state = 0;
-}
diff --git a/src/mess/machine/ti99/ti990.h b/src/mess/machine/ti99/ti990.h
deleted file mode 100644
index 36c0c77cb88..00000000000
--- a/src/mess/machine/ti99/ti990.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- ti990.h: header file for ti990.c
-*/
-
-void ti990_reset_int(void);
-void ti990_set_int_line(running_machine &machine, int line, int state);
-void ti990_set_int2(device_t *device, int state);
-void ti990_set_int3(running_machine &machine, int state);
-void ti990_set_int6(running_machine &machine, int state);
-void ti990_set_int7(running_machine &machine, int state);
-void ti990_set_int9(running_machine &machine, int state);
-void ti990_set_int10(running_machine &machine, int state);
-void ti990_set_int13(running_machine &machine, int state);
-
-void ti990_hold_load(running_machine &machine);
-
- DECLARE_READ8_HANDLER ( ti990_panel_read );
-DECLARE_WRITE8_HANDLER ( ti990_panel_write );
-
-void ti990_line_interrupt(running_machine &machine);
-void ti990_ckon_ckof_callback(device_t *device, int state);
-
-void ti990_cpuboard_reset(void);
diff --git a/src/mess/mess.mak b/src/mess/mess.mak
index 580b6169727..ad99a39addc 100644
--- a/src/mess/mess.mak
+++ b/src/mess/mess.mak
@@ -1851,7 +1851,6 @@ $(MESSOBJ)/ti.a: \
$(MESS_MACHINE)/ti99/990_dk.o \
$(MESS_MACHINE)/ti99/990_hd.o \
$(MESS_MACHINE)/ti99/990_tap.o \
- $(MESS_MACHINE)/ti99/ti990.o \
$(MESS_MACHINE)/ti99/datamux.o \
$(MESS_MACHINE)/ti99/videowrp.o \
$(MESS_MACHINE)/ti99/grom.o \