Sync with MESS, OG work credited there (no whatsnew)

This commit is contained in:
Miodrag Milanovic 2011-11-11 08:40:31 +00:00
parent 6fdb70f2f8
commit 47cc156fe2
5 changed files with 179 additions and 465 deletions

View File

@ -390,7 +390,7 @@ void amiga_fdc::index_callback(floppy_image_device *floppy, int state)
{
/* Issue a index pulse when a disk revolution completes */
device_t *cia = machine().device("cia_1");
mos6526_flag_w(cia, state);
mos6526_flag_w(cia, !state);
}
void amiga_fdc::pll_t::set_clock(attotime period)

View File

@ -29,7 +29,7 @@ const char *adf_format::extensions() const
bool adf_format::supports_save() const
{
return false;
return true;
}
int adf_format::identify(io_generic *io)
@ -59,7 +59,73 @@ bool adf_format::load(io_generic *io, floppy_image *image)
}
}
return TRUE;
return true;
}
UINT32 adf_format::g32(const UINT8 *trackbuf, int track_size, int pos)
{
if(pos >= 0 && track_size-pos >= 40) {
int pp = pos >> 3;
int dp = pos & 7;
return
(trackbuf[pp] << (24+dp)) |
(trackbuf[pp+1] << (16+dp)) |
(trackbuf[pp+2] << (8+dp)) |
(trackbuf[pp+3] << dp) |
(trackbuf[pp+4] >> (8-dp));
} else {
UINT32 res = 0;
for(int i=0; i<32; i++) {
int pp = (pos+i) % track_size;
if(trackbuf[pp>>3] & (0x80 >> (pp & 7)))
res |= 0x80000000 >> i;
}
return res;
}
}
UINT32 adf_format::checksum(const UINT8 *trackbuf, int track_size, int pos, int long_count)
{
UINT32 check = 0;
for(int i=0; i<long_count; i++)
check ^= g32(trackbuf, track_size, pos+32*i);
return check & 0x55555555;
}
bool adf_format::save(io_generic *io, floppy_image *image)
{
// TODO: HD support
UINT8 sectdata[512*11];
UINT8 trackbuf[150000/8];
for(int track=0; track < 80; track++) {
for(int side=0; side < 2; side++) {
int track_size;
generate_bitstream_from_track(track, side, 2000, trackbuf, track_size, image);
for(int i=0; i<track_size; i++)
if(g32(trackbuf, track_size, i) == 0x44894489 &&
(g32(trackbuf, track_size, i+384) & 0x55555555) == checksum(trackbuf, track_size, i+32, 10) &&
(g32(trackbuf, track_size, i+448) & 0x55555555) == checksum(trackbuf, track_size, i+480, 256)) {
UINT32 head = ((g32(trackbuf, track_size, i+32) & 0x55555555) << 1) | (g32(trackbuf, track_size, i+64) & 0x55555555);
int sect = (head >> 8) & 0xff;
if(sect > 11)
continue;
UINT8 *dest = sectdata + 512*sect;
for(int j=0; j<128; j++) {
UINT32 val = ((g32(trackbuf, track_size, i+480+32*j) & 0x55555555) << 1) | (g32(trackbuf, track_size, i+4576+32*j) & 0x55555555);
*dest++ = val >> 24;
*dest++ = val >> 16;
*dest++ = val >> 8;
*dest++ = val;
}
io_generic_write(io, sectdata, (track*2 + side)*512*11, 512*11);
}
}
}
return true;
}
const floppy_format_type FLOPPY_ADF_FORMAT = &floppy_image_format_creator<adf_format>;

View File

@ -18,11 +18,16 @@ public:
virtual int identify(io_generic *io);
virtual bool load(io_generic *io, floppy_image *image);
virtual bool save(io_generic *io, floppy_image *image);
virtual const char *name() const;
virtual const char *description() const;
virtual const char *extensions() const;
virtual bool supports_save() const;
private:
static UINT32 g32(const UINT8 *trackbuf, int track_size, int pos);
static UINT32 checksum(const UINT8 *trackbuf, int track_size, int pos, int long_count);
};
extern const floppy_format_type FLOPPY_ADF_FORMAT;

View File

