forked from OpenCBM/nibtools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
nibwrite.c
301 lines (257 loc) · 7.07 KB
/
nibwrite.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
/*
NIBWRITE - part of the NIBTOOLS package for 1541/1571 disk image nibbling
by Peter Rittwage <peter(at)rittwage(dot)com>
based on code from MNIB, by Dr. Markus Brenner
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <time.h>
#include <ctype.h>
#include "mnibarch.h"
#include "gcr.h"
#include "nibtools.h"
#include "prot.h"
#include "lz.h"
int _dowildcard = 1;
char bitrate_range[4] = { 43 * 2, 31 * 2, 25 * 2, 18 * 2 };
char bitrate_value[4] = { 0x00, 0x20, 0x40, 0x60 };
char density_branch[4] = { 0xb1, 0xb5, 0xb7, 0xb9 };
BYTE compressed_buffer[(MAX_HALFTRACKS_1541 + 2) * NIB_TRACK_LENGTH];
BYTE file_buffer[(MAX_HALFTRACKS_1541 + 2) * NIB_TRACK_LENGTH];
BYTE track_buffer[(MAX_HALFTRACKS_1541 + 2) * NIB_TRACK_LENGTH];
BYTE track_density[MAX_HALFTRACKS_1541 + 2];
BYTE track_alignment[MAX_HALFTRACKS_1541 + 2];
size_t track_length[MAX_HALFTRACKS_1541 + 2];
int file_buffer_size;
int start_track, end_track, track_inc;
int reduce_sync;
int fix_gcr, aggressive_gcr;
int align;
extern unsigned int lpt[4];
extern int lpt_num;
extern unsigned int floppybytes;
int drivetype;
int imagetype;
int mode;
int verify;
int auto_capacity_adjust;
int align_disk;
int gap_match_length;
int cap_min_ignore;
int verbose = 0;
float motor_speed;
int skew = 0;
int ihs = 0;
int rpm_real;
int unformat_passes;
int align_delay;
int increase_sync = 0;
int presync = 0;
BYTE fillbyte = 0x55;
BYTE drive = 8;
char * cbm_adapter = "";
int use_floppycode_srq = 0;
int override_srq = 0;
int extra_capacity_margin=5;
int sync_align_buffer=0;
int fattrack=0;
int track_match=0;
int old_g64=0;
int read_killer=1;
int extended_parallel_test=0;
int backwards=0;
int nb2cycle=0;
CBM_FILE fd;
FILE *fplog;
int ARCH_MAINDECL
main(int argc, char *argv[])
{
int bump, reset, i;
char filename[256];
char argcache[256];
fprintf(stdout,
"nibwrite - Commodore 1541/1571 disk image 'remastering' tool\n"
AUTHOR VERSION "\n");
/* we can do nothing with no switches */
if (argc < 2)
usage();
#ifdef DJGPP
fd = 1;
#endif
bump = 1; /* failing to bump sometimes give us wrong tracks on heavily protected disks */
reset = 1;
start_track = 2;
end_track = 82;
track_inc = 2;
reduce_sync = 4;
fix_gcr = 1;
align_disk = 0;
auto_capacity_adjust = 1;
gap_match_length = 7;
cap_min_ignore = 0;
motor_speed = 300;
unformat_passes = 1;
mode = MODE_WRITE_DISK;
align = ALIGN_NONE;
/* clear heap buffers */
memset(compressed_buffer, 0x00, sizeof(compressed_buffer));
memset(file_buffer, 0x00, sizeof(file_buffer));
memset(track_buffer, 0x00, sizeof(track_buffer));
/* default is to reduce sync */
memset(reduce_map, REDUCE_SYNC, MAX_TRACKS_1541+1);
/* cache our arguments for logfile generation */
strcpy(argcache, "");
for (i = 0; i < argc; i++)
{
strcat(argcache, argv[i]);
strcat(argcache," ");
}
while (--argc && (*(++argv)[0] == '-'))
parseargs(argv);
printf("\n");
if (argc > 0) strcpy(filename, argv[0]);
if(mode == MODE_WRITE_DISK)
{
if(!(loadimage(filename)))
{
printf("\nImage loading failed\n");
exit(0);
}
}
#ifdef DJGPP
calibrate();
if (!detect_ports(reset))
return 0;
#elif defined(OPENCBM_42)
/* remain compatible with OpenCBM < 0.4.99 */
if (cbm_driver_open(&fd, 0) != 0)
{
printf("Is your X-cable properly configured?\n");
exit(0);
}
#else /* assume > 0.4.99 */
if (cbm_driver_open_ex(&fd, cbm_adapter) != 0)
{
printf("Is your X-cable properly configured?\n");
exit(0);
}
#endif
/* Once the drive is accessed, we need to close out state when exiting */
atexit(handle_exit);
signal(SIGINT, handle_signals);
printf("Using device #%d\n",drive);
if(!(init_floppy(fd, drive, bump)))
{
printf("\nFloppy drive initialization failed\n");
exit(0);
}
switch (mode)
{
case MODE_WRITE_DISK:
case MODE_WRITE_RAW:
/*printf("Current disk WILL be OVERWRITTEN!\n"
"Press ENTER to continue or CTRL-C to quit.\n");
getchar();
*/
writeimage(fd);
break;
case MODE_UNFORMAT_DISK:
/*printf("Ready to unformat disk.\n");
printf("Current disk WILL be DESTROYED!\n"
"Press ENTER to continue or CTRL-C to quit.\n");
getchar();
*/
unformat_disk(fd);
break;
case MODE_SPEED_ADJUST:
speed_adjust(fd);
break;
}
motor_on(fd);
step_to_halftrack(fd, 18 * 2);
exit(0);
}
int loadimage(char *filename)
{
/* read and remaster disk */
if (compare_extension(filename, "D64"))
{
if(!(read_d64(filename, track_buffer, track_density, track_length))) return 0;
}
else if (compare_extension(filename, "G64"))
{
if(!(read_g64(filename, track_buffer, track_density, track_length))) return 0;
if(sync_align_buffer) sync_tracks(track_buffer, track_density, track_length, track_alignment);
search_fat_tracks(track_buffer, track_density, track_length);
}
else if (compare_extension(filename, "NBZ"))
{
printf("Uncompressing NBZ...\n");
if(!(file_buffer_size = load_file(filename, compressed_buffer))) return 0;
if(!(file_buffer_size = LZ_Uncompress(compressed_buffer, file_buffer, file_buffer_size))) return 0;
if(!(read_nib(file_buffer, file_buffer_size, track_buffer, track_density, track_length))) return 0;
align_tracks(track_buffer, track_density, track_length, track_alignment);
search_fat_tracks(track_buffer, track_density, track_length);
}
else if (compare_extension(filename, "NIB"))
{
if(!(file_buffer_size = load_file(filename, file_buffer))) return 0;
if(!(read_nib(file_buffer, file_buffer_size, track_buffer, track_density, track_length))) return 0;
align_tracks(track_buffer, track_density, track_length, track_alignment);
search_fat_tracks(track_buffer, track_density, track_length);
}
else if (compare_extension(filename, "NB2"))
{
if(!(read_nb2(filename, track_buffer, track_density, track_length, nb2cycle))) return 0;
align_tracks(track_buffer, track_density, track_length, track_alignment);
search_fat_tracks(track_buffer, track_density, track_length);
}
else
{
printf("\nUnknown image type");
return 0;
}
return 1;
}
int writeimage(CBM_FILE fd)
{
/* turn on motor and measure speed */
motor_on(fd);
if(auto_capacity_adjust)
adjust_target(fd);
if(fattrack)
{
printf("File contains possible FAT track on T%d - Attempt to write? (y/N)",fattrack/2);
if(getchar() != 'y') fattrack=0;
}
if((fattrack)&&(fattrack!=99))
unformat_disk(fd);
//if(align_disk)
// init_aligned_disk(fd);
if(mode == MODE_WRITE_RAW)
master_disk_raw(fd, track_buffer, track_density, track_length);
else
master_disk(fd, track_buffer, track_density, track_length);
step_to_halftrack(fd, 18 * 2);
printf("\n");
return 1;
}
void
usage(void)
{
printf("usage: nibwrite [options] <filename>\n\n"
" -@x: Use OpenCBM device 'x' (xa1541, xum1541:0, xum1541:1, etc.)\n"
" -D[n]: Use drive #[n]\n"
" -S[n]: Override starting track\n"
" -E[n]: Override ending track\n"
" -m[n]: Change extra capacity margin to [n] (default: 0)\n"
" -P: Use parallel instead of SRQ on 1571\n"
" -t: Enable timer-based track alignment\n"
" -c: Disable automatic capacity adjustment\n"
" -u: Unformat disk. (writes all 0 bits to surface)\n"
);
switchusage();
exit(1);
}