diff options
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 |
commit | 72292ef70ad882d18aa22296500bc881ffea5727 (patch) | |
tree | 77755b59fc56616dd4a103c085fff72398937939 | |
parent | 0a18895d99575ebaf54888a253b11793e9e62e53 (diff) |
modernized 990_hd, moved some code into ti990_10.c, and simplified harddriv.c and remove some legacy leftovers (nw)
-rw-r--r-- | .gitattributes | 2 | ||||
-rw-r--r-- | src/emu/diimage.h | 7 | ||||
-rw-r--r-- | src/emu/driver.h | 1 | ||||
-rw-r--r-- | src/emu/imagedev/harddriv.c | 10 | ||||
-rw-r--r-- | src/emu/imagedev/harddriv.h | 15 | ||||
-rw-r--r-- | src/emu/machine/corvushd.c | 2 | ||||
-rw-r--r-- | src/emu/machine/nscsi_hd.c | 2 | ||||
-rw-r--r-- | src/emu/machine/scsihd.c | 2 | ||||
-rw-r--r-- | src/mess/drivers/ti990_10.c | 172 | ||||
-rw-r--r-- | src/mess/includes/next.h | 1 | ||||
-rw-r--r-- | src/mess/machine/ti99/990_hd.c | 550 | ||||
-rw-r--r-- | src/mess/machine/ti99/990_hd.h | 70 | ||||
-rw-r--r-- | src/mess/machine/ti99/ti990.c | 177 | ||||
-rw-r--r-- | src/mess/machine/ti99/ti990.h | 23 | ||||
-rw-r--r-- | src/mess/mess.mak | 1 |
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 = ℑ 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 \ |