diff options
Diffstat (limited to 'src/mame/machine/microdrv.c')
-rw-r--r-- | src/mame/machine/microdrv.c | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/src/mame/machine/microdrv.c b/src/mame/machine/microdrv.c new file mode 100644 index 00000000000..803f1d921d8 --- /dev/null +++ b/src/mame/machine/microdrv.c @@ -0,0 +1,197 @@ +// 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 +const device_type MICRODRIVE = &device_creator<microdrive_image_device>; + +//------------------------------------------------- +// microdrive_image_device - constructor +//------------------------------------------------- + +microdrive_image_device::microdrive_image_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, MICRODRIVE, "Microdrive", tag, owner, clock, "microdrive_image", __FILE__), + device_image_interface(mconfig, *this), + m_write_comms_out(*this) +{ +} + +//------------------------------------------------- +// microdrive_image_device - destructor +//------------------------------------------------- + +microdrive_image_device::~microdrive_image_device() +{ +} + +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void microdrive_image_device::device_config_complete() +{ + // set brief and instance name + update_names(); +} + + +void microdrive_image_device::device_start() +{ + // resolve callbacks + m_write_comms_out.resolve_safe(); + + // allocate track buffers + m_left = auto_alloc_array(machine(), UINT8, MDV_IMAGE_LENGTH / 2); + m_right = auto_alloc_array(machine(), UINT8, 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; +} + +bool microdrive_image_device::call_load() +{ + if (length() != MDV_IMAGE_LENGTH) + return IMAGE_INIT_FAIL; + + for (int i = 0; i < MDV_IMAGE_LENGTH / 2; i++) + { + fread(m_left, 1); + fread(m_right, 1); + } + + m_bit_offset = 0; + m_byte_offset = 0; + + return IMAGE_INIT_PASS; +} + +void microdrive_image_device::call_unload() +{ + memset(m_left, 0, MDV_IMAGE_LENGTH / 2); + memset(m_right, 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; +} |