1 #include "ibm.h"
2
3 #include "config.h"
4 #include "disc.h"
5 #include "disc_fdi.h"
6 #include "disc_img.h"
7 #include "fdc.h"
8 #include "fdd.h"
9 #include "timer.h"
10
11 int disc_drivesel = 0;
12 int disc_poll_time = 16;
13
14 int disc_track[2];
15 int writeprot[2], fwriteprot[2];
16
17 DRIVE drives[2];
18 int drive_type[2];
19
20 int curdrive = 0;
21
22 //char discfns[2][260] = {"", ""};
23 int defaultwriteprot = 0;
24
25 int fdc_time;
26 int disc_time;
27
28 int fdc_ready;
29
30 int drive_empty[2] = {1, 1};
31 int disc_changed[2];
32
33 int motorspin;
34 int motoron;
35
36 int fdc_indexcount = 52;
37
38 /*void (*fdc_callback)();
39 void (*fdc_data)(uint8_t dat);
40 void (*fdc_spindown)();
41 void (*fdc_finishread)();
42 void (*fdc_notfound)();
43 void (*fdc_datacrcerror)();
44 void (*fdc_headercrcerror)();
45 void (*fdc_writeprotect)();
46 int (*fdc_getdata)(int last);
47 void (*fdc_sectorid)(uint8_t track, uint8_t side, uint8_t sector, uint8_t size, uint8_t crc1, uint8_t crc2);
48 void (*fdc_indexpulse)();*/
49
50 static struct
51 {
52 char *ext;
53 void (*load)(int drive, char *fn);
54 void (*close)(int drive);
55 int size;
56 }
57 loaders[]=
58 {
59 {"IMG", img_load, img_close, -1},
60 {"IMA", img_load, img_close, -1},
61 {"360", img_load, img_close, -1},
62 {"XDF", img_load, img_close, -1},
63 {"FDI", fdi_load, fdi_close, -1},
64 {0,0,0}
65 };
66
67 static int driveloaders[4];
68
disc_load(int drive,char * fn)69 void disc_load(int drive, char *fn)
70 {
71 int c = 0, size;
72 char *p;
73 FILE *f;
74 // pclog("disc_load %i %s\n", drive, fn);
75 // setejecttext(drive, "");
76 if (!fn) return;
77 p = get_extension(fn);
78 if (!p) return;
79 // setejecttext(drive, fn);
80 pclog("Loading :%i %s %s\n", drive, fn,p);
81 f = fopen(fn, "rb");
82 if (!f) return;
83 fseek(f, -1, SEEK_END);
84 size = ftell(f) + 1;
85 fclose(f);
86 while (loaders[c].ext)
87 {
88 if (!strcasecmp(p, loaders[c].ext) && (size == loaders[c].size || loaders[c].size == -1))
89 {
90 pclog("Loading as %s\n", p);
91 driveloaders[drive] = c;
92 loaders[c].load(drive, fn);
93 drive_empty[drive] = 0;
94 disc_changed[drive] = 1;
95 strcpy(discfns[drive], fn);
96 fdd_disc_changed(drive);
97 return;
98 }
99 c++;
100 }
101 pclog("Couldn't load %s %s\n",fn,p);
102 drive_empty[drive] = 1;
103 discfns[drive][0] = 0;
104 }
105
disc_close(int drive)106 void disc_close(int drive)
107 {
108 // pclog("disc_close %i\n", drive);
109 if (loaders[driveloaders[drive]].close) loaders[driveloaders[drive]].close(drive);
110 drive_empty[drive] = 1;
111 discfns[drive][0] = 0;
112 drives[drive].hole = NULL;
113 drives[drive].poll = NULL;
114 drives[drive].seek = NULL;
115 drives[drive].readsector = NULL;
116 drives[drive].writesector = NULL;
117 drives[drive].readaddress = NULL;
118 drives[drive].format = NULL;
119 }
120
121 int disc_notfound=0;
122 static int disc_period = 32;
123
disc_hole(int drive)124 int disc_hole(int drive)
125 {
126 drive ^= fdd_swap;
127
128 if (drive < 2 && drives[drive].hole)
129 {
130 return drives[drive].hole(drive);
131 }
132 else
133 {
134 return 0;
135 }
136 }
137
disc_poll()138 void disc_poll()
139 {
140 disc_poll_time += disc_period * TIMER_USEC;
141
142 if (disc_drivesel < 2 && drives[disc_drivesel].poll)
143 drives[disc_drivesel].poll();
144
145 if (disc_notfound)
146 {
147 disc_notfound--;
148 if (!disc_notfound)
149 fdc_notfound();
150 }
151 }
152
disc_get_bitcell_period(int rate)153 int disc_get_bitcell_period(int rate)
154 {
155 int bit_rate = 0;
156
157 switch (rate)
158 {
159 case 0: /*High density*/
160 bit_rate = 500;
161 break;
162 case 1: /*Double density (360 rpm)*/
163 bit_rate = 300;
164 break;
165 case 2: /*Double density*/
166 bit_rate = 250;
167 break;
168 case 3: /*Extended density*/
169 bit_rate = 1000;
170 break;
171 }
172
173 return 1000000 / bit_rate*2; /*Bitcell period in ns*/
174 }
175
176
disc_set_rate(int drive,int drvden,int rate)177 void disc_set_rate(int drive, int drvden, int rate)
178 {
179 switch (rate)
180 {
181 case 0: /*High density*/
182 disc_period = 16;
183 break;
184 case 1:
185 switch(drvden)
186 {
187 case 0: /*Double density (360 rpm)*/
188 disc_period = 26;
189 break;
190 case 1: /*High density (360 rpm)*/
191 disc_period = 16;
192 break;
193 case 2:
194 disc_period = 4;
195 break;
196 }
197 case 2: /*Double density*/
198 disc_period = 32;
199 break;
200 case 3: /*Extended density*/
201 disc_period = 8;
202 break;
203 }
204 }
205
disc_reset()206 void disc_reset()
207 {
208 int drive;
209
210 curdrive = 0;
211 disc_period = 32;
212 timer_add(disc_poll, &disc_poll_time, &motoron, NULL);
213
214 for (drive = 0; drive < 2; drive++)
215 {
216 if (loaders[driveloaders[drive]].close)
217 loaders[driveloaders[drive]].close(drive);
218 drive_empty[drive] = 1;
219 drives[drive].hole = NULL;
220 drives[drive].poll = NULL;
221 drives[drive].seek = NULL;
222 drives[drive].readsector = NULL;
223 drives[drive].writesector = NULL;
224 drives[drive].readaddress = NULL;
225 drives[drive].format = NULL;
226 }
227 }
228
disc_init()229 void disc_init()
230 {
231 disc_reset();
232 }
233
234 int oldtrack[2] = {0, 0};
disc_seek(int drive,int track)235 void disc_seek(int drive, int track)
236 {
237 // pclog("disc_seek: drive=%i track=%i\n", drive, track);
238 if (drive < 2 && drives[drive].seek)
239 drives[drive].seek(drive, track);
240 // if (track != oldtrack[drive])
241 // fdc_discchange_clear(drive);
242 // ddnoise_seek(track - oldtrack[drive]);
243 // oldtrack[drive] = track;
244 }
245
disc_readsector(int drive,int sector,int track,int side,int density,int sector_size)246 void disc_readsector(int drive, int sector, int track, int side, int density, int sector_size)
247 {
248 drive ^= fdd_swap;
249
250 if (drive < 2 && drives[drive].readsector)
251 drives[drive].readsector(drive, sector, track, side, density, sector_size);
252 else
253 disc_notfound = 1000;
254 }
255
disc_writesector(int drive,int sector,int track,int side,int density,int sector_size)256 void disc_writesector(int drive, int sector, int track, int side, int density, int sector_size)
257 {
258 drive ^= fdd_swap;
259
260 if (drive < 2 && drives[drive].writesector)
261 drives[drive].writesector(drive, sector, track, side, density, sector_size);
262 else
263 disc_notfound = 1000;
264 }
265
disc_readaddress(int drive,int track,int side,int density)266 void disc_readaddress(int drive, int track, int side, int density)
267 {
268 drive ^= fdd_swap;
269
270 if (drive < 2 && drives[drive].readaddress)
271 drives[drive].readaddress(drive, track, side, density);
272 }
273
disc_format(int drive,int track,int side,int density,uint8_t fill)274 void disc_format(int drive, int track, int side, int density, uint8_t fill)
275 {
276 drive ^= fdd_swap;
277
278 if (drive < 2 && drives[drive].format)
279 drives[drive].format(drive, track, side, density, fill);
280 else
281 disc_notfound = 1000;
282 }
283
disc_stop(int drive)284 void disc_stop(int drive)
285 {
286 drive ^= fdd_swap;
287
288 if (drive < 2 && drives[drive].stop)
289 drives[drive].stop(drive);
290 }
291
disc_set_drivesel(int drive)292 void disc_set_drivesel(int drive)
293 {
294 drive ^= fdd_swap;
295
296 disc_drivesel = drive;
297 }
298