summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/coco/coco_fdc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/coco/coco_fdc.cpp')
-rw-r--r--src/devices/bus/coco/coco_fdc.cpp753
1 files changed, 378 insertions, 375 deletions
diff --git a/src/devices/bus/coco/coco_fdc.cpp b/src/devices/bus/coco/coco_fdc.cpp
index 6635b8c84d3..2eac7f8b7f3 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
@@ -42,53 +41,68 @@
---------------------------------------------------------------------------
- Disto No Halt Extension
+ Disto Super Controller II
+ Mini Expansion Bus
+ No Halt Extension. Implemented by using a read and write cache.
- The Disto Super Controller II includes "no halt" circuitry. Implemented
- by using a read and write cache.
+ CachDat - Cache Data Register
+ $FF74 & $FF75: Read/Write cache data.
- 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: Read
- Bit 7 low indicates an interrupt request from the disk controller
-
- $FF76: Write:
- 00000000 = Caching off
- 00001000 = Tell cache controller to send interrupt when device is
- ready to send/receive a buffer (seek done, etc.)
- 00000111 = Read cache on - Get next 256 data bytes from controller
- to cache
- 00000100 = Write cache on - Next 256 bytes stored in cache are
- sector
- 00000110 = Copy Write cache to controller
+ 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/msm6242.h"
#include "machine/ds1315.h"
+#include "machine/input_merger.h"
+#include "machine/msm6242.h"
#include "machine/wd_fdc.h"
-#include "machine/ram.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_GENERAL (1U << 0) //defined in logmacro.h already
#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 )
+//#define VERBOSE (LOG_GENERAL|LOG_WDFDC|LOG_WDSCII)
#include "logmacro.h"
-#define LOGWDFDC(...) LOGMASKED(LOG_WDFDC, __VA_ARGS__)
+#define LOGWDFDC(...) LOGMASKED(LOG_WDFDC, __VA_ARGS__)
+#define LOGWDIO(...) LOGMASKED(LOG_WDIO, __VA_ARGS__)
+#define LOGWDSCII(...) LOGMASKED(LOG_WDSCII, __VA_ARGS__)
+
/***************************************************************************
PARAMETERS
@@ -96,9 +110,7 @@
#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>;
@@ -114,17 +126,6 @@ protected:
// construction/destruction
coco_fdc_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
- enum class rtc_type
- {
- DISTO = 0x00,
- CLOUD9 = 0x01,
- NONE = 0xFF
- };
-
- // device-level overrides
- virtual void device_start() override;
- virtual void device_reset() override;
-
// device-level overrides
virtual u8 cts_read(offs_t offset) override;
virtual u8 scs_read(offs_t offset) override;
@@ -134,31 +135,13 @@ protected:
// methods
virtual void update_lines() override;
void dskreg_w(u8 data);
- rtc_type real_time_clock();
// 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;
-
- // Protected
- u8 ff74_read(offs_t offset);
- void ff74_write(offs_t offset, u8 data);
-
-private:
- // registers
- u8 m_cache_controler;
- u8 m_cache_pointer;
- required_device<ram_device> m_cache_buffer;
};
-
/***************************************************************************
LOCAL VARIABLES
***************************************************************************/
@@ -166,11 +149,14 @@ private:
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_SDF_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)
@@ -185,17 +171,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, "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);
-
- RAM(config, "cachebuffer").set_default_size("256").set_default_value(0);
}
@@ -258,125 +240,8 @@ memory_region *coco_family_fdc_device_base::get_cart_memregion()
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")
- , m_cache_buffer(*this, "cachebuffer")
-{
-}
-
-
-//-------------------------------------------------
-// device_start - device-specific start
-//-------------------------------------------------
-
-void coco_fdc_device_base::device_start()
-{
- coco_family_fdc_device_base::device_start();
-
- install_readwrite_handler(0xFF74, 0xFF76,
- read8sm_delegate(*this, FUNC(coco_fdc_device_base::ff74_read)),
- write8sm_delegate(*this, FUNC(coco_fdc_device_base::ff74_write)));
-
- save_item(NAME(m_cache_controler));
- save_item(NAME(m_cache_pointer));
-}
-
-
-//-------------------------------------------------
-// device_reset - device-specific reset
-//-------------------------------------------------
-
-void coco_fdc_device_base::device_reset()
-{
- coco_family_fdc_device_base::device_reset();
-
- m_cache_controler = 0x80;
- m_cache_pointer = 0;
-}
-
-
-//-------------------------------------------------
-// ff74_read - no halt registers
-//-------------------------------------------------
-
-u8 coco_fdc_device_base::ff74_read(offs_t offset)
-{
- u8 data = 0x0;
-
- switch(offset)
- {
- case 0x0:
- data = m_cache_buffer->read(m_cache_pointer++);
- LOG( "CachDat_A read: %2.2x\n", data );
- break;
- case 0x1:
- data = m_cache_buffer->read(m_cache_pointer++);
- LOG( "CachDat_B read: %2.2x\n", data );
- break;
- case 0x2:
- data = m_cache_controler;
- LOG( "CachCtrl read: %2.2x\n", data );
- break;
- }
-
- return data;
-}
-
-
-//-------------------------------------------------
-// ff74_write - no halt registers
-//-------------------------------------------------
-
-void coco_fdc_device_base::ff74_write(offs_t offset, u8 data)
-{
- switch(offset)
- {
- case 0x0:
- LOG( "CachDat_A write: %2.2x\n", data );
- m_cache_buffer->write(m_cache_pointer++, data);
- break;
- case 0x1:
- LOG( "CachDat_B write: %2.2x\n", data );
- m_cache_buffer->write(m_cache_pointer++, data);
- break;
- case 0x2:
- LOG( "CachCtrl write: %2.2x\n", data );
-
- // reset static ram buffer pointer on any write
- m_cache_pointer = 0;
-
- if(data == 0)
- {
- // Clear interrupt when caching is turned off
- set_line_value(line::CART, CLEAR_LINE);
- m_cache_controler |= 0x80;
- }
-
- m_cache_controler = (m_cache_controler & 0x80) | (data & 0x7f);
- break;
- }
-}
-
-
-//-------------------------------------------------
-// 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;
}
@@ -387,60 +252,15 @@ coco_fdc_device_base::rtc_type coco_fdc_device_base::real_time_clock()
void coco_fdc_device_base::update_lines()
{
- if( (m_cache_controler & 0x7f) == 0) /* cache disabled */
- {
- // clear HALT enable under certain circumstances
- if (intrq() && (dskreg() & 0x20))
- set_dskreg(dskreg() & ~0x80); // clear halt enable
+ // clear HALT enable under certain circumstances
+ if (intrq())
+ set_dskreg(dskreg() & ~0x80); // clear halt enable
- // set the NMI line
- set_line_value(line::NMI, intrq() && (dskreg() & 0x20));
+ // set the NMI line
+ set_line_value(line::NMI, intrq() && (dskreg() & 0x20));
- // set the HALT line
- set_line_value(line::HALT, !drq() && (dskreg() & 0x80));
- }
- else
- {
- if( drq() == ASSERT_LINE)
- {
- if( (m_cache_controler & 0x07) == 0x07) /* Read cache on */
- {
- u8 data = m_wd17xx->data_r();
- LOG("Cached drq read: %2.2x\n", data );
- m_cache_buffer->write(m_cache_pointer++, data);
- }
- else if( (m_cache_controler & 0x07) == 0x04 ) /* Write cache on */
- {
- u8 data = m_cache_buffer->read(m_cache_pointer++);
- LOG("Cached drq write: %2.2x\n", data );
- m_wd17xx->data_w(data);
- }
- else if( (m_cache_controler & 0x07) == 0x06 ) /* Copy Write cache to controller */
- {
- u8 data = m_cache_buffer->read(m_cache_pointer++);
- LOG("Cached drq write: %2.2x\n", data );
- m_wd17xx->data_w(data);
- }
- else
- {
- LOG("illegal DRQ cached assert mode\n" );
- }
- }
-
- if( (m_cache_controler & 0x08) == 0x08)
- {
- set_line_value(line::CART, intrq());
- }
-
- if( intrq() == ASSERT_LINE)
- {
- m_cache_controler &= 0x7f;
- }
- else
- {
- m_cache_controler |= 0x80;
- }
- }
+ // set the HALT line
+ set_line_value(line::HALT, !drq() && (dskreg() & 0x80));
}
@@ -466,7 +286,7 @@ void coco_fdc_device_base::dskreg_w(u8 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.
@@ -525,43 +345,19 @@ u8 coco_fdc_device_base::scs_read(offs_t offset)
{
case 8:
result = m_wd17xx->status_r();
- LOGWDFDC("m_wd17xx->status_r: %2.2x\n", result );
+ LOGWDFDC("m_wd17xx->status_r: %02x\n", result );
break;
case 9:
result = m_wd17xx->track_r();
- LOGWDFDC("m_wd17xx->track_r: %2.2x\n", result );
+ LOGWDFDC("m_wd17xx->track_r: %02x\n", result );
break;
case 10:
result = m_wd17xx->sector_r();
- LOGWDFDC("m_wd17xx->sector_r: %2.2x\n", result );
+ LOGWDFDC("m_wd17xx->sector_r: %02x\n", result );
break;
case 11:
result = m_wd17xx->data_r();
- LOGWDFDC("m_wd17xx->data_r: %2.2x\n", result );
- break;
- }
-
- /* other stuff for RTCs */
- switch (offset)
- {
- case 0x10: /* FF50 */
- if (real_time_clock() == rtc_type::DISTO)
- result = m_disto_msm6242->read(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();
+ LOGWDIO("m_wd17xx->data_r: %02x\n", result );
break;
}
@@ -582,48 +378,122 @@ void coco_fdc_device_base::scs_write(offs_t offset, u8 data)
dskreg_w(data);
break;
case 8:
- LOGWDFDC("m_wd17xx->cmd_w: %2.2x\n", data );
+ LOGWDFDC("m_wd17xx->cmd_w: %02x\n", data );
m_wd17xx->cmd_w(data);
break;
case 9:
- LOGWDFDC("m_wd17xx->track_w: %2.2x\n", data );
+ LOGWDFDC("m_wd17xx->track_w: %02x\n", data );
m_wd17xx->track_w(data);
break;
case 10:
- LOGWDFDC("m_wd17xx->sector_w: %2.2x\n", data );
+ LOGWDFDC("m_wd17xx->sector_w: %02x\n", data );
m_wd17xx->sector_w(data);
break;
case 11:
- LOGWDFDC("m_wd17xx->data_w: %2.2x\n", data );
+ 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(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
@@ -636,121 +506,267 @@ namespace
}
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, u32 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;
+ virtual void device_reset() 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;
+
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, u32 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);
-DEFINE_DEVICE_TYPE_PRIVATE(COCO3_HDB1, coco_family_fdc_device_base, coco3_hdb1_device, "coco3_hdb1", "CoCo3 HDB-DOS")
+ 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;
+ }
+ }
-//**************************************************************************
-// COCO-2 HDB-DOS
-//**************************************************************************
+ if ((m_cache_controler & 0x08) == 0x08)
+ {
+ m_carts->in_w<0>(intrq());
+ }
+ else
+ {
+ m_carts->in_w<0>(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
+ if ((m_cache_controler & 0x04) == 0x00)
+ {
+ set_line_value(line::NMI, intrq() && (dskreg() & 0x20));
+ }
+ else
+ {
+ set_line_value(line::NMI, CLEAR_LINE);
+ }
+ }
-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, u32 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)
@@ -761,13 +777,6 @@ 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:
@@ -784,9 +793,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)
@@ -795,13 +802,6 @@ 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:
@@ -818,6 +818,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)")