diff options
Diffstat (limited to 'src/mame/machine/swim.c')
-rw-r--r-- | src/mame/machine/swim.c | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/src/mame/machine/swim.c b/src/mame/machine/swim.c new file mode 100644 index 00000000000..9e1506ad9ab --- /dev/null +++ b/src/mame/machine/swim.c @@ -0,0 +1,222 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +/********************************************************************* + + 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, "swim", __FILE__) +{ +} + + + +//------------------------------------------------- +// 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); +} |