svi318: updated to use the new wd fdc. floppy support has been restored,

which was broken for a long time.
This commit is contained in:
Dirk Best 2015-06-03 18:55:46 +02:00
parent 25a8f0715d
commit 8afcf3f9ce
5 changed files with 181 additions and 213 deletions

View File

@ -1,174 +1,143 @@
// license:BSD-3-Clause
// copyright-holders:Miodrag Milanovic
/*********************************************************************
// license:GPL-2.0+
// copyright-holders:Dirk Best
/***************************************************************************
formats/svi_dsk.c
Spectravideo SVI-318/328
SVI318 disk images
Disk image format
*********************************************************************/
#include <string.h>
#include <assert.h>
***************************************************************************/
#include "svi_dsk.h"
#include "basicdsk.h"
static FLOPPY_IDENTIFY(svi_dsk_identify)
svi_format::svi_format()
{
*vote = ((floppy_image_size(floppy) == (172032)) || (floppy_image_size(floppy) == (346112))) ? 100 : 0;
return FLOPPY_ERROR_SUCCESS;
}
static int svi_get_heads_per_disk(floppy_image_legacy *floppy)
const char *svi_format::name() const
{
return (floppy_image_size(floppy) == (172032)) ? 1 : 2;
return "svi";
}
static int svi_get_tracks_per_disk(floppy_image_legacy *floppy)
const char *svi_format::description() const
{
return 40;
return "SVI-318/328 disk image";
}
static UINT64 svi_translate_offset(floppy_image_legacy *floppy,
int track, int head, int sector)
const char *svi_format::extensions() const
{
UINT64 o;
if ((track==0) && (head==0))
o = sector*128;
else
o = ((track*((floppy_image_size(floppy) == (172032)) ? 1 : 2)+head)*17+sector)*256-2048; /* (17*256)-(18*128)=2048 */
return o;
return "dsk";
}
static floperr_t get_offset(floppy_image_legacy *floppy, int head, int track, int sector, int sector_is_index, UINT64 *offset)
int svi_format::identify(io_generic *io, UINT32 form_factor)
{
UINT64 offs;
/* translate the sector to a raw sector */
if (!sector_is_index)
UINT64 size = io_generic_size(io);
if (size == 172032 || size == 346112)
return 50;
return 0;
}
bool svi_format::load(io_generic *io, UINT32 form_factor, floppy_image *image)
{
UINT64 size = io_generic_size(io);
int head_count;
switch (size)
{
sector -= 1;
case 172032: head_count = 1; break;
case 346112: head_count = 2; break;
default: return false;
}
/* check to see if we are out of range */
if ((head < 0) || (head >= ((floppy_image_size(floppy) == (172032)) ? 1 : 2)) || (track < 0) || (track >= 40)
|| (sector < 0) || (sector >= ((head==0 && track==0) ? 18 : 17)))
return FLOPPY_ERROR_SEEKERROR;
offs = svi_translate_offset(floppy, track, head, sector);
if (offset)
*offset = offs;
return FLOPPY_ERROR_SUCCESS;
}
int file_offset = 0;
for (int track = 0; track < 40; track++)
{
for (int head = 0; head < head_count ; head++)
{
int sector_count = (track == 0 && head == 0) ? 18 : 17;
int sector_size = (track == 0 && head == 0) ? 128 : 256;
desc_pc_sector sectors[20];
UINT8 sector_data[5000];
int sector_offset = 0;
static floperr_t internal_svi_read_sector(floppy_image_legacy *floppy, int head, int track, int sector, int sector_is_index, void *buffer, size_t buflen)
{
UINT64 offset;
floperr_t err;
err = get_offset(floppy, head, track, sector, sector_is_index, &offset);
if (err)
return err;
for (int i = 0; i < sector_count; i++)
{
sectors[i].track = track;
sectors[i].head = head;
sectors[i].sector = i + 1;
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];
floppy_image_read(floppy, buffer, offset, buflen);
return FLOPPY_ERROR_SUCCESS;
}
io_generic_read(io, sectors[i].data, file_offset, sector_size);
sector_offset += sector_size;
file_offset += sector_size;
}
static floperr_t internal_svi_write_sector(floppy_image_legacy *floppy, int head, int track, int sector, int sector_is_index, const void *buffer, size_t buflen, int ddam)
{
UINT64 offset;
floperr_t err;
err = get_offset(floppy, head, track, sector, sector_is_index, &offset);
if (err)
return err;
floppy_image_write(floppy, buffer, offset, buflen);
return FLOPPY_ERROR_SUCCESS;
}
static floperr_t svi_read_sector(floppy_image_legacy *floppy, int head, int track, int sector, void *buffer, size_t buflen)
{
return internal_svi_read_sector(floppy, head, track, sector, FALSE, buffer, buflen);
}
static floperr_t svi_write_sector(floppy_image_legacy *floppy, int head, int track, int sector, const void *buffer, size_t buflen, int ddam)
{
return internal_svi_write_sector(floppy, head, track, sector, FALSE, buffer, buflen, ddam);
}
static floperr_t svi_read_indexed_sector(floppy_image_legacy *floppy, int head, int track, int sector, void *buffer, size_t buflen)
{
return internal_svi_read_sector(floppy, head, track, sector, TRUE, buffer, buflen);
}
static floperr_t svi_write_indexed_sector(floppy_image_legacy *floppy, int head, int track, int sector, const void *buffer, size_t buflen, int ddam)
{
return internal_svi_write_sector(floppy, head, track, sector, TRUE, buffer, buflen, ddam);
}
static floperr_t svi_get_sector_length(floppy_image_legacy *floppy, int head, int track, int sector, UINT32 *sector_length)
{
floperr_t err;
err = get_offset(floppy, head, track, sector, FALSE, NULL);
if (err)
return err;
if (sector_length) {
*sector_length = (head==0 && track==0) ? 128 : 256;
if (track == 0 && head == 0)
build_wd_track_fm(track, head, image, 50000, sector_count, sectors, 10, 26, 11);
else
build_wd_track_mfm(track, head, image, 100000, sector_count, sectors, 32, 50, 22);
}
}
return FLOPPY_ERROR_SUCCESS;
return true;
}
static floperr_t svi_get_indexed_sector_info(floppy_image_legacy *floppy, int head, int track, int sector_index, int *cylinder, int *side, int *sector, UINT32 *sector_length, unsigned long *flags)
bool svi_format::save(io_generic *io, floppy_image *image)
{
sector_index += 1;
if (cylinder)
*cylinder = track;
if (side)
*side = head;
if (sector)
*sector = sector_index;
if (flags)
/* TODO: read DAM or DDAM and determine flags */
*flags = 0;
return svi_get_sector_length(floppy, head, track, sector_index, sector_length);
UINT8 bitstream[500000/8];
UINT8 sector_data[50000];
desc_xs sectors[256];
int track_size;
UINT64 file_offset = 0;
int track_count, head_count;
image->get_actual_geometry(track_count, head_count);
// initial fm track
generate_bitstream_from_track(0, 0, 4000, bitstream, track_size, image);
extract_sectors_from_bitstream_fm_pc(bitstream, track_size, sectors, sector_data, sizeof(sector_data));
for (int i = 0; i < 18; i++)
{
io_generic_write(io, sectors[i + 1].data, file_offset, 128);
file_offset += 128;
}
// rest are mfm tracks
for (int track = 0; track < track_count; track++)
{
for (int head = 0; head < head_count; head++)
{
// skip track 0, head 0
if (track == 0) { if (head_count == 1) break; else head++; }
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 < 17; i++)
{
io_generic_write(io, sectors[i + 1].data, file_offset, 256);
file_offset += 256;
}
}
}
return true;
}
static FLOPPY_CONSTRUCT(svi_dsk_construct)
bool svi_format::supports_save() const
{
struct FloppyCallbacks *callbacks;
callbacks = floppy_callbacks(floppy);
callbacks->read_sector = svi_read_sector;
callbacks->write_sector = svi_write_sector;
callbacks->read_indexed_sector = svi_read_indexed_sector;
callbacks->write_indexed_sector = svi_write_indexed_sector;
callbacks->get_sector_length = svi_get_sector_length;
callbacks->get_heads_per_disk = svi_get_heads_per_disk;
callbacks->get_tracks_per_disk = svi_get_tracks_per_disk;
callbacks->get_indexed_sector_info = svi_get_indexed_sector_info;
return FLOPPY_ERROR_SUCCESS;
return true;
}
const floppy_format_type FLOPPY_SVI_FORMAT = &floppy_image_format_creator<svi_format>;
/* ----------------------------------------------------------------------- */
LEGACY_FLOPPY_OPTIONS_START( svi318 )
LEGACY_FLOPPY_OPTION( svi_dsk, "dsk", "SVI-318 floppy disk image", svi_dsk_identify, svi_dsk_construct, NULL, NULL)
LEGACY_FLOPPY_OPTION( svi_cpm, "dsk", "SVI-728 DSDD CP/M disk image", basicdsk_identify_default, basicdsk_construct_default, NULL,
HEADS([2])
TRACKS([40])
SECTORS([17])
SECTOR_LENGTH([256])
FIRST_SECTOR_ID([1]))
LEGACY_FLOPPY_OPTIONS_END

