Mercurial > sdl-ios-xcode
comparison src/cdrom/mint/SDL_syscdrom.c @ 727:cb1208fcd946
Update MiNT CD-ROM driver
author | Patrice Mandin <patmandin@gmail.com> |
---|---|
date | Wed, 01 Oct 2003 07:52:33 +0000 |
parents | 6b3dfe0198bb |
children | b8d311d90021 |
comparison
equal
deleted
inserted
replaced
726:5429a06aa816 | 727:cb1208fcd946 |
---|---|
18 | 18 |
19 Sam Lantinga | 19 Sam Lantinga |
20 slouken@libsdl.org | 20 slouken@libsdl.org |
21 */ | 21 */ |
22 | 22 |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* | 23 /* |
29 Atari MetaDOS CD-ROM functions | 24 Atari MetaDOS CD-ROM functions |
30 | 25 |
31 Patrice Mandin | 26 Patrice Mandin |
32 */ | 27 */ |
41 | 36 |
42 #include "SDL_error.h" | 37 #include "SDL_error.h" |
43 #include "SDL_cdrom.h" | 38 #include "SDL_cdrom.h" |
44 #include "SDL_syscdrom.h" | 39 #include "SDL_syscdrom.h" |
45 | 40 |
41 /* Some ioctl() errno values which occur when the tray is empty */ | |
42 #ifndef ENOMEDIUM | |
43 #define ENOMEDIUM ENOENT | |
44 #endif | |
45 #define ERRNO_TRAYEMPTY(errno) \ | |
46 ((errno == EIO) || (errno == ENOENT) || \ | |
47 (errno == EINVAL) || (errno == ENOMEDIUM)) | |
46 | 48 |
47 /* The maximum number of CD-ROM drives we'll detect */ | 49 /* The maximum number of CD-ROM drives we'll detect */ |
48 #define MAX_DRIVES 32 | 50 #define MAX_DRIVES 32 |
49 | 51 |
50 /* Type of CD-ROM drive */ | |
51 #define DRIVE_TYPE_NOCD -1 | |
52 #define DRIVE_TYPE_STANDARD 0 | |
53 #define DRIVE_TYPE_CDAR 1 | |
54 | |
55 typedef struct { | 52 typedef struct { |
56 int type; /* Standard, or old CDAR-type CD drive ? */ | |
57 unsigned char device[3]; /* Physical device letter + ':' + '\0' */ | 53 unsigned char device[3]; /* Physical device letter + ':' + '\0' */ |
58 metaopen_t metaopen; /* Infos on opened drive */ | 54 metaopen_t metaopen; /* Infos on opened drive */ |
59 } metados_drive_t; | 55 } metados_drive_t; |
60 | 56 |
61 static metados_drive_t metados_drives[MAX_DRIVES]; | 57 static metados_drive_t metados_drives[MAX_DRIVES]; |
63 /* The system-dependent CD control functions */ | 59 /* The system-dependent CD control functions */ |
64 static const char *SDL_SYS_CDName(int drive); | 60 static const char *SDL_SYS_CDName(int drive); |
65 static int SDL_SYS_CDOpen(int drive); | 61 static int SDL_SYS_CDOpen(int drive); |
66 static void SDL_SYS_CDClose(SDL_CD *cdrom); | 62 static void SDL_SYS_CDClose(SDL_CD *cdrom); |
67 static int SDL_SYS_CDioctl(int id, int command, void *arg); | 63 static int SDL_SYS_CDioctl(int id, int command, void *arg); |
68 | |
69 /* Commands using ioctl() */ | |
70 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom); | 64 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom); |
71 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position); | 65 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position); |
72 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length); | 66 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length); |
73 static int SDL_SYS_CDPause(SDL_CD *cdrom); | 67 static int SDL_SYS_CDPause(SDL_CD *cdrom); |
74 static int SDL_SYS_CDResume(SDL_CD *cdrom); | 68 static int SDL_SYS_CDResume(SDL_CD *cdrom); |
75 static int SDL_SYS_CDStop(SDL_CD *cdrom); | 69 static int SDL_SYS_CDStop(SDL_CD *cdrom); |
76 static int SDL_SYS_CDEject(SDL_CD *cdrom); | 70 static int SDL_SYS_CDEject(SDL_CD *cdrom); |
77 | 71 |
78 /* Commands using Meta*() CDAR functions */ | |
79 static int SDL_SYS_CD_BcdToBinary(int value); | |
80 static int SDL_SYS_CDGetTOC_CDAR(SDL_CD *cdrom); | |
81 static CDstatus SDL_SYS_CDStatus_CDAR(SDL_CD *cdrom, int *position); | |
82 | |
83 int SDL_SYS_CDInit(void) | 72 int SDL_SYS_CDInit(void) |
84 { | 73 { |
85 metainit_t metainit={0,0,0,0}; | 74 metainit_t metainit={0,0,0,0}; |
86 metaopen_t metaopen; | 75 metaopen_t metaopen; |
87 int i, handle; | 76 int i, handle; |
77 struct cdrom_subchnl info; | |
88 | 78 |
89 Metainit(&metainit); | 79 Metainit(&metainit); |
90 if (metainit.version == NULL) { | 80 if (metainit.version == NULL) { |
91 #ifdef DEBUG_CDROM | 81 #ifdef DEBUG_CDROM |
92 fprintf(stderr, "MetaDOS not installed\n"); | 82 fprintf(stderr, "MetaDOS not installed\n"); |
102 } | 92 } |
103 | 93 |
104 SDL_numcds = 0; | 94 SDL_numcds = 0; |
105 | 95 |
106 for (i='A'; i<='Z'; i++) { | 96 for (i='A'; i<='Z'; i++) { |
107 metados_drives[SDL_numcds].type = DRIVE_TYPE_NOCD; | |
108 metados_drives[SDL_numcds].device[0] = 0; | 97 metados_drives[SDL_numcds].device[0] = 0; |
109 metados_drives[SDL_numcds].device[1] = ':'; | 98 metados_drives[SDL_numcds].device[1] = ':'; |
110 metados_drives[SDL_numcds].device[2] = 0; | 99 metados_drives[SDL_numcds].device[2] = 0; |
111 | 100 |
112 if (metainit.drives_map & (1<<(i-'A'))) { | 101 if (metainit.drives_map & (1<<(i-'A'))) { |
113 handle = Metaopen(i, &metaopen); | 102 handle = Metaopen(i, &metaopen); |
114 if (handle == 0) { | 103 if (handle == 0) { |
115 | 104 |
116 if ( (metaopen.name[0]=='C') && (metaopen.name[1]=='D') && | 105 info.cdsc_format = CDROM_MSF; |
117 (metaopen.name[2]=='A') && (metaopen.name[3]=='R')) { | 106 if ( (Metaioctl(i, METADOS_IOCTL_MAGIC, CDROMSUBCHNL, &info) == 0) || ERRNO_TRAYEMPTY(errno) ) { |
118 /* Drive compatible with CDAR */ | |
119 metados_drives[SDL_numcds].type = DRIVE_TYPE_CDAR; | |
120 metados_drives[SDL_numcds].device[0] = i; | 107 metados_drives[SDL_numcds].device[0] = i; |
121 ++SDL_numcds; | 108 ++SDL_numcds; |
122 } else { | |
123 /* Check for a CD-ROM device */ | |
124 if ((Metastatus(i, NULL) & 0x7fff) >= 0) { | |
125 /* Drive compatible with new ioctl functions */ | |
126 metados_drives[SDL_numcds].type = DRIVE_TYPE_STANDARD; | |
127 metados_drives[SDL_numcds].device[0] = i; | |
128 ++SDL_numcds; | |
129 } | |
130 } | 109 } |
131 | 110 |
132 Metaclose(i); | 111 Metaclose(i); |
133 } | 112 } |
134 } | 113 } |
186 SDL_SetError("ioctl() error: %s", strerror(errno)); | 165 SDL_SetError("ioctl() error: %s", strerror(errno)); |
187 } | 166 } |
188 return(retval); | 167 return(retval); |
189 } | 168 } |
190 | 169 |
191 static int SDL_SYS_CD_BcdToBinary(int value) | |
192 { | |
193 int tmp; | |
194 | |
195 tmp = (value>>4) & 0xf; | |
196 return (tmp*10)+(value & 0xf); | |
197 } | |
198 | |
199 static int SDL_SYS_CDGetTOC_CDAR(SDL_CD *cdrom) | |
200 { | |
201 int errorcode, i, minute, second, frame; | |
202 metatocentry_t *toc_entries; | |
203 metadiscinfo_t disc_info; | |
204 | |
205 /* First, read disc info */ | |
206 errorcode = Metadiscinfo(metados_drives[cdrom->id].device[0], &disc_info); | |
207 if (errorcode<0) { | |
208 #ifdef DEBUG_CDROM | |
209 fprintf(stderr, "Can not read disc info\n"); | |
210 #endif | |
211 return -1; | |
212 } | |
213 | |
214 cdrom->numtracks = disc_info.last - disc_info.first + 1; | |
215 | |
216 /* Then read toc entries for tracks */ | |
217 toc_entries = (metatocentry_t *)malloc(100*sizeof(metatocentry_t)); | |
218 if (toc_entries == NULL) { | |
219 #ifdef DEBUG_CDROM | |
220 fprintf(stderr, "Can not allocate memory for TOC entries\n"); | |
221 #endif | |
222 return -1; | |
223 } | |
224 | |
225 errorcode = Metagettoc(metados_drives[cdrom->id].device[0], 0, toc_entries); | |
226 if (errorcode<0) { | |
227 #ifdef DEBUG_CDROM | |
228 fprintf(stderr, "Can not read TOC\n"); | |
229 #endif | |
230 free(toc_entries); | |
231 return -1; | |
232 } | |
233 | |
234 i=0; | |
235 for (;;) { | |
236 if ((toc_entries[i].track==0) && (toc_entries[i].minute==0) && | |
237 (toc_entries[i].second==0) && (toc_entries[i].frame==0) | |
238 ) { | |
239 break; | |
240 } | |
241 | |
242 if (toc_entries[i].track == CDROM_LEADOUT_CDAR) { | |
243 cdrom->track[i].id = CDROM_LEADOUT; | |
244 } else { | |
245 cdrom->track[i].id = toc_entries[i].track; | |
246 } | |
247 if (disc_info.disctype == 0) { | |
248 cdrom->track[i].type = SDL_AUDIO_TRACK; | |
249 } else { | |
250 cdrom->track[i].type = SDL_DATA_TRACK; | |
251 } | |
252 minute = SDL_SYS_CD_BcdToBinary(toc_entries[i].minute); | |
253 second = SDL_SYS_CD_BcdToBinary(toc_entries[i].second); | |
254 frame = SDL_SYS_CD_BcdToBinary(toc_entries[i].frame); | |
255 cdrom->track[i].offset = MSF_TO_FRAMES(minute, second, frame); | |
256 | |
257 if ( i > 0 ) { | |
258 cdrom->track[i-1].length = cdrom->track[i].offset - cdrom->track[i-1].offset; | |
259 } | |
260 | |
261 ++i; | |
262 } | |
263 | |
264 free(toc_entries); | |
265 return 0; | |
266 } | |
267 | |
268 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom) | 170 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom) |
269 { | 171 { |
270 int i,okay; | 172 int i,okay; |
271 struct cdrom_tochdr toc; | 173 struct cdrom_tochdr toc; |
272 struct cdrom_tocentry entry; | 174 struct cdrom_tocentry entry; |
273 | |
274 /* CDAR compatible drive ? */ | |
275 if (metados_drives[cdrom->id].type == DRIVE_TYPE_CDAR) { | |
276 return SDL_SYS_CDGetTOC_CDAR(cdrom); | |
277 } | |
278 | 175 |
279 /* Use standard ioctl() */ | 176 /* Use standard ioctl() */ |
280 if (SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCHDR, &toc)<0) { | 177 if (SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCHDR, &toc)<0) { |
281 return -1; | 178 return -1; |
282 } | 179 } |
318 | 215 |
319 return(okay ? 0 : -1); | 216 return(okay ? 0 : -1); |
320 } | 217 } |
321 | 218 |
322 /* Get CD-ROM status */ | 219 /* Get CD-ROM status */ |
323 static CDstatus SDL_SYS_CDStatus_CDAR(SDL_CD *cdrom, int *position) | |
324 { | |
325 return CD_ERROR; | |
326 } | |
327 | |
328 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) | 220 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) |
329 { | 221 { |
330 CDstatus status; | 222 CDstatus status; |
331 struct cdrom_tochdr toc; | 223 struct cdrom_tochdr toc; |
332 struct cdrom_subchnl info; | 224 struct cdrom_subchnl info; |
333 | 225 |
334 /* CDAR compatible drive ? */ | |
335 if (metados_drives[cdrom->id].type == DRIVE_TYPE_CDAR) { | |
336 return SDL_SYS_CDStatus_CDAR(cdrom, position); | |
337 } | |
338 | |
339 /* Standard ioctl */ | |
340 info.cdsc_format = CDROM_MSF; | 226 info.cdsc_format = CDROM_MSF; |
341 if ( SDL_SYS_CDioctl(cdrom->id, CDROMSUBCHNL, &info) < 0 ) { | 227 if ( SDL_SYS_CDioctl(cdrom->id, CDROMSUBCHNL, &info) < 0 ) { |
342 status = CD_TRAYEMPTY; | 228 if ( ERRNO_TRAYEMPTY(errno) ) { |
229 status = CD_TRAYEMPTY; | |
230 } else { | |
231 status = CD_ERROR; | |
232 } | |
343 } else { | 233 } else { |
344 switch (info.cdsc_audiostatus) { | 234 switch (info.cdsc_audiostatus) { |
345 case CDROM_AUDIO_INVALID: | 235 case CDROM_AUDIO_INVALID: |
346 case CDROM_AUDIO_NO_STATUS: | 236 case CDROM_AUDIO_NO_STATUS: |
347 /* Try to determine if there's a CD available */ | 237 /* Try to determine if there's a CD available */ |
382 } | 272 } |
383 return(status); | 273 return(status); |
384 } | 274 } |
385 | 275 |
386 /* Start play */ | 276 /* Start play */ |
387 static int SDL_SYS_CDPlay_CDAR(SDL_CD *cdrom, int start, int length) | 277 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) |
388 { | 278 { |
389 struct cdrom_msf playtime; | 279 struct cdrom_msf playtime; |
390 | |
391 FRAMES_TO_MSF(start, | |
392 &playtime.cdmsf_min0, &playtime.cdmsf_sec0, &playtime.cdmsf_frame0); | |
393 FRAMES_TO_MSF(start+length, | |
394 &playtime.cdmsf_min1, &playtime.cdmsf_sec1, &playtime.cdmsf_frame1); | |
395 | |
396 return Metasetsongtime(metados_drives[cdrom->id].device[0], 0, | |
397 (playtime.cdmsf_min0<<16)|(playtime.cdmsf_sec0<<8)|(playtime.cdmsf_frame0), | |
398 (playtime.cdmsf_min1<<16)|(playtime.cdmsf_sec1<<8)|(playtime.cdmsf_frame1) | |
399 ); | |
400 } | |
401 | |
402 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) | |
403 { | |
404 struct cdrom_msf playtime; | |
405 | |
406 /* CDAR compatible drive ? */ | |
407 if (metados_drives[cdrom->id].type == DRIVE_TYPE_CDAR) { | |
408 return SDL_SYS_CDPlay_CDAR(cdrom, start, length); | |
409 } | |
410 | 280 |
411 FRAMES_TO_MSF(start, | 281 FRAMES_TO_MSF(start, |
412 &playtime.cdmsf_min0, &playtime.cdmsf_sec0, &playtime.cdmsf_frame0); | 282 &playtime.cdmsf_min0, &playtime.cdmsf_sec0, &playtime.cdmsf_frame0); |
413 FRAMES_TO_MSF(start+length, | 283 FRAMES_TO_MSF(start+length, |
414 &playtime.cdmsf_min1, &playtime.cdmsf_sec1, &playtime.cdmsf_frame1); | 284 &playtime.cdmsf_min1, &playtime.cdmsf_sec1, &playtime.cdmsf_frame1); |
415 #ifdef DEBUG_CDROM | 285 #ifdef DEBUG_CDROM |
416 fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n", | 286 fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n", |
417 playtime.cdmsf_min0, playtime.cdmsf_sec0, playtime.cdmsf_frame0, | 287 playtime.cdmsf_min0, playtime.cdmsf_sec0, playtime.cdmsf_frame0, |
418 playtime.cdmsf_min1, playtime.cdmsf_sec1, playtime.cdmsf_frame1); | 288 playtime.cdmsf_min1, playtime.cdmsf_sec1, playtime.cdmsf_frame1); |
419 #endif | 289 #endif |
420 return(SDL_SYS_CDioctl(cdrom->id, CDROMPLAYMSF, &playtime)); | 290 |
291 return SDL_SYS_CDioctl(cdrom->id, CDROMPLAYMSF, &playtime); | |
421 } | 292 } |
422 | 293 |
423 /* Pause play */ | 294 /* Pause play */ |
424 static int SDL_SYS_CDPause(SDL_CD *cdrom) | 295 static int SDL_SYS_CDPause(SDL_CD *cdrom) |
425 { | 296 { |
426 /* CDAR compatible drive ? */ | 297 return SDL_SYS_CDioctl(cdrom->id, CDROMPAUSE, 0); |
427 if (metados_drives[cdrom->id].type == DRIVE_TYPE_CDAR) { | |
428 return -1; | |
429 } | |
430 | |
431 return(SDL_SYS_CDioctl(cdrom->id, CDROMPAUSE, 0)); | |
432 } | 298 } |
433 | 299 |
434 /* Resume play */ | 300 /* Resume play */ |
435 static int SDL_SYS_CDResume(SDL_CD *cdrom) | 301 static int SDL_SYS_CDResume(SDL_CD *cdrom) |
436 { | 302 { |
437 /* CDAR compatible drive ? */ | 303 return SDL_SYS_CDioctl(cdrom->id, CDROMRESUME, 0); |
438 if (metados_drives[cdrom->id].type == DRIVE_TYPE_CDAR) { | |
439 return -1; | |
440 } | |
441 | |
442 return(SDL_SYS_CDioctl(cdrom->id, CDROMRESUME, 0)); | |
443 } | 304 } |
444 | 305 |
445 /* Stop play */ | 306 /* Stop play */ |
446 static int SDL_SYS_CDStop(SDL_CD *cdrom) | 307 static int SDL_SYS_CDStop(SDL_CD *cdrom) |
447 { | 308 { |
448 /* CDAR compatible drive ? */ | 309 return SDL_SYS_CDioctl(cdrom->id, CDROMSTOP, 0); |
449 if (metados_drives[cdrom->id].type == DRIVE_TYPE_CDAR) { | |
450 return Metastopaudio(metados_drives[cdrom->id].device[0]); | |
451 } | |
452 | |
453 return(SDL_SYS_CDioctl(cdrom->id, CDROMSTOP, 0)); | |
454 } | 310 } |
455 | 311 |
456 /* Eject the CD-ROM */ | 312 /* Eject the CD-ROM */ |
457 static int SDL_SYS_CDEject(SDL_CD *cdrom) | 313 static int SDL_SYS_CDEject(SDL_CD *cdrom) |
458 { | 314 { |
459 /* CDAR compatible drive ? */ | 315 return SDL_SYS_CDioctl(cdrom->id, CDROMEJECT, 0); |
460 if (metados_drives[cdrom->id].type == DRIVE_TYPE_CDAR) { | 316 } |
461 return -1; | |
462 } | |
463 | |
464 return(SDL_SYS_CDioctl(cdrom->id, CDROMEJECT, 0)); | |
465 } |