coco: updated to use the new wd fdc

This commit is contained in:
Dirk Best 2015-06-04 16:55:13 +02:00
parent 27138786f8
commit a444bc8e25
5 changed files with 283 additions and 36 deletions

View File

@ -265,6 +265,8 @@ project "formats"
MAME_DIR .. "src/lib/formats/imd_dsk.h",
MAME_DIR .. "src/lib/formats/ipf_dsk.c",
MAME_DIR .. "src/lib/formats/ipf_dsk.h",
MAME_DIR .. "src/lib/formats/jvc_dsk.c",
MAME_DIR .. "src/lib/formats/jvc_dsk.h",
MAME_DIR .. "src/lib/formats/kaypro_dsk.c",
MAME_DIR .. "src/lib/formats/kaypro_dsk.h",
MAME_DIR .. "src/lib/formats/kc_cas.c",

View File

@ -73,7 +73,9 @@
#include "imagedev/flopdrv.h"
#include "includes/coco.h"
#include "imagedev/flopdrv.h"
#include "formats/coco_dsk.h"
#include "formats/dmk_dsk.h"
#include "formats/jvc_dsk.h"
#include "formats/vdk_dsk.h"
/***************************************************************************
@ -94,12 +96,15 @@
LOCAL VARIABLES
***************************************************************************/
static const floppy_interface coco_floppy_interface =
{
FLOPPY_STANDARD_5_25_DSHD,
LEGACY_FLOPPY_OPTIONS_NAME(coco),
"floppy_5_25"
};
FLOPPY_FORMATS_MEMBER( coco_fdc_device::floppy_formats )
FLOPPY_DMK_FORMAT,
FLOPPY_JVC_FORMAT,
FLOPPY_VDK_FORMAT
FLOPPY_FORMATS_END
static SLOT_INTERFACE_START( coco_fdc_floppies )
SLOT_INTERFACE("qd", FLOPPY_525_QD)
SLOT_INTERFACE_END
/***************************************************************************
@ -149,15 +154,17 @@ WRITE_LINE_MEMBER( coco_fdc_device::fdc_drq_w )
//**************************************************************************
static MACHINE_CONFIG_FRAGMENT(coco_fdc)
MCFG_DEVICE_ADD(WD_TAG, WD1773, 0)
MCFG_WD17XX_DEFAULT_DRIVE4_TAGS
MCFG_WD17XX_INTRQ_CALLBACK(WRITELINE(coco_fdc_device, fdc_intrq_w))
MCFG_WD17XX_DRQ_CALLBACK(WRITELINE(coco_fdc_device, fdc_drq_w))
MCFG_WD1773x_ADD(WD_TAG, XTAL_8MHz)
MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(coco_fdc_device, fdc_intrq_w))
MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(coco_fdc_device, fdc_drq_w))
MCFG_FLOPPY_DRIVE_ADD(WD_TAG ":0", coco_fdc_floppies, "qd", coco_fdc_device::floppy_formats)
MCFG_FLOPPY_DRIVE_ADD(WD_TAG ":1", coco_fdc_floppies, "qd", coco_fdc_device::floppy_formats)
MCFG_FLOPPY_DRIVE_ADD(WD_TAG ":2", coco_fdc_floppies, "", coco_fdc_device::floppy_formats)
MCFG_FLOPPY_DRIVE_ADD(WD_TAG ":3", coco_fdc_floppies, "", coco_fdc_device::floppy_formats)
MCFG_DEVICE_ADD(DISTO_TAG, MSM6242, XTAL_32_768kHz)
MCFG_DS1315_ADD(CLOUD9_TAG)
MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(coco_floppy_interface)
MACHINE_CONFIG_END
ROM_START( coco_fdc )
@ -291,16 +298,17 @@ void coco_fdc_device::dskreg_w(UINT8 data)
else if (data & 0x40)
drive = 3;
legacy_floppy_image_device *floppy[4];
floppy_image_device *floppy[4];
floppy[0] = subdevice<legacy_floppy_image_device>(FLOPPY_0);
floppy[1] = subdevice<legacy_floppy_image_device>(FLOPPY_1);
floppy[2] = subdevice<legacy_floppy_image_device>(FLOPPY_2);
floppy[3] = subdevice<legacy_floppy_image_device>(FLOPPY_3);
floppy[0] = subdevice<floppy_connector>(WD_TAG ":0")->get_device();
floppy[1] = subdevice<floppy_connector>(WD_TAG ":1")->get_device();
floppy[2] = subdevice<floppy_connector>(WD_TAG ":2")->get_device();
floppy[3] = subdevice<floppy_connector>(WD_TAG ":3")->get_device();
for (int i = 0; i < 4; i++)
{
floppy[i]->floppy_mon_w(i == drive ? CLEAR_LINE : ASSERT_LINE);
if (floppy[i])
floppy[i]->mon_w(i == drive ? CLEAR_LINE : ASSERT_LINE);
}
head = ((data & 0x40) && (drive != 3)) ? 1 : 0;
@ -309,8 +317,11 @@ void coco_fdc_device::dskreg_w(UINT8 data)
update_lines();
m_wd17xx->set_drive(drive);
m_wd17xx->set_side(head);
m_wd17xx->set_floppy(floppy[drive]);
if (floppy[drive])
floppy[drive]->ss_w(head);
m_wd17xx->dden_w(!BIT(m_dskreg, 5));
}
@ -379,7 +390,7 @@ WRITE8_MEMBER(coco_fdc_device::write)
dskreg_w(data);
break;
case 8:
m_wd17xx->command_w(space, 0, data);
m_wd17xx->cmd_w(space, 0, data);
break;
case 9:
m_wd17xx->track_w(space, 0, data);
@ -388,6 +399,7 @@ WRITE8_MEMBER(coco_fdc_device::write)
m_wd17xx->sector_w(space, 0, data);
break;
case 11:
//printf("data w %02x\n", data);
m_wd17xx->data_w(space, 0, data);
break;
};
@ -413,10 +425,12 @@ WRITE8_MEMBER(coco_fdc_device::write)
//**************************************************************************
static MACHINE_CONFIG_FRAGMENT(dragon_fdc)
MCFG_DEVICE_ADD(WD2797_TAG, WD2797, 0)
MCFG_WD17XX_DEFAULT_DRIVE4_TAGS
MCFG_WD2797x_ADD(WD2797_TAG, XTAL_1MHz)
MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(coco_floppy_interface)
MCFG_FLOPPY_DRIVE_ADD(WD2797_TAG ":0", coco_fdc_floppies, "qd", coco_fdc_device::floppy_formats)
MCFG_FLOPPY_DRIVE_ADD(WD2797_TAG ":1", coco_fdc_floppies, "qd", coco_fdc_device::floppy_formats)
MCFG_FLOPPY_DRIVE_ADD(WD2797_TAG ":2", coco_fdc_floppies, "", coco_fdc_device::floppy_formats)
MCFG_FLOPPY_DRIVE_ADD(WD2797_TAG ":3", coco_fdc_floppies, "", coco_fdc_device::floppy_formats)
MACHINE_CONFIG_END
@ -511,10 +525,20 @@ void dragon_fdc_device::dskreg_w(UINT8 data)
data);
}
if (data & 0x04)
m_wd2797->set_drive(data & 0x03);
floppy_image_device *floppy = NULL;
switch (data & 0x03)
{
case 0: floppy = subdevice<floppy_connector>(WD2797_TAG ":0")->get_device(); break;
case 1: floppy = subdevice<floppy_connector>(WD2797_TAG ":1")->get_device(); break;
case 2: floppy = subdevice<floppy_connector>(WD2797_TAG ":2")->get_device(); break;
case 3: floppy = subdevice<floppy_connector>(WD2797_TAG ":3")->get_device(); break;
}
m_wd2797->set_floppy(floppy);
m_wd2797->dden_w(BIT(data, 3));
m_dskreg = data;
}
@ -556,12 +580,7 @@ WRITE8_MEMBER(dragon_fdc_device::write)
switch(offset & 0xEF)
{
case 0:
m_wd2797->command_w(space, 0, data);
/* disk head is encoded in the command byte */
/* Only for type 3 & 4 commands */
if (data & 0x80)
m_wd2797->set_side((data & 0x02) ? 1 : 0);
m_wd2797->cmd_w(space, 0, data);
break;
case 1:
m_wd2797->track_w(space, 0, data);