View File

@ -1,20 +1,35 @@
// license:BSD-3-Clause
// copyright-holders:Miodrag Milanovic
/*********************************************************************
// license:GPL-2.0+
// copyright-holders:Dirk Best
/***************************************************************************
formats/svi_dsk.h
Spectravideo SVI-318/328
SVI318 disk images
Disk image format
*********************************************************************/
***************************************************************************/
#ifndef SVI_DSK_H
#define SVI_DSK_H
#pragma once
#ifndef __SVI_DSK_H__
#define __SVI_DSK_H__
#include "flopimg.h"
/**************************************************************************/
class svi_format : public floppy_image_format_t
{
public:
svi_format();
LEGACY_FLOPPY_OPTIONS_EXTERN(svi318);
virtual const char *name() const;
virtual const char *description() const;
virtual const char *extensions() const;
#endif /* SVI_DSK_H */
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;
};
extern const floppy_format_type FLOPPY_SVI_FORMAT;
#endif // __SVI_DSK_H__

View File

@ -245,12 +245,13 @@ WRITE_LINE_MEMBER(svi318_state::vdp_interrupt)
m_maincpu->set_input_line(0, (state ? HOLD_LINE : CLEAR_LINE));
}
static const floppy_interface svi318_floppy_interface =
{
FLOPPY_STANDARD_5_25_DSHD,
LEGACY_FLOPPY_OPTIONS_NAME(svi318),
"floppy_5_25"
};
FLOPPY_FORMATS_MEMBER( svi318_state::floppy_formats )
FLOPPY_SVI_FORMAT
FLOPPY_FORMATS_END
static SLOT_INTERFACE_START( svi_floppies )
SLOT_INTERFACE("dd", FLOPPY_525_DD)
SLOT_INTERFACE_END
static MACHINE_CONFIG_FRAGMENT( svi318_cartslot )
MCFG_GENERIC_CARTSLOT_ADD("cartslot", generic_plain_slot, "svi318_cart")
@ -307,16 +308,16 @@ static MACHINE_CONFIG_START( svi318, svi318_state )
MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_PLAY)
MCFG_CASSETTE_INTERFACE("svi318_cass")
MCFG_DEVICE_ADD("wd179x", FD1793, 0)
MCFG_WD17XX_DEFAULT_DRIVE2_TAGS
MCFG_WD17XX_INTRQ_CALLBACK(WRITELINE(svi318_state, fdc_intrq_w))
MCFG_WD17XX_DRQ_CALLBACK(WRITELINE(svi318_state, fdc_drq_w))
MCFG_SOFTWARE_LIST_ADD("cass_list", "svi318_cass")
MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(svi318_floppy_interface)
MCFG_FD1793x_ADD("wd179x", XTAL_1MHz)
MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(svi318_state, fdc_intrq_w))
MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(svi318_state, fdc_drq_w))
/* Software lists */
MCFG_SOFTWARE_LIST_ADD("cass_list", "svi318_flop")
MCFG_SOFTWARE_LIST_ADD("disk_list", "svi318_cass")
MCFG_FLOPPY_DRIVE_ADD("wd179x:0", svi_floppies, "dd", svi318_state::floppy_formats)
MCFG_FLOPPY_DRIVE_ADD("wd179x:1", svi_floppies, "dd", svi318_state::floppy_formats)
MCFG_SOFTWARE_LIST_ADD("disk_list", "svi318_flop")
MCFG_FRAGMENT_ADD(svi318_cartslot)
@ -436,16 +437,16 @@ static MACHINE_CONFIG_START( svi328_806, svi318_state )
MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_PLAY)
MCFG_CASSETTE_INTERFACE("svi318_cass")
MCFG_DEVICE_ADD("wd179x", FD1793, 0)
MCFG_WD17XX_DEFAULT_DRIVE2_TAGS
MCFG_WD17XX_INTRQ_CALLBACK(WRITELINE(svi318_state, fdc_intrq_w))
MCFG_WD17XX_DRQ_CALLBACK(WRITELINE(svi318_state, fdc_drq_w))
MCFG_SOFTWARE_LIST_ADD("cass_list", "svi318_cass")
MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(svi318_floppy_interface)
MCFG_FD1793x_ADD("wd179x", XTAL_1MHz)
MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(svi318_state, fdc_intrq_w))
MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(svi318_state, fdc_drq_w))
/* Software lists */
MCFG_SOFTWARE_LIST_ADD("cass_list", "svi318_flop")
MCFG_SOFTWARE_LIST_ADD("disk_list", "svi318_cass")
MCFG_FLOPPY_DRIVE_ADD("wd179x:0", svi_floppies, "dd", svi318_state::floppy_formats)
MCFG_FLOPPY_DRIVE_ADD("wd179x:1", svi_floppies, "dd", svi318_state::floppy_formats)
MCFG_SOFTWARE_LIST_ADD("disk_list", "svi318_flop")
MCFG_FRAGMENT_ADD(svi318_cartslot)

