diff options
Diffstat (limited to 'src/mame/drivers/cedar_magnet_flop.cpp')
-rw-r--r-- | src/mame/drivers/cedar_magnet_flop.cpp | 232 |
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 |