void morse(CBM_FILE f, unsigned char drv) { static char morsecode[] = { 0x20,0xe5,0xc1,0xd0,0x0a,0xa9,0x30,0x4c, 0xc8,0xc1,0xa2,0x08,0x20,0x4e,0x05,0xb1, 0xa3,0xaa,0xe0,0x30,0x90,0xef,0xe0,0x3a, 0xb0,0x05,0xbd,0x40,0x05,0xd0,0x0b,0xe0, 0x41,0x90,0xe2,0xe0,0x5b,0xb0,0xde,0xbd, 0x39,0x05,0x85,0x14,0x29,0x07,0x85,0x15, 0xa2,0x01,0x06,0x14,0x90,0x02,0xa2,0x04, 0x20,0x61,0x05,0xa2,0x01,0x20,0x68,0x05, 0xc6,0x15,0xd0,0xec,0xc8,0xcc,0x74,0x02, 0x90,0xc0,0x60,0x8d,0x00,0x1c,0x8a,0xa2, 0x80,0x84,0x1f,0xa0,0x00,0xc8,0xd0,0xfd, 0xe8,0xd0,0xfa,0x4a,0xd0,0xf7,0xa4,0x1f, 0x60,0xad,0x00,0x1c,0x09,0x08,0xd0,0xe3, 0xad,0x00,0x1c,0x29,0xf7,0x4c,0x4b,0x05, 0xfd,0x7d,0x3d,0x1d,0x0d,0x05,0x85,0xc5, 0xe5,0xf5,0x42,0x84,0xa4,0x83,0x01,0x24, 0xc3,0x04,0x02,0x74,0xa3,0x44,0xc2,0x82, 0xe3,0x64,0xd4,0x43,0x03,0x81,0x23,0x14, 0x63,0x94,0xb4,0xc4 }; int n; n = cbm_upload(f, drv, 0x500, morsecode, sizeof(morsecode)); printf("cbm_upload %s!\n", n == sizeof(morsecode) ? "success" : "FAILED"); cbm_exec_command(f, drv, "U3:SOS", 6); }
static int open_disk(CBM_FILE fd, d64copy_settings *settings, const void *arg, int for_writing, turbo_start start, d64copy_message_cb message_cb) { unsigned char d = (unsigned char)(ULONG_PTR)arg; const unsigned char *drive_prog; int prog_size; fd_cbm = fd; two_sided = settings->two_sided; if(settings->drive_type != cbm_dt_cbm1541) { drive_prog = pp1571_drive_prog; prog_size = sizeof(pp1571_drive_prog); } else { drive_prog = pp1541_drive_prog; prog_size = sizeof(pp1541_drive_prog); } /* make sure the XP1541 portion of the cable is in input mode */ cbm_pp_read(fd_cbm); cbm_upload(fd_cbm, d, 0x700, drive_prog, prog_size); start(fd, d); pp_check_direction(PP_READ); cbm_iec_set(fd_cbm, IEC_CLOCK); cbm_iec_wait(fd_cbm, IEC_DATA, 1); return 0; }
int ARCH_MAINDECL main(int argc, char *argv[]) { __u_char drv = argc > 1 ? arch_atoc(argv[1]) : 8; CBM_FILE fd; if(cbm_driver_open(&fd, 0) == 0) { cbm_upload(fd, drv, 0x0500, flash, sizeof(flash)); cbm_exec_command(fd, drv, "U3:", 0); cbm_driver_close(fd); return 0; } return 1; }
static int upload(CBM_FILE fd, unsigned char drive) { enum cbm_device_type_e driveType; const unsigned char *pp_drive_prog = 0; unsigned int pp_drive_prog_length = 0; unsigned int bytesWritten; if (cbm_identify(fd, drive, &driveType, NULL)) return 1; switch (driveType) { case cbm_dt_cbm1581: DBG_ERROR((DBG_PREFIX "1581 not supported!")); return 1; case cbm_dt_cbm1541: DBG_PRINT((DBG_PREFIX "recognized 1541.")); pp_drive_prog = pp1541_drive_prog; pp_drive_prog_length = sizeof(pp1541_drive_prog); break; case cbm_dt_cbm1570: case cbm_dt_cbm1571: DBG_PRINT((DBG_PREFIX "recognized 1571.")); pp_drive_prog = pp1571_drive_prog; pp_drive_prog_length = sizeof(pp1571_drive_prog); break; case cbm_dt_unknown: /* FALL THROUGH */ default: DBG_ERROR((DBG_PREFIX "unknown device type!")); return 1; } bytesWritten = cbm_upload(fd, drive, 0x700, pp_drive_prog, pp_drive_prog_length); if (bytesWritten != pp_drive_prog_length) { DBG_ERROR((DBG_PREFIX "wanted to write %u bytes, but only %u " "bytes could be written", pp_drive_prog_length, bytesWritten)); return 1; } return 0; }
// // send drive code // static int send_turbo(imgcopy_settings *settings, CBM_FILE fd, unsigned char drv, int write) { //int warp, int drv_type :: settings->warp, settings->drive_type const struct drive_prog *prog; int warp, drv_type, idx; switch(settings->drive_type) { case cbm_dt_cbm1541: drv_type = 0; break; case cbm_dt_cbm1570: case cbm_dt_cbm1571: drv_type = 1; break; case cbm_dt_cbm1581: drv_type = 2; break; case cbm_dt_cbm2040: case cbm_dt_cbm2031: case cbm_dt_cbm3040: case cbm_dt_cbm4040: case cbm_dt_cbm4031: case cbm_dt_cbm8050: case cbm_dt_cbm8250: case cbm_dt_sfd1001: case cbm_dt_unknown: default: // drive type not allowed return -1; } warp = settings->warp ? 1 : 0; idx = drv_type * 4 + warp * 2 + write; printf("uploading drivecode %d\n", idx); prog = &drive_progs[idx]; return cbm_upload(fd, drv, 0x500, prog->prog, prog->size) != prog->size; }
int ARCH_MAINDECL main(int argc, char **argv) { unsigned char drive = 8; int i; unsigned char cmd[] = "M-R\x87\x00\x02"; static unsigned char rpm_prog[] = { #include "rpm1541.inc" }; unsigned long int count; unsigned short int currpm, tsize; struct { unsigned short int rpm; unsigned short int occurence; } occtable[OCCSZ]; const char *type_str; if (cbm_driver_open_ex(&fd, NULL) != 0) return -1; if (argc > 1) { drive = arch_atoc(argv[1]); if (drive < 8 || drive > 11) { printf("Usage: %s [driveNo]\n\ndriveNo - Commodore IEC bus" " disk drive number (range: 8..11)\n", argv[0]); exit(0); } } if (cbm_identify(fd, drive, NULL, &type_str) == 0) { printf( "Using drive %2d, drive type string: %s\n", drive, type_str ); } arch_set_ctrlbreak_handler(reset); cbm_exec_command(fd, drive, "I0:", 0); cbm_upload(fd, drive, 0x0500, rpm_prog, sizeof(rpm_prog)); count = 1ul; tsize = 0; for (i = 0; i < OCCSZ; ++i) { occtable[i].rpm=occtable[i].occurence=0; } while (1) { unsigned char int_count[2]; double rpm; cbm_exec_command(fd, drive, "U4:", 0); cbm_exec_command(fd, drive, cmd, sizeof(cmd)-1); cbm_talk(fd, drive, 15); cbm_raw_read(fd, &int_count, 2); cbm_untalk(fd); rpm = (600000.0*RUNS) / (int_count[0] + 256 * int_count[1]); /* printf("%3.2lf\n", rpm); */ currpm = (unsigned short int)(rpm*100 + .5); /* rounded! */ /* search occurency table for that value */ for (i=0;i<OCCSZ;++i) { if (occtable[i].rpm == 0) { /* value not found, but an empty field */ break; } else if (currpm == occtable[i].rpm) { /* value found, increase counter */ occtable[i].occurence++; break; } } if (i >= OCCSZ || occtable[i].rpm==0) { if (i >= OCCSZ) { printf("\rNo space left in occurrency table for rpm value %3.2f\n", rpm); } else /* if (occtable[i].rpm==0) */ { occtable[i].rpm=currpm; occtable[i].occurence++; } /* reprint table header either if the overflow warning * was printed or a new rpm value has been added */ printf("\r%10s: %6s", "count", "curRPM"); for (i = 0; i < OCCSZ && occtable[i].rpm != 0; ++i) { printf("|%3.2f", occtable[i].rpm / 100.0); } printf("|\n------------------"); for (i=0;i<OCCSZ && occtable[i].rpm!=0;++i) { printf("+------"); } printf("+\n"); } printf("\r%10lu: %3.2f", count++, rpm); for (i=0;i<OCCSZ && occtable[i].rpm!=0;++i) { printf("|%6u", occtable[i].occurence); } printf("|"); fflush(stdout); /* printf("%10lu: %3.2f %5u\n", count++, rpm, currpm); */ } return 0; }
int ARCH_MAINDECL main(int argc, char *argv[]) { int status = 0, id_ofs = 0, name_len, i; CBM_FILE fd; // unsigned char drive, tracks = 35, bump = 1, orig = 0, show_progress = 0; unsigned char drive, tracks = 35, bump = 1, orig = 0x4b, show_progress = 0; char cmd[40], name[20], *arg; int erroroccured = 0; char *adapter = NULL; int option; struct option longopts[] = { { "help" , no_argument , NULL, 'h' }, { "version" , no_argument , NULL, 'V' }, { "adapter" , required_argument, NULL, '@' }, { "no-bump" , no_argument , NULL, 'n' }, { "extended" , no_argument , NULL, 'x' }, // { "original" , no_argument , NULL, 'o' }, { "fill" , required_argument, NULL, 'f' }, { "status" , no_argument , NULL, 's' }, { "progress" , no_argument , NULL, 'p' }, /* undocumented */ { "end-track" , required_argument, NULL, 't' }, { NULL , 0 , NULL, 0 } }; // const char shortopts[] ="hVnxospt:"; const char shortopts[] ="hVnxf:spt:"; while((option = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) { switch(option) { case 'n': bump = 0; break; case 'f': //orig = 0x4b; orig=arch_atoc(optarg); break; case 's': status = 1; break; case 'x': tracks = 40; break; case 'h': help(); return 0; case 'V': printf("frm_analyzer %s\n", OPENCBM_VERSION); return 0; case 'p': show_progress = 1; break; case 't': tracks = arch_atoc(optarg); break; case '@': if (adapter == NULL) adapter = cbmlibmisc_strdup(optarg); else { fprintf(stderr, "--adapter/-@ given more than once."); hint(argv[0]); return 1; } break; default : hint(argv[0]); return 1; } } if(optind + 2 != argc) { fprintf(stderr, "Usage: %s [OPTION]... DRIVE NAME,ID\n", argv[0]); hint(argv[0]); return 1; } arg = argv[optind++]; drive = arch_atoc(arg); if(drive < 8 || drive > 11) { fprintf(stderr, "Invalid drive number (%s)\n", arg); return 1; } arg = argv[optind++]; name_len = 0; while(*arg) { unsigned char c; c = (unsigned char) toupper(*arg); if(c == ',') { if(id_ofs) { fprintf(stderr, "More than one `,' in disk name\n"); return 1; } id_ofs = name_len; } name[name_len++] = c; if(name_len > 19) { fprintf(stderr, "Disk name too long\n"); return 1; } arg++; } name[name_len] = 0; if(cbm_driver_open_ex(&fd, adapter) == 0) { cbm_upload(fd, drive, 0x0300, dskfrmt, sizeof(dskfrmt)); sprintf(cmd, "M-E%c%c%c%c%c%c0:%s", 3, 3, tracks + 1, orig, bump, show_progress, name); cbm_exec_command(fd, drive, cmd, 11+strlen(name)); #if 0 if(show_progress) { /* do some handshake */ cbm_iec_release(fd, IEC_CLOCK); for(i = 1; i <= tracks; i++) { cbm_iec_wait(fd, IEC_DATA, 1); cbm_iec_set(fd, IEC_CLOCK); cbm_iec_wait(fd, IEC_DATA, 0); cbm_iec_release(fd, IEC_CLOCK); printf("#"); fflush(stdout); } printf("\n"); } #endif erroroccured = cbm_device_status(fd, drive, cmd, sizeof(cmd)); if(erroroccured && status) { printf("%s\n", cmd); } if(!erroroccured && (tracks > 35)) { cbm_open(fd, drive, 2, "#", 1); cbm_exec_command(fd, drive, "U1:2 0 18 0", 11); cbm_exec_command(fd, drive, "B-P2 192", 8); cbm_listen(fd, drive, 2); while(tracks > 35) { cbm_raw_write(fd, "\021\377\377\001", 4); tracks--; } cbm_unlisten(fd); cbm_exec_command(fd, drive, "U2:2 0 18 0", 11); cbm_close(fd, drive, 2); } if(!erroroccured && status) { cbm_device_status(fd, drive, cmd, sizeof(cmd)); printf("%s\n", cmd); } #if 1 // verbose output { #if 0 // @TODO unused variables float RPMval; int sectors, virtGAPsze, remainder, trackTailGAP, flags, retry, lastTr; const char *vrfy; #endif unsigned char data[0x100]; if (cbm_download(fd, drive, 0x0500, data, sizeof(data)) == sizeof(data)) { #if 1 // TODO, Pattern analyzer, get the lenght of the PLL synchronization period // // search the last byte triple consisting of: 0x49, 0x24, 0x92 // int k; const unsigned char pattern[]={0x49, 0x24, 0x92}; // const unsigned char pattern[]={0xdb, 0x6d, 0xb6}; for(k=sizeof(data)-3; k>=0; --k) { if(data[k]==pattern[0] && data[k+1]==pattern[1] && data[k+2]==pattern[2]) break; } if(k<0) { // no part of the written sequence was found k=sizeof(data); } else { // now search the beginning of that "010010010010010010010010..." bit stream while(k>=0 && data[k]==pattern[0] && data[k+1]==pattern[1] && data[k+2]==pattern[2]) { k-=3; } k+=3; // do single byte decreases if(k>=1 && data[k-1]==pattern[2]) --k; if(k>=1 && data[k-1]==pattern[1]) --k; if(k>=1 && data[k-1]==pattern[0]) --k; } printf("Result with Pattern: 0x%02X / %3d, formatted on track %2d, PLL synchronization length: %3d\n", orig, orig, tracks, k); for (i=0; i < sizeof(data); i++) { /* if(data[i] == 0) { printf("\n"); break; } */ printf(" %02X", data[i]); if((i&0x0f) == 0x0f) printf("\n"); } #else int i; printf("Track|Retry|sctrs|slctd|| GAP |modulo |modulo|tail| Verify | RPM |\n" " | | | GAP ||adjst|complmt| dvsr |GAP | | |\n" "-----+-----+-----+-----++-----+-------+------+----+---------+------+\n"); lastTr=-1; for (i=0; i < sizeof(data); i+=4) { if(data[i]==0) break; // no more data is available if(data[i+3]>=0x40 && data[i]>42){ // logging continuation line printf(" | | debug log || $%02X | $%02X $%02X $%02X\n", data[i], data[i+1], data[i+2], data[i+3]); continue; // proceed with next loop run } if(data[i]==lastTr) retry++; else retry=0; lastTr=data[i]; if(data[i]>=25) // preselect track dependent constants { if(data[i]>=31) sectors=17, RPMval=60000000.0f/16; else sectors=18, RPMval=60000000.0f/15; } else { if(data[i]>=18) sectors=19, RPMval=60000000.0f/14; else sectors=21, RPMval=60000000.0f/13; } // separate some flags flags=(data[i+3]>>6)&0x03; data[i+3]&=0x3f; switch(flags) { case 0x01: vrfy="SYNC fail"; break; case 0x02: vrfy="verify OK"; break; case 0x03: vrfy="vrfy fail"; break; default: vrfy=" ./. "; } // recalculation of the track tail GAP out of the // choosen GAP for this track, the new GAP size // adjustment and the complement of the remainder // of the adjustment division virtGAPsze=data[i+1] -3; // virtual GAP increase to // prevent reformatting, when only one byte is missing remainder=((data[i+2]==0xff) ? virtGAPsze : sectors) - data[i+3]; trackTailGAP=((data[i+2]==0xff) ? 0 : data[i+2]*sectors + virtGAPsze) + remainder; // the following constants are nybble based (double the // size of the well known constants for SYNC lengths, // block header size, data block GAP and data block) // // (0x01&data[i+1]§ors) is a correction term, if "half // GAPs" are written and the number of sectors is odd // // RPMval / (sectors * (10+20+18+10 + 650 + data[i+1]) - (0x01&data[i+1]§ors) + trackTailGAP - data[i+1]) RPMval = (flags != 0x01) ? RPMval / (sectors * (10+20+18+10 + 650 + data[i+1]) - (0x01&data[i+1]§ors) + trackTailGAP - data[i+1]) : 0; printf(" %3u | ", data[i]); if(retry>0) printf("%3u", retry); else printf(" "); /* " |sctrs |slctd || GAP |modulo |modulo |tail | Verify | RPM |\n" * " | | GAP ||adjst |complmt | |GAP | | |\n" * "-+----- +----- ++----- +------- +------ +---- +---------+------+\n" */ printf(" | %2u | $%02X || $%02X | $%02X | $%02X |$%03X|%9s|%6.2f|\n", sectors, data[i+1], data[i+2], data[i+3], remainder, trackTailGAP, vrfy, RPMval); } printf("\n *) Note: All GAP based numbers shown here (sedecimal values) are\n" " nybble based (4 GCR Bits) instead of GCR byte based.\n"); #endif } else {
int ARCH_MAINDECL main(int argc, char *argv[]) { int status = 0, id_ofs = 0, name_len; CBM_FILE fd; unsigned char drive, starttrack = 1, endtrack = 35, bump = 1, orig = 0; unsigned char verify = 0, demagnetize = 0, retries = 7; char cmd[40], name[20], *arg; struct FormatParameters parmBlock; int berror = 0; char *adapter = NULL; int option; struct option longopts[] = { { "help" , no_argument , NULL, 'h' }, { "version" , no_argument , NULL, 'V' }, { "adapter" , required_argument, NULL, '@' }, { "no-bump" , no_argument , NULL, 'n' }, { "extended" , no_argument , NULL, 'x' }, { "original" , no_argument , NULL, 'o' }, { "status" , no_argument , NULL, 's' }, { "verify" , no_argument , NULL, 'v' }, { "clear" , no_argument , NULL, 'c' }, { "retries" , required_argument, NULL, 'r' }, /* undocumented */ { "fillpattern", required_argument, NULL, 'f' }, { "begin-track", required_argument, NULL, 'b' }, { "end-track" , required_argument, NULL, 'e' }, { NULL , 0 , NULL, 0 } }; const char shortopts[] ="hVnxosvcr:f:b:e:@:"; while((option = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) { switch(option) { case 'n': bump = 0; break; case 'o': orig = 0x4b; break; case 's': status = 1; break; case 'x': starttrack = 1; endtrack = 40; break; case 'h': help(); return 0; #ifdef CBMFORNG case 'V': printf("cbmforng %s\n", OPENCBM_VERSION); #else case 'V': printf("cbmformat %s\n", OPENCBM_VERSION); #endif return 0; case 'v': verify = 1; break; case 'c': demagnetize = 1; break; case 'r': retries = arch_atoc(optarg); if(retries<1) retries= 1; else if(retries>63) retries=63; break; case 'f': orig = arch_atoc(optarg); break; case 'b': starttrack = arch_atoc(optarg); break; case 'e': endtrack = arch_atoc(optarg); break; case '@': if (adapter == NULL) adapter = cbmlibmisc_strdup(optarg); else { fprintf(stderr, "--adapter/-@ given more than once."); hint(argv[0]); return 1; } break; default : hint(argv[0]); return 1; } } if(optind + 2 != argc) { fprintf(stderr, "Usage: %s [OPTION]... DRIVE NAME,ID\n", argv[0]); hint(argv[0]); return 1; } arg = argv[optind++]; drive = arch_atoc(arg); if(drive < 8 || drive > 11) { fprintf(stderr, "Invalid drive number (%s)\n", arg); return 1; } arg = argv[optind++]; name_len = 0; while(*arg) { unsigned char c; c = (unsigned char) toupper(*arg); if(c == ',') { if(id_ofs) { fprintf(stderr, "More than one `,' in disk name\n"); return 1; } id_ofs = name_len; } name[name_len++] = c; if(name_len > 19) { fprintf(stderr, "Disk name too long\n"); return 1; } arg++; } name[name_len] = 0; if(name_len - id_ofs != 3) { fprintf(stderr, "Missing `,' in disk name or ID field not equal to two characters\n"); return 1; } if(cbm_driver_open_ex(&fd, adapter) == 0) { cbm_upload(fd, drive, 0x0300, dskfrmt, sizeof(dskfrmt)); prepareFmtPattern(&parmBlock, orig, endtrack, name[id_ofs+1], name[id_ofs+2]); parmBlock.P_STRCK=starttrack; // start track parameter parmBlock.P_ETRCK=endtrack+1; // end track parameter parmBlock.P_RETRY=(retries & ~0xC0) | (bump?0x40:0xC0); // number of retries (per disk, not per track) parmBlock.P_DOBMP=bump; // flag, if an initial head bump should be done parmBlock.P_DEMAG=demagnetize; // flag, if the disk should be demagnetized parmBlock.P_VRIFY=verify; // flag, if the disk should be verified #if 0 // for checking the generated format patterns { int j,k; for(j=0;j<34;j+=5) { for(k=0;k<5;k++) { printf(" $%02X", ((char *)(&parmBlock))[j+k]&0xFF); } printf("\n"); } printf(" $%02X\n", ((char *)(&parmBlock))[j]&0xFF); } #endif cbm_upload(fd, drive, 0x0200 - sizeof(parmBlock), ((char *)(&parmBlock)), sizeof(parmBlock)); sprintf(cmd, "M-E%c%c0:%s", 3, 3, name); cbm_exec_command(fd, drive, cmd, 7+name_len); berror = cbm_device_status(fd, drive, cmd, sizeof(cmd)); if(berror && status) { printf("%s\n", cmd); } #if defined(DebugFormat) && DebugFormat!=0 // verbose output { float RPMval; int sectors, virtGAPsze, remainder, trackTailGAP, flags, retry = 0, lastTr; const char *vrfy; unsigned char data[0x100]; // in case of an error, get the logging buffer from 0x0700 instead of 0x0500 if (cbm_download(fd, drive, berror?0x0700:0x0500, data, sizeof(data)) == sizeof(data)) { int i; printf("Track|Retry|sctrs|slctd|| GAP |modulo |modulo|tail| Verify | RPM |\n" " | | | GAP ||adjst|complmt| dvsr |GAP | | |\n" "-----+-----+-----+-----++-----+-------+------+----+---------+------+\n"); lastTr=-1; for (i=0; i < sizeof(data); i+=4) { if(data[i]==0) break; // no more data is available if(data[i]==lastTr) retry++; else retry=0; lastTr=data[i]; if(data[i]>=25) // preselect track dependent constants { if(data[i]>=31) sectors=17, RPMval=60000000.0f/16; else sectors=18, RPMval=60000000.0f/15; } else { if(data[i]>=18) sectors=19, RPMval=60000000.0f/14; else sectors=21, RPMval=60000000.0f/13; } // separate some flags flags=(data[i+3]>>6)&0x03; data[i+3]&=0x3f; switch(flags) { case 0x01: vrfy="SYNC fail"; break; case 0x02: vrfy=" OK "; break; case 0x03: vrfy="vrfy fail"; break; default: vrfy=" ./. "; } // recalculation of the track tail GAP out of the // choosen GAP for this track, the new GAP size // adjustment and the complement of the remainder // of the adjustment division virtGAPsze=data[i+1] -5; // virtual GAP increase to // prevent reformatting, when only one byte is missing // and other offset compensations remainder=((data[i+2]==0xff) ? virtGAPsze : sectors) - data[i+3]; trackTailGAP=((data[i+2]==0xff) ? 0 : data[i+2]*sectors + virtGAPsze) + remainder; // the following constants are nybble based (double the // size of the well known constants for SYNC lengths, // block header size, data block GAP and data block) // // (0x01&data[i+1]§ors) is a correction term, if "half // GAPs" are written and the number of sectors is odd // // RPMval / (sectors * (10+20+18+10 + 650 + data[i+1]) - (0x01&data[i+1]§ors) + trackTailGAP - data[i+1]) RPMval = (flags != 0x01) ? RPMval / (sectors * (10+20+18+10 + 650 + data[i+1]) - (0x01&data[i+1]§ors) + trackTailGAP - data[i+1]) : 0; printf(" %3u | ", data[i]); if(retry>0) printf("%3u", retry); else printf(" "); /* " |sctrs |slctd || GAP |modulo |modulo |tail | Verify | RPM |\n" * " | | GAP ||adjst |complmt | | GAP | | |\n" * "-+----- +----- ++----- +------- +------ +---- +---------+------+\n" */ printf(" | %2u |$%02X.%d||$%02X.%d| $%02X.%d | $%02X.%d|$%03X|%9s|%6.2f|\n", sectors, data[i+1]>>1, (data[i+1]<<3)&8, // selected GAP (((signed char)data[i+2])>>1)&0xFF, (data[i+2]<<3)&8, // GAP adjust data[i+3]>>1, (data[i+3]<<3)&8, // modulo complement remainder>>1, (remainder<<3)&8, // modulo (trackTailGAP>>1) + 1, // track tail GAP (with roundup) vrfy, RPMval); } printf("\n *) Note: The fractional parts of all the GAP based numbers shown here\n" " (sedecimal values) are given due to nybble based calculations.\n"); } else {
int ARCH_MAINDECL main(int argc, char *argv[]) { int status = 0; char cmd[40]; unsigned char job = 1, begintrack = 1, endtrack = 35, retries = 5; char c, *arg; char *adapter = NULL; int sector = 0, berror = 0; struct option longopts[] = { { "help" , no_argument , NULL, 'h' }, { "version" , no_argument , NULL, 'V' }, { "adapter" , required_argument, NULL, '@' }, { "job" , no_argument , NULL, 'j' }, { "retries" , required_argument, NULL, 'r' }, { "extended" , no_argument , NULL, 'x' }, { "retries" , required_argument, NULL, 'r' }, { "begin-track", required_argument, NULL, 'b' }, { "end-track" , required_argument, NULL, 'e' }, { "sector" , required_argument, NULL, 'c' }, /* { "quiet" , no_argument , NULL, 'q' }, { "verbose" , no_argument , NULL, 'v' }, { "no-progress", no_argument , NULL, 'n' }, */ { NULL , 0 , NULL, 0 } }; // const char shortopts[] ="hVj:sr:xb:e:c:qvn"; const char shortopts[] ="hVj:sxr:b:e:c:@:"; while((c=(unsigned char)getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) { switch(c) { case 'h': help(); return 0; case 'V': printf("cbmrpm41 Version %s\n", OPENCBM_VERSION ", built on " __DATE__ " at " __TIME__ "\n"); return 0; case 'j': job = arch_atoc(optarg); break; case 's': status = 1; break; case 'x': begintrack = 1; endtrack = 40; break; case 'r': retries = arch_atoc(optarg); if(retries<1) retries = 1; else if(retries>63) retries = 63; break; case 'b': begintrack = arch_atoc(optarg); break; case 'e': endtrack = arch_atoc(optarg); break; case 'c': sector = atoi(optarg); break; case '@': if (adapter == NULL) adapter = cbmlibmisc_strdup(optarg); else { fprintf(stderr, "--adapter/-@ given more than once."); help(); return 0; } break; default : hint(argv[0]); return 1; } } if(optind + 1 != argc) { fprintf(stderr, "Usage: %s [OPTION]... DRIVE\n", argv[0]); hint(argv[0]); return 1; } arg = argv[optind++]; drive = arch_atoc(arg); if(drive < 8 || drive > 11) { fprintf(stderr, "Invalid drive number (%s)\n", arg); return 1; } if(begintrack < 1) { fprintf(stderr, "Beginning track is less than 1, it should be 1 or greater.\n"); return 1; } if(endtrack > 42) { fprintf(stderr, "Ending track is greater than 42, it should be 42 or less.\n"); return 1; } if(begintrack > endtrack) { fprintf(stderr, "Beginning track is greater than ending track, it should be less or equal."); return 1; } if(sector < 0) { fprintf(stderr, "Sector numbers less than zero are not allowed."); return 1; } SETSTATEDEBUG((void)0); printf("Please remove any diskettes used with production data on it. Insert a freshly\n" "formatted disk into drive %d; you can format a disk with e.g. the command:\n\n" " cbmforng -o -v %d freshdisk,fd\n\n" "If you desperately need to examine a production disk or even an original\n" "diskette, then please protect the disk with a write protect adhesive label.\n\n" "Press <Enter>, when ready or press <CTRL>-C to abort.\r", drive, drive); getchar(); if(cbm_driver_open_ex(&fd, adapter) == 0) do { arch_set_ctrlbreak_handler(handle_CTRL_C); SETSTATEDEBUG((void)0); if( cbm_upload(fd, drive, sizeof(cbmDev_StartAddress), cbmrpm41, sizeof(cbmrpm41)) != sizeof(cbmrpm41)) break; // location of the new U vector user commands table sprintf(cmd, "%c%c", UcmdTblAddr & 0xFF, UcmdTblAddr >> 8); // install the new U vector table SETSTATEDEBUG((void)0); if( cbm_upload(fd, drive, sizeof(cbmDev_UxCMDtVector), cmd, 2) != 2) break; // execute Ux command behind the symbolic name Init23_BitTimersStd SETSTATEDEBUG((void)0); if( cbm_sendUxCommand(fd, drive, Init23_BitTimersStd) != 0) break; // read disk ID and initialise other parameters // from the currently inserted disk into the // drive's RAM locations SETSTATEDEBUG((void)0); if( cbm_exec_command(fd, drive, "I0", 2) != 0) break; SETSTATEDEBUG((void)0); berror = cbm_device_status(fd, drive, cmd, sizeof(cmd)); if(berror && status) { printf("%s\n", cmd); } switch(job) { case 4: if( do_RPMadjustment (begintrack, endtrack, sector, retries) != 0 ) continue; // jump to begin of do{}while(0); break; case 3: if( do_RPMregression (begintrack, endtrack, sector, retries) != 0 ) continue; // jump to begin of do{}while(0); break; case 2: if( do_SKEWmeasurment(begintrack, endtrack, sector, retries) != 0 ) continue; // jump to begin of do{}while(0); break; default: if( do_RPMmeasurment (begintrack, endtrack, sector, retries) != 0 ) continue; // jump to begin of do{}while(0); } if( cbm_sendUxCommand(fd, drive, ResetVIA2ShiftRegConfig) != 0 ) break; if( cbm_sendUxCommand(fd, drive, ResetUxVectorTable) != 0 ) break; if( cbm_exec_command(fd, drive, "I", 2) != 0 ) break; if(!berror && status) { cbm_device_status(fd, drive, cmd, sizeof(cmd)); printf("%s\n", cmd); } cbm_driver_close(fd); cbmlibmisc_strfree(adapter); return 0; } while(0); else {