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 }