/* See if a file can be decompressed */ static dsk_err_t comp_iopen(COMPRESS_DATA **cd, const char *filename, int nc) { COMPRESS_CLASS *cc = classes[nc]; dsk_err_t err; if (!cc) return DSK_ERR_BADPTR; (*cd) = dsk_malloc(cc->cc_selfsize); if (!*cd) return DSK_ERR_NOMEM; memset((*cd), 0, cc->cc_selfsize); err = comp_construct(*cd, filename); (*cd)->cd_class = cc; if (err == DSK_ERR_OK) { char *s = dsk_malloc(strlen(cc->cc_description) + 50); if (s) { sprintf(s, "Checking compression: %s...", cc->cc_description); dsk_report(s); dsk_free(s); } else dsk_report("Checking compression..."); err = (cc->cc_open)(*cd); dsk_report_end(); } if (err == DSK_ERR_OK) return err; comp_free (*cd); *cd = NULL; return err; }
dsk_err_t comp_commit(COMPRESS_DATA **self) { dsk_err_t e; if (!self || (!(*self)) || (!(*self)->cd_class)) return DSK_ERR_BADPTR; dsk_report("Compressing..."); e = ((*self)->cd_class->cc_commit)(*self); dsk_report_end(); if ((*self)->cd_ufilename) remove((*self)->cd_ufilename); comp_free (*self); *self = NULL; return e; }
dsk_err_t p3fs_mkfs(PLUS3FS *pfs, const char *name, const char *type, const char *compression, unsigned char *boot_spec, int timestamped) { dsk_err_t err; dsk_ltrack_t track; int heads, dirent; char msg[50]; PLUS3FS fs; if (pfs == NULL) { return DSK_ERR_BADPTR; } fs = malloc(sizeof(PLUS3FS_IMPL)); *pfs = fs; memset(fs, 0, sizeof(*fs)); heads = (boot_spec[1] & 3) ? 2 : 1; /* Work out how big the buffers for the boot sector and directory * need to be. Start by getting the drive geometry straight. */ err = dg_pcwgeom(&fs->geom, boot_spec); if (err) return err; /* Now the CP/M filesystem parameters */ fs->blocksize = 128 << (boot_spec[6]); /* Block size */ fs->offset = boot_spec[5]; /* Reserved tracks */ fs->maxtrack = heads * boot_spec[2]; fs->dirblocks = boot_spec[7]; fs->nextblock = fs->dirblocks; /* First free block */ fs->maxdir = (fs->dirblocks * fs->blocksize) / 32; /* Max block number is number of usable sectors divided by * sectors per block */ fs->maxblock = ((fs->maxtrack - fs->offset) * fs->geom.dg_sectors) / (fs->blocksize / fs->geom.dg_secsize); --fs->maxblock; if (fs->maxblock < 256) fs->exm = (fs->blocksize / 1024) - 1; else fs->exm = (fs->blocksize / 2048) - 1; /* Allocate the buffers */ fs->bootsec = malloc(fs->geom.dg_secsize + 32 * fs->maxdir); if (!fs->bootsec) return DSK_ERR_NOMEM; fs->cpmdir = fs->bootsec + fs->geom.dg_secsize; memset(fs->cpmdir, 0xE5, 32 * fs->maxdir); fs->timestamped = timestamped; if (timestamped) { for (dirent = 3; dirent < fs->maxdir; dirent += 4) { memset(fs->cpmdir + 32 * dirent, 0, 32); fs->cpmdir[32 * dirent] = 0x21; } } memset(fs->bootsec, 0xe5, fs->geom.dg_secsize); memcpy(fs->bootsec, boot_spec, 10); /* Create a new DSK file */ err = dsk_creat(&fs->drive, name, type, compression); if (err) return err; /* Format all its tracks */ for (track = 0; track < fs->maxtrack; track++) { sprintf(msg, "Formatting track %d/%d", track, fs->maxtrack); dsk_report(msg); if (!err) err = dsk_alform(fs->drive, &fs->geom, track, 0xe5); } dsk_report("Writing boot sector"); if (!err) err = dsk_lwrite(fs->drive, &fs->geom, fs->bootsec, 0); dsk_report_end(); return err; }