summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/machine/microdrv.cpp
blob: 1947d22f840ee6204bd3cba7d265d43a7a3917ae (plain) (tree)
1
2

                               














                                                                            
             
 


                                                                          
 

                                       
 




                                                                                    
 
                                                                         





                                                                            
                                                                                                  




                                                   
                                                                                                                                   
                                                         

                                               
 









                                                   



                                            
                                         

                                 

                                                                    




                                                                               



                        

 
                                                      

                                         
                                               


                                                      

                                        




                          
                                       



                                           

                                                       



















                                                                                                      
                                                                     


                                         
                                                                                         
                                               






                                                        
                                                                          




                                                     
                                                                       




                                                          
                                                                            





































                                                                     
// license:BSD-3-Clause
// copyright-holders:Curt Coder
/*********************************************************************

    microdrv.c

    MESS interface to the Sinclair Microdrive image abstraction code

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

#include "emu.h"
#include "microdrv.h"

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

#define LOG 0

#define MDV_SECTOR_COUNT            255
#define MDV_SECTOR_LENGTH           686
#define MDV_IMAGE_LENGTH            (MDV_SECTOR_COUNT * MDV_SECTOR_LENGTH)

#define MDV_PREAMBLE_LENGTH         12
#define MDV_GAP_LENGTH              120

#define MDV_OFFSET_HEADER_PREAMBLE  0
#define MDV_OFFSET_HEADER           MDV_OFFSET_HEADER_PREAMBLE + MDV_PREAMBLE_LENGTH
#define MDV_OFFSET_DATA_PREAMBLE    28
#define MDV_OFFSET_DATA             MDV_OFFSET_DATA_PREAMBLE + MDV_PREAMBLE_LENGTH
#define MDV_OFFSET_GAP              566

#define MDV_BITRATE                 120000 // invalid, from ZX microdrive

/***************************************************************************
    TYPE DEFINITIONS
***************************************************************************/

// device type definition
DEFINE_DEVICE_TYPE(MICRODRIVE, microdrive_image_device, "microdrive_image", "Sinclair Microdrive")

//-------------------------------------------------
//  microdrive_image_device - constructor
//-------------------------------------------------

microdrive_image_device::microdrive_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
	device_t(mconfig, MICRODRIVE, tag, owner, clock),
	device_image_interface(mconfig, *this),
	m_write_comms_out(*this)
{
}

//-------------------------------------------------
//  microdrive_image_device - destructor
//-------------------------------------------------

microdrive_image_device::~microdrive_image_device()
{
}


void microdrive_image_device::device_start()
{
	// resolve callbacks
	m_write_comms_out.resolve_safe();

	// allocate track buffers
	m_left = std::make_unique<uint8_t[]>(MDV_IMAGE_LENGTH / 2);
	m_right = std::make_unique<uint8_t[]>(MDV_IMAGE_LENGTH / 2);

	// allocate timers
	m_bit_timer = timer_alloc();
	m_bit_timer->adjust(attotime::zero, 0, attotime::from_hz(MDV_BITRATE));
	m_bit_timer->enable(0);

	m_clk = 0;
	m_comms_in = 0;
	m_comms_out = 0;
}

image_init_result microdrive_image_device::call_load()
{
	if (length() != MDV_IMAGE_LENGTH)
		return image_init_result::FAIL;

	for (int i = 0; i < MDV_IMAGE_LENGTH / 2; i++)
	{
		fread(m_left.get(), 1);
		fread(m_right.get(), 1);
	}

	m_bit_offset = 0;
	m_byte_offset = 0;

	return image_init_result::PASS;
}

void microdrive_image_device::call_unload()
{
	memset(m_left.get(), 0, MDV_IMAGE_LENGTH / 2);
	memset(m_right.get(), 0, MDV_IMAGE_LENGTH / 2);
}

void microdrive_image_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
	m_bit_offset++;

	if (m_bit_offset == 8)
	{
		m_bit_offset = 0;
		m_byte_offset++;

		if (m_byte_offset == MDV_IMAGE_LENGTH)
		{
			m_byte_offset = 0;
		}
	}
}

WRITE_LINE_MEMBER( microdrive_image_device::clk_w )
{
	if (LOG) logerror("Microdrive '%s' CLK: %u\n", tag(), state);
	if (!m_clk && state)
	{
		m_comms_out = m_comms_in;
		if (LOG) logerror("Microdrive '%s' COMMS OUT: %u\n", tag(), m_comms_out);
		m_write_comms_out(m_comms_out);
		m_bit_timer->enable(m_comms_out);
	}
	m_clk = state;
}

WRITE_LINE_MEMBER( microdrive_image_device::comms_in_w )
{
	if (LOG) logerror("Microdrive '%s' COMMS IN: %u\n", tag(), state);
	m_comms_in = state;
}

WRITE_LINE_MEMBER( microdrive_image_device::erase_w )
{
	if (LOG) logerror("Microdrive '%s' ERASE: %u\n", tag(), state);
	m_erase = state;
}

WRITE_LINE_MEMBER( microdrive_image_device::read_write_w )
{
	if (LOG) logerror("Microdrive '%s' READ/WRITE: %u\n", tag(), state);
	m_read_write = state;
}

WRITE_LINE_MEMBER( microdrive_image_device::data1_w )
{
	if (m_comms_out && !m_read_write)
	{
		// TODO
	}
}

WRITE_LINE_MEMBER( microdrive_image_device::data2_w )
{
	if (m_comms_out && !m_read_write)
	{
		// TODO
	}
}

READ_LINE_MEMBER( microdrive_image_device::data1_r )
{
	int data = 0;
	if (m_comms_out && m_read_write)
	{
		data = BIT(m_left[m_byte_offset], 7 - m_bit_offset);
	}
	return data;
}

READ_LINE_MEMBER( microdrive_image_device::data2_r )
{
	int data = 0;
	if (m_comms_out && m_read_write)
	{
		data = BIT(m_right[m_byte_offset], 7 - m_bit_offset);
	}
	return data;
}