diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mess/drivers/mac.c | 1 | ||||
-rw-r--r-- | src/mess/machine/a2diskii.c | 4 | ||||
-rw-r--r-- | src/mess/machine/apple2gs.c | 4 | ||||
-rw-r--r-- | src/mess/machine/apple3.c | 9 | ||||
-rw-r--r-- | src/mess/machine/applefdc.c | 736 | ||||
-rw-r--r-- | src/mess/machine/applefdc.h | 137 | ||||
-rw-r--r-- | src/mess/machine/lisa.c | 12 | ||||
-rw-r--r-- | src/mess/machine/mac.c | 10 | ||||
-rw-r--r-- | src/mess/machine/oric.c | 20 | ||||
-rw-r--r-- | src/mess/machine/swim.c | 220 | ||||
-rw-r--r-- | src/mess/machine/swim.h | 61 | ||||
-rw-r--r-- | src/mess/mess.mak | 1 |
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 \ |