STDMETHODIMP CDisk::lwrite(IGeometry *g, VARIANT *buf, long lsect) { HRESULT hr; DSK_GEOMETRY geom; unsigned char *pData; g_to_dg(g, &geom); hr = GetBuffer(buf, &pData, geom.dg_secsize); if (FAILED(hr)) return hr; hr = MapError(dsk_lwrite(m_driver, &geom, pData, lsect)); dsk_free(pData); return hr; }
int do_format(char *outfile, char *outtyp, char *outcomp, int forcehead, dsk_format_t format) { DSK_PDRIVER outdr = NULL; dsk_err_t e; dsk_pcyl_t cyl; dsk_phead_t head; DSK_GEOMETRY dg; dsk_cchar_t fdesc; dsk_reportfunc_set(report, report_end); e = dsk_creat(&outdr, outfile, outtyp, outcomp); if (!e) e = dsk_set_retry(outdr, retries); if (!e && forcehead >= 0) e = dsk_set_forcehead(outdr, forcehead); if (!e) e = dg_stdformat(&dg, format, NULL, &fdesc); if (!e) { printf("Formatting %s as %s\n", outfile, fdesc); for (cyl = 0; cyl < dg.dg_cylinders; cyl++) { for (head = 0; head < dg.dg_heads; head++) { printf("Cyl %02d/%02d Head %d/%d\r", cyl +1, dg.dg_cylinders, head+1, dg.dg_heads); fflush(stdout); if (!e) e = dsk_apform(outdr, &dg, cyl, head, 0xE5); if (e) break; } } } /* Create a disc spec on the first sector, if the format's recognised */ if (!e) { unsigned char bootsec[512]; unsigned int do_bootsec = 0; memset(bootsec, 0xE5, sizeof(bootsec)); switch(format) { case FMT_180K: memcpy(bootsec, spec180, 10); do_bootsec = 1; break; case FMT_CPCSYS: memcpy(bootsec, spec169, 10); do_bootsec = 1; break; case FMT_CPCDATA: break; case FMT_200K: memcpy(bootsec, spec200, 10); do_bootsec = 1; break; case FMT_720K: memcpy(bootsec, spec720, 10); do_bootsec = 1; break; case FMT_800K: memcpy(bootsec, spec800, 10); do_bootsec = 1; break; default: break; } if (do_bootsec) e = dsk_lwrite(outdr, &dg, bootsec, 0); } printf("\r \r"); if (outdr) dsk_close(&outdr); if (e) { fprintf(stderr, "%s\n", dsk_strerror(e)); return 1; } return 0; }
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; }
int do_test(char *outfile, char *outtyp, char *outcomp, int forcehead) { DSK_PDRIVER outdr = NULL; dsk_err_t e; DSK_GEOMETRY dg, dg2; static DSK_FORMAT fmt[9] = { { 0, 0, 1, 512 }, { 0, 0, 3, 512 }, { 3, 1, 5, 512 }, { 0, 0, 7, 512 }, { 0, 0, 9, 512 }, { 0, 1, 2, 512 }, { 0, 0, 4, 512 }, { 2, 0, 6, 512 }, { 0, 0, 8, 512 }, }; static DSK_FORMAT fmt2[9] = { { 4, 0, 1, 512 }, { 4, 0, 3, 512 }, { 4, 0, 5, 512 }, { 4, 0, 7, 512 }, { 4, 0, 9, 512 }, { 4, 0, 2, 512 }, { 4, 0, 4, 512 }, { 4, 0, 6, 512 }, { 4, 0, 8, 512 }, }; DSK_FORMAT secid, *pfmt; char *comment; unsigned char status; dsk_psect_t count, n; char *optname; int value; dsk_reportfunc_set(report, report_end); dg_stdformat(&dg, FMT_180K, NULL, NULL); if (t80) dg.dg_cylinders = 80; printf("Checking dsk_creat\n"); e = dsk_creat(&outdr, outfile, outtyp, outcomp); CHECKERR("dsk_creat") else { dsk_set_option(outdr, "REMOTE:TESTING", 1); printf("Checking set_comment\n"); e = dsk_set_comment(outdr, "Example comment"); CHECKERR3("dsk_set_comment"); printf("Checking pformat\n"); e = dsk_pformat(outdr, &dg, 0, 0, fmt, 0xE5); CHECKERR("dsk_pformat") printf("Checking apform\n"); e = dsk_apform(outdr, &dg, 1, 0, 0xF6); CHECKERR("dsk_apform") printf("Checking lformat\n"); e = dsk_lformat(outdr, &dg, 2, fmt2, 0xD4); CHECKERR("dsk_pformat") printf("Checking ptrackids\n"); e = dsk_ptrackids(outdr, &dg, 0, 0, &count, &pfmt); CHECKERR("dsk_ptrackids") else { dsk_psect_t n; printf("Cyl Head Sec Size\n"); printf("-----------------\n"); for (n = 0; n < count; n++) { printf("%3d %3d %3d %4d\n", pfmt[n].fmt_cylinder, pfmt[n].fmt_head, pfmt[n].fmt_sector, (int)pfmt[n].fmt_secsize); } printf("-----------------\n"); dsk_free(pfmt); } memset(secbuf, 0, sizeof(secbuf)); memcpy(secbuf, spec180, sizeof(spec180)); printf("Checking dsk_lwrite\n"); e = dsk_lwrite(outdr, &dg, secbuf, 0); CHECKERR("dsk_lwrite") strcpy((char *)secbuf, "Cyl=3 Head=1 Sec=5"); printf("Checking dsk_xwrite\n"); e = dsk_xwrite(outdr, &dg, secbuf, 0, 0, 3, 1, 5, 512, 0); CHECKERR("dsk_xwrite") printf("Checking dsk_psecid\n"); e = dsk_psecid(outdr, &dg, 1, 0, &secid); CHECKERR("dsk_psecid") else { printf("%3d %3d %3d %4d\n", secid.fmt_cylinder, secid.fmt_head, secid.fmt_sector, (int)secid.fmt_secsize); if (secid.fmt_cylinder != 1 || secid.fmt_head != 0 || secid.fmt_secsize != 512) { ++failures; printf("-- mismatch!\n"); } } } if (outdr) { dsk_close(&outdr); CHECKERR("dsk_close") } printf("Checking dsk_open\n"); e = dsk_open(&outdr, outfile, outtyp, outcomp); CHECKERR("dsk_open") else { dsk_set_option(outdr, "REMOTE:TESTING", 1); printf("Checking dsk_getgeom\n"); e = dsk_getgeom(outdr, &dg2); if (t80 && dg2.dg_cylinders == 40) dg2.dg_cylinders = 80; CHECKERR("dsk_getgeom") else if (memcmp(&dg, &dg2, sizeof(dg))) { ++failures; printf("-- mismatch!\n"); printf("Cyls: %3d %3d\n", dg.dg_cylinders, dg2.dg_cylinders); printf("Heads: %3d %3d\n", dg.dg_heads, dg2.dg_heads); printf("Secs: %3d %3d\n", dg.dg_sectors, dg2.dg_sectors); } printf("Checking dsk_lread\n"); e = dsk_lread(outdr, &dg, secbuf, 0); CHECKERR("dsk_lread") else if (memcmp(secbuf, spec180, sizeof(spec180))) { ++failures; printf("-- mismatch!\n"); } printf("Checking dsk_xread\n"); e = dsk_xread(outdr, &dg, secbuf, 0, 0, 3, 1, 5, 512, NULL); CHECKERR("dsk_xread") else if (strcmp((char *)secbuf, "Cyl=3 Head=1 Sec=5")) { ++failures; printf("-- mismatch!\n"); } printf("Checking dsk_lseek\n"); e = dsk_lseek(outdr, &dg, 1); CHECKERR("dsk_lseek") printf("Checking dsk_drive_status\n"); e = dsk_drive_status(outdr, &dg, 0, &status); CHECKERR("dsk_drive_status") else printf("-- status=0x%02x\n", status); printf("Checking dsk_tread\n"); e = dsk_ptread(outdr, &dg, trkbuf, 1, 0); CHECKERR("dsk_ptread") else { for (n = 0; n < 4608; n++) if (trkbuf[n] != 0xF6) { printf("-- mismatch!\n"); ++failures; break; } } printf("Checking dsk_xtread\n"); e = dsk_xtread(outdr, &dg, trkbuf, 2, 0, 4, 0); CHECKERR("dsk_xtread") else { for (n = 0; n < 4608; n++) if (trkbuf[n] != 0xD4) { printf("-- mismatch!\n"); ++failures; break; } } printf("Checking dsk_option_enum\n"); e = dsk_option_enum(outdr, 0, &optname); CHECKERR("dsk_option_enum") else { printf("-- first option is %s\n", optname); } if (!optname) optname = "dummy"; printf("Checking dsk_get_option(%s)\n", optname); e = dsk_get_option(outdr, optname, &value); CHECKERR2("dsk_get_option") else { printf("-- value=%d\n", value); } printf("Checking dsk_set_option(example, 2)\n"); e = dsk_set_option(outdr, "example", 2); CHECKERR2("dsk_set_option") printf("Checking dsk_rtread\n"); e = dsk_rtread(outdr, &dg, trkbuf, 0, 0, 0); CHECKERR3("dsk_rtread") printf("Checking dsk_get_comment\n"); e = dsk_get_comment(outdr, &comment); CHECKERR3("dsk_get_comment") else if (comment) printf("-- comment=%s\n", comment); } if (outdr) { dsk_close(&outdr); CHECKERR("dsk_close") } printf("\n"); printf("Failed calls (failure important): %2d\n", failures); printf("Failed calls (failure unimportant): %2d\n", warnings); printf("Unimplemented functions: %2d\n", unimpl); printf("Unimplemented functions over RPC: %2d\n", rpcunimp); return failures; }