diff options
Diffstat (limited to 'src/devices/bus/coco/coco_fdc.cpp')
-rw-r--r-- | src/devices/bus/coco/coco_fdc.cpp | 652 |
1 files changed, 427 insertions, 225 deletions
diff --git a/src/devices/bus/coco/coco_fdc.cpp b/src/devices/bus/coco/coco_fdc.cpp index eded4ed4306..dfd68864f18 100644 --- a/src/devices/bus/coco/coco_fdc.cpp +++ b/src/devices/bus/coco/coco_fdc.cpp @@ -14,9 +14,8 @@ cartridge, it is dealt with in the main coco.cpp file. The wd's variables are mapped to $FF48-$FF4B on the CoCo and on $FF40-$FF43 - on the Dragon. In addition, there is another register - called DSKREG that controls the interface with the wd1793. DSKREG is - detailed below: But they appear to be + on the Dragon. In addition, there is another register called DSKREG that + controls the interface with the wd1793. DSKREG is detailed below: References: CoCo: Disk Basic Unravelled @@ -40,32 +39,77 @@ Reading from $FF48-$FF4F clears bit 7 of DSKREG ($FF40) + --------------------------------------------------------------------------- + + Disto Super Controller II + Mini Expansion Bus + No Halt Extension. Implemented by using a read and write cache. + + CachDat - Cache Data Register + $FF74 & $FF75: Read/Write cache data. + + Normally cache size is 256 bytes. But a common upgrade is to change + it to 512 bytes. + + CachCtrl - Cache Controller + $FF76 & $FF77: + write + clears buffer counter + + read bit: + 7: 0 - indicates an interrupt request from the disk controller + 1 - no interrupt + 3: 0 - disable CART / FIRQ (masked) + 1 - enable CART / FIRQ + 2: 0 - normal NMI + 1 - masked NMI + 1: 0 - compatible I/O mode + 1 - buffered I/O mode + 0: 0 - buffered write operation + 1 - buffered read operation + + There was a jumper to set the addresses to be FF58 or FF5B. Not implemented. + *********************************************************************/ #include "emu.h" -#include "cococart.h" #include "coco_fdc.h" + +#include "meb_intrf.h" + #include "imagedev/floppy.h" +#include "machine/input_merger.h" #include "machine/msm6242.h" -#include "machine/ds1315.h" #include "machine/wd_fdc.h" + #include "formats/dmk_dsk.h" +#include "formats/flex_dsk.h" +#include "formats/fs_coco_os9.h" +#include "formats/fs_coco_rsdos.h" #include "formats/jvc_dsk.h" -#include "formats/vdk_dsk.h" -#include "formats/sdf_dsk.h" #include "formats/os9_dsk.h" +#include "formats/sdf_dsk.h" +#include "formats/vdk_dsk.h" + +#define LOG_WDFDC (1U << 1) // Shows register setup +#define LOG_WDIO (1U << 2) // Shows data read and write +#define LOG_WDSCII (1U << 3) // Shows SCII register setup + +//#define VERBOSE (LOG_GENERAL|LOG_WDFDC|LOG_WDSCII) +#include "logmacro.h" + +#define LOGWDFDC(...) LOGMASKED(LOG_WDFDC, __VA_ARGS__) +#define LOGWDIO(...) LOGMASKED(LOG_WDIO, __VA_ARGS__) +#define LOGWDSCII(...) LOGMASKED(LOG_WDSCII, __VA_ARGS__) /*************************************************************************** PARAMETERS ***************************************************************************/ -#define LOG_FDC 0 #define WD_TAG "wd17xx" #define WD2797_TAG "wd2797" -#define DISTO_TAG "disto" -#define CLOUD9_TAG "cloud9" - +#define MEB_TAG "meb" template class device_finder<coco_family_fdc_device_base, false>; template class device_finder<coco_family_fdc_device_base, true>; @@ -79,54 +123,46 @@ class coco_fdc_device_base : public coco_family_fdc_device_base { protected: // construction/destruction - coco_fdc_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); - - enum class rtc_type - { - DISTO = 0x00, - CLOUD9 = 0x01, - NONE = 0xFF - }; + coco_fdc_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); // device-level overrides - virtual DECLARE_READ8_MEMBER(cts_read) override; - virtual DECLARE_READ8_MEMBER(scs_read) override; - virtual DECLARE_WRITE8_MEMBER(scs_write) override; - virtual void device_add_mconfig(machine_config &config) override; + virtual u8 cts_read(offs_t offset) override; + virtual u8 scs_read(offs_t offset) override; + virtual void scs_write(offs_t offset, u8 data) override; + virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; // methods virtual void update_lines() override; - void dskreg_w(uint8_t data); - rtc_type real_time_clock(); + void dskreg_w(u8 data); // devices required_device<wd1773_device> m_wd17xx; - required_device<ds1315_device> m_ds1315; required_device_array<floppy_connector, 4> m_floppies; - - // Disto RTC - required_device<msm6242_device> m_disto_msm6242; // 6242 RTC on Disto interface - offs_t m_msm6242_rtc_address; - optional_ioport m_rtc; }; - /*************************************************************************** LOCAL VARIABLES ***************************************************************************/ -FLOPPY_FORMATS_MEMBER( coco_family_fdc_device_base::floppy_formats ) - FLOPPY_DMK_FORMAT, - FLOPPY_JVC_FORMAT, - FLOPPY_VDK_FORMAT, - FLOPPY_SDF_FORMAT, - FLOPPY_OS9_FORMAT -FLOPPY_FORMATS_END +void coco_family_fdc_device_base::floppy_formats(format_registration &fr) +{ + fr.add_mfm_containers(); + fr.add(FLOPPY_FLEX_FORMAT); + fr.add(FLOPPY_DMK_FORMAT); + fr.add(FLOPPY_SDF_FORMAT); + fr.add(FLOPPY_JVC_FORMAT); + fr.add(FLOPPY_VDK_FORMAT); + fr.add(FLOPPY_OS9_FORMAT); + fr.add(fs::COCO_RSDOS); + fr.add(fs::COCO_OS9); +} static void coco_fdc_floppies(device_slot_interface &device) { - device.option_add("qd", FLOPPY_525_QD); + device.option_add("525qd", FLOPPY_525_QD); + device.option_add("525dd", FLOPPY_525_DD); + device.option_add("35dd", FLOPPY_35_DD); } void coco_fdc_device_base::device_add_mconfig(machine_config &config) @@ -134,15 +170,13 @@ void coco_fdc_device_base::device_add_mconfig(machine_config &config) WD1773(config, m_wd17xx, 8_MHz_XTAL); m_wd17xx->intrq_wr_callback().set(FUNC(coco_fdc_device_base::fdc_intrq_w)); m_wd17xx->drq_wr_callback().set(FUNC(coco_fdc_device_base::fdc_drq_w)); + m_wd17xx->set_disable_motor_control(true); + m_wd17xx->set_force_ready(true); - FLOPPY_CONNECTOR(config, m_floppies[0], coco_fdc_floppies, "qd", coco_fdc_device_base::floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, m_floppies[1], coco_fdc_floppies, "qd", coco_fdc_device_base::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppies[0], coco_fdc_floppies, "525dd", coco_fdc_device_base::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppies[1], coco_fdc_floppies, "525dd", coco_fdc_device_base::floppy_formats).enable_sound(true); FLOPPY_CONNECTOR(config, m_floppies[2], coco_fdc_floppies, nullptr, coco_fdc_device_base::floppy_formats).enable_sound(true); FLOPPY_CONNECTOR(config, m_floppies[3], coco_fdc_floppies, nullptr, coco_fdc_device_base::floppy_formats).enable_sound(true); - - MSM6242(config, m_disto_msm6242, 32.768_kHz_XTAL); - - DS1315(config, CLOUD9_TAG, 0); } @@ -178,16 +212,17 @@ void coco_family_fdc_device_base::device_reset() // coco_family_fdc_device_base::get_cart_base //------------------------------------------------- -uint8_t* coco_family_fdc_device_base::get_cart_base() +u8 *coco_family_fdc_device_base::get_cart_base() { return memregion("eprom")->base(); } + //------------------------------------------------- // coco_family_fdc_device_base::get_cart_memregion //------------------------------------------------- -memory_region* coco_family_fdc_device_base::get_cart_memregion() +memory_region *coco_family_fdc_device_base::get_cart_memregion() { return memregion("eprom"); } @@ -201,35 +236,13 @@ memory_region* coco_family_fdc_device_base::get_cart_memregion() // coco_fdc_device_base - constructor //------------------------------------------------- -coco_fdc_device_base::coco_fdc_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) +coco_fdc_device_base::coco_fdc_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : coco_family_fdc_device_base(mconfig, type, tag, owner, clock) , m_wd17xx(*this, WD_TAG) - , m_ds1315(*this, CLOUD9_TAG) , m_floppies(*this, WD_TAG ":%u", 0) - , m_disto_msm6242(*this, DISTO_TAG) - , m_msm6242_rtc_address(0) - , m_rtc(*this, ":real_time_clock") { } -//------------------------------------------------- -// real_time_clock -//------------------------------------------------- - -coco_fdc_device_base::rtc_type coco_fdc_device_base::real_time_clock() -{ - rtc_type result = (rtc_type) m_rtc.read_safe((ioport_value) rtc_type::NONE); - - // check to make sure we don't have any invalid values - if (((result == rtc_type::DISTO) && (m_disto_msm6242 == nullptr)) - || ((result == rtc_type::CLOUD9) && (m_ds1315 == nullptr))) - { - result = rtc_type::NONE; - } - - return result; -} - //------------------------------------------------- // update_lines - CoCo specific disk @@ -239,7 +252,7 @@ coco_fdc_device_base::rtc_type coco_fdc_device_base::real_time_clock() void coco_fdc_device_base::update_lines() { // clear HALT enable under certain circumstances - if (intrq() && (dskreg() & 0x20)) + if (intrq()) set_dskreg(dskreg() & ~0x80); // clear halt enable // set the NMI line @@ -254,28 +267,25 @@ void coco_fdc_device_base::update_lines() // dskreg_w - function to write to CoCo dskreg //------------------------------------------------- -void coco_fdc_device_base::dskreg_w(uint8_t data) +void coco_fdc_device_base::dskreg_w(u8 data) { - uint8_t drive = 0; - uint8_t head; - - if (LOG_FDC) - { - logerror("fdc_coco_dskreg_w(): %c%c%c%c%c%c%c%c ($%02x)\n", - data & 0x80 ? 'H' : 'h', - data & 0x40 ? '3' : '.', - data & 0x20 ? 'D' : 'S', - data & 0x10 ? 'P' : 'p', - data & 0x08 ? 'M' : 'm', - data & 0x04 ? '2' : '.', - data & 0x02 ? '1' : '.', - data & 0x01 ? '0' : '.', - data); - } + u8 drive = 0; + u8 head; + + LOG("fdc_coco_dskreg_w(): %c%c%c%c%c%c%c%c ($%02x)\n", + data & 0x80 ? 'H' : 'h', + data & 0x40 ? '3' : '.', + data & 0x20 ? 'D' : 'S', + data & 0x10 ? 'P' : 'p', + data & 0x08 ? 'M' : 'm', + data & 0x04 ? '2' : '.', + data & 0x02 ? '1' : '.', + data & 0x01 ? '0' : '.', + data); // An email from John Kowalski informed me that if the DS3 is // high, and one of the other drive bits is selected (DS0-DS2), then the - // second side of DS0, DS1, or DS2 is selected. If multiple bits are + // second side of DS0, DS1, or DS2 is selected. If multiple bits are // selected in other situations, then both drives are selected, and any // read signals get yucky. @@ -316,7 +326,7 @@ void coco_fdc_device_base::dskreg_w(uint8_t data) // cts_read //------------------------------------------------- -READ8_MEMBER(coco_fdc_device_base::cts_read) +u8 coco_fdc_device_base::cts_read(offs_t offset) { return memregion("eprom")->base()[offset]; } @@ -326,49 +336,30 @@ READ8_MEMBER(coco_fdc_device_base::cts_read) // scs_read //------------------------------------------------- -READ8_MEMBER(coco_fdc_device_base::scs_read) +u8 coco_fdc_device_base::scs_read(offs_t offset) { - uint8_t result = 0; + u8 result = 0; switch(offset & 0x1F) { case 8: result = m_wd17xx->status_r(); + LOGWDFDC("m_wd17xx->status_r: %02x\n", result ); break; case 9: result = m_wd17xx->track_r(); + LOGWDFDC("m_wd17xx->track_r: %02x\n", result ); break; case 10: result = m_wd17xx->sector_r(); + LOGWDFDC("m_wd17xx->sector_r: %02x\n", result ); break; case 11: result = m_wd17xx->data_r(); + LOGWDIO("m_wd17xx->data_r: %02x\n", result ); break; } - /* other stuff for RTCs */ - switch (offset) - { - case 0x10: /* FF50 */ - if (real_time_clock() == rtc_type::DISTO) - result = m_disto_msm6242->read(space, m_msm6242_rtc_address); - break; - - case 0x38: /* FF78 */ - if (real_time_clock() == rtc_type::CLOUD9) - m_ds1315->read_0(); - break; - - case 0x39: /* FF79 */ - if (real_time_clock() == rtc_type::CLOUD9) - m_ds1315->read_1(); - break; - - case 0x3C: /* FF7C */ - if (real_time_clock() == rtc_type::CLOUD9) - result = m_ds1315->read_data(); - break; - } return result; } @@ -377,7 +368,7 @@ READ8_MEMBER(coco_fdc_device_base::scs_read) // scs_write //------------------------------------------------- -WRITE8_MEMBER(coco_fdc_device_base::scs_write) +void coco_fdc_device_base::scs_write(offs_t offset, u8 data) { switch(offset & 0x1F) { @@ -386,171 +377,395 @@ WRITE8_MEMBER(coco_fdc_device_base::scs_write) dskreg_w(data); break; case 8: + LOGWDFDC("m_wd17xx->cmd_w: %02x\n", data ); m_wd17xx->cmd_w(data); break; case 9: + LOGWDFDC("m_wd17xx->track_w: %02x\n", data ); m_wd17xx->track_w(data); break; case 10: + LOGWDFDC("m_wd17xx->sector_w: %02x\n", data ); m_wd17xx->sector_w(data); break; case 11: + LOGWDIO("m_wd17xx->data_w: %02x\n", data ); m_wd17xx->data_w(data); break; }; - - /* other stuff for RTCs */ - switch(offset) - { - case 0x10: /* FF50 */ - if (real_time_clock() == rtc_type::DISTO) - m_disto_msm6242->write(space,m_msm6242_rtc_address, data); - break; - - case 0x11: /* FF51 */ - if (real_time_clock() == rtc_type::DISTO) - m_msm6242_rtc_address = data & 0x0f; - break; - } } //************************************************************************** -// COCO FDC +// CoCo DOS ROMs //************************************************************************** ROM_START(coco_fdc) + ROM_REGION(0x8000, "eprom", ROMREGION_ERASE00) + ROM_DEFAULT_BIOS("v11") + + ROM_SYSTEM_BIOS(0, "v10", "RSDOS v1.0") + ROMX_LOAD("disk10.rom", 0x0000, 0x2000, CRC(b4f9968e) SHA1(04115be3f97952b9d9310b52f806d04f80b40d03), ROM_BIOS(0)) + ROM_RELOAD(0x2000,0x2000) + ROM_RELOAD(0x4000,0x2000) + ROM_RELOAD(0x6000,0x2000) + + ROM_SYSTEM_BIOS(1, "v11", "RSDOS v1.1") + ROMX_LOAD("disk11.rom", 0x0000, 0x2000, CRC(0b9c5415) SHA1(10bdc5aa2d7d7f205f67b47b19003a4bd89defd1), ROM_BIOS(1)) + ROM_RELOAD(0x2000,0x2000) + ROM_RELOAD(0x4000,0x2000) + ROM_RELOAD(0x6000,0x2000) + + ROM_SYSTEM_BIOS(2, "ados", "ADOS v1.02 for CoCo 1/2") + ROMX_LOAD("ados.rom", 0x0000, 0x2000, CRC(24e807cf) SHA1(a935ea11af4c600a771e4540b661cbb4258a21d6), ROM_BIOS(2)) + ROM_RELOAD(0x2000,0x2000) + ROM_RELOAD(0x4000,0x2000) + ROM_RELOAD(0x6000,0x2000) + + ROM_SYSTEM_BIOS(3, "ados2b", "ADOS v1.02 for CoCo 2B") + ROMX_LOAD("ados2b.rom", 0x0000, 0x2000, CRC(47a59ad4) SHA1(66bd3cf08e7f1b318e82e8c4a9848233f38f1a56), ROM_BIOS(3)) + ROM_RELOAD(0x2000,0x2000) + ROM_RELOAD(0x4000,0x2000) + ROM_RELOAD(0x6000,0x2000) + + ROM_SYSTEM_BIOS(4, "ados3", "ADOS3 v1.01.01") + ROMX_LOAD("ados3.rom", 0x0000, 0x2000, CRC(6f824cd1) SHA1(de602d8d219094f1237d37a4f80032c25808b358), ROM_BIOS(4)) + ROM_RELOAD(0x2000,0x2000) + ROM_RELOAD(0x4000,0x2000) + ROM_RELOAD(0x6000,0x2000) + + ROM_SYSTEM_BIOS(5, "ados340", "ADOS3 v1.01.01, 40 track disk drives") + ROMX_LOAD("ados3-40.rom", 0x0000, 0x2000, CRC(8afe1a04) SHA1(a8dcc6fc0aa5589612cea2a318e7fae58d930c6c), ROM_BIOS(5)) + ROM_RELOAD(0x2000,0x2000) + ROM_RELOAD(0x4000,0x2000) + ROM_RELOAD(0x6000,0x2000) + + ROM_SYSTEM_BIOS(6, "ados380", "ADOS3 v1.01.01, 80 track disk drives") + ROMX_LOAD("ados3-80.rom", 0x0000, 0x2000, CRC(859762f5) SHA1(957f7d5a10e61266193b636dbf642002bcedfaa3), ROM_BIOS(6)) + ROM_RELOAD(0x2000,0x2000) + ROM_RELOAD(0x4000,0x2000) + ROM_RELOAD(0x6000,0x2000) + + ROM_SYSTEM_BIOS(7, "rgbdos", "Hard Disk Basic for Emudsk") + ROMX_LOAD("rgbdos_mess.rom", 0x0000, 0x2000, CRC(0b0e64db) SHA1(062ffab14dc788ec7744e528bf9bb425c3ec60ed), ROM_BIOS(7)) + ROM_RELOAD(0x2000,0x2000) + ROM_RELOAD(0x4000,0x2000) + ROM_RELOAD(0x6000,0x2000) + + ROM_SYSTEM_BIOS(8, "hdbk12", "Hard Disk Basic for Becker Port and DriveWire 3, CoCo 1/2") + ROMX_LOAD("hdbdw3bck.rom", 0x0000, 0x2000, CRC(867a3f42) SHA1(8fd64f1c246489e0bf2b3743ae76332ff324716a), ROM_BIOS(8)) + ROM_RELOAD(0x2000,0x2000) + ROM_RELOAD(0x4000,0x2000) + ROM_RELOAD(0x6000,0x2000) + + ROM_SYSTEM_BIOS(9, "hdbk3", "Hard Disk Basic for Becker Port and DriveWire 3, CoCo 3") + ROMX_LOAD("hdbdw3bc3.rom", 0x0000, 0x2000, CRC(309a9efd) SHA1(671605d61811953860466f771c1594bbade331f4), ROM_BIOS(9)) + ROM_RELOAD(0x2000,0x2000) + ROM_RELOAD(0x4000,0x2000) + ROM_RELOAD(0x6000,0x2000) +ROM_END + +ROM_START(coco_scii) + ROM_REGION(0x8000, "eprom", ROMREGION_ERASE00) + ROM_DEFAULT_BIOS("cdos3") + + ROM_SYSTEM_BIOS(0, "cdos", "Disto C-DOS v4.0 for the CoCo 1/2") + ROMX_LOAD("cdos 4 4-6-89 cc1.bin", 0x0000, 0x4000, CRC(9da6db28) SHA1(2cc6e275178ca8d8f281d845792fb0ae069aaeda), ROM_BIOS(0)) + ROM_RELOAD(0x4000,0x4000) + + ROM_SYSTEM_BIOS(1, "cdos3", "Disto C-DOS 3 v1.2 for the CoCo 3") + ROMX_LOAD("cdos 1_2 3-30-89 cc3.bin", 0x0000, 0x4000, CRC(891c0094) SHA1(c1fa0fcbf1202a9b63aafd98dce777b502584230), ROM_BIOS(1)) + ROM_RELOAD(0x4000,0x4000) +ROM_END + +ROM_START(cp450_fdc) ROM_REGION(0x4000, "eprom", ROMREGION_ERASE00) - ROM_LOAD("disk10.rom", 0x0000, 0x2000, CRC(b4f9968e) SHA1(04115be3f97952b9d9310b52f806d04f80b40d03)) + ROM_LOAD("cp450_basic_disco_v1.0.rom", 0x0000, 0x2000, CRC(e9ad60a0) SHA1(827697fa5b755f5dc1efb054cdbbeb04e405405b)) ROM_END +ROM_START(cd6809_fdc) + ROM_REGION(0x4000, "eprom", ROMREGION_ERASE00) + ROM_LOAD("cd6809dsk.u16", 0x0000, 0x2000, CRC(3c35bda8) SHA1(9b2eec25188bed4326b84739a666435884e4ddf4)) +ROM_END + + +//************************************************************************** +// COCO Floppy Disk Controller +//************************************************************************** + namespace { class coco_fdc_device : public coco_fdc_device_base { public: // construction/destruction - coco_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + coco_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : coco_fdc_device_base(mconfig, COCO_FDC, tag, owner, clock) { } protected: - // optional information overrides + // device_t implementation virtual const tiny_rom_entry *device_rom_region() const override { return ROM_NAME(coco_fdc); } - }; -} - -DEFINE_DEVICE_TYPE_PRIVATE(COCO_FDC, coco_family_fdc_device_base, coco_fdc_device, "coco_fdc", "CoCo FDC") - //************************************************************************** -// COCO FDC v1.1 +// Disto / CRC Super Controller II Base //************************************************************************** -ROM_START(coco_fdc_v11) - ROM_REGION(0x8000, "eprom", ROMREGION_ERASE00) - ROM_LOAD("disk11.rom", 0x0000, 0x2000, CRC(0b9c5415) SHA1(10bdc5aa2d7d7f205f67b47b19003a4bd89defd1)) - ROM_RELOAD(0x2000, 0x2000) - ROM_RELOAD(0x4000, 0x2000) - ROM_RELOAD(0x6000, 0x2000) -ROM_END - -namespace -{ - class coco_fdc_v11_device : public coco_fdc_device_base + class coco_scii_device + : public coco_fdc_device_base { public: // construction/destruction - coco_fdc_v11_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : coco_fdc_device_base(mconfig, COCO_FDC_V11, tag, owner, clock) + // construction/destruction + coco_scii_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : coco_fdc_device_base(mconfig, COCO_SCII, tag, owner, clock) + , m_slot(*this, MEB_TAG) + , m_carts(*this, "cart_line") { } protected: - // optional information overrides + // device_t implementation + virtual void device_start() override ATTR_COLD; + virtual void device_reset() override ATTR_COLD; + virtual u8 scs_read(offs_t offset) override; + virtual void scs_write(offs_t offset, u8 data) override; + + virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; + virtual const tiny_rom_entry *device_rom_region() const override { - return ROM_NAME(coco_fdc_v11); + return ROM_NAME(coco_scii); } + + // methods + virtual void update_lines() override; + + // Disto no halt registers + u8 ff74_read(offs_t offset); + void ff74_write(offs_t offset, u8 data); + + // device references + required_device<distomeb_slot_device> m_slot; + required_device<input_merger_device> m_carts; + + private: + // registers + std::unique_ptr<uint8_t[]> m_cache; + u8 m_cache_pointer; + u8 m_cache_controler; }; -} -DEFINE_DEVICE_TYPE_PRIVATE(COCO_FDC_V11, coco_family_fdc_device_base, coco_fdc_v11_device, "coco_fdc_v11", "CoCo FDC v1.1") +//------------------------------------------------- +// device_start - device-specific start +//------------------------------------------------- -//************************************************************************** -// COCO-3 HDB-DOS -//************************************************************************** + void coco_scii_device::device_start() + { + coco_family_fdc_device_base::device_start(); -ROM_START(coco3_hdb1) - ROM_REGION(0x8000, "eprom", ROMREGION_ERASE00) - ROM_LOAD("hdbdw3bc3.rom", 0x0000, 0x2000, CRC(309a9efd) SHA1(671605d61811953860466f771c1594bbade331f4)) - ROM_RELOAD(0x2000, 0x2000) - ROM_RELOAD(0x4000, 0x2000) - ROM_RELOAD(0x6000, 0x2000) -ROM_END + m_cache = std::make_unique<uint8_t[]>(0x200); -namespace -{ - class coco3_hdb1_device : public coco_fdc_device_base + install_readwrite_handler(0xFF74, 0xFF77, + read8sm_delegate(*this, FUNC(coco_scii_device::ff74_read)), + write8sm_delegate(*this, FUNC(coco_scii_device::ff74_write))); + + save_pointer(NAME(m_cache), 0x200); + save_item(NAME(m_cache_pointer)); + save_item(NAME(m_cache_controler)); + } + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + + void coco_scii_device::device_reset() { - public: - // construction/destruction - coco3_hdb1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : coco_fdc_device_base(mconfig, COCO3_HDB1, tag, owner, clock) + coco_family_fdc_device_base::device_reset(); + + m_cache_controler = 0x80; + m_cache_pointer = 0; + } + + static void disto_meb_slot(device_slot_interface &device) + { + disto_meb_add_basic_devices(device); + } + + +//------------------------------------------------- +// device_add_mconfig - device-specific machine config +//------------------------------------------------- + + void coco_scii_device::device_add_mconfig(machine_config &config) + { + coco_fdc_device_base::device_add_mconfig(config); + + INPUT_MERGER_ANY_HIGH(config, m_carts).output_handler().set([this](int state) { set_line_value(line::CART, state); }); + + DISTOMEB_SLOT(config, m_slot, DERIVED_CLOCK(1, 1), disto_meb_slot, "rtime"); + m_slot->cart_callback().set(m_carts, FUNC(input_merger_device::in_w<1>)); + } + + +//------------------------------------------------- +// scs_read +//------------------------------------------------- + + u8 coco_scii_device::scs_read(offs_t offset) + { + if (offset > 0x0f && offset < 0x18) + return m_slot->meb_read(offset - 0x10); + + return coco_fdc_device_base::scs_read(offset); + } + + +//------------------------------------------------- +// scs_write +//------------------------------------------------- + + void coco_scii_device::scs_write(offs_t offset, u8 data) + { + if (offset > 0x0f && offset < 0x18) + m_slot->meb_write(offset - 0x10, data); + else { + coco_fdc_device_base::scs_write(offset, data); } + } - protected: - // optional information overrides - virtual const tiny_rom_entry *device_rom_region() const override + +//------------------------------------------------- +// update_lines - SCII controller lines +//------------------------------------------------- + + void coco_scii_device::update_lines() + { + // clear HALT enable under certain circumstances + if (intrq()) + set_dskreg(dskreg() & ~0x80); // clear halt enable + + if ((m_cache_controler & 0x02) == 0) /* cache disabled */ { - return ROM_NAME(coco3_hdb1); + // set the HALT line + set_line_value(line::HALT, !drq() && (dskreg() & 0x80)); + } + else + { + set_line_value(line::HALT, CLEAR_LINE); + + if (drq() == ASSERT_LINE) + { + if ((m_cache_controler & 0x01) == 0x01) /* Read cache on */ + { + u8 data = m_wd17xx->data_r(); + LOGWDSCII("cache drq read: %02x\n", data ); + m_cache[m_cache_pointer++] = data; + } + else /* Write cache on */ + { + u8 data = m_cache[m_cache_pointer++]; + LOGWDSCII("cache drq write: %02x\n", data ); + m_wd17xx->data_w(data); + } + + m_cache_pointer &= 0x1ff; + } } - }; -} -DEFINE_DEVICE_TYPE_PRIVATE(COCO3_HDB1, coco_family_fdc_device_base, coco3_hdb1_device, "coco3_hdb1", "CoCo3 HDB-DOS") + if ((m_cache_controler & 0x08) == 0x08) + { + m_carts->in_w<0>(intrq()); + } + else + { + m_carts->in_w<0>(CLEAR_LINE); + } -//************************************************************************** -// COCO-2 HDB-DOS -//************************************************************************** + if ((m_cache_controler & 0x04) == 0x00) + { + set_line_value(line::NMI, intrq() && (dskreg() & 0x20)); + } + else + { + set_line_value(line::NMI, CLEAR_LINE); + } + } -ROM_START(coco2_hdb1) - ROM_REGION(0x8000, "eprom", ROMREGION_ERASE00) - ROM_LOAD("hdbdw3bck.rom", 0x0000, 0x2000, CRC(867a3f42) SHA1(8fd64f1c246489e0bf2b3743ae76332ff324716a)) - ROM_RELOAD(0x2000, 0x2000) - ROM_RELOAD(0x4000, 0x2000) - ROM_RELOAD(0x6000, 0x2000) -ROM_END -namespace -{ - class coco2_hdb1_device : public coco_fdc_device_base +//------------------------------------------------- +// ff74_read - no halt registers +//------------------------------------------------- + + u8 coco_scii_device::ff74_read(offs_t offset) { - public: - // construction/destruction - coco2_hdb1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : coco_fdc_device_base(mconfig, COCO2_HDB1, tag, owner, clock) + u8 data = 0x0; + + switch(offset) { + case 0x0: + case 0x1: + data = m_cache[m_cache_pointer++]; + LOGWDSCII("cache read: %04x = %02x\n", m_cache_pointer, data); + m_cache_pointer &= 0x1ff; + break; + + case 0x2: + case 0x3: + if (intrq() == ASSERT_LINE) + { + m_cache_controler &= 0x7f; + } + else + { + m_cache_controler |= 0x80; + } + + data = m_cache_controler; + LOGWDSCII("control read: %02x\n", data); + break; } - protected: - // optional information overrides - virtual const tiny_rom_entry *device_rom_region() const override + return data; + } + + +//------------------------------------------------- +// ff74_write - no halt registers +//------------------------------------------------- + + void coco_scii_device::ff74_write(offs_t offset, u8 data) + { + switch(offset) { - return ROM_NAME(coco2_hdb1); + case 0x0: + case 0x1: + LOGWDSCII("cache write: %04x = %02x\n", m_cache_pointer, data); + m_cache[m_cache_pointer++] = data; + m_cache_pointer &= 0x1ff; + break; + case 0x2: + case 0x3: + LOGWDSCII("control write: %02x\n", data); + + // reset static ram buffer pointer on any write + m_cache_pointer = 0; + + m_cache_controler = data; + update_lines(); + break; } - }; -} + } -DEFINE_DEVICE_TYPE_PRIVATE(COCO2_HDB1, coco_family_fdc_device_base, coco2_hdb1_device, "coco2_hdb1", "CoCo2 HDB-DOS") //************************************************************************** // Prológica CP-450 BASIC Disco V. 1.0 (1984) @@ -561,18 +776,11 @@ DEFINE_DEVICE_TYPE_PRIVATE(COCO2_HDB1, coco_family_fdc_device_base, coco2_hdb1_d // //************************************************************************** -ROM_START(cp450_fdc) - ROM_REGION(0x4000, "eprom", ROMREGION_ERASE00) - ROM_LOAD("cp450_basic_disco_v1.0.rom", 0x0000, 0x2000, CRC(e9ad60a0) SHA1(827697fa5b755f5dc1efb054cdbbeb04e405405b)) -ROM_END - -namespace -{ class cp450_fdc_device : public coco_fdc_device_base { public: // construction/destruction - cp450_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + cp450_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : coco_fdc_device_base(mconfig, CP450_FDC, tag, owner, clock) { } @@ -584,9 +792,7 @@ namespace return ROM_NAME(cp450_fdc); } }; -} -DEFINE_DEVICE_TYPE_PRIVATE(CP450_FDC, coco_family_fdc_device_base, cp450_fdc_device, "cp450_fdc", "Prológica CP-450 BASIC Disco V. 1.0 (1984)") //************************************************************************** // Codimex CD-6809 FDC (1986) @@ -595,18 +801,11 @@ DEFINE_DEVICE_TYPE_PRIVATE(CP450_FDC, coco_family_fdc_device_base, cp450_fdc_dev // More ifo at: http://amxproject.com/?p=2747 //************************************************************************** -ROM_START(cd6809_fdc) - ROM_REGION(0x4000, "eprom", ROMREGION_ERASE00) - ROM_LOAD("cd6809dsk.u16", 0x0000, 0x2000, CRC(3c35bda8) SHA1(9b2eec25188bed4326b84739a666435884e4ddf4)) -ROM_END - -namespace -{ class cd6809_fdc_device : public coco_fdc_device_base { public: // construction/destruction - cd6809_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + cd6809_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : coco_fdc_device_base(mconfig, CD6809_FDC, tag, owner, clock) { } @@ -618,6 +817,9 @@ namespace return ROM_NAME(cd6809_fdc); } }; -} +} // Anonymous namepace +DEFINE_DEVICE_TYPE_PRIVATE(COCO_FDC, coco_family_fdc_device_base, coco_fdc_device, "coco_fdc", "CoCo Floppy Disk Controller") +DEFINE_DEVICE_TYPE_PRIVATE(COCO_SCII, coco_family_fdc_device_base, coco_scii_device, "coco_scii", "Disto Super Controller II") +DEFINE_DEVICE_TYPE_PRIVATE(CP450_FDC, coco_family_fdc_device_base, cp450_fdc_device, "cp450_fdc", "Prológica CP-450 BASIC Disco V. 1.0 (1984)") DEFINE_DEVICE_TYPE_PRIVATE(CD6809_FDC, coco_family_fdc_device_base, cd6809_fdc_device, "cd6809_fdc", "Codimex CD-6809 Disk BASIC (1986)") |