View File

@ -14,7 +14,7 @@
#include "cpu/z80/z80.h"
#include "machine/i8255.h"
#include "machine/ins8250.h"
#include "machine/wd17xx.h"
#include "machine/wd_fdc.h"
#include "machine/ram.h"
#include "machine/buffer.h"
#include "imagedev/cassette.h"
@ -44,22 +44,25 @@ public:
m_ins8250_1(*this, "ins8250_1"),
m_cart(*this, "cartslot"),
m_fd1793(*this, "wd179x"),
m_floppy0(*this, "wd179x:0"),
m_floppy1(*this, "wd179x:1"),
m_crtc(*this, "crtc"),
m_line(*this, "LINE"),
m_joysticks(*this, "JOYSTICKS"),
m_buttons(*this, "BUTTONS"),
m_palette(*this, "palette"),
m_floppy(NULL),
m_bank1(*this, "bank1"),
m_bank2(*this, "bank2"),
m_bank3(*this, "bank3"),
m_bank4(*this, "bank4")
{ }
DECLARE_FLOPPY_FORMATS(floppy_formats);
// FDC
UINT8 m_driveselect;
int m_drq;
int m_irq;
UINT8 m_heads[2];
DECLARE_WRITE8_MEMBER(ppi_w);
DECLARE_READ8_MEMBER(psg_port_a_r);
@ -105,7 +108,9 @@ protected:
required_device<ins8250_device> m_ins8250_0;
required_device<ins8250_device> m_ins8250_1;
required_device<generic_slot_device> m_cart;
required_device<fd1793_device> m_fd1793;
required_device<fd1793_t> m_fd1793;
required_device<floppy_connector> m_floppy0;
required_device<floppy_connector> m_floppy1;
optional_device<mc6845_device> m_crtc;
required_ioport_array<11> m_line;
required_ioport m_joysticks;
@ -134,6 +139,8 @@ private:
// keyboard
UINT8 m_keyboard_row;
floppy_image_device *m_floppy;
// centronics
int m_centronics_busy;

