summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Tom <37988779+TwistedTom@users.noreply.github.com>2019-11-21 15:52:10 +0000
committer Vas Crabb <cuavas@users.noreply.github.com>2019-11-22 02:52:10 +1100
commitb4003648241f11e79808dba23e9c2db2c782d3f7 (patch)
tree4aa4b956be3bc7785ab43e703bee7afd0f71a793
parentc38f63c10afec9cd90ba48514a180344cb005762 (diff)
new working ZX Spectrum slot devices: DISCiPLE and +D disk interfaces (#5931)
* plusd working (rom patch) * plusd done * added disciple, not working * disciple working * wd_fdc fix * final tidy-up * ready for pr * Pernod70 changes * cuavas changes #1 * combine devices + files * sort out side_effects
-rw-r--r--hash/spectrum_cass.xml83
-rw-r--r--hash/spectrum_mgt_flop.xml111
-rw-r--r--scripts/src/bus.lua2
-rw-r--r--src/devices/bus/spectrum/exp.cpp8
-rw-r--r--src/devices/bus/spectrum/mgt.cpp677
-rw-r--r--src/devices/bus/spectrum/mgt.h103
-rw-r--r--src/devices/machine/wd_fdc.cpp8
-rw-r--r--src/devices/machine/wd_fdc.h1
-rw-r--r--src/lib/formats/coupedsk.cpp2
9 files changed, 949 insertions, 46 deletions
diff --git a/hash/spectrum_cass.xml b/hash/spectrum_cass.xml
index ede34d919a3..95200785229 100644
--- a/hash/spectrum_cass.xml
+++ b/hash/spectrum_cass.xml
@@ -60614,31 +60614,31 @@
</software>
<software name="disciple">
- <description>DISCiPLE System Tape v1</description>
- <year>19??</year>
- <publisher>&lt;unknown&gt;</publisher>
+ <description>DISCiPLE System Tape v2</description>
+ <year>1987</year>
+ <publisher>Miles Gordon Technology</publisher>
<part name="cass" interface="spectrum_cass">
<dataarea name="cass" size="13344">
- <rom name="disciple system tape v1.tzx" size="13344" crc="678e3e15" sha1="40aa91b4be6674d1d660fe7c6764af6e22a91e89"/>
+ <rom name="disciple system tape v2.tzx" size="13344" crc="678e3e15" sha1="40aa91b4be6674d1d660fe7c6764af6e22a91e89"/>
</dataarea>
</part>
</software>
<software name="disciple_a" cloneof="disciple">
- <description>DISCiPLE System Tape v2</description>
- <year>19??</year>
- <publisher>&lt;unknown&gt;</publisher>
+ <description>DISCiPLE System Tape v2b</description>
+ <year>1987</year>
+ <publisher>Miles Gordon Technology</publisher>
<part name="cass" interface="spectrum_cass">
<dataarea name="cass" size="13343">
- <rom name="disciple system tape v2.tzx" size="13343" crc="992a23fc" sha1="c0bea1d0275782a79762c2b8ba496dc255bcc414"/>
+ <rom name="disciple system tape v2b.tzx" size="13343" crc="992a23fc" sha1="c0bea1d0275782a79762c2b8ba496dc255bcc414"/>
</dataarea>
</part>
</software>
<software name="disciple_b" cloneof="disciple">
<description>DISCiPLE System Tape v2c</description>
- <year>19??</year>
- <publisher>&lt;unknown&gt;</publisher>
+ <year>1987</year>
+ <publisher>Miles Gordon Technology</publisher>
<part name="cass" interface="spectrum_cass">
<dataarea name="cass" size="13510">
<rom name="disciple system tape v2c.tzx" size="13510" crc="b45f0766" sha1="f72dabd21169113d0d96bdad9d08426c513e3935"/>
@@ -60648,19 +60648,30 @@
<software name="disciple_c" cloneof="disciple">
<description>DISCiPLE System Tape v3a</description>
- <year>19??</year>
- <publisher>&lt;unknown&gt;</publisher>
+ <year>1987</year>
+ <publisher>Miles Gordon Technology</publisher>
<part name="cass" interface="spectrum_cass">
<dataarea name="cass" size="13910">
<rom name="disciple system tape v3a.tzx" size="13910" crc="219af476" sha1="7bf03234dc817a857458406b8a20a75b1c5620de"/>
</dataarea>
</part>
</software>
-
+
<software name="disciple_d" cloneof="disciple">
+ <description>DISCiPLE System Tape v3b</description>
+ <year>1987</year>
+ <publisher>Miles Gordon Technology</publisher>
+ <part name="cass" interface="spectrum_cass">
+ <dataarea name="cass" size="13900">
+ <rom name="disciple system tape v3b.tzx" size="13900" crc="ce4f4108" sha1="62fa0f4ae51cea30b569c8019a05ffd8a1916970"/>
+ </dataarea>
+ </part>
+ </software>
+
+ <software name="disciple_e" cloneof="disciple">
<description>DISCiPLE System Tape v3d</description>
- <year>19??</year>
- <publisher>&lt;unknown&gt;</publisher>
+ <year>1987</year>
+ <publisher>Miles Gordon Technology</publisher>
<part name="cass" interface="spectrum_cass">
<dataarea name="cass" size="24077">
<rom name="disciple system tape v3d.tzx" size="24077" crc="e09fe7ff" sha1="239908071d560eeb4ae868097232afe3f1443503"/>
@@ -106717,45 +106728,35 @@
</software>
<software name="plusdsys">
- <description>Plus D System Tape (MGT)</description>
- <year>19??</year>
- <publisher>&lt;unknown&gt;</publisher>
+ <description>Plus D System Tape v2a</description>
+ <year>1987</year>
+ <publisher>Miles Gordon Technology</publisher>
<part name="cass" interface="spectrum_cass">
- <dataarea name="cass" size="24362">
- <rom name="plus d system tape (mgt).tzx" size="24362" crc="948c5cc9" sha1="1ef58a4d60c234fd187329ee1219ce969956f747"/>
+ <dataarea name="cass" size="24352">
+ <rom name="plus d system tape v2a.tzx" size="24352" crc="892644d5" sha1="6beb6507c01426e17679720604f4da4868b9ebfc"/>
</dataarea>
</part>
</software>
<software name="plusdsys_a" cloneof="plusdsys">
- <description>Plus D System Tape v1.0</description>
- <year>19??</year>
- <publisher>&lt;unknown&gt;</publisher>
+ <description>Plus D System Tape v1</description>
+ <year>1987</year>
+ <publisher>Miles Gordon Technology</publisher>
<part name="cass" interface="spectrum_cass">
- <dataarea name="cass" size="48402">
- <rom name="plus d system tape v1.0.tzx" size="48402" crc="a69bd63c" sha1="dd353f31dc5567a12755889163ca2d9d6b7447a7"/>
+ <dataarea name="cass" size="24266">
+ <rom name="plus d system tape v1.tzx" size="24266" crc="198fb732" sha1="128ed4ad929a8e856d57092bf1d21484090484f6"/>
</dataarea>
</part>
</software>
+ <!-- data is just 3 bytes different from v2a, title screen shows v2a, might just be bad dump? -->
<software name="plusdsys_b" cloneof="plusdsys">
- <description>Plus D System Tape v2.3</description>
- <year>19??</year>
- <publisher>&lt;unknown&gt;</publisher>
- <part name="cass" interface="spectrum_cass">
- <dataarea name="cass" size="24373">
- <rom name="plus d system tape v2.3.tzx" size="24373" crc="6e3f966b" sha1="85bacfdd3b3d4d969c423857899d7d31d4b1db12"/>
- </dataarea>
- </part>
- </software>
-
- <software name="plusdsys_c" cloneof="plusdsys">
- <description>Plus D System Tape v2a</description>
- <year>19??</year>
- <publisher>&lt;unknown&gt;</publisher>
+ <description>Plus D System Tape v2b?</description>
+ <year>1987</year>
+ <publisher>Miles Gordon Technology</publisher>
<part name="cass" interface="spectrum_cass">
- <dataarea name="cass" size="24269">
- <rom name="plus d system tape v2a.tzx" size="24269" crc="7e1a097c" sha1="1f702857d90dd49014f13aa86187152caf0d5a8b"/>
+ <dataarea name="cass" size="24362">
+ <rom name="plus d system tape v2b.tzx" size="24362" crc="efa5bdbe" sha1="00fd3ea95069b9ca0ffdd087e057a649ef3d8d6a"/>
</dataarea>
</part>
</software>
diff --git a/hash/spectrum_mgt_flop.xml b/hash/spectrum_mgt_flop.xml
new file mode 100644
index 00000000000..c777eef5ff1
--- /dev/null
+++ b/hash/spectrum_mgt_flop.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0"?>
+<!DOCTYPE softwarelist SYSTEM "softwarelist.dtd">
+
+<!-- ZX Spectrum MGT Disciple / +D disk images
+
+ images for the "Disciple" and "+D" ZX Spectrum fdd interfaces produced by MGT (Miles Gordan Technology)
+
+ insert system disk,
+ 'RUN' boots the main DOS from disk
+ 'CAT 1/2' lists disk 1/2 catalogue
+ 'LOAD Pn' loads program #n
+
+ more commands listed in devices\bus\spectrum\plusd.cpp or disciple.cpp
+
+ for disciple, must use matching rom/system disk versions:
+ v2 rom -> system disk/system tape ver 2, 2b, 2c
+ v3 rom -> system disk/system tape ver 3a, 3b or 3d
+-->
+
+<softwarelist name="spectrum_mgt_flop" description="ZX Spectrum MGT Disciple/Plus D disks">
+ <software name="plusdsys">
+ <description>Plus D System Disk v2a</description>
+ <year>1986</year>
+ <publisher>Miles Gordon Technology</publisher>
+ <part name="flop1" interface="floppy_3_5">
+ <dataarea name="flop" size="819200">
+ <rom name="plus d system disk v2a.mgt" size="819200" crc="abaeb064" sha1="d98dbf3bbdecd48e33a5c191ecaca29358984394"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="disciplesys">
+ <description>DISCiPLE System Disk v3d</description>
+ <year>1986</year>
+ <publisher>Miles Gordon Technology</publisher>
+ <part name="flop1" interface="floppy_3_5">
+ <dataarea name="flop" size="819200">
+ <rom name="disciple system disk v3d.mgt" size="819200" crc="fd931fba" sha1="6446120e6993dcae13e2259bf9a6d83ca300e166"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="disciplesys_a">
+ <description>DISCiPLE System Disk v3b</description>
+ <year>1986</year>
+ <publisher>Miles Gordon Technology</publisher>
+ <part name="flop1" interface="floppy_3_5">
+ <dataarea name="flop" size="819200">
+ <rom name="disciple system disk v3b.mgt" size="819200" crc="4fef82ca" sha1="69ab399bfc8b47090ca1c4cdaec8d01e6d901d06"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="disciplesys_b">
+ <description>DISCiPLE System Disk v3a</description>
+ <year>1986</year>
+ <publisher>Miles Gordon Technology</publisher>
+ <part name="flop1" interface="floppy_3_5">
+ <dataarea name="flop" size="819200">
+ <rom name="disciple system disk v3a.mgt" size="819200" crc="57a42968" sha1="435ae58de3dfdd1bbc17f97af8acf80328c276e6"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="disciplesys_c">
+ <description>DISCiPLE System Disk v2c</description>
+ <year>1986</year>
+ <publisher>Miles Gordon Technology</publisher>
+ <part name="flop1" interface="floppy_3_5">
+ <dataarea name="flop" size="819200">
+ <rom name="disciple system disk v2c.mgt" size="819200" crc="87e6484f" sha1="56cbaac201fdb8a4736c64adaeeb719a64d872d6"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="disciplesys_d">
+ <description>DISCiPLE System Disk v2b</description>
+ <year>1986</year>
+ <publisher>Miles Gordon Technology</publisher>
+ <part name="flop1" interface="floppy_3_5">
+ <dataarea name="flop" size="819200">
+ <rom name="disciple system disk v2b.mgt" size="819200" crc="84221dc8" sha1="6530305e69a9b02275b82abe0e7bca9afcc5c49f"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="disciplesys_e">
+ <description>DISCiPLE System Disk v2</description>
+ <year>1986</year>
+ <publisher>Miles Gordon Technology</publisher>
+ <part name="flop1" interface="floppy_3_5">
+ <dataarea name="flop" size="819200">
+ <rom name="disciple system disk v2.mgt" size="819200" crc="97de35a1" sha1="fa7bb3572910becbe9f9ed718ada43faf83e7f80"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="unidos">
+ <description>Uni-Dos</description>
+ <year>1990</year>
+ <publisher>S.D. Software</publisher>
+ <part name="flop1" interface="floppy_3_5">
+ <dataarea name="flop" size="819200">
+ <rom name="uni-dos v1.mgt" size="819200" crc="bfa654cd" sha1="1fafbdfdfe608bf20585fe46eace2eede3a95a6f"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="pickpoke">
+ <description>Pick-Poke-It</description>
+ <year>1989</year>
+ <publisher>Miles Gordon Technology</publisher>
+ <part name="flop1" interface="floppy_3_5">
+ <dataarea name="flop" size="819200">
+ <rom name="pick-poke-it.mgt" size="819200" crc="9efa0d0c" sha1="489a48fc842e79531b1a06c4f0c269ca696acccc"/>
+ </dataarea>
+ </part>
+ </software>
+</softwarelist>
diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua
index 710702aa78d..8a7ef8bc2cc 100644
--- a/scripts/src/bus.lua
+++ b/scripts/src/bus.lua
@@ -3611,6 +3611,8 @@ if (BUSES["SPECTRUM"]~=null) then
MAME_DIR .. "src/devices/bus/spectrum/melodik.h",
MAME_DIR .. "src/devices/bus/spectrum/mface.cpp",
MAME_DIR .. "src/devices/bus/spectrum/mface.h",
+ MAME_DIR .. "src/devices/bus/spectrum/mgt.cpp",
+ MAME_DIR .. "src/devices/bus/spectrum/mgt.h",
MAME_DIR .. "src/devices/bus/spectrum/mikroplus.cpp",
MAME_DIR .. "src/devices/bus/spectrum/mikroplus.h",
MAME_DIR .. "src/devices/bus/spectrum/opus.cpp",
diff --git a/src/devices/bus/spectrum/exp.cpp b/src/devices/bus/spectrum/exp.cpp
index e8890d824b9..160b4500eaf 100644
--- a/src/devices/bus/spectrum/exp.cpp
+++ b/src/devices/bus/spectrum/exp.cpp
@@ -156,17 +156,16 @@ void spectrum_expansion_slot_device::mreq_w(offs_t offset, uint8_t data)
// slot devices
#include "beta.h"
#include "beta128.h"
-//#include "disciple.h"
#include "intf1.h"
#include "intf2.h"
#include "fuller.h"
#include "kempjoy.h"
#include "melodik.h"
#include "mface.h"
+#include "mgt.h"
#include "mikroplus.h"
#include "opus.h"
#include "plus2test.h"
-//#include "plusd.h"
#include "protek.h"
#include "specdrum.h"
#include "uslot.h"
@@ -180,7 +179,7 @@ void spectrum_expansion_devices(device_slot_interface &device)
device.option_add("betav3", SPECTRUM_BETAV3);
device.option_add("betaplus", SPECTRUM_BETAPLUS);
device.option_add("beta128", SPECTRUM_BETA128);
- //device.option_add("disciple", SPECTRUM_DISCIPLE);
+ device.option_add("disciple", SPECTRUM_DISCIPLE);
device.option_add("intf1", SPECTRUM_INTF1);
device.option_add("intf2", SPECTRUM_INTF2);
device.option_add("fuller", SPECTRUM_FULLER);
@@ -191,7 +190,7 @@ void spectrum_expansion_devices(device_slot_interface &device)
device.option_add("mikroplus", SPECTRUM_MIKROPLUS);
device.option_add("mprint", SPECTRUM_MPRINT);
device.option_add("opus", SPECTRUM_OPUS);
- //device.option_add("plusd", SPECTRUM_PLUSD);
+ device.option_add("plusd", SPECTRUM_PLUSD);
device.option_add("protek", SPECTRUM_PROTEK);
device.option_add("specdrum", SPECTRUM_SPECDRUM);
device.option_add("uslot", SPECTRUM_USLOT);
@@ -211,6 +210,7 @@ void spec128_expansion_devices(device_slot_interface &device)
device.option_add("mikroplus", SPECTRUM_MIKROPLUS);
device.option_add("mprint", SPECTRUM_MPRINT);
device.option_add("opus", SPECTRUM_OPUS);
+ //device.option_add("plusd", SPECTRUM_PLUSD);
device.option_add("plus2test", SPECTRUM_PLUS2TEST);
device.option_add("protek", SPECTRUM_PROTEK);
device.option_add("specdrum", SPECTRUM_SPECDRUM);
diff --git a/src/devices/bus/spectrum/mgt.cpp b/src/devices/bus/spectrum/mgt.cpp
new file mode 100644
index 00000000000..6d3abff690e
--- /dev/null
+++ b/src/devices/bus/spectrum/mgt.cpp
@@ -0,0 +1,677 @@
+// license:BSD-3-Clause
+// copyright-holders:TwistedTom
+/**********************************************************************
+
+ DISCiPLE Multi-purpose Interface
+ +D Disk and Printer Interface
+
+ Miles Gordon Technology, UK, 1986-1990 (also produced the Sam Coupé home computer.)
+
+ DISCiPLE was MGT's first disk interface, a large plastic base that sat under the Spectrum, similar to Sinclair's official Interface 1.
+ +D was MGT's second (and last) disk interface, a cost and feature reduced version of the Disciple, a small metal-cased,
+ stand-alone unit which connects to ZX Spectrum's expansion slot via a ribbon cable.
+ A second Datel version of the +D exists (following the closure of MGT, it was licensed and produced by Datel.)
+ Many unofficial versions of +D exist and modern versions are still seen today as DIY-style projects/kits.
+ It's said the device's design and roms were officially released into the public domain at some point?
+
+ DISCiPLE features:
+ 8KB ROM
+ 8KB RAM
+ single floppy disk interface (2 drives)
+ Centronics parallel printer interface
+ "magic button" style memory snapshot grabber
+ 2 ATARI joystick ports (Sinclair 1/Kempston, Sinclair 2)
+ 2 network connectors (Interface 1 compatible, 3.5mm mono jack)
+ inhibit button (to lock out the interface)
+ pass-through expansion connector (to chain other devices)
+
+ +D features:
+ same as DISCiPLE
+ lost the joystick/network ports, inhibit button and pass-through expansion connector
+
+ DISCiPLE's official DOS was "GDOS".
+ +D's official DOS was "G+DOS".
+ Both of these were later superseded by "SAM DOS" (used by MGT's Sam Coupé.)
+ A 3rd party company SD Software released an alternative DOS "UNI-DOS" for both interfaces. (consisting of a disk and replacement ROM)
+
+ FDD support:
+
+ DISCiPLE's manual states any Shugart 400 SD/DD drive should work:
+ "The disciple will accept 5.25" or 3.5" drives, whether they are 40 track or 80 track,
+ single sided or double sided, single density or double density."
+
+ +D's manual states any Shugart 400 DD drive should work (but not SD)
+ "we recommend 3.5" or 5.25" 80-track double sided and double density drives,
+ which will give you up to 780K of storage per drive. But Shugart
+ 400-type 3" drives will also work."
+
+ +D only: Pin 26 /DDEN of the WD1772 is tied to ground, so permanent DD mode.
+ DISCiPLE only: /DDEN can be directly controlled via s/w by an IO write to 0x1f, bit 2.
+
+ Disks use "MGT filesystem".
+ A good description available at https://faqwiki.zxnet.co.uk/wiki/MGT_filesystem
+
+ Disk format is 512 bytes/sector, 10 sectors/track
+ 40 track, 1 side = 204,800 bytes (512*10*40*1)
+ 40 track, 2 side = 409,600 bytes
+ 80 track, 1 side = 409,600 bytes
+ 80 track, 2 side = 819,200 bytes <-- only this one supported so far
+
+ .mgt files work ok
+ .img files don't work (not in coupedsk.cpp)
+
+ The DOS must be loaded from a "System Disk" which is itself created from "System Tape" which was supplied with the unit.
+ The ROM provides just the RUN command, which boots the system disk and loads the full DOS.
+ Presumably the unit wasn't supplied with a system disk due to wide range of drives that can be used? (3", 3.5", 5.25")
+ The DOS survives a reset, so reloading of system disk is only required after full power cycle.
+
+ A few useful commands:
+ RUN Boots the system
+ CAT 1 Displays catalogue (drive 1)
+ CAT 1! Displays shortened catalogue (drive 1)
+ SAVE D1 "filename" Saves file
+ VERIFY D1 "filename" Confirms save has been made
+ LOAD D1 "filename" Loads file (except Snapshot files)
+ LOAD D1 "filename" S Loads 48K Snapshot file
+ LOAD D1 "filename" K Loads 128K Snapshot file
+ LOAD D1 "filename" SCREEN$ Loads screen file
+ LOAD Pn Loads the program (from its number)
+ ERASE D1 "file" TO "new file" Renames a file
+ ERASE D1 "filename" Erases a file
+ SAVE D1 "file" TO D2 Copies a file from drive1 to drive2
+ FORMAT D1 Formats disc in drive 1
+ FORMAT D1 TO 2 Formats drive 1; copies from 2 to 1
+
+ DISCiPLE snapshot button:
+ Caps Shift + button system freezes with a multi-coloured border effect
+ then, key 3 save current SCREEN
+ 4 save 48K PROGRAM
+ 5 save 128K PROGRAM
+ Caps Shift + number saves to drive 2 (or 1 if running from 2)
+
+ +D snapshot button:
+ button system freezes with a multi-coloured border effect (don't need to hold caps shift)
+ then, key 3 save current SCREEN
+ 4 save 48K PROGRAM
+ 5 save 128K PROGRAM
+ X do nothing, return to running program
+ Caps Shift + number saves to drive 2 (or 1 if running from 2)
+
+ DISCiPLE GDOS versions:
+ The rom/system disk versions must match,
+ v2 rom: use system disk/system tape ver 2, 2b, 2c
+ v3 rom: use system disk/system tape ver 3a, 3b or 3d
+
+ +D G+DOS versions:
+ a v1 (-non a) exists but has yet to be found/dumped,
+ from "pick-poke-it" user manual:
+ "A few PLUS D users are still using Version 1 of the ROM which was used in PLUS D's sold in December 1987-January 1988.
+ ... check the serial number on the bottom of your PLUS D. If it's a 4-figure number commencing with 1,
+ then you have a PLUS D with the Version 1 ROM."
+
+ DISCiPLE only curiosities:
+ The pass-through expansion connector has 4 extra pins (1 top/bottom each end)
+ so 2x30 pins compared to ususal 2x28 of Spectrum expansion slot.
+ Presumably this was intended for some unique expansion device that never appeared?
+ One of these extra pins can be directly controlled via s/w by an IO write to 0x1f, bit 5.
+ 2 other pins appear to be able to override the /ce signal from PAL ic9 to the rom.
+ 4th pin is unused.
+
+ The design allows for use of a larger 27128 (16KB) rom,
+ with the highest address line A13 controllable via s/w by an IO write to 0x1f, bit 3.
+ No larger roms seem to exist (or perhaps not yet found...?)
+ Some 16KB dumps can be found but these are combined dumps of the 8KB rom and 8KB ram (with the full DOS loaded).
+
+
+ Current status:
+ --------------
+
+ DISCiPLE
+ GDOS v3: all ok, occassional "no system file" when loading system disk, ok on 2nd attempt
+ GDOS v2: all ok
+ UNIDOS: all ok
+
+ +D
+ G+DOS: all ok
+ UNIDOS: all ok
+
+
+ Not working with 128K/+2 yet...
+
+**********************************************************************/
+
+
+#include "emu.h"
+#include "mgt.h"
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE(SPECTRUM_PLUSD, spectrum_plusd_device, "spectrum_plusd", "MGT +D")
+DEFINE_DEVICE_TYPE(SPECTRUM_DISCIPLE, spectrum_disciple_device, "spectrum_disciple", "MGT DISCiPLE")
+
+//-------------------------------------------------
+// INPUT_PORTS( plusd )
+//-------------------------------------------------
+
+INPUT_PORTS_START(plusd)
+ PORT_START("BUTTON")
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Snapshot Button") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHANGED_MEMBER(DEVICE_SELF, spectrum_plusd_device, snapshot_button, 0)
+INPUT_PORTS_END
+
+//-------------------------------------------------
+// INPUT_PORTS( disciple )
+//-------------------------------------------------
+
+INPUT_PORTS_START(disciple)
+ PORT_INCLUDE(plusd)
+
+ // Joystick 1 (right-hand) is both Kempston (port 0x1f) and Sinclair 1 (keys 6,7,8,9,0)
+ // Joystick 2 (left-hand) is Sinclair 2 (keys 1,2,3,4,5)
+
+ PORT_START("JOY1") /* Sinclair 1 (keys 6,7,8,9,0) 0xeffe , Kempston 0x1f */
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(1) PORT_NAME("Kempston\\Sinclair P1 Button 1")
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_8WAY PORT_PLAYER(1) PORT_NAME("Kempston\\Sinclair P1 Up")
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_8WAY PORT_PLAYER(1) PORT_NAME("Kempston\\Sinclair P1 Down")
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_8WAY PORT_PLAYER(1) PORT_NAME("Kempston\\Sinclair P1 Right")
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_8WAY PORT_PLAYER(1) PORT_NAME("Kempston\\Sinclair P1 Left")
+
+ PORT_START("JOY2") /* Sinclair 2 (keys 1,2,3,4,5) 0xf7fe */
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_8WAY PORT_PLAYER(2) PORT_NAME("Sinclair P2 Left") PORT_CODE(KEYCODE_4_PAD)
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_8WAY PORT_PLAYER(2) PORT_NAME("Sinclair P2 Right") PORT_CODE(KEYCODE_6_PAD)
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_8WAY PORT_PLAYER(2) PORT_NAME("Sinclair P2 Down") PORT_CODE(KEYCODE_2_PAD)
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_8WAY PORT_PLAYER(2) PORT_NAME("Sinclair P2 Up") PORT_CODE(KEYCODE_8_PAD)
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(2) PORT_NAME("Sinclair P2 Button 1") PORT_CODE(KEYCODE_0_PAD)
+INPUT_PORTS_END
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor spectrum_plusd_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(plusd);
+}
+
+ioport_constructor spectrum_disciple_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(disciple);
+}
+
+//-------------------------------------------------
+// SLOT_INTERFACE( plusd_floppies )
+//-------------------------------------------------
+
+static void plusd_floppies(device_slot_interface &device)
+{
+ device.option_add("35dd", FLOPPY_35_DD);
+}
+
+//-------------------------------------------------
+// floppy_format_type floppy_formats
+//-------------------------------------------------
+
+FLOPPY_FORMATS_MEMBER(spectrum_plusd_device::floppy_formats)
+ FLOPPY_MGT_FORMAT
+FLOPPY_FORMATS_END
+
+//-------------------------------------------------
+// ROM( plusd )
+//-------------------------------------------------
+
+ROM_START(plusd)
+ ROM_REGION(0x2000, "rom", 0)
+
+ ROM_DEFAULT_BIOS("gdos")
+
+ ROM_SYSTEM_BIOS(0, "gdos", "G+DOS v1a")
+ ROMX_LOAD("plusd_g.rom", 0x0000, 0x2000, CRC(569f7e55) SHA1(6b841dc5797ef7eb219ad455cd1e434ca3b9d30d), ROM_BIOS(0))
+
+ ROM_SYSTEM_BIOS(1, "unidos", "UNI-DOS v2")
+ ROMX_LOAD("plusd_uni.rom", 0x0000, 0x2000, CRC(60920496) SHA1(399c8c7c8335bc59849a2182c32347603fd0288a), ROM_BIOS(1))
+
+ ROM_REGION( 0x200, "plds", 0 )
+ ROM_LOAD( "alice_pal20l8.ic4", 0x000, 0x144, CRC(60135856) SHA1(41273f13a3680b29ba84ae1e85829482c783c55e) )
+ROM_END
+
+//-------------------------------------------------
+// ROM( disciple )
+//-------------------------------------------------
+
+ROM_START(disciple)
+ ROM_REGION(0x2000, "rom", 0)
+
+ ROM_DEFAULT_BIOS("gdos")
+
+ ROM_SYSTEM_BIOS(0, "gdos", "GDOS v3")
+ ROMX_LOAD("disciple_g.rom", 0x0000, 0x2000, CRC(82047489) SHA1(9a75ed4b293f968985be4c9aa893cd88276d1ced), ROM_BIOS(0))
+
+ ROM_SYSTEM_BIOS(1, "gdos2", "GDOS v2")
+ ROMX_LOAD("disciple_g2.rom", 0x0000, 0x2000, CRC(9d971781) SHA1(a03e67e4ee275a85153843f42269fa980875d551), ROM_BIOS(1))
+
+ ROM_SYSTEM_BIOS(2, "unidos", "UNI-DOS v2")
+ ROMX_LOAD("disciple_uni.rom", 0x0000, 0x2000, CRC(1fe7f4fa) SHA1(6277abe6358c99ab894795536a1eb9393f25b9b1), ROM_BIOS(2))
+
+ ROM_REGION( 0x400, "plds", 0 )
+ ROM_LOAD( "pal20l8.ic8", 0x000, 0x144, CRC(e53b2fcc) SHA1(85ce9634890d41be37cd9e0252698e5350a4c9c9) )
+ ROM_LOAD( "pal20l8.ic9", 0x200, 0x144, CRC(43ff2e38) SHA1(b872377ea9f91b29a811b0d484699ffe87bdf9fd) )
+ROM_END
+
+//-------------------------------------------------
+// device_add_mconfig - add device configuration
+//-------------------------------------------------
+
+void spectrum_plusd_device::device_add_mconfig(machine_config &config)
+{
+ WD1772(config, m_fdc, 8_MHz_XTAL);
+ FLOPPY_CONNECTOR(config, "fdc:0", plusd_floppies, "35dd", spectrum_plusd_device::floppy_formats).enable_sound(true);
+ FLOPPY_CONNECTOR(config, "fdc:1", plusd_floppies, "35dd", spectrum_plusd_device::floppy_formats).enable_sound(true);
+
+ /* printer port */
+ CENTRONICS(config, m_centronics, centronics_devices, "printer");
+ m_centronics->busy_handler().set(FUNC(spectrum_plusd_device::busy_w));
+
+ /* software list */
+ SOFTWARE_LIST(config, "flop_list").set_original("spectrum_mgt_flop");
+}
+
+void spectrum_disciple_device::device_add_mconfig(machine_config &config)
+{
+ spectrum_plusd_device::device_add_mconfig(config);
+
+ /* pass-through */
+ SPECTRUM_EXPANSION_SLOT(config, m_exp, spectrum_expansion_devices, nullptr);
+ m_exp->irq_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::irq_w));
+ m_exp->nmi_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::nmi_w));
+}
+
+const tiny_rom_entry *spectrum_plusd_device::device_rom_region() const
+{
+ return ROM_NAME(plusd);
+}
+
+const tiny_rom_entry *spectrum_disciple_device::device_rom_region() const
+{
+ return ROM_NAME(disciple);
+}
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// spectrum_plusd_device - constructor
+//-------------------------------------------------
+
+spectrum_plusd_device::spectrum_plusd_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, type, tag, owner, clock)
+ , device_spectrum_expansion_interface(mconfig, *this)
+ , m_rom(*this, "rom")
+ , m_fdc(*this, "fdc")
+ , m_floppy(*this, "fdc:%u", 0)
+ , m_centronics(*this, "centronics")
+ , m_centronics_busy(false)
+{
+}
+
+spectrum_plusd_device::spectrum_plusd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : spectrum_plusd_device(mconfig, SPECTRUM_PLUSD, tag, owner, clock)
+{
+}
+
+//-------------------------------------------------
+// spectrum_disciple_device - constructor
+//-------------------------------------------------
+
+spectrum_disciple_device::spectrum_disciple_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : spectrum_plusd_device(mconfig, SPECTRUM_DISCIPLE, tag, owner, clock)
+ , m_exp(*this, "exp")
+ , m_joy1(*this, "JOY1")
+ , m_joy2(*this, "JOY2")
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void spectrum_plusd_device::device_start()
+{
+ std::fill(std::begin(m_ram), std::end(m_ram), 0);
+ save_item(NAME(m_romcs));
+ save_item(NAME(m_ram));
+ save_item(NAME(m_centronics_busy));
+}
+
+void spectrum_disciple_device::device_start()
+{
+ spectrum_plusd_device::device_start();
+ save_item(NAME(m_map));
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void spectrum_plusd_device::device_reset()
+{
+ m_romcs = 0;
+}
+
+void spectrum_disciple_device::device_reset()
+{
+ spectrum_plusd_device::device_reset();
+ m_map = false;
+}
+
+//**************************************************************************
+// IMPLEMENTATION spectrum_plusd_device
+//**************************************************************************
+
+READ_LINE_MEMBER(spectrum_plusd_device::romcs)
+{
+ return m_romcs;
+}
+
+void spectrum_plusd_device::pre_opcode_fetch(offs_t offset)
+{
+ if (!machine().side_effects_disabled())
+ {
+ switch (offset)
+ {
+ case 0x0000:
+ case 0x0008:
+ case 0x003a:
+ case 0x0066:
+ m_romcs = 1;
+ break;
+ }
+ }
+}
+
+uint8_t spectrum_plusd_device::iorq_r(offs_t offset)
+{
+ uint8_t data = 0xff;
+
+ switch (offset & 0xff)
+ {
+ case 0xe3: // fdc status reg
+ case 0xeb: // fdc track reg
+ case 0xf3: // fdc sector reg
+ case 0xfb: // fdc data reg
+ data = m_fdc->read((offset >> 3) & 0x03);
+ break;
+ case 0xe7: // page in
+ if (!machine().side_effects_disabled())
+ m_romcs = 1;
+ break;
+ case 0xf7: // bit 7: printer busy
+ data = m_centronics_busy ? 0x80 : 0x00;
+ break;
+ }
+
+ return data;
+}
+
+void spectrum_plusd_device::iorq_w(offs_t offset, uint8_t data)
+{
+ switch (offset & 0xff)
+ {
+ case 0xe3: // fdc command reg
+ case 0xeb: // fdc track reg
+ case 0xf3: // fdc sector reg
+ case 0xfb: // fdc data reg
+ m_fdc->write((offset >> 3) & 0x03, data);
+ break;
+ case 0xef: // bit 0-1: drive select, 6: printer strobe, 7: side select
+ {
+ uint8_t drive = data & 3;
+ floppy_image_device* floppy = m_floppy[drive > 0 ? drive-1 : drive]->get_device();
+ m_fdc->set_floppy(floppy);
+ m_centronics->write_strobe(BIT(data, 6));
+ if (floppy) floppy->ss_w(BIT(data, 7));
+ }
+ break;
+ case 0xe7: // page out
+ m_romcs = 0;
+ break;
+ case 0xf7: // printer data
+ m_centronics->write_data0(BIT(data, 0));
+ m_centronics->write_data1(BIT(data, 1));
+ m_centronics->write_data2(BIT(data, 2));
+ m_centronics->write_data3(BIT(data, 3));
+ m_centronics->write_data4(BIT(data, 4));
+ m_centronics->write_data5(BIT(data, 5));
+ m_centronics->write_data6(BIT(data, 6));
+ m_centronics->write_data7(BIT(data, 7));
+ break;
+ }
+}
+
+uint8_t spectrum_plusd_device::mreq_r(offs_t offset)
+{
+ uint8_t data = 0xff;
+
+ if (m_romcs)
+ {
+ switch (offset & 0xe000)
+ {
+ case 0x0000:
+ data = m_rom->base()[offset & 0x1fff];
+ break;
+ case 0x2000:
+ data = m_ram[offset & 0x1fff];
+ break;
+ }
+ }
+
+ return data;
+}
+
+void spectrum_plusd_device::mreq_w(offs_t offset, uint8_t data)
+{
+ if (m_romcs)
+ {
+ switch (offset & 0xe000)
+ {
+ case 0x2000:
+ m_ram[offset & 0x1fff] = data;
+ break;
+ }
+ }
+}
+
+INPUT_CHANGED_MEMBER(spectrum_plusd_device::snapshot_button)
+{
+ if (newval && !oldval)
+ {
+ m_slot->nmi_w(CLEAR_LINE);
+ }
+ else
+ {
+ m_slot->nmi_w(ASSERT_LINE);
+ }
+}
+
+WRITE_LINE_MEMBER(spectrum_plusd_device::busy_w)
+{
+ m_centronics_busy = state;
+}
+
+//**************************************************************************
+// IMPLEMENTATION spectrum_disciple_device
+//**************************************************************************
+
+READ_LINE_MEMBER(spectrum_disciple_device::romcs)
+{
+ return m_romcs | m_exp->romcs();
+}
+
+void spectrum_disciple_device::pre_opcode_fetch(offs_t offset)
+{
+ m_exp->pre_opcode_fetch(offset);
+
+ if (!machine().side_effects_disabled())
+ {
+ switch (offset)
+ {
+ case 0x0000:
+ case 0x0008:
+ case 0x0066:
+ case 0x028e:
+ m_romcs = 1;
+ break;
+ }
+ }
+}
+
+uint8_t spectrum_disciple_device::iorq_r(offs_t offset)
+{
+ uint8_t data = m_exp->iorq_r(offset);
+
+ switch (offset & 0xff)
+ {
+ case 0x1b: // fdc status reg
+ case 0x5b: // fdc track reg
+ case 0x9b: // fdc sector reg
+ case 0xdb: // fdc data reg
+ data = m_fdc->read((offset >> 6) & 0x03);
+ break;
+ case 0x1f: // bit 0-4: kempston joystick, bit 6: printer busy, bit 7: network
+ data = bitswap<8>(~m_joy1->read(), 7, 6, 5, 0, 1, 2, 4, 3 ) & 0x1f;
+ data |= m_centronics_busy ? 0x00 : 0x40; // inverted by IC10 74ls240
+ // 7: network...
+ break;
+ case 0x7b: // reset boot
+ if (!machine().side_effects_disabled())
+ m_map = false;
+ break;
+ case 0xbb: // page in
+ if (!machine().side_effects_disabled())
+ m_romcs = 1;
+ break;
+ case 0xfe: // sinclair joysticks
+ if (((offset >> 8) & 16) == 0)
+ data = m_joy1->read() | (0xff ^ 0x1f);
+ if (((offset >> 8) & 8) == 0)
+ data = m_joy2->read() | (0xff ^ 0x1f);
+ break;
+ }
+
+ return data;
+}
+
+void spectrum_disciple_device::iorq_w(offs_t offset, uint8_t data)
+{
+ switch (offset & 0xff)
+ {
+ case 0x1b: // fdc command reg
+ case 0x5b: // fdc track reg
+ case 0x9b: // fdc sector reg
+ case 0xdb: // fdc data reg
+ m_fdc->write((offset >> 6) & 0x03, data);
+ break;
+ case 0x1f: // bit 0: drive select, 1: side select, 2: density, 3: rom bank, 4: inhibit switch control, 5: exp select, 6: printer strobe, 7: network
+ {
+ floppy_image_device* floppy = m_floppy[~data & 1]->get_device();
+ m_fdc->set_floppy(floppy);
+ if (floppy) floppy->ss_w(BIT(data, 1));
+ m_fdc->dden_w(BIT(data, 2));
+ // 3: rom bank...
+ // 4: inhibit switch control...
+ // 5: exp select...
+ m_centronics->write_strobe(BIT(data, 6));
+ // 7: network...
+ }
+ break;
+ case 0x3b: // wait when net=1
+ // ...
+ break;
+ case 0x7b: // set boot
+ m_map = true;
+ break;
+ case 0xbb: // page out
+ m_romcs = 0;
+ break;
+ case 0xfb: // printer data
+ m_centronics->write_data0(BIT(data, 0));
+ m_centronics->write_data1(BIT(data, 1));
+ m_centronics->write_data2(BIT(data, 2));
+ m_centronics->write_data3(BIT(data, 3));
+ m_centronics->write_data4(BIT(data, 4));
+ m_centronics->write_data5(BIT(data, 5));
+ m_centronics->write_data6(BIT(data, 6));
+ m_centronics->write_data7(BIT(data, 7));
+ break;
+ }
+
+ m_exp->iorq_w(offset, data);
+}
+
+uint8_t spectrum_disciple_device::mreq_r(offs_t offset)
+{
+ uint8_t data = 0xff;
+
+ if (m_romcs)
+ {
+ if (m_map)
+ {
+ switch (offset & 0xe000)
+ {
+ case 0x0000:
+ data = m_ram[offset & 0x1fff];
+ break;
+ case 0x2000:
+ data = m_rom->base()[offset & 0x1fff];
+ break;
+ }
+ }
+ else
+ {
+ switch (offset & 0xe000)
+ {
+ case 0x0000:
+ data = m_rom->base()[offset & 0x1fff];
+ break;
+ case 0x2000:
+ data = m_ram[offset & 0x1fff];
+ break;
+ }
+ }
+ }
+
+ if (m_exp->romcs())
+ data &= m_exp->mreq_r(offset);
+
+ return data;
+}
+
+void spectrum_disciple_device::mreq_w(offs_t offset, uint8_t data)
+{
+ if (m_romcs)
+ {
+ if (m_map)
+ {
+ switch (offset & 0xe000)
+ {
+ case 0x0000:
+ m_ram[offset & 0x1fff] = data;
+ break;
+ }
+ }
+ else
+ {
+ switch (offset & 0xe000)
+ {
+ case 0x2000:
+ m_ram[offset & 0x1fff] = data;
+ break;
+ }
+ }
+ }
+
+ if (m_exp->romcs())
+ m_exp->mreq_w(offset, data);
+}
diff --git a/src/devices/bus/spectrum/mgt.h b/src/devices/bus/spectrum/mgt.h
new file mode 100644
index 00000000000..e87cca4f276
--- /dev/null
+++ b/src/devices/bus/spectrum/mgt.h
@@ -0,0 +1,103 @@
+// license:BSD-3-Clause
+// copyright-holders:TwistedTom
+/**********************************************************************
+
+ DISCiPLE Multi-purpose Interface
+ +D Disk and Printer Interface
+
+ (Miles Gordon Technology)
+
+**********************************************************************/
+
+#ifndef MAME_BUS_SPECTRUM_MGT_H
+#define MAME_BUS_SPECTRUM_MGT_H
+
+#pragma once
+
+#include "exp.h"
+#include "softlist.h"
+#include "imagedev/floppy.h"
+#include "machine/wd_fdc.h"
+#include "bus/centronics/ctronics.h"
+#include "formats/coupedsk.h"
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+class spectrum_plusd_device: public device_t, public device_spectrum_expansion_interface
+{
+public:
+ // construction/destruction
+ spectrum_plusd_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+ spectrum_plusd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ DECLARE_FLOPPY_FORMATS(floppy_formats);
+ DECLARE_INPUT_CHANGED_MEMBER(snapshot_button);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ // optional information overrides
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual ioport_constructor device_input_ports() const override;
+ virtual const tiny_rom_entry *device_rom_region() const override;
+
+ virtual void pre_opcode_fetch(offs_t offset) override;
+ virtual uint8_t mreq_r(offs_t offset) override;
+ virtual void mreq_w(offs_t offset, uint8_t data) override;
+ virtual uint8_t iorq_r(offs_t offset) override;
+ virtual void iorq_w(offs_t offset, uint8_t data) override;
+ virtual DECLARE_READ_LINE_MEMBER(romcs) override;
+
+ DECLARE_WRITE_LINE_MEMBER(busy_w);
+
+ required_memory_region m_rom;
+ required_device<wd_fdc_device_base> m_fdc;
+ required_device_array<floppy_connector, 2> m_floppy;
+ required_device<centronics_device> m_centronics;
+
+ int m_romcs;
+ uint8_t m_ram[8 * 1024];
+ bool m_centronics_busy;
+};
+
+class spectrum_disciple_device: public spectrum_plusd_device
+{
+public:
+ // construction/destruction
+ spectrum_disciple_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ // optional information overrides
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual ioport_constructor device_input_ports() const override;
+ virtual const tiny_rom_entry *device_rom_region() const override;
+
+ virtual void pre_opcode_fetch(offs_t offset) override;
+ virtual uint8_t mreq_r(offs_t offset) override;
+ virtual void mreq_w(offs_t offset, uint8_t data) override;
+ virtual uint8_t iorq_r(offs_t offset) override;
+ virtual void iorq_w(offs_t offset, uint8_t data) override;
+ virtual DECLARE_READ_LINE_MEMBER(romcs) override;
+
+private:
+ required_device<spectrum_expansion_slot_device> m_exp;
+ required_ioport m_joy1;
+ required_ioport m_joy2;
+
+ bool m_map;
+};
+
+
+// device type definition
+DECLARE_DEVICE_TYPE(SPECTRUM_PLUSD, spectrum_plusd_device)
+DECLARE_DEVICE_TYPE(SPECTRUM_DISCIPLE, spectrum_disciple_device)
+
+#endif // MAME_BUS_SPECTRUM_MGT_H
diff --git a/src/devices/machine/wd_fdc.cpp b/src/devices/machine/wd_fdc.cpp
index 691a7914b10..d2353fd26a5 100644
--- a/src/devices/machine/wd_fdc.cpp
+++ b/src/devices/machine/wd_fdc.cpp
@@ -91,6 +91,7 @@ wd_fdc_device_base::wd_fdc_device_base(const machine_config &mconfig, device_typ
{
force_ready = false;
disable_motor_control = false;
+ spinup_on_interrupt = false;
}
void wd_fdc_device_base::set_force_ready(bool _force_ready)
@@ -1122,6 +1123,8 @@ void wd_fdc_device_base::cmd_w(uint8_t val)
{
// checkme
delay_cycles(t_cmd, dden ? delay_register_commit * 2 : delay_register_commit);
+ if (spinup_on_interrupt) // see note in WD1772 constructor
+ spinup();
}
else
{
@@ -2895,6 +2898,11 @@ wd1772_device::wd1772_device(const machine_config &mconfig, const char *tag, dev
head_control = false;
motor_control = true;
ready_hooked = false;
+
+ /* Sam Coupe/+D/Disciple expect a 0xd0 force interrupt command to cause a spin-up.
+ eg. +D issues 2x 0xd0, then waits for index pulses to start, bails out with no disk error if that doesn't happen.
+ Not sure if other chips should do this too? */
+ spinup_on_interrupt = true;
}
int wd1772_device::settle_time() const
diff --git a/src/devices/machine/wd_fdc.h b/src/devices/machine/wd_fdc.h
index 038fee362f6..d6b07260078 100644
--- a/src/devices/machine/wd_fdc.h
+++ b/src/devices/machine/wd_fdc.h
@@ -108,6 +108,7 @@ protected:
const int *step_times;
int delay_register_commit;
int delay_command_commit;
+ bool spinup_on_interrupt;
static constexpr int fd179x_step_times[4] = { 6000, 12000, 20000, 30000 };
static constexpr int fd176x_step_times[4] = { 12000, 24000, 40000, 60000 };
diff --git a/src/lib/formats/coupedsk.cpp b/src/lib/formats/coupedsk.cpp
index 803f69bbbb7..045e42b7bb5 100644
--- a/src/lib/formats/coupedsk.cpp
+++ b/src/lib/formats/coupedsk.cpp
@@ -115,7 +115,7 @@ bool mgt_format::save(io_generic *io, floppy_image *image)
for(int head=0; head < 2; head++) {
for(int track=0; track < 80; track++) {
get_track_data_mfm_pc(track, head, image, 2000, 512, sector_count, sectdata);
- io_generic_write(io, sectdata, (head*80 + track)*track_size, track_size);
+ io_generic_write(io, sectdata, (track*2+head)*track_size, track_size);
}
}