summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mess/drivers/mac.c1
-rw-r--r--src/mess/machine/a2diskii.c4
-rw-r--r--src/mess/machine/apple2gs.c4
-rw-r--r--src/mess/machine/apple3.c9
-rw-r--r--src/mess/machine/applefdc.c736
-rw-r--r--src/mess/machine/applefdc.h137
-rw-r--r--src/mess/machine/lisa.c12
-rw-r--r--src/mess/machine/mac.c10
-rw-r--r--src/mess/machine/oric.c20
-rw-r--r--src/mess/machine/swim.c220
-rw-r--r--src/mess/machine/swim.h61
-rw-r--r--src/mess/mess.mak1
12 files changed, 629 insertions, 586 deletions
diff --git a/src/mess/drivers/mac.c b/src/mess/drivers/mac.c
index f43c34d3815..7b3ca00a1e6 100644
--- a/src/mess/drivers/mac.c
+++ b/src/mess/drivers/mac.c
@@ -50,6 +50,7 @@
#include "machine/6522via.h"
#include "machine/ncr5380.h"
#include "machine/applefdc.h"
+#include "machine/swim.h"
#include "devices/sonydriv.h"
#include "formats/ap_dsk35.h"
#include "machine/ram.h"
diff --git a/src/mess/machine/a2diskii.c b/src/mess/machine/a2diskii.c
index eab937f882c..bb0ca541257 100644
--- a/src/mess/machine/a2diskii.c
+++ b/src/mess/machine/a2diskii.c
@@ -138,7 +138,7 @@ void a2bus_floppy_device::device_reset()
UINT8 a2bus_floppy_device::read_c0nx(address_space &space, UINT8 offset)
{
- return applefdc_r(m_fdc, space, offset);
+ return m_fdc->read(offset);
}
@@ -148,7 +148,7 @@ UINT8 a2bus_floppy_device::read_c0nx(address_space &space, UINT8 offset)
void a2bus_floppy_device::write_c0nx(address_space &space, UINT8 offset, UINT8 data)
{
- applefdc_w(m_fdc, space, offset, data);
+ m_fdc->write(offset, data);
}
/*-------------------------------------------------
diff --git a/src/mess/machine/apple2gs.c b/src/mess/machine/apple2gs.c
index e24d12dd3a1..3033a245ed7 100644
--- a/src/mess/machine/apple2gs.c
+++ b/src/mess/machine/apple2gs.c
@@ -1049,7 +1049,7 @@ READ8_MEMBER( apple2gs_state::apple2gs_c0xx_r )
case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef:
if ((m_sltromsel & (1 << 6)) == 0)
{
- result = applefdc_r(m_fdc, space, offset);
+ result = m_fdc->read(offset);
}
else
{
@@ -1205,7 +1205,7 @@ WRITE8_MEMBER( apple2gs_state::apple2gs_c0xx_w )
case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef:
if ((m_sltromsel & (1 << 6)) == 0)
{
- applefdc_w(m_fdc, space, offset, data);
+ m_fdc->write(offset, data);
}
else
{
diff --git a/src/mess/machine/apple3.c b/src/mess/machine/apple3.c
index 8df05a380bd..e18330101b4 100644
--- a/src/mess/machine/apple3.c
+++ b/src/mess/machine/apple3.c
@@ -104,7 +104,7 @@ void apple3_state::apple3_profile_w(offs_t offset, UINT8 data)
READ8_MEMBER(apple3_state::apple3_c0xx_r)
{
acia6551_device *acia = machine().device<acia6551_device>("acia");
- device_t *fdc = machine().device("fdc");
+ applefdc_base_device *fdc = machine().device<applefdc_base_device>("fdc");
UINT8 result = 0xFF;
switch(offset)
@@ -171,7 +171,7 @@ READ8_MEMBER(apple3_state::apple3_c0xx_r)
case 0xE4: case 0xE5: case 0xE6: case 0xE7:
case 0xE8: case 0xE9: case 0xEA: case 0xEB:
case 0xEC: case 0xED: case 0xEE: case 0xEF:
- result = applefdc_r(fdc, space, offset);
+ result = fdc->read(offset);
break;
case 0xF0:
@@ -189,7 +189,8 @@ READ8_MEMBER(apple3_state::apple3_c0xx_r)
WRITE8_MEMBER(apple3_state::apple3_c0xx_w)
{
acia6551_device *acia = machine().device<acia6551_device>("acia");
- device_t *fdc = machine().device("fdc");
+ applefdc_base_device *fdc = machine().device<applefdc_base_device>("fdc");
+
switch(offset)
{
case 0x10: case 0x11: case 0x12: case 0x13:
@@ -234,7 +235,7 @@ WRITE8_MEMBER(apple3_state::apple3_c0xx_w)
case 0xE4: case 0xE5: case 0xE6: case 0xE7:
case 0xE8: case 0xE9: case 0xEA: case 0xEB:
case 0xEC: case 0xED: case 0xEE: case 0xEF:
- applefdc_w(fdc, space, offset, data);
+ fdc->write(offset, data);
break;
case 0xF0:
diff --git a/src/mess/machine/applefdc.c b/src/mess/machine/applefdc.c
index e681fcdf4c7..75af66dc081 100644
--- a/src/mess/machine/applefdc.c
+++ b/src/mess/machine/applefdc.c
@@ -39,38 +39,24 @@
/***************************************************************************
- PARAMETERS
+ CONSTANTS
***************************************************************************/
-/* logging */
+// logging
#define LOG_APPLEFDC 0
#define LOG_APPLEFDC_EXTRA 0
+// mask for FDC lines
+#define IWM_MOTOR 0x10
+#define IWM_DRIVE 0x20
+#define IWM_Q6 0x40
+#define IWM_Q7 0x80
+const device_timer_id TIMER_MOTOR_ONOFF = 1;
-/***************************************************************************
- CONSTANTS
-***************************************************************************/
-
-/* mask for FDC lines */
-#define IWM_MOTOR 0x10
-#define IWM_DRIVE 0x20
-#define IWM_Q6 0x40
-#define IWM_Q7 0x80
-enum applefdc_t
-{
- APPLEFDC_APPLE2, /* classic Apple II disk controller (pre-IWM) */
- APPLEFDC_IWM, /* Integrated Woz Machine */
- APPLEFDC_SWIM /* Sander/Woz Integrated Machine */
-};
-static UINT8 swim_default_parms[16] =
-{
- 0x38, 0x18, 0x41, 0x2e, 0x2e, 0x18, 0x18, 0x1b,
- 0x1b, 0x2f, 0x2f, 0x19, 0x19, 0x97, 0x1b, 0x57
-};
/***************************************************************************
IWM MODE
@@ -107,180 +93,131 @@ enum
IWM_MODE_LATCHMODE = 0x01
};
-enum
-{
- SWIM_MODE_IWM,
- SWIM_MODE_SWIM,
- SWIM_MODE_SWIM2,
- SWIM_MODE_SWIM3
-};
-
-/***************************************************************************
- TYPE DEFINITIONS
-***************************************************************************/
-
-struct applefdc_token
-{
- /* data that is constant for the lifetime of the emulation */
- emu_timer *motor_timer;
- applefdc_t type;
-
- /* data that changes at emulation time */
- UINT8 write_byte;
- UINT8 lines; /* flags from IWM_MOTOR - IWM_Q7 */
- UINT8 mode; /* 0-31; see above */
- UINT8 handshake_hack; /* not sure what this is for */
-
- /* SWIM extentions */
- UINT8 swim_mode;
- UINT8 swim_magic_state;
- UINT8 ism_regs[8];
- UINT8 parm_offset;
- UINT8 parms[16];
-};
-
/***************************************************************************
- PROTOTYPES
+ BASE DEVICE
***************************************************************************/
-static TIMER_CALLBACK(iwm_turnmotor_onoff);
-
-
-
-/***************************************************************************
- INLINE FUNCTIONS
-***************************************************************************/
+//-------------------------------------------------
+// ctor
+//-------------------------------------------------
-INLINE void assert_is_applefdc(device_t *device)
+applefdc_base_device::applefdc_base_device(applefdc_base_device::applefdc_t fdc_type, const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, type, name, tag, owner, clock)
{
- assert(device != NULL);
- assert((device->type() == APPLEFDC) || (device->type() == IWM) || (device->type() == SWIM));
+ m_type = fdc_type;
}
-INLINE applefdc_token *get_token(device_t *device)
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void applefdc_base_device::device_start()
{
- assert_is_applefdc(device);
- return (applefdc_token *) downcast<applefdc_base_device *>(device)->token();
+ // timer
+ m_motor_timer = timer_alloc(TIMER_MOTOR_ONOFF);
+
+ // state
+ m_write_byte = 0x00;
+ m_lines = 0x00;
+ m_mode = 0x1F; // default value needed by Lisa 2 - no, I don't know if it is true
+ m_handshake_hack = 0x00;
+
+ // register save states
+ save_item(NAME(m_write_byte));
+ save_item(NAME(m_lines));
+ save_item(NAME(m_mode));
+ save_item(NAME(m_handshake_hack));
}
-INLINE const applefdc_interface *get_interface(device_t *device)
-{
- static const applefdc_interface dummy_interface = {0, };
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
- assert_is_applefdc(device);
- return (device->static_config() != NULL)
- ? (const applefdc_interface *) device->static_config()
- : &dummy_interface;
+void applefdc_base_device::device_reset(void)
+{
+ m_handshake_hack = 0x00;
+ m_write_byte = 0x00;
+ m_lines = 0x00;
+ m_mode = 0x1F; /* default value needed by Lisa 2 - no, I don't know if it is true */
+ m_motor_timer->reset();
}
-/***************************************************************************
- CORE IMPLEMENTATION
-***************************************************************************/
-
-/*-------------------------------------------------
- applefdc_start - starts up an FDC
--------------------------------------------------*/
+//-------------------------------------------------
+// device_timer - device-specific timer callbacks
+//-------------------------------------------------
-static void applefdc_start(device_t *device, applefdc_t type)
+void applefdc_base_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
- applefdc_token *fdc = get_token(device);
-
- memset(fdc, 0, sizeof(*fdc));
- fdc->type = type;
- fdc->motor_timer = device->machine().scheduler().timer_alloc(FUNC(iwm_turnmotor_onoff), (void *) device);
- fdc->lines = 0x00;
- fdc->mode = 0x1F; /* default value needed by Lisa 2 - no, I don't know if it is true */
- fdc->swim_mode = SWIM_MODE_IWM;
-
- /* register save states */
- state_save_register_item(device->machine(), "applefdc", NULL, 0, fdc->write_byte);
- state_save_register_item(device->machine(), "applefdc", NULL, 0, fdc->lines);
- state_save_register_item(device->machine(), "applefdc", NULL, 0, fdc->mode);
- state_save_register_item(device->machine(), "applefdc", NULL, 0, fdc->handshake_hack);
+ switch(id)
+ {
+ case TIMER_MOTOR_ONOFF:
+ turn_motor_onoff(param != 0);
+ break;
+ }
}
-/*-------------------------------------------------
- DEVICE_RESET(applefdc) - resets an FDC
--------------------------------------------------*/
+//-------------------------------------------------
+// get_interface - gets the interface
+//-------------------------------------------------
-static DEVICE_RESET(applefdc)
+const applefdc_interface *applefdc_base_device::get_interface()
{
- applefdc_token *fdc = get_token(device);
-
- fdc->handshake_hack = 0x00;
- fdc->write_byte = 0x00;
- fdc->lines = 0x00;
- fdc->mode = 0x1F; /* default value needed by Lisa 2 - no, I don't know if it is true */
- fdc->swim_magic_state = 0;
- fdc->swim_mode = SWIM_MODE_IWM;
- fdc->parm_offset = 0;
-
- // setup SWIM default parms if it's a SWIM
- if (fdc->type == APPLEFDC_SWIM)
- {
- for (int i = 0; i < 16; i++)
- {
- fdc->parms[i] = swim_default_parms[i];
- }
- }
+ static const applefdc_interface dummy_interface = {0, };
- fdc->motor_timer->reset();
+ return (static_config() != NULL)
+ ? (const applefdc_interface *) static_config()
+ : &dummy_interface;
}
-/*-------------------------------------------------
- iwm_enable2 - hackish function
--------------------------------------------------*/
+//-------------------------------------------------
+// iwm_enable2 - hackish function
+//-------------------------------------------------
-static int iwm_enable2(device_t *device)
+int applefdc_base_device::iwm_enable2()
{
- applefdc_token *fdc = get_token(device);
-
/* R. Nabet : This function looks more like a hack than a real feature of the IWM; */
/* it is not called from the Mac Plus driver */
- return (fdc->lines & APPLEFDC_PH1) && (fdc->lines & APPLEFDC_PH3);
+ return (m_lines & APPLEFDC_PH1) && (m_lines & APPLEFDC_PH3);
}
-/*-------------------------------------------------
- iwm_readenable2handshake - hackish function
--------------------------------------------------*/
+//-------------------------------------------------
+// iwm_readenable2handshake - hackish function
+//-------------------------------------------------
-static UINT8 iwm_readenable2handshake(device_t *device)
+UINT8 applefdc_base_device::iwm_readenable2handshake()
{
- applefdc_token *fdc = get_token(device);
-
/* R. Nabet : This function looks more like a hack than a real feature of the IWM; */
/* it is not called from the Mac Plus driver */
- fdc->handshake_hack++;
- fdc->handshake_hack %= 4;
- return (fdc->handshake_hack != 0) ? 0xc0 : 0x80;
+ m_handshake_hack++;
+ m_handshake_hack %= 4;
+ return (m_handshake_hack != 0) ? 0xc0 : 0x80;
}
-/*-------------------------------------------------
- applefdc_statusreg_r - reads the status register
--------------------------------------------------*/
+//-------------------------------------------------
+// statusreg_r - reads the status register
+//-------------------------------------------------
-static UINT8 applefdc_statusreg_r(device_t *device)
+UINT8 applefdc_base_device::statusreg_r()
{
UINT8 result;
int status;
- applefdc_token *fdc = get_token(device);
- const applefdc_interface *intf = get_interface(device);
+ const applefdc_interface *intf = get_interface();
/* IWM status:
*
@@ -290,120 +227,75 @@ static UINT8 applefdc_statusreg_r(device_t *device)
* Bits 4-0 Same as IWM mode bits 4-0
*/
- status = iwm_enable2(device) ? 1 : (intf->read_status ? intf->read_status(device) : 0);
+ status = iwm_enable2() ? 1 : (intf->read_status ? intf->read_status(this) : 0);
result = (status ? 0x80 : 0x00);
- if (fdc->type != APPLEFDC_APPLE2)
- result |= (((fdc->lines & IWM_MOTOR) ? 1 : 0) << 5) | fdc->mode;
+ if (m_type != APPLEFDC_APPLE2)
+ result |= (((m_lines & IWM_MOTOR) ? 1 : 0) << 5) | m_mode;
return result;
}
-/*-------------------------------------------------
- iwm_modereg_w - changes the mode register
--------------------------------------------------*/
+//-------------------------------------------------
+// iwm_modereg_w - changes the mode register
+//-------------------------------------------------
-static void iwm_modereg_w(device_t *device, UINT8 data)
+void applefdc_base_device::iwm_modereg_w(UINT8 data)
{
- applefdc_token *fdc = get_token(device);
-
- fdc->mode = data & 0x1f; /* write mode register */
-
- // SWIM mode is unlocked by writing 1/0/1/1 in a row to bit 6 (which is unused on IWM)
- // when SWIM mode engages, the IWM is disconnected from both the 68k and the drives,
- // and the ISM is substituted.
- if (fdc->type == APPLEFDC_SWIM)
- {
- switch (fdc->swim_magic_state)
- {
- case 0:
- case 2:
- case 3:
- if (data & 0x40)
- {
- fdc->swim_magic_state++;
- }
- else
- {
- fdc->swim_magic_state = 0;
- }
- break;
- case 1:
- if (!(data & 0x40))
- {
- fdc->swim_magic_state++;
- }
- else
- {
- fdc->swim_magic_state = 0;
- }
- break;
- }
-
- if (fdc->swim_magic_state == 4)
- {
- fdc->swim_magic_state = 0;
-// printf("IWM: switching to SWIM mode\n");
- fdc->swim_mode = SWIM_MODE_SWIM;
- }
- }
+ m_mode = data & 0x1f; /* write mode register */
if (LOG_APPLEFDC_EXTRA)
- logerror("iwm_modereg_w: iwm_mode=0x%02x\n", (unsigned) fdc->mode);
+ logerror("iwm_modereg_w: iwm_mode=0x%02x\n", (unsigned) m_mode);
}
-/*-------------------------------------------------
- applefdc_read_reg - reads a register
--------------------------------------------------*/
+//-------------------------------------------------
+// read_reg - reads a register
+//-------------------------------------------------
-static UINT8 applefdc_read_reg(device_t *device, int lines)
+UINT8 applefdc_base_device::read_reg(int lines)
{
- applefdc_token *fdc = get_token(device);
- const applefdc_interface *intf = get_interface(device);
+ const applefdc_interface *intf = get_interface();
UINT8 result = 0;
switch(lines)
{
case 0:
- /* Read data register */
- if ((fdc->type != APPLEFDC_APPLE2) && (iwm_enable2(device) || !(fdc->lines & IWM_MOTOR)))
+ // read data register
+ if ((m_type != APPLEFDC_APPLE2) && (iwm_enable2() || !(m_lines & IWM_MOTOR)))
{
result = 0xFF;
}
else
{
- /*
- * Right now, this function assumes latch mode; which is always used for
- * 3.5 inch drives. Eventually we should check to see if latch mode is
- * off
- */
+ // Right now, this function assumes latch mode; which is always used for
+ // 3.5 inch drives. Eventually we should check to see if latch mode is
+ // off
if (LOG_APPLEFDC)
{
- if ((fdc->mode & IWM_MODE_LATCHMODE) == 0x00)
+ if ((m_mode & IWM_MODE_LATCHMODE) == 0x00)
logerror("applefdc_read_reg(): latch mode off not implemented\n");
}
- result = (intf->read_data ? intf->read_data(device) : 0x00);
+ result = (intf->read_data ? intf->read_data(this) : 0x00);
}
break;
case IWM_Q6:
- /* Read status register */
- result = applefdc_statusreg_r(device);
+ // read status register
+ result = statusreg_r();
break;
case IWM_Q7:
- /* Classic Apple II: Read status register
- * IWM: Read handshake register
- */
- if (fdc->type == APPLEFDC_APPLE2)
- result = applefdc_statusreg_r(device);
+ // Classic Apple II: Read status register
+ // IWM: Read handshake register
+ if (m_type == APPLEFDC_APPLE2)
+ result = statusreg_r();
else
- result = iwm_enable2(device) ? iwm_readenable2handshake(device) : 0x80;
+ result = iwm_enable2() ? iwm_readenable2handshake() : 0x80;
break;
}
return result;
@@ -411,37 +303,34 @@ static UINT8 applefdc_read_reg(device_t *device, int lines)
-/*-------------------------------------------------
- applefdc_write_reg - writes a register
--------------------------------------------------*/
+//-------------------------------------------------
+// write_reg - writes a register
+//-------------------------------------------------
-static void applefdc_write_reg(device_t *device, UINT8 data)
+void applefdc_base_device::write_reg(UINT8 data)
{
- applefdc_token *fdc = get_token(device);
- const applefdc_interface *intf = get_interface(device);
+ const applefdc_interface *intf = get_interface();
- switch(fdc->lines & (IWM_Q6 | IWM_Q7))
+ switch(m_lines & (IWM_Q6 | IWM_Q7))
{
case IWM_Q6 | IWM_Q7:
- if (!(fdc->lines & IWM_MOTOR))
+ if (!(m_lines & IWM_MOTOR))
{
- iwm_modereg_w(device, data);
+ iwm_modereg_w(data);
}
- else if (!iwm_enable2(device))
+ else if (!iwm_enable2())
{
- /*
- * Right now, this function assumes latch mode; which is always used for
- * 3.5 inch drives. Eventually we should check to see if latch mode is
- * off
- */
+ // Right now, this function assumes latch mode; which is always used for
+ // 3.5 inch drives. Eventually we should check to see if latch mode is
+ // off
if (LOG_APPLEFDC)
{
- if ((fdc->mode & IWM_MODE_LATCHMODE) == 0)
+ if ((m_mode & IWM_MODE_LATCHMODE) == 0)
logerror("applefdc_write_reg(): latch mode off not implemented\n");
}
if (intf->write_data != NULL)
- intf->write_data(device,data);
+ intf->write_data(this, data);
}
break;
}
@@ -449,37 +338,34 @@ static void applefdc_write_reg(device_t *device, UINT8 data)
-/*-------------------------------------------------
- TIMER_CALLBACK(iwm_turnmotor_onoff) - timer
- callback for turning motor on or off
--------------------------------------------------*/
+//-------------------------------------------------
+// turn_motor_onoff - timer callback for turning
+// motor on or off
+//-------------------------------------------------
-static TIMER_CALLBACK(iwm_turnmotor_onoff)
+void applefdc_base_device::turn_motor_onoff(bool status)
{
- device_t *device = (device_t *) ptr;
- applefdc_token *fdc = get_token(device);
- const applefdc_interface *intf = get_interface(device);
- int status = param;
+ const applefdc_interface *intf = get_interface();
int enable_lines;
- if (status != 0)
+ if (status)
{
- fdc->lines |= IWM_MOTOR;
- enable_lines = (fdc->lines & IWM_DRIVE) ? 2 : 1;
+ m_lines |= IWM_MOTOR;
+ enable_lines = (m_lines & IWM_DRIVE) ? 2 : 1;
}
else
{
- fdc->lines &= ~IWM_MOTOR;
+ m_lines &= ~IWM_MOTOR;
- if (fdc->type == APPLEFDC_APPLE2)
- enable_lines = (fdc->lines & IWM_DRIVE) ? 2 : 1;
+ if (m_type == APPLEFDC_APPLE2)
+ enable_lines = (m_lines & IWM_DRIVE) ? 2 : 1;
else
enable_lines = 0;
}
/* invoke callback, if present */
if (intf->set_enable_lines != NULL)
- intf->set_enable_lines(device,enable_lines);
+ intf->set_enable_lines(this, enable_lines);
if (LOG_APPLEFDC_EXTRA)
logerror("iwm_turnmotor_onoff(): Turning motor %s\n", status ? "on" : "off");
@@ -487,11 +373,11 @@ static TIMER_CALLBACK(iwm_turnmotor_onoff)
-/*-------------------------------------------------
- iwm_access
--------------------------------------------------*/
+//-------------------------------------------------
+// iwm_access
+//-------------------------------------------------
-static void iwm_access(device_t *device, int offset)
+void applefdc_base_device::iwm_access(int offset)
{
static const char *const lines[] =
{
@@ -505,124 +391,107 @@ static void iwm_access(device_t *device, int offset)
"Q7"
};
- applefdc_token *fdc = get_token(device);
- const applefdc_interface *intf = get_interface(device);
+ const applefdc_interface *intf = get_interface();
if (offset & 1)
- fdc->lines |= (1 << (offset >> 1));
+ m_lines |= (1 << (offset >> 1));
else
- fdc->lines &= ~(1 << (offset >> 1));
+ m_lines &= ~(1 << (offset >> 1));
if (LOG_APPLEFDC_EXTRA)
{
logerror("iwm_access(): %s line %s => %02x\n",
- (offset & 1) ? "setting" : "clearing", lines[offset >> 1], fdc->lines);
+ (offset & 1) ? "setting" : "clearing", lines[offset >> 1], m_lines);
}
if ((offset < 0x08) && (intf->set_lines != NULL))
- intf->set_lines(device,fdc->lines & 0x0f);
+ intf->set_lines(this, m_lines & 0x0f);
switch(offset)
{
case 0x08:
/* turn off motor */
- fdc->motor_timer->adjust(
- (fdc->mode & IWM_MODE_MOTOROFFDELAY) ? attotime::zero : attotime::from_seconds(1), 0);
+ m_motor_timer->adjust(
+ (m_mode & IWM_MODE_MOTOROFFDELAY) ? attotime::zero : attotime::from_seconds(1), 0);
break;
case 0x09:
/* turn on motor */
- fdc->motor_timer->adjust(attotime::zero, 1);
+ m_motor_timer->adjust(attotime::zero, 1);
break;
case 0x0A:
/* turn off IWM_DRIVE */
- if ((fdc->lines & IWM_MOTOR) && (intf->set_enable_lines != NULL))
- intf->set_enable_lines(device,1);
+ if ((m_lines & IWM_MOTOR) && (intf->set_enable_lines != NULL))
+ intf->set_enable_lines(this, 1);
break;
case 0x0B:
/* turn on IWM_DRIVE */
- if ((fdc->lines & IWM_MOTOR) && (intf->set_enable_lines != NULL))
- intf->set_enable_lines(device,2);
+ if ((m_lines & IWM_MOTOR) && (intf->set_enable_lines != NULL))
+ intf->set_enable_lines(this, 2);
break;
}
}
-/*-------------------------------------------------
- applefdc_r - reads a byte from the FDC
--------------------------------------------------*/
+//-------------------------------------------------
+// read - reads a byte from the FDC
+//-------------------------------------------------
-READ8_DEVICE_HANDLER( applefdc_r )
+UINT8 applefdc_base_device::read(UINT8 offset)
{
- applefdc_token *fdc = get_token(device);
- const applefdc_interface *intf = get_interface(device);
+ const applefdc_interface *intf = get_interface();
UINT8 result = 0;
- /* normalize offset */
+ // normalize offset
offset &= 0xf;
if (LOG_APPLEFDC_EXTRA)
logerror("applefdc_r: offset=%i\n", offset);
- if ((fdc->type < APPLEFDC_SWIM) || (fdc->swim_mode == SWIM_MODE_IWM))
- {
- iwm_access(device, offset);
+ iwm_access(offset);
- switch(fdc->type)
- {
- case APPLEFDC_APPLE2:
- switch(offset)
- {
- case 0x0C:
- if (fdc->lines & IWM_Q7)
- {
- if (intf->write_data != NULL)
- intf->write_data(device,fdc->write_byte);
- result = 0;
- }
- else
- result = applefdc_read_reg(device, 0);
-
- break;
- case 0x0D:
- result = applefdc_read_reg(device, IWM_Q6);
- break;
- case 0x0E:
- result = applefdc_read_reg(device, IWM_Q7);
- break;
- case 0x0F:
- result = applefdc_read_reg(device, IWM_Q7 | IWM_Q6);
- break;
- }
- break;
-
- case APPLEFDC_IWM:
- if ((offset & 1) == 0)
- result = applefdc_read_reg(device, fdc->lines & (IWM_Q6 | IWM_Q7));
- break;
-
- case APPLEFDC_SWIM:
- if ((offset & 1) == 0)
- result = applefdc_read_reg(device, fdc->lines & (IWM_Q6 | IWM_Q7));
- break;
- }
- }
- else if (fdc->swim_mode >= SWIM_MODE_SWIM)
+ switch(m_type)
{
- // reading parameter RAM?
- if ((offset & 7) == 3)
- {
- result = fdc->parms[fdc->parm_offset++];
- fdc->parm_offset &= 0xf;
- }
- else
- {
- result = fdc->ism_regs[offset&7];
- }
- printf("SWIM: read %02x from offset %x\n", result, offset & 7);
+ case APPLEFDC_APPLE2:
+ switch(offset)
+ {
+ case 0x0C:
+ if (m_lines & IWM_Q7)
+ {
+ if (intf->write_data != NULL)
+ intf->write_data(this, m_write_byte);
+ result = 0;
+ }
+ else
+ result = read_reg(0);
+ break;
+
+ case 0x0D:
+ result = read_reg(IWM_Q6);
+ break;
+
+ case 0x0E:
+ result = read_reg(IWM_Q7);
+ break;
+
+ case 0x0F:
+ result = read_reg(IWM_Q7 | IWM_Q6);
+ break;
+ }
+ break;
+
+ case APPLEFDC_IWM:
+ if ((offset & 1) == 0)
+ result = read_reg(m_lines & (IWM_Q6 | IWM_Q7));
+ break;
+
+ case APPLEFDC_SWIM:
+ if ((offset & 1) == 0)
+ result = read_reg(m_lines & (IWM_Q6 | IWM_Q7));
+ break;
}
return result;
@@ -630,14 +499,13 @@ READ8_DEVICE_HANDLER( applefdc_r )
-/*-------------------------------------------------
- applefdc_w - writes a byte to the FDC
--------------------------------------------------*/
+//-------------------------------------------------
+// write - writes a byte to the FDC
+//-------------------------------------------------
-WRITE8_DEVICE_HANDLER( applefdc_w )
+void applefdc_base_device::write(UINT8 offset, UINT8 data)
{
- applefdc_token *fdc = get_token(device);
- const applefdc_interface *intf = get_interface(device);
+ const applefdc_interface *intf = get_interface();
/* normalize offset */
offset &= 15;
@@ -645,202 +513,72 @@ WRITE8_DEVICE_HANDLER( applefdc_w )
if (LOG_APPLEFDC_EXTRA)
logerror("applefdc_w: offset=%i data=0x%02x\n", offset, data);
- if ((fdc->type < APPLEFDC_SWIM) || (fdc->swim_mode == SWIM_MODE_IWM))
- {
- iwm_access(device, offset);
+ iwm_access(offset);
- switch(fdc->type)
- {
- case APPLEFDC_APPLE2:
- switch(offset)
- {
- case 0x0C:
- if (fdc->lines & IWM_Q7)
- {
- if (intf->write_data != NULL)
- intf->write_data(device,fdc->write_byte);
- }
- break;
-
- case 0x0D:
- fdc->write_byte = data;
- break;
- }
- break;
-
- case APPLEFDC_IWM:
- if (offset & 1)
- applefdc_write_reg(device, data);
- break;
-
- case APPLEFDC_SWIM:
- if (offset & 1)
- applefdc_write_reg(device, data);
- break;
- }
- }
- else if (fdc->swim_mode >= SWIM_MODE_SWIM)
+ switch(m_type)
{
- printf("SWIM: write %02x to offset %x\n", data, offset & 7);
- switch (offset & 7)
- {
- case 2: // write CRC
- break;
-
- case 3: // write parameter
- fdc->parms[fdc->parm_offset++] = data;
- fdc->parm_offset &= 0xf;
- break;
-
- case 6: // write zeros to status (also zeroes parameter RAM pointer)
- fdc->ism_regs[6] &= ~data;
- fdc->parm_offset = 0;
-
- if (data == 0xf8) // magic "revert to IWM" value
- {
- printf("SWIM: reverting to IWM\n");
- fdc->swim_mode = SWIM_MODE_IWM;
- }
- break;
-
- case 7: // write ones to status
- fdc->ism_regs[6] |= data;
- break;
+ case APPLEFDC_APPLE2:
+ switch(offset)
+ {
+ case 0x0C:
+ if (m_lines & IWM_Q7)
+ {
+ if (intf->write_data != NULL)
+ intf->write_data(this, m_write_byte);
+ }
+ break;
+
+ case 0x0D:
+ m_write_byte = data;
+ break;
+ }
+ break;
- default:
- fdc->ism_regs[offset & 7] = data;
- break;
+ case APPLEFDC_IWM:
+ if (offset & 1)
+ write_reg(data);
+ break;
- }
+ case APPLEFDC_SWIM:
+ if (offset & 1)
+ write_reg(data);
+ break;
}
}
-/*-------------------------------------------------
- applefdc_w - writes a byte to the FDC
--------------------------------------------------*/
-
-UINT8 applefdc_get_lines(device_t *device)
-{
- applefdc_token *fdc = get_token(device);
- return fdc->lines & 0x0f;
-}
-
-
-
-/***************************************************************************
- INTERFACE
-***************************************************************************/
-
-/*-------------------------------------------------
- DEVICE_START(oldfdc) - device start
- callback
--------------------------------------------------*/
-
-static DEVICE_START(oldfdc)
-{
- applefdc_start(device, APPLEFDC_APPLE2);
-}
-
-
-
-/*-------------------------------------------------
- DEVICE_START(iwm) - device start
- callback
--------------------------------------------------*/
-
-static DEVICE_START(iwm)
-{
- applefdc_start(device, APPLEFDC_IWM);
-}
-
-
-/*-------------------------------------------------
- DEVICE_START(iwm) - device start
- callback
--------------------------------------------------*/
-
-static DEVICE_START(swim)
-{
- applefdc_start(device, APPLEFDC_SWIM);
-}
-
-
-applefdc_base_device::applefdc_base_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock)
- : device_t(mconfig, type, name, tag, owner, clock)
-{
- m_token = global_alloc_clear(applefdc_token);
-}
-
//-------------------------------------------------
-// device_config_complete - perform any
-// operations now that the configuration is
-// complete
+// get_lines - accessor
//-------------------------------------------------
-void applefdc_base_device::device_config_complete()
+UINT8 applefdc_base_device::get_lines()
{
+ return m_lines & 0x0f;
}
-//-------------------------------------------------
-// device_reset - device-specific reset
-//-------------------------------------------------
-void applefdc_base_device::device_reset()
-{
- DEVICE_RESET_NAME( applefdc )(this);
-}
+/***************************************************************************
+ APPLE FDC - Used on Apple II
+***************************************************************************/
const device_type APPLEFDC = &device_creator<applefdc_device>;
applefdc_device::applefdc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : applefdc_base_device(mconfig, APPLEFDC, "Apple FDC", tag, owner, clock)
+ : applefdc_base_device(APPLEFDC_APPLE2, mconfig, APPLEFDC, "Apple FDC", tag, owner, clock)
{
}
-//-------------------------------------------------
-// device_start - device-specific startup
-//-------------------------------------------------
-void applefdc_device::device_start()
-{
- DEVICE_START_NAME( oldfdc )(this);
-}
+/***************************************************************************
+ IWM - Used on early Macs
+***************************************************************************/
const device_type IWM = &device_creator<iwm_device>;
iwm_device::iwm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : applefdc_base_device(mconfig, IWM, "Apple IWM (Integrated Woz Machine)", tag, owner, clock)
-{
-}
-
-//-------------------------------------------------
-// device_start - device-specific startup
-//-------------------------------------------------
-
-void iwm_device::device_start()
-{
- DEVICE_START_NAME( iwm )(this);
-}
-
-
-const device_type SWIM = &device_creator<swim_device>;
-
-swim_device::swim_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : applefdc_base_device(mconfig, SWIM, "Apple SWIM (Steve Woz Integrated Machine)", tag, owner, clock)
+ : applefdc_base_device(APPLEFDC_IWM, mconfig, IWM, "Apple IWM (Integrated Woz Machine)", tag, owner, clock)
{
}
-
-//-------------------------------------------------
-// device_start - device-specific startup
-//-------------------------------------------------
-
-void swim_device::device_start()
-{
- DEVICE_START_NAME( swim )(this);
-}
-
-
diff --git a/src/mess/machine/applefdc.h b/src/mess/machine/applefdc.h
index d3e2b34dc44..8b19d29f5c0 100644
--- a/src/mess/machine/applefdc.h
+++ b/src/mess/machine/applefdc.h
@@ -28,85 +28,114 @@
#define APPLEFDC_PH2 0x04
#define APPLEFDC_PH3 0x08
-class applefdc_base_device : public device_t
-{
-public:
- applefdc_base_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
- ~applefdc_base_device() { global_free(m_token); }
+extern const device_type APPLEFDC;
+extern const device_type IWM;
+extern const device_type SWIM;
- // access to legacy token
- void *token() const { assert(m_token != NULL); return m_token; }
-protected:
- // device-level overrides
- virtual void device_config_complete();
- virtual void device_start() { }
- virtual void device_reset();
-private:
- // internal state
- void *m_token;
-};
-class applefdc_device : public applefdc_base_device
-{
-public:
- applefdc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-protected:
- // device-level overrides
- virtual void device_start();
-};
-extern const device_type APPLEFDC;
+/***************************************************************************
+ INTERFACE
+***************************************************************************/
-class iwm_device : public applefdc_base_device
+struct applefdc_interface
{
-public:
- iwm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-protected:
- // device-level overrides
- virtual void device_start();
+ void (*set_lines)(device_t *device, UINT8 lines);
+ void (*set_enable_lines)(device_t *device, int enable_mask);
+
+ UINT8 (*read_data)(device_t *device);
+ void (*write_data)(device_t *device, UINT8 data);
+ int (*read_status)(device_t *device);
};
-extern const device_type IWM;
-class swim_device : public applefdc_base_device
+
+/***************************************************************************
+ BASE DEVICE
+***************************************************************************/
+
+class applefdc_base_device : public device_t
{
public:
- swim_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ // read/write handlers
+ virtual UINT8 read(UINT8 offset);
+ virtual void write(UINT8 offset, UINT8 data);
+
+ // read/write handlers overloads
+ UINT8 read(offs_t offset) { return read((UINT8) offset); }
+ void write(offs_t offset, UINT8 data) { write((UINT8) offset, data); }
+ DECLARE_READ8_MEMBER( read ) { return read((UINT8) offset); }
+ DECLARE_WRITE8_MEMBER( write ) { write((UINT8) offset, data); }
+
+ // accessor
+ UINT8 get_lines();
+
protected:
+ enum applefdc_t
+ {
+ APPLEFDC_APPLE2, /* classic Apple II disk controller (pre-IWM) */
+ APPLEFDC_IWM, /* Integrated Woz Machine */
+ APPLEFDC_SWIM /* Sander/Woz Integrated Machine */
+ };
+
+ // constructor
+ applefdc_base_device(applefdc_t fdc_type, const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
+
// device-level overrides
virtual void device_start();
-};
+ virtual void device_reset();
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
-extern const device_type SWIM;
+ // other protecteds
+ virtual void iwm_modereg_w(UINT8 data);
+private:
+ // data that is constant for the lifetime of the emulation
+ emu_timer * m_motor_timer;
+ applefdc_t m_type;
+
+ // data that changes at emulation time
+ UINT8 m_write_byte;
+ UINT8 m_lines; /* flags from IWM_MOTOR - IWM_Q7 */
+ UINT8 m_mode; /* 0-31; see above */
+ UINT8 m_handshake_hack; /* not sure what this is for */
+
+ // functions
+ const applefdc_interface *get_interface();
+ int iwm_enable2();
+ UINT8 iwm_readenable2handshake();
+ UINT8 statusreg_r();
+ UINT8 read_reg(int lines);
+ void write_reg(UINT8 data);
+ void turn_motor_onoff(bool status);
+ void iwm_access(int offset);
+};
/***************************************************************************
- TYPE DEFINITIONS
+ APPLE FDC - Used on Apple II
***************************************************************************/
-struct applefdc_interface
+class applefdc_device : public applefdc_base_device
{
- void (*set_lines)(device_t *device, UINT8 lines);
- void (*set_enable_lines)(device_t *device, int enable_mask);
-
- UINT8 (*read_data)(device_t *device);
- void (*write_data)(device_t *device, UINT8 data);
- int (*read_status)(device_t *device);
+public:
+ applefdc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
};
/***************************************************************************
- PROTOTYPES
+ IWM - Used on early Macs
***************************************************************************/
-/* read/write handlers */
-DECLARE_READ8_DEVICE_HANDLER(applefdc_r);
-DECLARE_WRITE8_DEVICE_HANDLER(applefdc_w);
-/* accessor */
-UINT8 applefdc_get_lines(device_t *device);
+class iwm_device : public applefdc_base_device
+{
+public:
+ iwm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+
/***************************************************************************
DEVICE CONFIGURATION MACROS
@@ -128,13 +157,5 @@ UINT8 applefdc_get_lines(device_t *device);
MCFG_DEVICE_MODIFY(_tag) \
MCFG_DEVICE_CONFIG(_intrf)
-#define MCFG_SWIM_ADD(_tag, _intrf) \
- MCFG_DEVICE_ADD(_tag, SWIM, 0) \
- MCFG_DEVICE_CONFIG(_intrf)
-
-#define MCFG_SWIM_MODIFY(_tag, _intrf) \
- MCFG_DEVICE_MODIFY(_tag) \
- MCFG_DEVICE_CONFIG(_intrf)
-
#endif /* __APPLEFDC_H__ */
diff --git a/src/mess/machine/lisa.c b/src/mess/machine/lisa.c
index 165376c2956..ecc957eb84a 100644
--- a/src/mess/machine/lisa.c
+++ b/src/mess/machine/lisa.c
@@ -1196,10 +1196,10 @@ INLINE void lisa_fdc_ttl_glue_access(running_machine &machine, offs_t offset)
state->m_MT1 = offset & 1;
if (state->m_MT1 && ! oldMT1)
{
- device_t *fdc = machine.device("fdc");
+ applefdc_base_device *fdc = machine.device<applefdc_base_device>("fdc");
state->m_PWM_floppy_motor_speed = (state->m_PWM_floppy_motor_speed << 1) & 0xff;
- if (applefdc_get_lines(fdc) & APPLEFDC_PH0)
+ if (fdc->get_lines() & APPLEFDC_PH0)
state->m_PWM_floppy_motor_speed |= 1;
sony_set_speed(((256-state->m_PWM_floppy_motor_speed) * 1.3) + 237);
}
@@ -1233,12 +1233,12 @@ INLINE void lisa_fdc_ttl_glue_access(running_machine &machine, offs_t offset)
READ8_MEMBER(lisa_state::lisa_fdc_io_r)
{
int answer=0;
- device_t *fdc = machine().device("fdc");
+ applefdc_base_device *fdc = machine().device<applefdc_base_device>("fdc");
switch ((offset & 0x0030) >> 4)
{
case 0: /* IWM */
- answer = applefdc_r(fdc, space, offset);
+ answer = fdc->read(offset);
break;
case 1: /* TTL glue */
@@ -1260,12 +1260,12 @@ READ8_MEMBER(lisa_state::lisa_fdc_io_r)
WRITE8_MEMBER(lisa_state::lisa_fdc_io_w)
{
- device_t *fdc = machine().device("fdc");
+ applefdc_base_device *fdc = machine().device<applefdc_base_device>("fdc");
switch ((offset & 0x0030) >> 4)
{
case 0: /* IWM */
- applefdc_w(fdc, space, offset, data);
+ fdc->write(offset, data);
break;
case 1: /* TTL glue */
diff --git a/src/mess/machine/mac.c b/src/mess/machine/mac.c
index 529d93c8532..d3150daf7ba 100644
--- a/src/mess/machine/mac.c
+++ b/src/mess/machine/mac.c
@@ -1140,9 +1140,9 @@ READ16_MEMBER ( mac_state::mac_iwm_r )
*/
UINT16 result = 0;
- device_t *fdc = space.machine().device("fdc");
+ applefdc_base_device *fdc = space.machine().device<applefdc_base_device>("fdc");
- result = applefdc_r(fdc, space, (offset >> 8));
+ result = fdc->read(offset >> 8);
if (LOG_MAC_IWM)
printf("mac_iwm_r: offset=0x%08x mem_mask %04x = %02x (PC %x)\n", offset, mem_mask, result, m_maincpu->pc());
@@ -1152,15 +1152,15 @@ READ16_MEMBER ( mac_state::mac_iwm_r )
WRITE16_MEMBER ( mac_state::mac_iwm_w )
{
- device_t *fdc = space.machine().device("fdc");
+ applefdc_base_device *fdc = space.machine().device<applefdc_base_device>("fdc");
if (LOG_MAC_IWM)
printf("mac_iwm_w: offset=0x%08x data=0x%04x mask %04x (PC=%x)\n", offset, data, mem_mask, m_maincpu->pc());
if (ACCESSING_BITS_0_7)
- applefdc_w(fdc, space, (offset >> 8), data & 0xff);
+ fdc->write((offset >> 8), data & 0xff);
else
- applefdc_w(fdc, space, (offset >> 8), data>>8);
+ fdc->write((offset >> 8), data>>8);
}
READ8_MEMBER(mac_state::mac_adb_via_in_cb2)
diff --git a/src/mess/machine/oric.c b/src/mess/machine/oric.c
index 69a4b6f2ad0..28f45dde26e 100644
--- a/src/mess/machine/oric.c
+++ b/src/mess/machine/oric.c
@@ -417,18 +417,18 @@ CALL &320 to start, or use BOBY rom.
static void oric_install_apple2_interface(running_machine &machine)
{
oric_state *state = machine.driver_data<oric_state>();
- device_t *fdc = machine.device("fdc");
+ applefdc_base_device *fdc = machine.device<applefdc_base_device>("fdc");
address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM);
if (state->m_is_telestrat)
return;
- space.install_read_handler(0x0300, 0x030f, read8_delegate(FUNC(oric_state::oric_IO_r),state));
- space.install_legacy_read_handler(*fdc, 0x0310, 0x031f, FUNC(applefdc_r));
+ space.install_read_handler(0x0300, 0x030f, read8_delegate(FUNC(oric_state::oric_IO_r), state));
+ space.install_read_handler(0x0310, 0x031f, read8_delegate(FUNC(applefdc_base_device::read), fdc));
space.install_read_bank(0x0320, 0x03ff, "bank4");
- space.install_write_handler(0x0300, 0x030f, write8_delegate(FUNC(oric_state::oric_IO_w),state));
- space.install_legacy_write_handler(*fdc, 0x0310, 0x031f, FUNC(applefdc_w));
+ space.install_write_handler(0x0300, 0x030f, write8_delegate(FUNC(oric_state::oric_IO_w), state));
+ space.install_write_handler(0x0310, 0x031f, write8_delegate(FUNC(applefdc_base_device::write), fdc));
state->membank("bank4")->set_base( state->memregion("maincpu")->base() + 0x014000 + 0x020);
}
@@ -541,15 +541,15 @@ WRITE8_MEMBER(oric_state::apple2_v2_interface_w)
static void oric_install_apple2_v2_interface(running_machine &machine)
{
oric_state *state = machine.driver_data<oric_state>();
- device_t *fdc = machine.device("fdc");
+ applefdc_base_device *fdc = machine.device<applefdc_base_device>("fdc");
address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM);
- space.install_read_handler(0x0300, 0x030f, read8_delegate(FUNC(oric_state::oric_IO_r),state));
- space.install_legacy_read_handler(*fdc, 0x0310, 0x031f, FUNC(applefdc_r));
+ space.install_read_handler(0x0300, 0x030f, read8_delegate(FUNC(oric_state::oric_IO_r), state));
+ space.install_read_handler(0x0310, 0x031f, read8_delegate(FUNC(applefdc_base_device::read), fdc));
space.install_read_bank(0x0320, 0x03ff, "bank4");
- space.install_write_handler(0x0300, 0x030f, write8_delegate(FUNC(oric_state::oric_IO_w),state));
- space.install_legacy_write_handler(*fdc, 0x0310, 0x031f, FUNC(applefdc_w));
+ space.install_write_handler(0x0300, 0x030f, write8_delegate(FUNC(oric_state::oric_IO_w), state));
+ space.install_write_handler(0x0310, 0x031f, write8_delegate(FUNC(applefdc_base_device::write), fdc));
space.install_write_handler(0x0380, 0x0383, write8_delegate(FUNC(oric_state::apple2_v2_interface_w),state));
state->apple2_v2_interface_w(space, 0, 0);
diff --git a/src/mess/machine/swim.c b/src/mess/machine/swim.c
new file mode 100644
index 00000000000..e7ab69fc14b
--- /dev/null
+++ b/src/mess/machine/swim.c
@@ -0,0 +1,220 @@
+/*********************************************************************
+
+ swim.c
+
+ Implementation of the Apple SWIM FDC controller; used on (less)
+ early Macs
+
+*********************************************************************/
+
+#include "machine/swim.h"
+
+
+/***************************************************************************
+ CONSTANTS
+***************************************************************************/
+
+#define LOG_SWIM 0
+
+enum
+{
+ SWIM_MODE_IWM,
+ SWIM_MODE_SWIM,
+ SWIM_MODE_SWIM2,
+ SWIM_MODE_SWIM3
+};
+
+
+/***************************************************************************
+ DEVICE
+***************************************************************************/
+
+const device_type SWIM = &device_creator<swim_device>;
+
+//-------------------------------------------------
+// ctor
+//-------------------------------------------------
+
+swim_device::swim_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : applefdc_base_device(APPLEFDC_SWIM, mconfig, SWIM, "Apple SWIM (Steve Woz Integrated Machine)", tag, owner, clock)
+{
+}
+
+
+
+//-------------------------------------------------
+// device_start - device-specific start
+//-------------------------------------------------
+
+void swim_device::device_start()
+{
+ // call inherited version
+ applefdc_base_device::device_start();
+
+ m_swim_mode = SWIM_MODE_IWM;
+ m_swim_magic_state = 0x00;
+ m_parm_offset = 0x00;
+ memset(m_ism_regs, 0, sizeof(m_ism_regs));
+ memset(m_parms, 0, sizeof(m_parms));
+}
+
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void swim_device::device_reset()
+{
+ // call inherited version
+ applefdc_base_device::device_reset();
+
+ static UINT8 swim_default_parms[16] =
+ {
+ 0x38, 0x18, 0x41, 0x2e, 0x2e, 0x18, 0x18, 0x1b,
+ 0x1b, 0x2f, 0x2f, 0x19, 0x19, 0x97, 0x1b, 0x57
+ };
+
+ for (int i = 0; i < 16; i++)
+ {
+ m_parms[i] = swim_default_parms[i];
+ }
+
+ m_swim_magic_state = 0;
+ m_swim_mode = SWIM_MODE_IWM;
+ m_parm_offset = 0;
+}
+
+
+
+//-------------------------------------------------
+// read - reads a byte from the FDC
+//-------------------------------------------------
+
+UINT8 swim_device::read(UINT8 offset)
+{
+ UINT8 result = 0;
+
+ if (m_swim_mode == SWIM_MODE_IWM)
+ {
+ // IWM mode
+ result = applefdc_base_device::read(offset);
+ }
+ else if (m_swim_mode >= SWIM_MODE_SWIM)
+ {
+ // reading parameter RAM?
+ if ((offset & 7) == 3)
+ {
+ result = m_parms[m_parm_offset++];
+ m_parm_offset &= 0xf;
+ }
+ else
+ {
+ result = m_ism_regs[offset&7];
+ }
+
+ if (LOG_SWIM)
+ logerror("SWIM: read %02x from offset %x\n", result, offset & 7);
+ }
+ return result;
+}
+
+
+
+//-------------------------------------------------
+// write - write a byte to the FDC
+//-------------------------------------------------
+
+void swim_device::write(UINT8 offset, UINT8 data)
+{
+ if (m_swim_mode == SWIM_MODE_IWM)
+ {
+ // IWM mode
+ applefdc_base_device::write(offset, data);
+ }
+ else if (m_swim_mode >= SWIM_MODE_SWIM)
+ {
+ if (LOG_SWIM)
+ logerror("SWIM: write %02x to offset %x\n", data, offset & 7);
+
+ switch (offset & 7)
+ {
+ case 2: // write CRC
+ break;
+
+ case 3: // write parameter
+ m_parms[m_parm_offset++] = data;
+ m_parm_offset &= 0xf;
+ break;
+
+ case 6: // write zeros to status (also zeroes parameter RAM pointer)
+ m_ism_regs[6] &= ~data;
+ m_parm_offset = 0;
+
+ if (data == 0xf8) // magic "revert to IWM" value
+ {
+ if (LOG_SWIM)
+ logerror("SWIM: reverting to IWM\n");
+ m_swim_mode = SWIM_MODE_IWM;
+ }
+ break;
+
+ case 7: // write ones to status
+ m_ism_regs[6] |= data;
+ break;
+
+ default:
+ m_ism_regs[offset & 7] = data;
+ break;
+
+ }
+ }
+}
+
+
+
+//-------------------------------------------------
+// iwm_modereg_w - changes the mode register
+//-------------------------------------------------
+
+void swim_device::iwm_modereg_w(UINT8 data)
+{
+ // SWIM mode is unlocked by writing 1/0/1/1 in a row to bit 6 (which is unused on IWM)
+ // when SWIM mode engages, the IWM is disconnected from both the 68k and the drives,
+ // and the ISM is substituted.
+
+ switch (m_swim_magic_state)
+ {
+ case 0:
+ case 2:
+ case 3:
+ if (data & 0x40)
+ {
+ m_swim_magic_state++;
+ }
+ else
+ {
+ m_swim_magic_state = 0;
+ }
+ break;
+ case 1:
+ if (!(data & 0x40))
+ {
+ m_swim_magic_state++;
+ }
+ else
+ {
+ m_swim_magic_state = 0;
+ }
+ break;
+ }
+
+ if (m_swim_magic_state == 4)
+ {
+ m_swim_magic_state = 0;
+ m_swim_mode = SWIM_MODE_SWIM;
+ }
+
+ // call inherited version
+ applefdc_base_device::iwm_modereg_w(data);
+}
diff --git a/src/mess/machine/swim.h b/src/mess/machine/swim.h
new file mode 100644
index 00000000000..1b9f2309134
--- /dev/null
+++ b/src/mess/machine/swim.h
@@ -0,0 +1,61 @@
+/*********************************************************************
+
+ swim.h
+
+ Implementation of the Apple SWIM FDC controller; used on (less)
+ early Macs
+
+*********************************************************************/
+
+#ifndef __SWIM_H__
+#define __SWIM_H__
+
+#include "machine/applefdc.h"
+
+
+/***************************************************************************
+ DEVICE
+***************************************************************************/
+
+extern const device_type SWIM;
+
+class swim_device : public applefdc_base_device
+{
+public:
+ swim_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // read/write
+ virtual UINT8 read(UINT8 offset);
+ virtual void write(UINT8 offset, UINT8 data);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // other overrides
+ virtual void iwm_modereg_w(UINT8 data);
+
+private:
+ UINT8 m_swim_mode;
+ UINT8 m_swim_magic_state;
+ UINT8 m_parm_offset;
+ UINT8 m_ism_regs[8];
+ UINT8 m_parms[16];
+};
+
+
+
+/***************************************************************************
+ DEVICE CONFIGURATION MACROS
+***************************************************************************/
+
+#define MCFG_SWIM_ADD(_tag, _intrf) \
+ MCFG_DEVICE_ADD(_tag, SWIM, 0) \
+ MCFG_DEVICE_CONFIG(_intrf)
+
+#define MCFG_SWIM_MODIFY(_tag, _intrf) \
+ MCFG_DEVICE_MODIFY(_tag) \
+ MCFG_DEVICE_CONFIG(_intrf)
+
+#endif // __SWIM_H__
diff --git a/src/mess/mess.mak b/src/mess/mess.mak
index 0cfb29847ce..41db8bebfc3 100644
--- a/src/mess/mess.mak
+++ b/src/mess/mess.mak
@@ -710,6 +710,7 @@ $(MESSOBJ)/apple.a: \
$(MESS_MACHINE)/egret.o \
$(MESS_MACHINE)/cuda.o \
$(MESS_MACHINE)/mackbd.o \
+ $(MESS_MACHINE)/swim.o \
$(MESS_VIDEO)/nubus_48gc.o \
$(MESS_VIDEO)/nubus_cb264.o \
$(MESS_VIDEO)/nubus_vikbw.o \