View File

@ -223,23 +223,26 @@ WRITE_LINE_MEMBER(svi318_state::fdc_drq_w)
WRITE8_MEMBER(svi318_state::fdc_drive_motor_w)
{
switch (data & 3)
{
case 1:
m_fd1793->set_drive(0);
m_driveselect = 0;
break;
case 2:
m_fd1793->set_drive(1);
m_driveselect = 1;
break;
}
m_floppy = NULL;
if (BIT(data, 0)) m_floppy = m_floppy0->get_device();
if (BIT(data, 1)) m_floppy = m_floppy1->get_device();
m_fd1793->set_floppy(m_floppy);
if (m_floppy0->get_device())
m_floppy0->get_device()->mon_w(!BIT(data, 2));
if (m_floppy1->get_device())
m_floppy1->get_device()->mon_w(!BIT(data, 3));
}
WRITE8_MEMBER(svi318_state::fdc_density_side_w)
{
m_fd1793->dden_w(BIT(data, 0));
m_fd1793->set_side(BIT(data, 1));
if (m_floppy)
m_floppy->ss_w(BIT(data, 1));
}
READ8_MEMBER(svi318_state::fdc_irqdrq_r)
@ -445,10 +448,8 @@ void svi318_state::machine_start()
}
// register for savestates
save_item(NAME(m_driveselect));
save_item(NAME(m_drq));
save_item(NAME(m_irq));
save_item(NAME(m_heads));
save_item(NAME(m_bank_switch));
save_item(NAME(m_bank_low));
@ -465,34 +466,12 @@ void svi318_state::machine_start()
machine().save().register_postload(save_prepost_delegate(FUNC(svi318_state::postload), this));
}
static void svi318_load_proc(device_image_interface &image)
{
svi318_state *state = image.device().machine().driver_data<svi318_state>();
int size = image.length();
int id = floppy_get_drive(&image.device());
switch (size)
{
case 172032: /* SVI-328 SSDD */
state->m_heads[id] = 1;
break;
case 346112: /* SVI-328 DSDD */
state->m_heads[id] = 2;
break;
case 348160: /* SVI-728 DSDD CP/M */
state->m_heads[id] = 2;
break;
}
}
void svi318_state::machine_reset()
{
m_keyboard_row = 0;
m_centronics_busy = 0;
m_svi806_present = 0;
m_svi806_ram_enabled = 0;
m_driveselect = 0;
m_drq = 0;
m_irq = 0;
@ -504,9 +483,6 @@ void svi318_state::machine_reset()
m_bank_switch = 0xff;
set_banks();
for (int drive = 0; drive < 2; drive++)
floppy_get_device(machine(), drive)->floppy_install_load_proc(svi318_load_proc);
}
/* Memory */
@ -760,7 +736,7 @@ WRITE8_MEMBER(svi318_state::io_ext_w)
break;
case 0x30:
m_fd1793->command_w(space, 0, data);
m_fd1793->cmd_w(space, 0, data);
break;
case 0x31:
m_fd1793->track_w(space, 0, data);