summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2012-08-07 22:15:04 (GMT)
committerH. Peter Anvin <hpa@zytor.com>2012-08-07 22:15:04 (GMT)
commite390259c0dba344a3d51c6a706f03daee498df53 (patch)
tree7b84b267ded1793591a36eee082d315ada7352f4
parent989900bc216dab07bfc3a83f028c39a20ac5fa5c (diff)
downloadabcdisk-e390259c0dba344a3d51c6a706f03daee498df53.zip
abcdisk-e390259c0dba344a3d51c6a706f03daee498df53.tar.gz
abcdisk-e390259c0dba344a3d51c6a706f03daee498df53.tar.bz2
abcdisk-e390259c0dba344a3d51c6a706f03daee498df53.tar.xz
Handle 8" disks and pre-UFD-DOS disks with the smaller MFD
8" disks don't have tracks that contain an integral number of clusters. Pre-ABC-832/UFD-DOS disks not only had the MFD in a different place, but a different size.
-rw-r--r--abcread.c10
-rw-r--r--abcwrite.c12
-rw-r--r--formats.c17
-rw-r--r--util.c22
-rw-r--r--util.h6
5 files changed, 40 insertions, 27 deletions
diff --git a/abcread.c b/abcread.c
index fc6f08f..302670a 100644
--- a/abcread.c
+++ b/abcread.c
@@ -80,6 +80,14 @@ extract_dir_sector(struct disk *disk, const char *dirpath, int sectnr)
/* Length of file in sectors, including header block */
len = sector[2] + (sector[3] << 8);
+ /*
+ * Early version of ABC-DOS didn't fill in the length field; those
+ * versions all had cluster size == 1 so we can just read until the
+ * header block runs out...
+ */
+ if (len == 0)
+ len = disk->fmt->sectors;
+
ufd = !memcmp(sector+12, "Ufd", 3);
p = filename + sprintf(filename, "%s/", dirpath);
unmangle_filename(p, sector + 4);
@@ -163,7 +171,7 @@ int main(int argc, char *argv[])
disk = allocate_disk(fmt);
f = fopen(argp[0], "rb");
- fread(disk->image, 1, fmt->ntracks << (fmt->track_shift + 8), f);
+ fread(disk->image, 1, fmt->sectors << 8, f);
fclose(f);
/* Extract files */
diff --git a/abcwrite.c b/abcwrite.c
index 27b2e9f..afb6316 100644
--- a/abcwrite.c
+++ b/abcwrite.c
@@ -26,8 +26,7 @@ static int get_cluster(struct disk *disk, unsigned int cluster_hint)
best = -1;
bnc = 0;
- nclust = disk->fmt->ntracks
- << (disk->fmt->track_shift - disk->fmt->cluster_shift);
+ nclust = disk->fmt->sectors << disk->fmt->cluster_shift;
for (i = 0; i < nclust; i++) {
if (!is_used(disk, i)) {
@@ -196,14 +195,14 @@ create_file(struct directory *dir, const char *mangled_name,
/* Find and create directory entry */
dirp = -1;
- for ( dirs = 0 ; dirs < 16 ; dirs++ ) {
+ for ( dirs = 0 ; dirs < disk->fmt->dirsecs ; dirs++ ) {
if ( dir->bitmap[0xEF+dirs] < 0x10 ) {
dirp = dir->bitmap[0xEF+dirs]++;
break;
}
}
- if ( dirs == 16 ) {
+ if ( dirs >= disk->fmt->dirsecs ) {
/* Directory full */
fprintf(stderr, "%s: directory full\n", program);
return NULL;
@@ -329,7 +328,8 @@ struct directory *make_ufd(struct directory *dir, const char *filename)
bitmap[0] = dirs_block & 0xFF;
bitmap[1] = dirs_block >> 8;
- header = create_file(dir, mangled_name, bitmap, 17*253, 1);
+ header = create_file(dir, mangled_name, bitmap,
+ (dir->disk->fmt->dirsecs+1)*253, 1);
if (!header) {
fprintf(stderr, "%s: header returns NULL\n", program);
return NULL;
@@ -419,7 +419,7 @@ int main(int argc, char *argv[])
get_files(&disk->mfd, *argp);
/* Finally, write out image */
- fwrite(disk->image, 1, fmt->ntracks << (fmt->track_shift + 8), stdout);
+ fwrite(disk->image, 1, fmt->sectors << 8, stdout);
return 0;
}
diff --git a/formats.c b/formats.c
index 104b62b..96a3abc 100644
--- a/formats.c
+++ b/formats.c
@@ -5,14 +5,15 @@
static const struct diskfmt formats[] =
{
- { "fd2", 40, 3, 0, 6 },
- { "abc830", 80, 3, 0, 6 },
- { "abc830-ufd", 80, 3, 0, 14 },
- { "abc832", 80, 5, 2, 14 },
- { "abc834", 80, 5, 2, 14 },
- { "hd", 238, 8, 5, 14 },
- { "", 238, 8, 5, 14 },
- { NULL, 0, 0, 0, 0 }
+ { "fd2", 40*1* 8, 0, 6, 8 },
+ { "abc830", 40*1*16, 0, 6, 8 },
+ { "abc830-ufd", 40*1*16, 0, 14, 16 },
+ { "abc832", 80*2*16, 2, 14, 16 },
+ { "abc834", 80*2*16, 2, 14, 16 },
+ { "abc838", 77*2*26, 2, 14, 16 },
+ { "hd", 238*8*32, 5, 14, 16 },
+ { "", 238*8*32, 5, 14, 16 },
+ { NULL, 0, 0, 0 }
};
const struct diskfmt *get_format(const char *name)
diff --git a/util.c b/util.c
index 675050c..81906cb 100644
--- a/util.c
+++ b/util.c
@@ -20,8 +20,9 @@ void *xmalloc(size_t len)
struct disk *allocate_disk(const struct diskfmt *fmt)
{
struct disk *disk = xmalloc(sizeof(struct disk));
- size_t size = (fmt->ntracks) << (fmt->track_shift + 8);
+ size_t size = fmt->sectors << 8;
int i, starter;
+ int secperclust = 1 << fmt->cluster_shift;
memset(disk, 0, sizeof *disk);
@@ -37,13 +38,15 @@ struct disk *allocate_disk(const struct diskfmt *fmt)
memset(disk->image, 0x40, size);
/* Create empty bitmap */
- memset(disk->bitmap, 0, fmt->ntracks);
- memset(disk->bitmap+fmt->ntracks, 0xff, 239-fmt->ntracks);
- memset(disk->bitmap+239, 0x01, 16); /* MFD bitmap */
+ memset(disk->bitmap, 0, 239);
+ for (i = fmt->sectors >> fmt->cluster_shift; i < 239*8; i++)
+ mark_used(disk, i); /* Mark nonexistent clusters busy */
+ memset(disk->bitmap+239, 0x01, fmt->dirsecs); /* MFD bitmap */
disk->bitmap[0xff] = 0x00;
- /* Mark the first 32 sectors used */
- starter = 32 >> fmt->cluster_shift;
+ /* Mark the first 16/32 sectors used */
+ starter = (fmt->syssec + 2 + fmt->dirsecs + secperclust - 1)
+ >> fmt->cluster_shift;
for (i = 0; i < starter; i++)
mark_used(disk, i);
@@ -51,9 +54,10 @@ struct disk *allocate_disk(const struct diskfmt *fmt)
memcpy(disk->bitmap + 256, disk->bitmap, 256);
/* Create MFD directory sectors */
- for ( i = 16 ; i < 32 ; i++ ) {
- memset(disk->image+(i << 8), 0x00, 16);
- memset(disk->image+(i << 8)+16, 0xFF, 240);
+ for (i = 0; i < fmt->dirsecs; i++) {
+ unsigned char *p = disk->image + ((i + fmt->syssec) << 8);
+ memset(p, 0x00, 16);
+ memset(p+16, 0xFF, 240);
}
return disk;
diff --git a/util.h b/util.h
index 7cac824..94d6806 100644
--- a/util.h
+++ b/util.h
@@ -5,10 +5,10 @@
struct diskfmt {
const char *name;
- int ntracks; /* Total tracks (max 238) */
- unsigned int track_shift; /* Size of a track in sectors (max 256) */
- unsigned int cluster_shift; /* Size of a cluster (typically track/8) */
+ int sectors; /* Total sectors (max 1911 clusters) */
+ unsigned int cluster_shift; /* Size of a cluster, log2 */
int syssec; /* First system sector (bitmap) */
+ int dirsecs; /* Number of directory sectors */
};
struct disk;