summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/cedar_magnet_flop.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/cedar_magnet_flop.cpp')
-rw-r--r--src/mame/drivers/cedar_magnet_flop.cpp232
1 files changed, 232 insertions, 0 deletions
diff --git a/src/mame/drivers/cedar_magnet_flop.cpp b/src/mame/drivers/cedar_magnet_flop.cpp
new file mode 100644
index 00000000000..7d4bdd8d42c
--- /dev/null
+++ b/src/mame/drivers/cedar_magnet_flop.cpp
@@ -0,0 +1,232 @@
+// license:BSD-3-Clause
+// copyright-holders:David Haywood
+
+// todo, scrap this and use the core SAB 2797B emulation
+// (FM - MFM type) @ 1.25mhz (oscillates 1.250~1.251)
+
+
+#include "emu.h"
+#include "cedar_magnet_flop.h"
+
+extern const device_type CEDAR_MAGNET_FLOP = &device_creator<cedar_magnet_flop_device>;
+
+cedar_magnet_flop_device::cedar_magnet_flop_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, CEDAR_MAGNET_FLOP, "Cedar Floppy Simulation", tag, owner, clock, "cedmag_flop", __FILE__)
+{
+}
+
+
+static MACHINE_CONFIG_FRAGMENT( cedar_magnet_flop )
+ MCFG_NVRAM_ADD_NO_FILL("floppy_nvram")
+MACHINE_CONFIG_END
+
+machine_config_constructor cedar_magnet_flop_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( cedar_magnet_flop );
+}
+
+void cedar_magnet_flop_device::device_start()
+{
+ subdevice<nvram_device>("floppy_nvram")->set_base(memregion("disk")->base(), 0xf0000);
+}
+
+void cedar_magnet_flop_device::device_reset()
+{
+ m_flopdat = 0;
+ m_flopcmd = 0;
+ m_flopsec = 0;
+ m_flopstat = 0;
+ m_floptrk = 0;
+}
+
+READ8_MEMBER(cedar_magnet_flop_device::port60_r)
+{
+ UINT8 ret = m_flopstat;
+ return ret;
+}
+
+READ8_MEMBER(cedar_magnet_flop_device::port61_r)
+{
+ UINT8 ret = m_curtrack;
+ return ret;
+}
+
+READ8_MEMBER(cedar_magnet_flop_device::port63_r)
+{
+ UINT8 ret = rand();
+
+ // printf("%s: port63_r (DATA) (%02x)\n", device().machine().describe_context(), ret);
+
+ if ((m_flopcmd&0xf0) == 0x90) // reading data
+ {
+ UINT8 *flop = memregion("disk")->base();
+ int side = (m_flopcmd & 0x02)>>1;
+ int read_offset_base = (m_flopsec * 0x400) + (m_curtrack * 0x3000) + (side * 0x1800);
+
+ int sector_size = 1024;
+
+ if (m_secoffs < sector_size)
+ {
+ m_flopstat |= 0x05;
+
+ int read_offset = read_offset_base + m_secoffs;
+ ret = flop[read_offset];
+
+ if (m_secoffs == 0)
+ {
+ // this is weird data, protection??
+ if(read_offset_base==0xea400)
+ printf("reading sector %d offset %d (from disk image at %04x) (cur track %02x cur side %02x cur sector %02x)\n", m_flopsec, m_secoffs, read_offset, m_curtrack, side, m_flopsec);
+ }
+
+ m_secoffs++;
+
+ if (m_secoffs == sector_size)
+ {
+ //printf("finished sector read\n");
+ m_flopstat &= ~0x05;
+
+ m_secoffs = 0;
+ m_flopsec++;
+ }
+ }
+ else
+ {
+ printf("read past sector!! %d\n", m_secoffs);
+ m_secoffs++;
+ }
+
+ }
+ else
+ {
+ fatalerror("read data in non-read mode?\n");
+ }
+//
+ return ret;
+}
+
+WRITE8_MEMBER(cedar_magnet_flop_device::port60_w)
+{
+ //printf("%s: port60_w (COMMAND) %02x\n", device().machine().describe_context(), data);
+ m_flopcmd = data;
+
+
+ switch (m_flopcmd & 0xf0)
+ {
+ case 0x00:
+ //printf("restore\n");
+ m_flopstat = 0x06;
+ m_curtrack = 0x00;
+ break;
+
+ case 0x10:
+ //printf("seek track\n");
+ m_curtrack = m_flopdat;
+ break;
+
+
+ case 0x90:
+ //printf("read sector\n");
+ m_flopstat |= 0x07;
+ m_secoffs = 0;
+ break;
+
+ case 0xb0:
+ //printf("write sector\n");
+ m_flopstat |= 0x07;
+ m_secoffs = 0;
+ break;
+
+ case 0xd0:
+ //printf("force interrupt?\n");
+ // m_flopstat = 0x06;
+ // m_flopstat &= ~0x07;
+ // m_maincpu->set_input_line(0, HOLD_LINE);
+
+ break;
+
+
+ default:
+ printf("unhandled disk command %02x\n", m_flopcmd);
+ }
+
+}
+
+WRITE8_MEMBER(cedar_magnet_flop_device::port62_w)
+{
+ //printf("%s: port62_w (SECTOR) %02x\n", device().machine().describe_context(), data);
+ m_flopsec = data;
+
+ if (m_flopsec < 200)
+ {
+ printf("sector specified <200!\n");
+ }
+
+ m_flopsec -= 200;
+}
+
+WRITE8_MEMBER(cedar_magnet_flop_device::port63_w)
+{
+ //printf("%s: port63_w (DATA) %02x\n", device().machine().describe_context(), data);
+ m_flopdat = data;
+
+ if ((m_flopcmd & 0xf0) == 0xb0) // writing data
+ {
+ UINT8 *flop = memregion("disk")->base();
+ int side = (m_flopcmd & 0x02)>>1;
+ int read_offset_base = (m_flopsec * 0x400) + (m_curtrack * 0x3000) + (side * 0x1800);
+
+ int sector_size = 1024;
+
+ if (m_secoffs < sector_size)
+ {
+ m_flopstat |= 0x05;
+
+ int read_offset = read_offset_base + m_secoffs;
+ flop[read_offset] = data;
+
+ if (m_secoffs == 0)
+ {
+ printf("writing sector %d offset %d (from disk image at %04x) (cur track %02x cur side %02x cur sector %02x)\n", m_flopsec, m_secoffs, read_offset, m_curtrack, side, m_flopsec);
+ }
+
+ m_secoffs++;
+
+ if (m_secoffs == sector_size)
+ {
+ //printf("finished sector read\n");
+ m_flopstat &= ~0x05;
+
+ m_secoffs = 0;
+ m_flopsec++;
+ }
+ }
+ }
+
+}
+
+WRITE8_MEMBER(cedar_magnet_flop_device::write)
+{
+ switch (offset & 3)
+ {
+ case 0x00:port60_w(space, offset, data);break;
+ // case 0x01:port61_w(space, offset, data);break;
+ case 0x02:port62_w(space, offset, data);break;
+ case 0x03:port63_w(space, offset, data);break;
+ default:break;
+ }
+}
+
+READ8_MEMBER(cedar_magnet_flop_device::read)
+{
+ switch (offset & 3)
+ {
+ case 0x00: return port60_r(space, offset);
+ case 0x01: return port61_r(space, offset);
+ //case 0x02: return port62_r(space, offset);
+ case 0x03: return port63_r(space, offset);
+ default: return 0x00;
+ }
+
+ return 0x00;
+} \ No newline at end of file