32
32
****************************************************************************/
35
* Support auto-identification heuristics for determining disk image speed,
36
capture clock rate, and number of multireads per image.
38
* Scale captured data based on the guessed clock rate and samplerate to match
39
the internal 200mhz representation
40
* Handle 0xFF bytes properly
41
* Correctly note exact index timing.
35
45
#include "dfi_dsk.h"
47
#define NUMBER_OF_MULTIREADS 3
48
// threshholds for brickwall windowing
49
//define MIN_CLOCKS 65
50
// number_please apple2 wants 40 min
52
//define MAX_CLOCKS 260
53
#define MAX_CLOCKS 270
54
#define MIN_THRESH (MIN_CLOCKS*(clock_rate/25000000))
55
#define MAX_THRESH (MAX_CLOCKS*(clock_rate/25000000))
56
// constants to help guess clockrate and rpm
57
// constant is 25mhz / 6 revolutions per second (360rpm) = 4166667 +- 2.5%
58
#define REV25_MIN 4062500
59
#define REV25_MAX 4270833
60
// define the following to show a histogram per track
61
//define TRACK_HISTOGRAM 1
62
#undef TRACK_HISTOGRAM
38
64
dfi_format::dfi_format() : floppy_image_format_t()
94
127
data = global_alloc_array(UINT8, data_size);
97
io_generic_read(io, data, pos+16, tsize);
99
tsize--; // Drop the extra 0x00 at the end
130
pos += 10; // skip the header, we already read it
131
io_generic_read(io, data, pos, tsize);
132
pos += tsize; // for next time we read, increment to the beginning of next header
134
int index_time = 0; // what point the last index happened
135
int index_count = 0; // number of index pulses per track
136
//int index_polarity = 1; // current polarity of index, starts high
137
int total_time = 0; // total sampled time per track
103
138
for(int i=0; i<tsize; i++) {
104
139
UINT8 v = data[i];
140
if (v == 0xFF) { fprintf(stderr,"DFI stream contained a 0xFF at t%d, position%d, THIS SHOULD NEVER HAPPEN! Bailing out!\n", track, i); exit(1); }
105
141
if((v & 0x7f) == 0x7f)
106
142
total_time += 0x7f;
108
total_time += v & 0x7f;
109
if((v & 0x80) && !index_time)
110
index_time = total_time;
144
total_time += v & 0x7f;
145
index_time = total_time;
146
//index_polarity ^= 1;
147
//fprintf(stderr,"index state changed to %d at time=%d\n", index_polarity, total_time);
148
//fprintf(stderr,"index rising edge seen at time=%d\n", total_time);
149
if (onerev_time == 0) onerev_time = total_time;
150
index_count += 1;//index_polarity;
151
} else // (v & 0x80) == 0
152
total_time += v & 0x7f;
155
// its possible on single read images for there to be no index pulse during the image at all!
156
if (onerev_time == 0) onerev_time = total_time;
114
158
if(!track && !head)
115
159
fprintf(stderr, "%02d:%d tt=%10d it=%10d\n", track, head, total_time, index_time);
160
if(!track && !head) {
161
fprintf(stderr, "index_count: %d, onerev_time: %d\n", index_count, onerev_time);
162
if ((onerev_time > REV25_MIN) && (onerev_time < REV25_MAX)) {
163
fprintf(stderr, "Guess: speed: 360rpm, clock 25MHz\n");
164
clock_rate = 25000000; rpm = 360;
165
} else if ((onerev_time > REV25_MIN*1.2) && (onerev_time < REV25_MAX*1.2)) {
166
fprintf(stderr, "Guess: speed: 300rpm, clock 25MHz\n");
167
clock_rate = 25000000; rpm = 300;
168
} else if ((onerev_time > REV25_MIN*2) && (onerev_time < REV25_MAX*2)) {
169
fprintf(stderr, "Guess: speed: 360rpm, clock 50MHz\n");
170
clock_rate = 50000000; rpm = 360;
171
} else if ((onerev_time > (REV25_MIN*2)*1.2) && (onerev_time < (REV25_MAX*2)*1.2)) {
172
fprintf(stderr, "Guess: speed: 300rpm, clock 50MHz\n");
173
clock_rate = 50000000; rpm = 300;
174
} else if ((onerev_time > REV25_MIN*4) && (onerev_time < REV25_MAX*4)) {
175
fprintf(stderr, "Guess: speed: 360rpm, clock 100MHz\n");
176
clock_rate = 100000000; rpm = 360;
177
} else if ((onerev_time > (REV25_MIN*4)*1.2) && (onerev_time < (REV25_MAX*4)*1.2)) {
178
fprintf(stderr, "Guess: speed: 300rpm, clock 100MHz\n");
179
clock_rate = 100000000; rpm = 300;
181
fprintf(stderr, "WARNING: Cannot Guess Speed! Assuming 360rpm, 100Mhz clock!\n");
182
fprintf(stderr,"Actual rpm based on index: %f\n", ((double)clock_rate/(double)onerev_time)*60);
185
rpm += 0; // HACK: prevent GCC 4.6+ from warning "variable set but unused"
118
188
index_time = total_time;
120
190
image->set_track_size(track, head, tsize);
122
192
int cur_time = 0;
194
#ifdef TRACK_HISTOGRAM
196
int time_buckets[4096];
197
for (int i = 0; i < 4096; i++)
201
//index_polarity = 0;
123
202
UINT32 mg = floppy_image::MG_A;
124
203
UINT32 *buf = image->get_buffer(track, head);
126
205
buf[tpos++] = mg;
127
206
for(int i=0; i<tsize; i++) {
128
207
UINT8 v = data[i];
129
if((v & 0x7f) == 0x7f)
208
if((v & 0x7f) == 0x7f) // 0x7F : no transition, but a carry (FF is a board-on-fire error and is checked for above)
130
209
cur_time += 0x7f;
132
cur_time += v & 0x7f;
135
mg = mg == floppy_image::MG_A ? floppy_image::MG_B : floppy_image::MG_A;
136
buf[tpos++] = mg | UINT32(200000000ULL*cur_time/index_time);
210
else if(v & 0x80) { // 0x80 set, note the index (TODO: actually do this!) and add number to count
211
cur_time += v & 0x7f;
212
//index_polarity ^= 1;
213
index_count += 1;//index_polarity;
214
//if (index_count == NUMBER_OF_MULTIREADS) break;
216
else if((v & 0x80) == 0) { // 0x00-0x7E: not an index or carry, add the number and store transition
217
cur_time += v & 0x7f;
218
int trans_time = cur_time - prev_time;
219
#ifdef TRACK_HISTOGRAM
220
time_buckets[(trans_time<4096)?trans_time:4095]++;
222
// cur_time and onerev_time need to be converted to something standard, so we'll stick with 300rpm at the standard 200mhz rate that mfi uses internally
223
// TODO for 4/22/2012: ACTUALLY DO THIS RESCALING STEP
224
// filter out spurious crap
225
//if (trans_time <= MIN_THRESH) fprintf(stderr, "DFI: Throwing out short transition of length %d\n", trans_time);
226
// the normal case: write the transition at the appropriate time
227
if ((prev_time == 0) || ((trans_time > MIN_THRESH) && (trans_time <= MAX_THRESH))) {
228
mg = mg == floppy_image::MG_A ? floppy_image::MG_B : floppy_image::MG_A;
229
buf[tpos++] = mg | UINT32((200000000ULL*cur_time)/index_time);
230
prev_time = cur_time;
232
// the long case: we probably missed a transition, stuff an extra guessed one in there to see if it helps
233
if (trans_time > MAX_THRESH) {
234
mg = mg == floppy_image::MG_A ? floppy_image::MG_B : floppy_image::MG_A;
235
if (((track%2)==0)&&(head==0)) fprintf(stderr,"missed transition, total time for transition is %d\n",trans_time);
236
#ifndef FAKETRANS_ONE
237
buf[tpos++] = mg | UINT32((200000000ULL*(cur_time-(trans_time/2)))/index_time); // generate imaginary transition at half period
239
buf[tpos++] = mg | UINT32((200000000ULL*(cur_time-((trans_time*2)/3)))/index_time);
240
mg = mg == floppy_image::MG_A ? floppy_image::MG_B : floppy_image::MG_A;
241
buf[tpos++] = mg | UINT32((200000000ULL*(cur_time-(trans_time/3)))/index_time);
243
mg = mg == floppy_image::MG_A ? floppy_image::MG_B : floppy_image::MG_A;
244
buf[tpos++] = mg | UINT32(200000000ULL*cur_time/index_time); // generate transition now
245
prev_time = cur_time;
249
#ifdef TRACK_HISTOGRAM
250
if (((track%2)==0)&&(head==0)) {
251
for (int i = 0; i < 4096; i++) {
252
fprintf(stderr,"%4d:%4d ", i, time_buckets[i]);
253
if (((i+1)%10)==0) fprintf(stderr,"\n");
256
fprintf(stderr,"\n");
139
259
image->set_track_size(track, head, tpos);