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
This commit is contained in:
Tom 2019-11-21 15:52:10 +00:00 committed by Vas Crabb
parent c38f63c10a
commit b400364824
9 changed files with 949 additions and 46 deletions

View File

@ -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>
<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="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>
<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>

111
hash/spectrum_mgt_flop.xml Normal file
View File

@ -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>

View File

@ -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",

View File

@ -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);

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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 };

View File

@ -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);
}
}