@ -6,483 +6,116 @@
**************************************************************************/
#include "coupedsk.h"
#include "formats/basicdsk.h"
#include "emu.h"
#include "formats/coupedsk.h"
#include "flopimg.h"
#define SAD_HEADER_LEN 22
#define SAD_SIGNATURE "Aley's disk backup"
#define SDF_TRACKSIZE (512 * 12)
struct sdf_tag
{
UINT8 heads;
UINT8 tracks;
const floppy_image_format_t::desc_e mgt_format::desc_10[] = {
{ MFM, 0x4e, 60 },
{ SECTOR_LOOP_START, 0, 9 },
{ MFM, 0x00, 12 },
{ CRC_CCITT_START, 1 },
{ RAW, 0x4489, 3 },
{ MFM, 0xfe, 1 },
{ TRACK_ID },
{ HEAD_ID },
{ SECTOR_ID },
{ SIZE_ID },
{ CRC_END, 1 },
{ CRC, 1 },
{ MFM, 0x4e, 22 },
{ MFM, 0x00, 12 },
{ CRC_CCITT_START, 2 },
{ RAW, 0x4489, 3 },
{ MFM, 0xfb, 1 },
{ SECTOR_DATA, -1 },
{ CRC_END, 2 },
{ CRC, 2 },
{ MFM, 0x4e, 24 },
{ SECTOR_LOOP_END },
{ MFM, 0x4e, 210 },
{ END }
};
/*************************************
*
* MGT disk image format
*
*************************************/
/*
Straight rip without any header
Data:
Side 0 Track 0
Side 1 Track 0
Side 0 Track 1
Side 1 Track 1
...
*/
FLOPPY_CONSTRUCT( coupe_mgt_construct )
mgt_format::mgt_format()
{
struct basicdsk_geometry geometry;
}
memset(&geometry, 0, sizeof(geometry));
geometry.heads = 2;
geometry.tracks = 80;
geometry.sector_length = 512;
geometry.first_sector_id = 1;
const char *mgt_format::name() const
{
return "mgt";
}
if (params)
{
/* create */
geometry.sectors = option_resolution_lookup_int(params, PARAM_SECTORS);
}
else
{
/* load */
UINT64 size = floppy_image_size(floppy);
const char *mgt_format::description() const
{
return "Sam Coupe MGT image format";
}
/* verify size */
if (size != 737280 && size != 819200)
return FLOPPY_ERROR_INVALIDIMAGE;
const char *mgt_format::extensions() const
{
return "mgt,dsk";
}
geometry.sectors = size / 81920;
bool mgt_format::supports_save() const
{
return true;
}
int mgt_format::identify(io_generic *io)
{
int size = io_generic_size(io);
if(/*size == 737280 || */ size == 819200)
return 50;
return 0;
}
bool mgt_format::load(io_generic *io, floppy_image *image)
{
int size = io_generic_size(io);
int sector_count = size == 737280 ? 9 : 10;
UINT8 sectdata[10*512];
desc_s sectors[10];
for(int i=0; i<sector_count; i++) {
sectors[i].data = sectdata + 512*i;
sectors[i].size = 512;
sectors[i].sector_id = i + 1;
}
return basicdsk_construct(floppy, &geometry);
}
FLOPPY_IDENTIFY( coupe_mgt_identify )
{
UINT64 size;
size = floppy_image_size(floppy);
*vote = (size == 737280 || size == 819200) ? 100 : 0;
return FLOPPY_ERROR_SUCCESS;
}
/*************************************
*
* SAD disk image format
*
*************************************/
/*
Header (22 bytes):
0-17 "Aley's disk backup"
18 number of sides
19 number of tracks
20 number of sectors per track
21 sector size divided by 64
Data:
Side 0 Track 0
Side 0 Track 1
Side 0 Track 2
...
Side 1 Track 0
Side 1 Track 1
...
*/
static UINT64 coupe_sad_translate_offset(floppy_image_legacy *floppy,
const struct basicdsk_geometry *geom, int track, int head, int sector)
{
return head * geom->tracks * geom->sectors + geom->sectors * track + sector;
}
static void coupe_sad_interpret_header(floppy_image_legacy *floppy,
int *heads, int *tracks, int *sectors, int *sector_size)
{
UINT8 header[SAD_HEADER_LEN];
floppy_image_read(floppy, header, 0, SAD_HEADER_LEN);
*heads = header[18];
*tracks = header[19];
*sectors = header[20];
*sector_size = header[21] << 6;
}
FLOPPY_CONSTRUCT( coupe_sad_construct )
{
struct basicdsk_geometry geometry;
int heads, tracks, sectors, sector_length;
memset(&geometry, 0, sizeof(geometry));
if (params)
{
/* create */
UINT8 header[SAD_HEADER_LEN];
/* get format options */
heads = option_resolution_lookup_int(params, PARAM_HEADS);
tracks = option_resolution_lookup_int(params, PARAM_TRACKS);
sectors = option_resolution_lookup_int(params, PARAM_SECTORS);
sector_length = option_resolution_lookup_int(params, PARAM_SECTOR_LENGTH);
/* build the header */
memset(header, 0, SAD_HEADER_LEN);
memcpy(header, SAD_SIGNATURE, 18);
header[18] = heads;
header[19] = tracks;
header[20] = sectors;
header[21] = sector_length >> 6;
/* and write it to disk */
floppy_image_write(floppy, header, 0, sizeof(header));
}
else
{
/* load */
coupe_sad_interpret_header(floppy, &heads, &tracks, &sectors, &sector_length);
}
/* fill in the data */
geometry.offset = SAD_HEADER_LEN;
geometry.heads = heads;
geometry.tracks = tracks;
geometry.sectors = sectors;
geometry.first_sector_id = 1;
geometry.sector_length = sector_length;
geometry.translate_offset = coupe_sad_translate_offset;
return basicdsk_construct(floppy, &geometry);
}
FLOPPY_IDENTIFY( coupe_sad_identify )
{
int heads, tracks, sectors, sector_size;
UINT64 size, calculated_size;
size = floppy_image_size(floppy);
/* read values from SAD header */
coupe_sad_interpret_header(floppy, &heads, &tracks, &sectors, &sector_size);
/* calculate expected disk image size */
calculated_size = SAD_HEADER_LEN + heads * tracks * sectors * sector_size;
*vote = (size == calculated_size) ? 100 : 0;
return FLOPPY_ERROR_SUCCESS;
}
/*************************************
*
* SDF disk image format
*
* TODO: wd17xx status codes are
* currently ignored
*
*************************************/
static int coupe_sdf_get_heads_per_disk(floppy_image_legacy *floppy)
{
struct sdf_tag *tag = (sdf_tag *)floppy_tag(floppy);
return tag->heads;
}
static int coupe_sdf_get_tracks_per_disk(floppy_image_legacy *floppy)
{
struct sdf_tag *tag = (sdf_tag *)floppy_tag(floppy);
return tag->tracks;
}
static UINT32 coupe_sdf_get_track_size(floppy_image_legacy *floppy, int head, int track)
{
return SDF_TRACKSIZE;
}
static floperr_t coupe_sdf_get_offset(floppy_image_legacy *floppy,
int head, int track, UINT64 *offset)
{
struct sdf_tag *tag = (sdf_tag *)floppy_tag(floppy);
if (head > tag->heads || track > tag->tracks)
return FLOPPY_ERROR_SEEKERROR;
*offset = (head * tag->tracks + track) * SDF_TRACKSIZE;
return FLOPPY_ERROR_SUCCESS;
}
static floperr_t coupe_sdf_read_track(floppy_image_legacy *floppy,
int head, int track, UINT64 offset, void *buffer, size_t buflen)
{
floperr_t err;
UINT64 track_offset;
/* get the offset to this track */
err = coupe_sdf_get_offset(floppy, head, track, &track_offset);
if (err) return err;
/* read track data into buffer */
floppy_image_read(floppy, buffer, offset + track_offset, buflen);
return FLOPPY_ERROR_SUCCESS;
}
static floperr_t coupe_sdf_write_track(floppy_image_legacy *floppy,
int head, int track, UINT64 offset, const void *buffer, size_t buflen)
{
floperr_t err;
UINT64 track_offset;
/* get the offset to this track */
err = coupe_sdf_get_offset(floppy, head, track, &track_offset);
if (err) return err;
/* write buffer to image */
floppy_image_write(floppy, buffer, offset + track_offset, buflen);
return FLOPPY_ERROR_SUCCESS;
}
static floperr_t coupe_sdf_get_sector_offset(floppy_image_legacy *floppy,
int head, int track, int sector, UINT64 *offset)
{
floperr_t err;
UINT8 buffer[SDF_TRACKSIZE];
int i, buffer_pos = 1;
/* get track data */
err = coupe_sdf_read_track(floppy, head, track, 0, &buffer, SDF_TRACKSIZE);
if (err) return err;
/* check if the sector is available in this track */
if (sector >= buffer[0])
return FLOPPY_ERROR_SEEKERROR;
/* find the right sector in this track */
for (i = 0; i < buffer[0]; i++)
{
int sector_number = buffer[buffer_pos + 4];
if (sector_number - 1 == sector)
{
*offset = buffer_pos;
return FLOPPY_ERROR_SUCCESS;
int track_size = sector_count*512;
for(int head=0; head < 2; head++) {
for(int track=0; track < 80; track++) {
io_generic_read(io, sectdata, (track*2+head)*track_size, track_size);
generate_track(desc_10, track, head, sectors, sector_count+1, 100000, image);
}
buffer_pos += (128 << buffer[buffer_pos + 5]) + 8;
}
return FLOPPY_ERROR_INVALIDIMAGE;
return true;
}
static floperr_t coupe_sdf_get_total_sector_offset(floppy_image_legacy *floppy,
int head, int track, int sector, UINT64 *offset)
bool mgt_format::save(io_generic *io, floppy_image *image)
{
floperr_t err;
UINT64 track_offset, sector_offset;
int track_count, head_count, sector_count;
get_geometry_mfm_pc(image, 2000, track_count, head_count, sector_count);
/* get offset to the track start */
err = coupe_sdf_get_offset(floppy, head, track, &track_offset);
if (err) return err;
if(sector_count > 10)
sector_count = 10;
else if(sector_count < 9)
sector_count = 9;
/* get offset to the start of the sector */
err = coupe_sdf_get_sector_offset(floppy, head, track, sector, &sector_offset);
if (err) return err;
UINT8 sectdata[10*512];
int track_size = sector_count*512;
*offset = track_offset + sector_offset;
return FLOPPY_ERROR_SUCCESS;
}
static floperr_t coupe_sdf_get_sector_length(floppy_image_legacy *floppy,
int head, int track, int sector, UINT32 *sector_length)
{
floperr_t err;
UINT8 buffer[SDF_TRACKSIZE];
UINT64 offset;
/* get track data */
err = coupe_sdf_read_track(floppy, head, track, 0, &buffer, SDF_TRACKSIZE);
if (err) return err;
/* get offset to the start of the sector */
err = coupe_sdf_get_sector_offset(floppy, head, track, sector, &offset);
if (err) return err;
/* get size */
*sector_length = 128 << buffer[offset + 5];
return FLOPPY_ERROR_SUCCESS;
}
static floperr_t coupe_sdf_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)
{
floperr_t err;
UINT8 buffer[SDF_TRACKSIZE];
UINT64 offset;
/* get track data */
err = coupe_sdf_read_track(floppy, head, track, 0, &buffer, SDF_TRACKSIZE);
if (err) return err;
/* get offset to the start of the sector */
err = coupe_sdf_get_sector_offset(floppy, head, track, sector_index, &offset);
if (err) return err;
/* extract data */
if (cylinder) *cylinder = buffer[offset + 2];
if (side) *side = buffer[offset + 3];
if (sector) *sector = buffer[offset + 4];
if (sector_length) *sector_length = 128 << buffer[offset + 5];
if (flags) *flags = 0; /* TODO: read DAM or DDAM and determine flags */
return FLOPPY_ERROR_SUCCESS;
}
static floperr_t coupe_sdf_read_indexed_sector(floppy_image_legacy *floppy,
int head, int track, int sector, void *buffer, size_t buflen)
{
floperr_t err;
UINT64 offset;
err = coupe_sdf_get_total_sector_offset(floppy, head, track, sector, &offset);
if (err) return err;
/* read sector data into buffer */
floppy_image_read(floppy, buffer, offset + 8, buflen);
return FLOPPY_ERROR_SUCCESS;
}
static floperr_t coupe_sdf_write_indexed_sector(floppy_image_legacy *floppy,
int head, int track, int sector, const void *buffer, size_t buflen, int ddam)
{
floperr_t err;
UINT64 offset;
err = coupe_sdf_get_total_sector_offset(floppy, head, track, sector, &offset);
if (err) return err;
/* write buffer into image */
floppy_image_write(floppy, buffer, offset + 8, buflen);
return FLOPPY_ERROR_SUCCESS;
}
static void coupe_sdf_interpret_header(floppy_image_legacy *floppy, int *heads, int *tracks)
{
UINT64 size = floppy_image_size(floppy);
if (size % SDF_TRACKSIZE == 0)
{
*heads = 2;
*tracks = size / (SDF_TRACKSIZE * 2);
}
else
{
*heads = 0;
*tracks = 0;
}
}
FLOPPY_CONSTRUCT( coupe_sdf_construct )
{
struct FloppyCallbacks *callbacks;
struct sdf_tag *tag;
int heads, tracks;
if (params)
{
/* create */
return FLOPPY_ERROR_UNSUPPORTED;
}
else
{
/* load */
coupe_sdf_interpret_header(floppy, &heads, &tracks);
for(int head=0; head < 2; head++) {
for(int track=0; track < 80; track++) {
get_track_data_mfm_pc(track, head, image, 2000, 512, sector_count, sectdata);
io_generic_write(io, sectdata, (head*80 + track)*track_size, track_size);
}
}
tag = (sdf_tag *)floppy_create_tag(floppy, sizeof(struct sdf_tag));
if (!tag)
return FLOPPY_ERROR_OUTOFMEMORY;
tag->heads = heads;
tag->tracks = tracks;
callbacks = floppy_callbacks(floppy);
callbacks->read_track = coupe_sdf_read_track;
callbacks->write_track = coupe_sdf_write_track;
callbacks->get_heads_per_disk = coupe_sdf_get_heads_per_disk;
callbacks->get_tracks_per_disk = coupe_sdf_get_tracks_per_disk;
callbacks->get_track_size = coupe_sdf_get_track_size;
callbacks->get_sector_length = coupe_sdf_get_sector_length;
callbacks->read_indexed_sector = coupe_sdf_read_indexed_sector;
callbacks->write_indexed_sector = coupe_sdf_write_indexed_sector;
callbacks->get_indexed_sector_info = coupe_sdf_get_indexed_sector_info;
return FLOPPY_ERROR_SUCCESS;
return true;
}
FLOPPY_IDENTIFY( coupe_sdf_identify )
{
int heads, tracks;
/* read header values */
coupe_sdf_interpret_header(floppy, &heads, &tracks);
/* check for sensible values */
if (heads > 0 && heads < 3 && tracks > 0 && tracks < 84)
*vote = 100;
else
*vote = 0;
return FLOPPY_ERROR_SUCCESS;
}
const floppy_format_type FLOPPY_MGT_FORMAT = &floppy_image_format_creator<mgt_format>;

View File

@ -11,13 +11,23 @@
#include "flopimg.h"
class mgt_format : public floppy_image_format_t
{
public:
mgt_format();
FLOPPY_CONSTRUCT( coupe_mgt_construct );
FLOPPY_IDENTIFY( coupe_mgt_identify );
FLOPPY_CONSTRUCT( coupe_sad_construct );
FLOPPY_IDENTIFY( coupe_sad_identify );
FLOPPY_CONSTRUCT( coupe_sdf_construct );
FLOPPY_IDENTIFY( coupe_sdf_identify );
virtual int identify(io_generic *io);
virtual bool load(io_generic *io, floppy_image *image);
virtual bool save(io_generic *io, floppy_image *image);
virtual const char *name() const;
virtual const char *description() const;
virtual const char *extensions() const;
virtual bool supports_save() const;
static const floppy_image_format_t::desc_e desc_10[];
};
extern const floppy_format_type FLOPPY_MGT_FORMAT;
#endif /* __COUPEDSK_H__ */