diff options
author | tim lindner <tlindner@macmess.org> | 2020-05-08 20:38:56 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-09 13:38:56 +1000 |
commit | 2d0820850cfa001c8d831a9e5503861de53e57c3 (patch) | |
tree | b8b73f28a38ea3773d9b299c76e61bb77ccdf68d /src/devices/bus | |
parent | cc0293b1cd00939dd1bcf77f66d0aa0bc17bd113 (diff) |
CoCo: added Disto no-halt disk controller (#6632)
* initial stab at the no halt floppy disk driver controller
* removed the drive 3 and 4 like they were before
* Clean up
* comment fixes
* comment fixes
Diffstat (limited to 'src/devices/bus')
-rw-r--r-- | src/devices/bus/coco/coco_fdc.cpp | 267 |
1 files changed, 227 insertions, 40 deletions
diff --git a/src/devices/bus/coco/coco_fdc.cpp b/src/devices/bus/coco/coco_fdc.cpp index c0f8295716b..4ee5a759c30 100644 --- a/src/devices/bus/coco/coco_fdc.cpp +++ b/src/devices/bus/coco/coco_fdc.cpp @@ -40,6 +40,32 @@ Reading from $FF48-$FF4F clears bit 7 of DSKREG ($FF40) + --------------------------------------------------------------------------- + + Disto No Halt Extension + + 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. + + 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 + + + *********************************************************************/ #include "emu.h" @@ -49,18 +75,20 @@ #include "machine/msm6242.h" #include "machine/ds1315.h" #include "machine/wd_fdc.h" +#include "machine/ram.h" #include "formats/dmk_dsk.h" #include "formats/jvc_dsk.h" #include "formats/vdk_dsk.h" #include "formats/sdf_dsk.h" #include "formats/os9_dsk.h" +// #define VERBOSE (LOG_GENERAL ) +#include "logmacro.h" /*************************************************************************** PARAMETERS ***************************************************************************/ -#define LOG_FDC 0 #define WD_TAG "wd17xx" #define WD2797_TAG "wd2797" #define DISTO_TAG "disto" @@ -89,6 +117,10 @@ protected: }; // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // device-level overrides virtual DECLARE_READ8_MEMBER(cts_read) override; virtual DECLARE_READ8_MEMBER(scs_read) override; virtual DECLARE_WRITE8_MEMBER(scs_write) override; @@ -108,6 +140,16 @@ protected: required_device<msm6242_device> m_disto_msm6242; // 6242 RTC on Disto interface offs_t m_msm6242_rtc_address; optional_ioport m_rtc; + + // Protected + virtual DECLARE_READ8_MEMBER(ff74_read); + virtual DECLARE_WRITE8_MEMBER(ff74_write); + +private: + // registers + uint8_t m_cache_controler; + uint8_t m_cache_pointer; + required_device<ram_device> m_cache_buffer; }; @@ -143,6 +185,8 @@ void coco_fdc_device_base::device_add_mconfig(machine_config &config) 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); } @@ -183,6 +227,7 @@ uint8_t* coco_family_fdc_device_base::get_cart_base() return memregion("eprom")->base(); } + //------------------------------------------------- // coco_family_fdc_device_base::get_cart_memregion //------------------------------------------------- @@ -209,9 +254,100 @@ coco_fdc_device_base::coco_fdc_device_base(const machine_config &mconfig, device , 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() +{ + install_readwrite_handler(0xFF74, 0xFF76, + read8_delegate(*this, FUNC(coco_fdc_device_base::ff74_read)), + write8_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() +{ + m_cache_controler = 0x80; + m_cache_pointer = 0; +} + + +//------------------------------------------------- +// ff74_read - no halt registers +//------------------------------------------------- + +READ8_MEMBER(coco_fdc_device_base::ff74_read) +{ + uint8_t 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 +//------------------------------------------------- + +WRITE8_MEMBER(coco_fdc_device_base::ff74_write) { + 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 //------------------------------------------------- @@ -238,15 +374,60 @@ 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)) - set_dskreg(dskreg() & ~0x80); // clear halt enable + 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 + + // 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 */ + { + uint8_t 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 */ + { + uint8_t 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 */ + { + uint8_t 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" ); + } + } - // set the NMI line - set_line_value(line::NMI, intrq() && (dskreg() & 0x20)); + if( (m_cache_controler & 0x08) == 0x08) + { + set_line_value(line::CART, intrq()); + } - // set the HALT line - set_line_value(line::HALT, !drq() && (dskreg() & 0x80)); + if( intrq() == ASSERT_LINE) + { + m_cache_controler &= 0x7f; + } + else + { + m_cache_controler |= 0x80; + } + } } @@ -259,19 +440,16 @@ void coco_fdc_device_base::dskreg_w(uint8_t 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); - } + 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 @@ -334,41 +512,46 @@ READ8_MEMBER(coco_fdc_device_base::scs_read) { case 8: result = m_wd17xx->status_r(); + LOG("m_wd17xx->status_r: %2.2x\n", result ); break; case 9: result = m_wd17xx->track_r(); + LOG("m_wd17xx->track_r: %2.2x\n", result ); break; case 10: result = m_wd17xx->sector_r(); + LOG("m_wd17xx->sector_r: %2.2x\n", result ); break; case 11: result = m_wd17xx->data_r(); + LOG("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(); - break; + 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(); + break; } + return result; } @@ -386,15 +569,19 @@ WRITE8_MEMBER(coco_fdc_device_base::scs_write) dskreg_w(data); break; case 8: + LOG("m_wd17xx->cmd_w: %2.2x\n", data ); m_wd17xx->cmd_w(data); break; case 9: + LOG("m_wd17xx->track_w: %2.2x\n", data ); m_wd17xx->track_w(data); break; case 10: + LOG("m_wd17xx->sector_w: %2.2x\n", data ); m_wd17xx->sector_w(data); break; case 11: + LOG("m_wd17xx->data_w: %2.2x\n", data ); m_wd17xx->data_w(data); break; }; |