View File

@ -9,7 +9,7 @@
#include "cococart.h"
#include "machine/msm6242.h"
#include "machine/ds1315.h"
#include "machine/wd17xx.h"
#include "machine/wd_fdc.h"
//**************************************************************************
@ -37,6 +37,8 @@ public:
coco_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
coco_fdc_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
DECLARE_FLOPPY_FORMATS(floppy_formats);
// optional information overrides
virtual machine_config_constructor device_mconfig_additions() const;
virtual const rom_entry *device_rom_region() const;
@ -66,8 +68,8 @@ protected:
UINT8 m_drq : 1;
UINT8 m_intrq : 1;
optional_device<wd1773_device> m_wd17xx; /* WD17xx */
optional_device<wd2797_device> m_wd2797; /* WD2797 */
optional_device<wd1773_t> m_wd17xx; /* WD17xx */
optional_device<wd2797_t> m_wd2797; /* WD2797 */
optional_device<ds1315_device> m_ds1315; /* DS1315 */
/* Disto RTC */

174
src/lib/formats/jvc_dsk.c Normal file
View File

@ -0,0 +1,174 @@
// license:GPL-2.0+
// copyright-holders:Dirk Best
/***************************************************************************
JVC
Disk image format
Named after its creator, Jeff Vavasour
TODO:
- Support writing unusal formats?
***************************************************************************/
#include "emu.h"
#include "jvc_dsk.h"
jvc_format::jvc_format()
{
}
const char *jvc_format::name() const
{
return "jvc";
}
const char *jvc_format::description() const
{
return "JVC disk image";
}
const char *jvc_format::extensions() const
{
return "jvc,dsk";
}
bool jvc_format::parse_header(io_generic *io, int &header_size, int &tracks, int &heads, int &sectors, int &sector_size, int &base_sector_id)
{
UINT64 size = io_generic_size(io);
header_size = size % 256;
UINT8 header[5];
if (header_size > 0)
io_generic_read(io, header, 0, header_size);
if (header_size > 5)
return false;
// default values
heads = 1;
sectors = 18;
sector_size = 256;
base_sector_id = 1;
switch (header_size)
{
case 5: emu_fatalerror("jvc_format: sector attribute flag unsupported\n");
break;
case 4: base_sector_id = header[3];
// no break
case 3: sector_size = 128 << header[2];
// no break
case 2: heads = header[1];
// no break
case 1: sectors = header[0];
// no break
case 0: tracks = (size - header_size) / sector_size / sectors;
break;
}
return tracks * heads * sectors * sector_size == (size - header_size);
}
int jvc_format::identify(io_generic *io, UINT32 form_factor)
{
int header_size, tracks, heads, sectors, sector_size, sector_base_id;
return parse_header(io, header_size, tracks, heads, sectors, sector_size, sector_base_id) ? 50 : 0;
}
bool jvc_format::load(io_generic *io, UINT32 form_factor, floppy_image *image)
{
int header_size, track_count, head_count, sector_count, sector_size, sector_base_id;
if (!parse_header(io, header_size, track_count, head_count, sector_count, sector_size, sector_base_id))
return false;
// safety check
if (sector_count * sector_size > 10000)
emu_fatalerror("jvc_format: incorrect track layout\n");
int file_offset = header_size;
for (int track = 0; track < track_count; track++)
{
for (int head = 0; head < head_count ; head++)
{
desc_pc_sector sectors[256];
UINT8 sector_data[10000];
int sector_offset = 0;
for (int i = 0; i < sector_count; i++)
{
sectors[i].track = track;
sectors[i].head = head;
sectors[i].sector = sector_base_id + i;
sectors[i].actual_size = sector_size;
sectors[i].size = sector_size >> 8;
sectors[i].deleted = false;
sectors[i].bad_crc = false;
sectors[i].data = &sector_data[sector_offset];
io_generic_read(io, sectors[i].data, file_offset, sector_size);
sector_offset += sector_size;
file_offset += sector_size;
}
build_wd_track_mfm(track, head, image, 100000, sector_count, sectors, 22, 32, 24);
}
}
return true;
}
bool jvc_format::save(io_generic *io, floppy_image *image)
{
UINT8 bitstream[500000/8];
UINT8 sector_data[50000];
desc_xs sectors[256];
UINT64 file_offset = 0;
int track_count, head_count;
image->get_actual_geometry(track_count, head_count);
// we'll write a header if the disk is two-sided
if (head_count == 2)
{
UINT8 header[2];
header[0] = 18;
header[1] = 2;
io_generic_write(io, header, file_offset, sizeof(header));
file_offset += sizeof(header);
}
// write disk data
for (int track = 0; track < track_count; track++)
{
for (int head = 0; head < head_count; head++)
{
int track_size;
generate_bitstream_from_track(track, head, 2000, bitstream, track_size, image);
extract_sectors_from_bitstream_mfm_pc(bitstream, track_size, sectors, sector_data, sizeof(sector_data));
for (int i = 0; i < 18; i++)
{
if (sectors[1 + i].size != 256)
emu_fatalerror("jvc_format: invalid sector size: %d\n", sectors[1 + i].size);
io_generic_write(io, sectors[1 + i].data, file_offset, sectors[1 + i].size);
file_offset += sectors[1 + i].size;
}
}
}
return true;
}
bool jvc_format::supports_save() const
{
return true;
}
const floppy_format_type FLOPPY_JVC_FORMAT = &floppy_image_format_creator<jvc_format>;

50
src/lib/formats/jvc_dsk.h Normal file
View File

@ -0,0 +1,50 @@
// license:GPL-2.0+
// copyright-holders:Dirk Best
/***************************************************************************
JVC
Disk image format
Named after its creator, Jeff Vavasour
***************************************************************************/
#pragma once
#ifndef __JVC_DSK_H__
#define __JVC_DSK_H__
#include "flopimg.h"
class jvc_format : public floppy_image_format_t
{
public:
jvc_format();
struct jvc_header
{
UINT8 sectors_per_track;
UINT8 side_count;
UINT8 sector_size;
UINT8 first_sector_id;
UINT8 sector_attribute_flag;
int header_size;
};
virtual const char *name() const;
virtual const char *description() const;
virtual const char *extensions() const;
virtual int identify(io_generic *io, UINT32 form_factor);
virtual bool load(io_generic *io, UINT32 form_factor, floppy_image *image);
virtual bool save(io_generic *io, floppy_image *image);
virtual bool supports_save() const;
private:
bool parse_header(io_generic *io, int &header_size, int &tracks, int &heads, int &sectors, int &sector_size, int &base_sector_id);
};
extern const floppy_format_type FLOPPY_JVC_FORMAT;
#endif // __JVC_DSK_H__