summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/machine/swim.cpp
blob: 6e901d1f2887e9ed3521227a0575a9b1e324783a (plain) (tree)
1
2
3
4
5
6
7
8

                               




                                                                      
              


                                                                      
                






                                                                            
                     













                                                                            
                                                                                         




                                                   
                                                                                                         
                                                                               













                                                   


                                            














                                                   
                                               




















                                                               
                                         
 
                           






























                                                                                         
                                                     
























                                                                                            
                                                                                  
























                                                                                     
                                             







































                                                                                              
// license:BSD-3-Clause
// copyright-holders:R. Belmont
/*********************************************************************

    swim.c

    Implementation of the Apple SWIM FDC controller; used on (less)
    early Macs

*********************************************************************/

#include "emu.h"
#include "machine/swim.h"


/***************************************************************************
    CONSTANTS
***************************************************************************/

#define LOG_SWIM    0

enum
{
	SWIM_MODE_IWM,
	SWIM_MODE_SWIM,
	SWIM_MODE_SWIM2,
	SWIM_MODE_SWIM3
};


/***************************************************************************
    DEVICE
***************************************************************************/

DEFINE_DEVICE_TYPE(SWIM, swim_device, "swim", "Apple SWIM (Steve Woz Integrated Machine")

//-------------------------------------------------
//  ctor
//-------------------------------------------------

swim_device::swim_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
	: applefdc_base_device(APPLEFDC_SWIM, mconfig, SWIM, 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_t 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_t swim_device::read(uint8_t offset)
{
	uint8_t 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_t offset, uint8_t 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_t 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);
}