summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib
diff options
context:
space:
mode:
author Curt Coder <curtcoder@mail.com>2012-08-12 20:21:35 +0000
committer Curt Coder <curtcoder@mail.com>2012-08-12 20:21:35 +0000
commitb3cb6449554368783bf379ddd3c78b9b3c100d96 (patch)
treeef2213fefbd3b207a67f7cbeab3eccf9930cb5c7 /src/lib
parenteecf68e68073cd38885dc812ef77a07adec948c8 (diff)
Sync with MESS. (nw)
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/formats/g64_dsk.c124
-rw-r--r--src/lib/formats/g64_dsk.h5
2 files changed, 80 insertions, 49 deletions
diff --git a/src/lib/formats/g64_dsk.c b/src/lib/formats/g64_dsk.c
index 395dac5cc5a..6b89b266503 100644
--- a/src/lib/formats/g64_dsk.c
+++ b/src/lib/formats/g64_dsk.c
@@ -4,30 +4,31 @@
Floppy format code for Commodore 1541 GCR disk images
+ http://www.unusedino.de/ec64/technical/formats/g64.html
+
*********************************************************************/
/*
TODO:
- - speed zones
- - writing
+ - write to disk
*/
#define XTAL_16MHz 16000000
#define XTAL_12MHz 12000000
+
#include "g64_dsk.h"
#include "flopimg.h"
+#include "imageutl.h"
/***************************************************************************
PARAMETERS
***************************************************************************/
-#define LOG 0
-
-#define HEADER_LENGTH 0x2ac /* standard length for 84 half tracks */
-#define MAX_TRACKS 84
+#define HEADER_LENGTH 0x2ac // standard length for 84 half tracks
+#define MAX_TRACKS 84
/***************************************************************************
TYPE DEFINITIONS
@@ -36,11 +37,11 @@
struct g64dsk_tag
{
int version;
- int heads; /* number of physical heads */
- int tracks; /* number of physical tracks */
- UINT16 track_size; /* size of each track */
- UINT32 track_offset[MAX_TRACKS]; /* offset within data for each track */
- UINT32 speed_zone_offset[MAX_TRACKS]; /* offset within data for each track */
+ int heads; // number of physical heads
+ int tracks; // number of physical tracks
+ UINT16 track_size[MAX_TRACKS]; // size of each track
+ UINT32 track_offset[MAX_TRACKS]; // offset within data for each track
+ UINT32 speed_zone_offset[MAX_TRACKS]; // offset within data for each track
};
/***************************************************************************
@@ -108,17 +109,21 @@ static floperr_t get_track_offset(floppy_image_legacy *floppy, int head, int tra
static UINT32 g64_get_track_size(floppy_image_legacy *floppy, int head, int track)
{
- /* get track offset */
+ // get track offset
+ UINT32 track_length = 0;
UINT64 track_offset;
floperr_t err = get_track_offset(floppy, head, track, &track_offset);
if (err)
return 0;
- /* read track length */
- UINT8 size[2];
- floppy_image_read(floppy, &size, track_offset, 2);
- UINT32 track_length = (size[1] << 8) | size[0];
+ // read track length
+ if (track_offset > 0)
+ {
+ UINT8 size[2];
+ floppy_image_read(floppy, &size, track_offset, 2);
+ track_length = pick_integer_le(size, 0, 2);
+ }
return track_length;
}
@@ -130,12 +135,23 @@ static UINT32 g64_get_track_size(floppy_image_legacy *floppy, int head, int trac
static floperr_t g64_read_track(floppy_image_legacy *floppy, int head, int track, UINT64 offset, void *buffer, size_t buflen)
{
+ /*
+
+ The following is written into the buffer:
+
+ n bytes of track data
+ 1982 bytes of speed zone data
+
+ get_track_size() returns n (size of track data)
+
+ */
+
struct g64dsk_tag *tag = get_tag(floppy);
floperr_t err;
UINT64 track_offset;
- UINT16 track_length = 0;
+ UINT16 track_length = tag->track_size[track];
- /* get track offset */
+ // get track offset
err = get_track_offset(floppy, head, track, &track_offset);
if (err)
@@ -143,18 +159,32 @@ static floperr_t g64_read_track(floppy_image_legacy *floppy, int head, int track
if (!head && track_offset)
{
- if (buflen < tag->track_size) { printf("G64 track buffer too small: %u!", (UINT32)buflen); exit(-1); }
+ if (buflen < track_length) { printf("G64 track buffer too small: %u < %u!", (UINT32)buflen, track_length); exit(-1); }
+
+ // read track data
+ floppy_image_read(floppy, ((UINT8*)buffer), track_offset + 2, track_length); // skip the 2 track length bytes in the beginning of track data
- /* read track */
- floppy_image_read(floppy, buffer, track_offset + 2, tag->track_size);
+ if (tag->speed_zone_offset[track] > 3)
+ {
+ // read speed block
+ floppy_image_read(floppy, ((UINT8*)buffer) + track_length, tag->speed_zone_offset[track], G64_SPEED_BLOCK_SIZE);
+ }
+ else
+ {
+ // create a speed block with the same speed zone for the whole track
+ UINT8 speed = tag->speed_zone_offset[track] & 0x03;
+ UINT8 speed_byte = (speed << 6) | (speed << 4) | (speed << 2) | speed;
+
+ memset(((UINT8*)buffer) + track_length, speed_byte, G64_SPEED_BLOCK_SIZE);
+ }
}
else
{
- /* set track length to 0 */
- memset(buffer, 0, buflen);
+ // no data for given track, or tried to read side 1
+ memset(((UINT8*)buffer), 0, buflen);
}
- if (LOG) LOG_FORMATS("G64 track %.1f length %u\n", get_dos_track(track), track_length);
+ LOG_FORMATS("G64 track %.1f length %u\n", get_dos_track(track), track_length);
return FLOPPY_ERROR_SUCCESS;
}
@@ -231,12 +261,12 @@ FLOPPY_CONSTRUCT( g64_dsk_construct )
struct FloppyCallbacks *callbacks;
struct g64dsk_tag *tag;
UINT8 header[HEADER_LENGTH];
- UINT64 pos = 0;
+ UINT64 pos = 0xc;
int i;
if (params)
{
- /* create not supported */
+ // create not supported
return FLOPPY_ERROR_UNSUPPORTED;
}
@@ -244,46 +274,46 @@ FLOPPY_CONSTRUCT( g64_dsk_construct )
if (!tag) return FLOPPY_ERROR_OUTOFMEMORY;
- /* version */
- floppy_image_read(floppy, header, pos, 0x0c); pos += 0xc;
+ // read header
+ floppy_image_read(floppy, header, 0, HEADER_LENGTH);
+
+ // get version
tag->version = header[8];
- if (LOG) LOG_FORMATS("G64 version: %u\n", tag->version);
+ LOG_FORMATS("G64 version: %u\n", tag->version);
- /* number of half tracks */
+ // get number of tracks
tag->heads = 1;
tag->tracks = header[9];
- if (LOG) LOG_FORMATS("G64 tracks: %u\n", tag->tracks);
-
- /* size of each stored half track */
- tag->track_size = (header[11] << 8) | header[10];
- if (LOG) LOG_FORMATS("G64 track size: %04x\n", tag->track_size);
+ LOG_FORMATS("G64 tracks: %u\n", tag->tracks);
- /* data offsets */
+ // get data offsets
for (i = 0; i < tag->tracks; i++)
{
- floppy_image_read(floppy, header, pos, 4); pos += 4;
- tag->track_offset[i] = (header[3] << 24) | (header[2] << 16) | (header[1] << 8) | header[0];
-
- if (LOG) LOG_FORMATS("G64 track %.1f data offset: %04x\n", get_dos_track(i), tag->track_offset[i]);
+ tag->track_offset[i] = pick_integer_le(header, pos, 4);
+ pos += 4;
}
- /* speed zone offsets */
+ // get speed zone information
for (i = 0; i < tag->tracks; i++)
{
- floppy_image_read(floppy, header, pos, 4); pos += 4;
- tag->speed_zone_offset[i] = (header[3] << 24) | (header[2] << 16) | (header[1] << 8) | header[0];
+ tag->speed_zone_offset[i] = pick_integer_le(header, pos, 4);
+ pos += 4;
- if (LOG)
+ tag->track_size[i] = g64_get_track_size(floppy, 0, i);
+
+ if (tag->track_offset[i] > 0)
{
+ LOG_FORMATS("G64 track %.1f offset %05x length %04x ", get_dos_track(i), tag->track_offset[i], tag->track_size[i]);
+
if (tag->speed_zone_offset[i] < 4) {
- LOG_FORMATS("G64 track %.1f speed zone: %u\n", get_dos_track(i), tag->speed_zone_offset[i]);
+ LOG_FORMATS("speed %u\n", tag->speed_zone_offset[i]);
} else {
- LOG_FORMATS("G64 track %.1f speed zone offset: %04x\n", get_dos_track(i), tag->speed_zone_offset[i]);
+ LOG_FORMATS("speed offset %04x\n", tag->speed_zone_offset[i]);
}
}
}
- /* set callbacks */
+ // set callbacks
callbacks = floppy_callbacks(floppy);
callbacks->read_track = g64_read_track;
diff --git a/src/lib/formats/g64_dsk.h b/src/lib/formats/g64_dsk.h
index 20c5a6d253b..d8f793de514 100644
--- a/src/lib/formats/g64_dsk.h
+++ b/src/lib/formats/g64_dsk.h
@@ -15,9 +15,10 @@
MACROS / CONSTANTS
***************************************************************************/
-#define G64_SYNC_MARK 0x3ff /* 10 consecutive 1-bits */
+#define G64_SYNC_MARK 0x3ff /* 10 consecutive 1-bits */
-#define G64_BUFFER_SIZE 16384
+#define G64_BUFFER_SIZE 16384
+#define G64_SPEED_BLOCK_SIZE 1982
const int C2040_BITRATE[] =
{