~ubuntu-branches/debian/sid/mame/sid

« back to all changes in this revision

Viewing changes to src/lib/formats/dfi_dsk.c

  • Committer: Package Import Robot
  • Author(s): Jordi Mallach, Emmanuel Kasper, Jordi Mallach
  • Date: 2012-06-05 20:02:23 UTC
  • mfrom: (0.3.1) (0.1.4)
  • Revision ID: package-import@ubuntu.com-20120605200223-gnlpogjrg6oqe9md
Tags: 0.146-1
[ Emmanuel Kasper ]
* New upstream release
* Drop patch to fix man pages section and patches to link with flac 
  and jpeg system lib: all this has been pushed upstream by Cesare Falco
* Add DM-Upload-Allowed: yes field.

[ Jordi Mallach ]
* Create a "gnu" TARGETOS stanza that defines NO_AFFINITY_NP.
* Stop setting TARGETOS to "unix" in d/rules. It should be autodetected,
  and set to the appropriate value.
* mame_manpage_section.patch: Change mame's manpage section to 6 (games),
  in the TH declaration.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
 
32
32
****************************************************************************/
33
33
 
 
34
/* DONE:
 
35
 * Support auto-identification heuristics for determining disk image speed,
 
36
   capture clock rate, and number of multireads per image.
 
37
 * TODO:
 
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.
 
42
 */
 
43
 
34
44
#include "emu.h"
35
45
#include "dfi_dsk.h"
36
46
#include <zlib.h>
 
47
#define NUMBER_OF_MULTIREADS 3
 
48
// threshholds for brickwall windowing
 
49
//define MIN_CLOCKS 65
 
50
// number_please apple2 wants 40 min
 
51
#define MIN_CLOCKS 60
 
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
37
63
 
38
64
dfi_format::dfi_format() : floppy_image_format_t()
39
65
{
46
72
 
47
73
const char *dfi_format::description() const
48
74
{
49
 
        return "DiskFerret flux dump format";
 
75
        return "DiscFerret flux dump format";
50
76
}
51
77
 
52
78
const char *dfi_format::extensions() const
63
89
{
64
90
        char sign[4];
65
91
        io_generic_read(io, sign, 0, 4);
 
92
        if (memcmp(sign, "DFER", 4)==0)
 
93
                fatalerror("Old type Discferret image detected; the mess Discferret decoder will not handle this properly, bailing out!\n");
66
94
        return memcmp(sign, "DFE2", 4) ? 0 : 100;
67
95
}
68
96
 
71
99
        int size = io_generic_size(io);
72
100
        int pos = 4;
73
101
        UINT8 *data = 0;
74
 
        int data_size = 0;
75
 
 
 
102
        int data_size = 0; // size of currently allocated array for a track
 
103
        int onerev_time = 0; // time for one revolution, used to guess clock and rpm for DFE2 files
 
104
        unsigned long clock_rate = 100000000; // sample clock rate in megahertz
 
105
        int rpm=360; // drive rpm
76
106
        while(pos < size) {
77
107
                UINT8 h[10];
78
108
                io_generic_read(io, h, pos, 10);
81
111
                // Ignore sector
82
112
                UINT32 tsize = (h[6] << 24) | (h[7] << 16) | (h[8] << 8) | h[9];
83
113
 
 
114
                // if the position-so-far-in-file plus 10 (for the header) plus track size
 
115
                // is larger than the size of the file, free buffers and bail out
84
116
                if(pos+tsize+10 > size) {
85
117
                        if(data)
86
118
                                global_free(data);
87
119
                        return false;
88
120
                }
89
121
 
 
122
                // reallocate the data array if it gets too small
90
123
                if(tsize > data_size) {
91
124
                        if(data)
92
125
                                global_free(data);
94
127
                        data = global_alloc_array(UINT8, data_size);
95
128
                }
96
129
 
97
 
                io_generic_read(io, data, pos+16, tsize);
98
 
                pos += tsize+10;
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
100
133
 
101
 
                int index_time = 0;
102
 
                int total_time = 0;
 
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;
107
 
                        else {
108
 
                                total_time += v & 0x7f;
109
 
                                if((v & 0x80) && !index_time)
110
 
                                        index_time = total_time;
111
 
                        }
 
143
                        else if(v & 0x80) {
 
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;
112
153
                }
113
154
 
 
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;
 
157
 
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;
 
180
                        } else
 
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);
 
183
                }
 
184
 
 
185
        rpm += 0;   // HACK: prevent GCC 4.6+ from warning "variable set but unused"
116
186
 
117
187
                if(!index_time)
118
188
                        index_time = total_time;
120
190
                image->set_track_size(track, head, tsize);
121
191
 
122
192
                int cur_time = 0;
 
193
                int prev_time = 0;
 
194
#ifdef TRACK_HISTOGRAM
 
195
                // histogram
 
196
                int time_buckets[4096];
 
197
                for (int i = 0; i < 4096; i++)
 
198
                        time_buckets[i] = 0;
 
199
#endif
 
200
                index_count = 0;
 
201
                //index_polarity = 0;
123
202
                UINT32 mg = floppy_image::MG_A;
124
203
                UINT32 *buf = image->get_buffer(track, head);
125
204
                int tpos = 0;
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;
131
 
                        else {
132
 
                                cur_time += v & 0x7f;
133
 
                                if(v & 0x80)
134
 
                                        break;
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);
137
 
                        }
138
 
                }
 
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;
 
215
                                }
 
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]++;
 
221
#endif
 
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;
 
231
                                }
 
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
 
238
#else
 
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);
 
242
#endif
 
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;
 
246
                                        }
 
247
                        }
 
248
                }
 
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");
 
254
                        }
 
255
                }
 
256
                fprintf(stderr,"\n");
 
257
#endif
 
258
                index_count = 0;
139
259
                image->set_track_size(track, head, tpos);
140
260
        }
141
261