void fdc_readtrk(void) { FDC.led = 1; // turn the drive LED on check_unit(); // switch to target drive if (init_status_regs() == 0) { // drive Ready? active_drive->current_side = (FDC.command[CMD_UNIT] & 4) >> 2; // extract target side dword side = active_drive->sides ? active_drive->current_side : 0; // single sided drives only acccess side 1 if ((active_drive->flipped)) { // did the user request to access the "other" side? side = side ? 0 : 1; // reverse the side to access } active_track = &active_drive->track[active_drive->current_track][side]; if (active_track->sectors != 0) { // track is formatted? FDC.command[CMD_R] = 1; // set sector ID to 1 active_drive->current_sector = 0; // reset sector table index cmd_readtrk(); } else { // unformatted track FDC.result[RES_ST0] |= 0x40; // AT FDC.result[RES_ST1] |= 0x01; // Missing AM LOAD_RESULT_WITH_CHRN FDC.phase = RESULT_PHASE; // switch to result phase } }
void qinquire(int *iunit, char *filename, int *flen, int filename_l) #endif { #ifdef F77STRING char *filename = f77str->str; int filename_l = f77str->len; #endif int unit = *iunit - 1; Unit *u = check_unit(unit, "qinquire", 0); if (u) { /* generic stat is not good enough on Windows */ #ifdef _WIN32 struct _stat64 buf; _stat64(u->fname, &buf); #else struct stat buf; stat(u->fname, &buf); #endif set_fstr(filename, filename_l, u->fname); *flen = (int)((double)buf.st_size / 1024.); } else { /* DNM: HUH? */ /* set_fstr(filename, filename_l, ""); */ *flen = -1; } }
void qread(int *iunit, char *array, int *nitems, int *ier) { int unit = *iunit - 1; Unit *u = check_unit(unit, "qread", 0); if (u) { int bc = *nitems; if (u->write_only) { fprintf(stdout, "\nERROR: qread - '%s' is write only.\n", u->tailName); exit(3); } errno = 0; if (b3dFread(array, 1, bc, u->fp) != bc) { unit = errno; fprintf(stdout, "\nERROR: qread - reading '%s'\n", u->tailName); if (unit) fprintf(stdout, "ERROR: from system - %s\n", strerror(unit)); exit(3); } u->pos += bc; *ier = 0; } else { *ier = -1; } }
void fdc_seek(void) { check_unit(); // switch to target drive if (init_status_regs() == 0) { // drive Ready? active_drive->current_track = FDC.command[CMD_C]; if (active_drive->current_track >= DSK_TRACKMAX) { // beyond valid range? active_drive->current_track = DSK_TRACKMAX-1; // limit to maximum } } FDC.flags |= (FDC.command[CMD_UNIT] & 1) ? SEEKDRVB_flag : SEEKDRVA_flag; // signal completion of seek operation FDC.phase = CMD_PHASE; // switch back to command phase (fdc_seek has no result phase!) }
/* qskip needs to move by large amounts within sections so it takes two numbers and moves by the product */ void qskip(int *iunit, int *ireclength, int *nrecords) { int unit = *iunit - 1; Unit *u = check_unit(unit, "qskip", 1); u->pos += *ireclength * *nrecords; errno = 0; if (mrc_big_seek(u->fp, 0, *ireclength, *nrecords, SEEK_CUR)) { unit = errno; fprintf(stdout, "\nERROR: qskip - Doing seek in '%s'\n", u->tailName); if (unit) fprintf(stdout, "ERROR: from system - %s\n", strerror(unit)); exit(3); } }
/* qback is used only for small movements, within a section, so it doesn't need to call big_seek. However, change the test for error to test for = -1 instead of < 0; then to test for !=0 when switch to fseek */ void qback(int *iunit, int *ireclength) { int unit = *iunit - 1; Unit *u = check_unit(unit, "qback", 1); int amt = -(*ireclength); u->pos += amt; errno = 0; if (b3dFseek(u->fp, amt, SEEK_CUR)) { unit = errno; fprintf(stdout, "\nERROR: qback - Doing seek in '%s'\n", u->tailName); if (unit) fprintf(stdout, "ERROR: from system - %s\n", strerror(unit)); exit(3); } }
void fdc_drvstat(void) { byte val; check_unit(); // switch to target drive val = FDC.command[CMD_UNIT] & 7; // keep head and unit of command if ((active_drive->write_protected) || (active_drive->tracks == 0)) { // write protected, or disk missing? val |= 0x48; // set Write Protect + Two Sided (?) } if ((active_drive->tracks) && (FDC.motor)) { val |= 0x20; // set Ready } if (active_drive->current_track == 0) { // drive head is over track 0? val |= 0x10; // set Track 0 } FDC.result[RES_ST0] = val; FDC.phase = RESULT_PHASE; // switch to result phase }
void qwrite(int *iunit, char *array, int *nitems) { int unit = *iunit - 1; Unit *u = check_unit(unit, "qwrite", 1); int bc = *nitems; if (u->read_only) { fprintf(stdout, "\nERROR: qwrite - '%s' is read only.\n", u->tailName); exit(3); } errno = 0; if (b3dFwrite(array, 1, bc, u->fp) != bc) { unit = errno; fprintf(stdout, "\nERROR: qwrite - writing '%s'\n", u->tailName); if (unit) fprintf(stdout, "ERROR: from system - %s\n", strerror(unit)); exit(3); } u->pos += bc; }
/* DNM 10/23/00: switch from using system-dependent "seek_name" to call a big_seek function that seeks in chunks less than 2 GB; also change test for error to test for -1 returned rather than a negative number. Change to test for nonzero when switch to fseek */ void qseek(int *iunit, int *base, int *line, int *section, int *nxbytes, int *nylines) { int unit = *iunit - 1; Unit *u = check_unit(unit, "qseek", 1); u->pos = ((unsigned int)(*nxbytes) * (unsigned int)((*line - 1) + (unsigned int)*nylines * (unsigned int)(*section - 1)) + (unsigned int)(*base - 1)); /* if (lseek(u->fp, u->pos = pos, 0) < 0) */ errno = 0; if (mrcHugeSeek(u->fp, *base - 1, 0, *line - 1, *section - 1, *nxbytes, *nylines, 1, SEEK_SET)) { unit = errno; fprintf(stdout, "\nERROR: qseek - Doing mrcHugeSeek in '%s'\n", u->tailName); if (unit) fprintf(stdout, "ERROR: from system - %s\n", strerror(unit)); exit(3); } }
/* This will fail for large files, but try to keep pos good up to 4 GB by making it an unsigned int */ void qlocate(int *iunit, int *location) { int unit = *iunit - 1; Unit *u = check_unit(unit, "qlocate", 1); *location = u->pos + 1; }