summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/imagedev
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2019-07-30 21:02:54 -0400
committer AJR <ajrhacker@users.noreply.github.com>2019-07-30 21:04:38 -0400
commitb218528e1f1857d06d7c08b8ffccdfef50c24e43 (patch)
tree2f76c449d90304ca39e4f2f4ba82b17c301c3827 /src/devices/imagedev
parentab6a69e531c9f2b6772f09a4ea3604edf838ce4d (diff)
microdrv: Change image type to magtape; default clock; move to imagedev (nw)
Diffstat (limited to 'src/devices/imagedev')
-rw-r--r--src/devices/imagedev/microdrv.cpp185
-rw-r--r--src/devices/imagedev/microdrv.h94
2 files changed, 279 insertions, 0 deletions
diff --git a/src/devices/imagedev/microdrv.cpp b/src/devices/imagedev/microdrv.cpp
new file mode 100644
index 00000000000..1947d22f840
--- /dev/null
+++ b/src/devices/imagedev/microdrv.cpp
@@ -0,0 +1,185 @@
+// 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;
+}
diff --git a/src/devices/imagedev/microdrv.h b/src/devices/imagedev/microdrv.h
new file mode 100644
index 00000000000..4ec1f728d83
--- /dev/null
+++ b/src/devices/imagedev/microdrv.h
@@ -0,0 +1,94 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/*********************************************************************
+
+ microdrv.h
+
+ MESS interface to the Sinclair Microdrive image abstraction code
+
+*********************************************************************/
+
+#ifndef MAME_DEVICES_IMAGEDEV_MICRODRV_H
+#define MAME_DEVICES_IMAGEDEV_MICRODRV_H
+
+#pragma once
+
+#include "softlist_dev.h"
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MDV_1 "mdv1"
+#define MDV_2 "mdv2"
+
+
+/***************************************************************************
+ TYPE DEFINITIONS
+***************************************************************************/
+
+// ======================> microdrive_image_device
+
+class microdrive_image_device : public device_t,
+ public device_image_interface
+{
+public:
+ // construction/destruction
+ microdrive_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
+ virtual ~microdrive_image_device();
+
+ auto comms_out_wr_callback() { return m_write_comms_out.bind(); }
+
+ // image-level overrides
+ virtual image_init_result call_load() override;
+ virtual void call_unload() override;
+ virtual const software_list_loader &get_software_list_loader() const override { return image_software_list_loader::instance(); }
+
+ virtual iodevice_t image_type() const override { return IO_MAGTAPE; }
+
+ virtual bool is_readable() const override { return 1; }
+ virtual bool is_writeable() const override { return 1; }
+ virtual bool is_creatable() const override { return 0; }
+ virtual bool must_be_loaded() const override { return 0; }
+ virtual bool is_reset_on_load() const override { return 0; }
+ virtual const char *image_interface() const override { return "ql_cass"; }
+ virtual const char *file_extensions() const override { return "mdv"; }
+
+ // specific implementation
+ DECLARE_WRITE_LINE_MEMBER( clk_w );
+ DECLARE_WRITE_LINE_MEMBER( comms_in_w );
+ DECLARE_WRITE_LINE_MEMBER( erase_w );
+ DECLARE_WRITE_LINE_MEMBER( read_write_w );
+ DECLARE_WRITE_LINE_MEMBER( data1_w );
+ DECLARE_WRITE_LINE_MEMBER( data2_w );
+ DECLARE_READ_LINE_MEMBER ( data1_r );
+ DECLARE_READ_LINE_MEMBER ( data2_r );
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+private:
+ devcb_write_line m_write_comms_out;
+
+ int m_clk;
+ int m_comms_in;
+ int m_comms_out;
+ int m_erase;
+ int m_read_write;
+
+ std::unique_ptr<uint8_t[]> m_left;
+ std::unique_ptr<uint8_t[]> m_right;
+
+ int m_bit_offset;
+ int m_byte_offset;
+
+ emu_timer *m_bit_timer;
+};
+
+
+// device type definition
+DECLARE_DEVICE_TYPE(MICRODRIVE, microdrive_image_device)
+
+#endif // MAME_DEVICES_IMAGEDEV_MICRODRV_H