mirror of
https://github.com/holub/mame
synced 2025-05-20 04:39:11 +03:00
292 lines
7.7 KiB
C++
292 lines
7.7 KiB
C++
// license:BSD-3-Clause
|
|
// copyright-holders:Curt Coder
|
|
/*********************************************************************
|
|
|
|
formats/fdi_dsk.h
|
|
|
|
Floppy format code for Formatted Disk Image (FDI) v2.0 images
|
|
|
|
*********************************************************************/
|
|
|
|
/*
|
|
|
|
TODO:
|
|
|
|
- everything
|
|
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include "imageutl.h"
|
|
#include "flopimg.h"
|
|
|
|
/***************************************************************************
|
|
PARAMETERS
|
|
***************************************************************************/
|
|
|
|
#define LOG 1
|
|
|
|
#define MAX_TRACKS 180
|
|
|
|
#define FLAGS_WRITE_PROTECTED 0x01
|
|
#define FLAGS_INDEX_SYNC 0x02
|
|
|
|
/* media type */
|
|
enum
|
|
{
|
|
TYPE_8_INCH = 0,
|
|
TYPE_5_25_INCH,
|
|
TYPE_3_5_INCH,
|
|
TYPE_3_INCH
|
|
};
|
|
|
|
static const char *const MEDIA_TYPE[] = { "8", "5.25", "3.5", "3" };
|
|
|
|
/* tracks per inch */
|
|
enum
|
|
{
|
|
TPI_48 = 0,
|
|
TPI_67,
|
|
TPI_96,
|
|
TPI_100,
|
|
TPI_135,
|
|
TPI_192
|
|
};
|
|
|
|
static const int TRACKS_PER_INCH[] = { 48, 67, 96, 100, 135, 192 };
|
|
|
|
/* high level track types */
|
|
enum
|
|
{
|
|
TRACK_BLANK = 0, /* not supported */
|
|
TRACK_AMIGA_DD, /* not supported */
|
|
TRACK_AMIGA_HD, /* not supported */
|
|
TRACK_ST_DD_9, /* not supported */
|
|
TRACK_ST_DD_10, /* not supported */
|
|
TRACK_PC_DD_8, /* not supported */
|
|
TRACK_PC_DD_9, /* not supported */
|
|
TRACK_PC_HD_15, /* not supported */
|
|
TRACK_IBM_HD_18, /* not supported */
|
|
TRACK_IBM_ED_36, /* not supported */
|
|
TRACK_CBM_1541, /* not supported */
|
|
TRACK_APPLE_DOS_32, /* not supported */
|
|
TRACK_APPLE_DOS_33, /* not supported */
|
|
TRACK_APPLE_GCR, /* not supported */
|
|
TRACK_IBM_SD_10 /* not supported */
|
|
};
|
|
|
|
//static const int SECTORS_PER_TRACK[] = { 0, 11, 22, 9, 10, 8, 9, 15, 18, 36, -1, -1, -1, -1, 10 };
|
|
|
|
/***************************************************************************
|
|
TYPE DEFINITIONS
|
|
***************************************************************************/
|
|
|
|
struct fdidsk_tag
|
|
{
|
|
int version;
|
|
int heads; /* number of physical heads */
|
|
int tracks; /* number of physical tracks */
|
|
uint32_t track_offset[MAX_TRACKS]; /* offset within data for each track */
|
|
uint8_t track_type[MAX_TRACKS];
|
|
};
|
|
|
|
struct fdi_track
|
|
{
|
|
uint8_t type;
|
|
uint8_t size;
|
|
};
|
|
|
|
struct fdi_header
|
|
{
|
|
uint8_t signature[27];
|
|
uint8_t creator[32];
|
|
uint8_t comment[80];
|
|
uint8_t eof;
|
|
uint8_t version[2];
|
|
uint8_t ltrack[2];
|
|
uint8_t lhead;
|
|
uint8_t type;
|
|
uint8_t rotspeed;
|
|
uint8_t flags;
|
|
uint8_t tpi;
|
|
uint8_t headwidth;
|
|
uint8_t reserved[2];
|
|
struct fdi_track track[MAX_TRACKS];
|
|
};
|
|
|
|
struct fdi_pulse_track_header
|
|
{
|
|
uint8_t numpulses[4];
|
|
uint8_t averagesz[3];
|
|
uint8_t minsize[3];
|
|
uint8_t maxsize[3];
|
|
uint8_t indexsize[3];
|
|
// uint8_t averagedt[averagesz];
|
|
// uint8_t mindata[minsize];
|
|
// uint8_t maxdata[maxsize];
|
|
// uint8_t indexdata[indexsize];
|
|
};
|
|
|
|
/***************************************************************************
|
|
INLINE FUNCTIONS
|
|
***************************************************************************/
|
|
|
|
static inline struct fdidsk_tag *get_tag(floppy_image_legacy *floppy)
|
|
{
|
|
return (fdidsk_tag *)floppy_tag(floppy);
|
|
}
|
|
|
|
/***************************************************************************
|
|
IMPLEMENTATION
|
|
***************************************************************************/
|
|
|
|
static int fdi_get_heads_per_disk(floppy_image_legacy *floppy)
|
|
{
|
|
return get_tag(floppy)->heads;
|
|
}
|
|
|
|
static int fdi_get_tracks_per_disk(floppy_image_legacy *floppy)
|
|
{
|
|
return get_tag(floppy)->tracks;
|
|
}
|
|
|
|
static int fdi_get_sectors_per_track(floppy_image_legacy *floppy, int head, int track)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static floperr_t fdi_get_sector_length(floppy_image_legacy *floppy, int head, int track, int sector, uint32_t *sector_length)
|
|
{
|
|
return FLOPPY_ERROR_SUCCESS;
|
|
}
|
|
/*
|
|
static uint32_t fdi_get_sector_offset(floppy_image_legacy* floppy, int head, int track, int sector)
|
|
{
|
|
return 0;
|
|
}
|
|
*/
|
|
static floperr_t fdi_get_indexed_sector_info(floppy_image_legacy *floppy, int head, int track, int sector_index, int *cylinder, int *side, int *sector, uint32_t *sector_length, unsigned long *flags)
|
|
{
|
|
return FLOPPY_ERROR_UNSUPPORTED;
|
|
}
|
|
|
|
static floperr_t fdi_read_track(floppy_image_legacy *floppy, int head, int track, uint64_t offset, void *buffer, size_t buflen)
|
|
{
|
|
return FLOPPY_ERROR_UNSUPPORTED;
|
|
}
|
|
|
|
static floperr_t fdi_read_sector(floppy_image_legacy *floppy, int head, int track, int sector, void *buffer, size_t buflen)
|
|
{
|
|
return FLOPPY_ERROR_UNSUPPORTED;
|
|
}
|
|
|
|
static floperr_t fdi_read_indexed_sector(floppy_image_legacy *floppy, int head, int track, int sector, void *buffer, size_t buffer_len)
|
|
{
|
|
return FLOPPY_ERROR_UNSUPPORTED;
|
|
}
|
|
|
|
static floperr_t fdi_write_sector(floppy_image_legacy *floppy, int head, int track, int sector, const void *buffer, size_t buflen, int ddam)
|
|
{
|
|
return FLOPPY_ERROR_UNSUPPORTED;
|
|
}
|
|
|
|
static floperr_t fdi_write_indexed_sector(floppy_image_legacy *floppy, int head, int track, int sector, const void *buffer, size_t buflen, int ddam)
|
|
{
|
|
return FLOPPY_ERROR_UNSUPPORTED;
|
|
}
|
|
|
|
/*-------------------------------------------------
|
|
FLOPPY_IDENTIFY( fdi_dsk_identify )
|
|
-------------------------------------------------*/
|
|
|
|
FLOPPY_IDENTIFY( fdi_dsk_identify )
|
|
{
|
|
uint8_t header[25];
|
|
|
|
floppy_image_read(floppy, header, 0, 25);
|
|
|
|
if (!strncmp((const char *)header, "Formatted Disk Image file", 25))
|
|
{
|
|
*vote = 100;
|
|
}
|
|
else
|
|
{
|
|
*vote = 0;
|
|
}
|
|
|
|
return FLOPPY_ERROR_SUCCESS;
|
|
}
|
|
|
|
/*-------------------------------------------------
|
|
FLOPPY_CONSTRUCT( fdi_dsk_construct )
|
|
-------------------------------------------------*/
|
|
|
|
FLOPPY_CONSTRUCT( fdi_dsk_construct )
|
|
{
|
|
if (params)
|
|
{
|
|
/* create not supported */
|
|
return FLOPPY_ERROR_UNSUPPORTED;
|
|
}
|
|
|
|
struct fdidsk_tag *tag = (struct fdidsk_tag *) floppy_create_tag(floppy, sizeof(struct fdidsk_tag));
|
|
|
|
if (!tag) return FLOPPY_ERROR_OUTOFMEMORY;
|
|
|
|
/* read header */
|
|
struct fdi_header header;
|
|
floppy_image_read(floppy, &header, 0, sizeof(header));
|
|
|
|
tag->version = header.version[0];
|
|
tag->tracks = pick_integer_be(header.ltrack, 0, 2) + 1;
|
|
tag->heads = header.lhead + 1;
|
|
|
|
if (LOG)
|
|
{
|
|
LOG_FORMATS("FDI creator: %s\n", header.creator);
|
|
LOG_FORMATS("FDI comment: %s\n", header.comment);
|
|
LOG_FORMATS("FDI version: %u\n", tag->version);
|
|
LOG_FORMATS("FDI tracks: %u\n", tag->tracks);
|
|
LOG_FORMATS("FDI heads: %u\n", tag->heads);
|
|
LOG_FORMATS("FDI media type: %s\"\n", MEDIA_TYPE[header.type]);
|
|
LOG_FORMATS("FDI rotation speed: %u\n", header.rotspeed + 128);
|
|
if (header.flags & FLAGS_WRITE_PROTECTED) LOG_FORMATS("FDI is write protected\n");
|
|
if (header.flags & FLAGS_INDEX_SYNC) LOG_FORMATS("FDI is index synchronized\n");
|
|
LOG_FORMATS("FDI media TPI: %u\n", TRACKS_PER_INCH[header.tpi]);
|
|
LOG_FORMATS("FDI head TPI: %u\n", TRACKS_PER_INCH[header.headwidth]);
|
|
}
|
|
|
|
/* find track offsets */
|
|
int offset = sizeof(header);
|
|
|
|
for (int track = 0; track < tag->tracks; track++)
|
|
{
|
|
uint8_t type = header.track[track].type;
|
|
int size = header.track[track].size * 256;
|
|
|
|
if (LOG) LOG_FORMATS("FDI track %d type %02x size %d offset %d\n", track, type, size, offset);
|
|
|
|
tag->track_offset[track] = offset;
|
|
tag->track_type[track] = type;
|
|
|
|
offset += size;
|
|
}
|
|
|
|
/* set callbacks */
|
|
struct FloppyCallbacks *callbacks = floppy_callbacks(floppy);
|
|
|
|
callbacks->read_track = fdi_read_track;
|
|
callbacks->get_heads_per_disk = fdi_get_heads_per_disk;
|
|
callbacks->get_tracks_per_disk = fdi_get_tracks_per_disk;
|
|
callbacks->get_sector_length = fdi_get_sector_length;
|
|
callbacks->read_sector = fdi_read_sector;
|
|
callbacks->read_indexed_sector = fdi_read_indexed_sector;
|
|
// callbacks->write_track = fdi_write_track;
|
|
callbacks->write_sector = fdi_write_sector;
|
|
callbacks->write_indexed_sector = fdi_write_indexed_sector;
|
|
callbacks->get_indexed_sector_info = fdi_get_indexed_sector_info;
|
|
callbacks->get_sectors_per_track = fdi_get_sectors_per_track;
|
|
|
|
return FLOPPY_ERROR_SUCCESS;
|
|
}
|