25 static d64copy_severity_e verbosity = sev_warning;
26 static int no_progress = 0;
32 static int is_cbm(
char *name)
34 return((strcmp(name,
"8" ) == 0) || (strcmp(name,
"9" ) == 0) ||
35 (strcmp(name,
"10") == 0) || (strcmp(name,
"11") == 0) );
42 "Usage: d64copy [OPTION]... [SOURCE] [TARGET]\n"
43 "Copy .d64 disk images to a CBM-1541 or compatible drive and vice versa\n"
46 " -h, --help display this help and exit\n"
47 " -V, --version display version information and exit\n"
48 " -@, --adapter=plugin:bus tell OpenCBM which backend plugin and bus to use\n"
49 " -q, --quiet quiet output\n"
50 " -v, --verbose control verbosity (repeatedly, up to 3 times)\n"
51 " -n, --no-progress do not display progress information\n"
53 " -s, --start-track=TRACK set start track\n"
54 " -e, --end-track=TRACK set end track (start <= end <= 42/70)\n"
56 " -t, --transfer=TRANSFER set transfermode; valid modes:\n"
58 " original (slowest)\n"
61 " parallel (fastest)\n"
62 " (can be abbreviated, if unambiguous)\n"
63 " `original' and `serial1' should work in any case;\n"
64 " `serial2' won't work if more than one device is\n"
65 " connected to the IEC bus;\n"
66 " `parallel' needs a XP1541/XP1571 cable in addition\n"
67 " to the serial one.\n"
68 " `auto' tries to determine the best option.\n"
70 " -i, --interleave=VALUE set interleave value; ignored when reading with\n"
71 " warp mode; default values are:\n"
75 " turbo r/w warp write\n"
80 " INTERLEAVE is ignored when reading with warp mode;\n"
81 " if data transfer is very slow, increasing this\n"
84 " -w, --warp enable warp mode; this is not possible if\n"
85 " TRANSFER is set to `original'\n"
86 " This is the default if transfer is not `original'.\n"
88 " --no-warp disable warp mode; this is the default if\n"
89 " TRANSFER is set to `original'.\n"
91 " -b, --bam-only BAM-only copy; only allocated blocks are copied;\n"
92 " for extended tracks (36-40), SpeedDOS BAM format\n"
93 " is assumed. Use with caution.\n"
95 " -B, --bam-save save BAM-only copy; this is like the `-b' option\n"
96 " but copies always the entire directory track.\n"
98 " -d, --drive-type=TYPE specify drive type:\n"
100 " 1 or 1571 = 1570/1571\n"
102 " -r, --retry-count=COUNT set retry count\n"
104 " -E, --error-map=WHEN control whether the error map is appended.\n"
105 " possible values for WHEN are (abbreviations\n"
108 " on_errors (default)\n"
111 " -2, --two-sided two-sided disk transfer (.d71): Requires 1571.\n"
112 " Warp mode is not available for .d71 images.\n"
117 static void hint(
char *s)
119 fprintf(stderr,
"Try `%s' --help for more information.\n", s);
122 static void my_message_cb(
int severity,
const char *format, ...)
126 static const char *severities[4] =
134 if(verbosity >= severity)
136 fprintf(stderr,
"[%s] ", severities[severity]);
137 va_start(args, format);
138 vfprintf(stderr, format, args);
140 fprintf(stderr,
"\n");
146 static char trackmap[MAX_SECTORS+1];
147 static int last_track;
151 static const char bs2char[] =
153 ' ',
'.',
'-',
'?',
'*'
156 if(status.track == 0)
167 if(last_track != status.track)
171 printf(
"\r%2d: %-24s \n", last_track, trackmap);
174 for(s = status.bam[status.track-1], d = trackmap; *s; s++, d++)
176 *d = bs2char[(int)*s];
179 last_track = status.track;
182 trackmap[status.sector] =
183 bs2char[(status.read_result ||
184 status.write_result) ? bs_error : bs_copied];
186 printf(
"\r%2d: %-24s%3d%% %4d/%d", status.track, trackmap,
187 100 * status.sectors_processed / status.total_sectors,
188 status.sectors_processed, status.total_sectors);
195 static void ARCH_SIGNALDECL reset(
int dummy)
204 fd_cbm_local = fd_cbm;
207 fprintf(stderr,
"\nSIGINT caught X-( Resetting IEC bus...\n");
208 #ifdef LIBD64COPY_DEBUG
209 printDebugLibD64Counters(my_message_cb);
217 int ARCH_MAINDECL
main(
int argc,
char *argv[])
224 char *adapter = NULL;
233 struct option longopts[] =
235 {
"help" , no_argument , NULL,
'h' },
236 {
"version" , no_argument , NULL,
'V' },
237 {
"adapter" , required_argument, NULL,
'@' },
238 {
"warp" , no_argument , NULL,
'w' },
239 {
"no-warp" , no_argument , &settings->warp, 0 },
240 {
"quiet" , no_argument , NULL,
'q' },
241 {
"verbose" , no_argument , NULL,
'v' },
242 {
"no-progress", no_argument , NULL,
'n' },
243 {
"interleave" , required_argument, NULL,
'i' },
244 {
"start-track", required_argument, NULL,
's' },
245 {
"end-track" , required_argument, NULL,
'e' },
246 {
"transfer" , required_argument, NULL,
't' },
247 {
"bam-only" , no_argument , NULL,
'b' },
248 {
"bam-save" , no_argument , NULL,
'B' },
249 {
"drive-type" , required_argument, NULL,
'd' },
250 {
"retry-count", required_argument, NULL,
'r' },
251 {
"two-sided" , no_argument , NULL,
'2' },
252 {
"error-map" , required_argument, NULL,
'E' },
253 { NULL , 0 , NULL, 0 }
256 const char shortopts[] =
"hVwqbBt:i:s:e:d:r:2vnE:@:";
258 while((option = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1)
264 case 'V': printf(
"d64copy %s\n", OPENCBM_VERSION);
266 case 'w': settings->warp = 1;
268 case 'q':
if(verbosity > 0) verbosity--;
270 case 'v': verbosity++;
272 case 'n': no_progress = 1;
274 case 'i': settings->interleave = arch_atoc(optarg);
276 case 's': settings->start_track = atoi(optarg);
278 case 'e': settings->end_track = atoi(optarg);
280 case 't': tm = optarg;
282 case 'b': settings->bam_mode = bm_allocated;
284 case 'B': settings->bam_mode = bm_save;
286 case 'd':
if(strcmp(optarg,
"1541") == 0)
290 else if(strcmp(optarg,
"1571") == 0)
294 else if(strcmp(optarg,
"1570") == 0)
300 settings->drive_type = atoi(optarg) != 0 ?
304 case 'r': settings->retries = atoi(optarg);
306 case '2': settings->two_sided = 1;
308 case 'E': l = strlen(optarg);
309 if(strncmp(optarg,
"always", l) == 0)
311 settings->error_mode = em_always;
313 else if(strncmp(optarg,
"on_errors", l) == 0)
315 settings->error_mode = em_on_error;
317 else if(strncmp(optarg,
"never", l) == 0)
319 settings->error_mode = em_never;
327 case '@':
if (adapter == NULL)
331 my_message_cb(sev_fatal,
"--adapter/-@ given more than once.");
337 default : hint(argv[0]);
342 settings->transfer_mode = d64copy_get_transfer_mode_index(tm);
343 if(settings->transfer_mode < 0)
345 char *modes = d64copy_get_transfer_modes();
348 fprintf(stderr,
"Unknown transfer mode: %s\nAvailable modes:\n", tm);
350 for(m = modes; *m; m+=(strlen(m)+1))
352 fprintf(stderr,
" %s\n", m);
359 my_message_cb(3,
"transfer mode is %d", settings->transfer_mode );
361 if(optind + 2 != argc)
363 fprintf(stderr,
"Usage: %s [OPTION]... [SOURCE] [TARGET]\n", argv[0]);
368 src_arg = argv[optind];
369 dst_arg = argv[optind+1];
371 src_is_cbm = is_cbm(src_arg);
372 dst_is_cbm = is_cbm(dst_arg);
374 if(src_is_cbm == dst_is_cbm)
376 my_message_cb(0,
"either source or target must be a CBM drive");
386 settings->transfer_mode =
387 d64copy_check_auto_transfer_mode(fd_cbm,
388 settings->transfer_mode,
389 atoi(src_is_cbm ? src_arg : dst_arg));
391 my_message_cb(3,
"decided to use transfer mode %d", settings->transfer_mode );
397 rv = d64copy_read_image(fd_cbm, settings, atoi(src_arg), dst_arg,
398 my_message_cb, my_status_cb);
402 rv = d64copy_write_image(fd_cbm, settings, src_arg, atoi(dst_arg),
403 my_message_cb, my_status_cb);
406 if(!no_progress && rv >= 0)
408 printf(
"\n%d blocks copied.\n", rv);
char * cbmlibmisc_strdup(const char *const OldString)
Duplicate a given string.
void cbmlibmisc_strfree(const char *String)
Free a string.
const char *CBMAPIDECL cbm_get_driver_name_ex(char *Adapter)
Get the name of the driver for a specific parallel port, extended version.
int ARCH_MAINDECL main(int argc, char **argv)
Initialize the xum1541 device This function tries to find and identify the xum1541 device...
int CBMAPIDECL cbm_driver_open_ex(CBM_FILE *HandleDevice, char *Adapter)
Opens the driver, extended version.
void CBMAPIDECL cbm_driver_close(CBM_FILE HandleDevice)
Closes the driver.
void arch_set_ctrlbreak_handler(ARCH_CTRLBREAK_HANDLER Handler)
Set the Ctrl+C / Ctrl+Break handler.
int CBMAPIDECL cbm_reset(CBM_FILE HandleDevice)
RESET all devices.
DLL interface for accessing the driver.
Define makros and functions which account for differences between the different architectures.
Some functions for string handling.