Mercurial > sdl-ios-xcode
comparison src/cdrom/bsdi/SDL_syscdrom.c @ 1662:782fd950bd46 SDL-1.3
Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API.
WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid.
The code is now run through a consistent indent format:
indent -i4 -nut -nsc -br -ce
The headers are being converted to automatically generate doxygen documentation.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 28 May 2006 13:04:16 +0000 |
parents | 92947e3a18db |
children | 4da1ee79c9af |
comparison
equal
deleted
inserted
replaced
1661:281d3f4870e5 | 1662:782fd950bd46 |
---|---|
50 | 50 |
51 #define FRAMES_PER_SECOND 75 | 51 #define FRAMES_PER_SECOND 75 |
52 #define FRAMES_PER_MINUTE (FRAMES_PER_SECOND * 60) | 52 #define FRAMES_PER_MINUTE (FRAMES_PER_SECOND * 60) |
53 | 53 |
54 int | 54 int |
55 msf_to_frame(int minute, int second, int frame) | 55 msf_to_frame (int minute, int second, int frame) |
56 { | 56 { |
57 return(minute * FRAMES_PER_MINUTE + second * FRAMES_PER_SECOND + frame); | 57 return (minute * FRAMES_PER_MINUTE + second * FRAMES_PER_SECOND + frame); |
58 } | 58 } |
59 | 59 |
60 void | 60 void |
61 frame_to_msf(int frame, int *minp, int *secp, int *framep) | 61 frame_to_msf (int frame, int *minp, int *secp, int *framep) |
62 { | 62 { |
63 *minp = frame / FRAMES_PER_MINUTE; | 63 *minp = frame / FRAMES_PER_MINUTE; |
64 *secp = (frame % FRAMES_PER_MINUTE) / FRAMES_PER_SECOND; | 64 *secp = (frame % FRAMES_PER_MINUTE) / FRAMES_PER_SECOND; |
65 *framep = frame % FRAMES_PER_SECOND; | 65 *framep = frame % FRAMES_PER_SECOND; |
66 } | 66 } |
67 | 67 |
68 /* The maximum number of CD-ROM drives we'll detect */ | 68 /* The maximum number of CD-ROM drives we'll detect */ |
69 #define MAX_DRIVES 16 | 69 #define MAX_DRIVES 16 |
70 | 70 |
71 /* A list of available CD-ROM drives */ | 71 /* A list of available CD-ROM drives */ |
72 static char *SDL_cdlist[MAX_DRIVES]; | 72 static char *SDL_cdlist[MAX_DRIVES]; |
73 static dev_t SDL_cdmode[MAX_DRIVES]; | 73 static dev_t SDL_cdmode[MAX_DRIVES]; |
74 | 74 |
75 /* The system-dependent CD control functions */ | 75 /* The system-dependent CD control functions */ |
76 static const char *SDL_SYS_CDName(int drive); | 76 static const char *SDL_SYS_CDName (int drive); |
77 static int SDL_SYS_CDOpen(int drive); | 77 static int SDL_SYS_CDOpen (int drive); |
78 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom); | 78 static int SDL_SYS_CDGetTOC (SDL_CD * cdrom); |
79 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position); | 79 static CDstatus SDL_SYS_CDStatus (SDL_CD * cdrom, int *position); |
80 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length); | 80 static int SDL_SYS_CDPlay (SDL_CD * cdrom, int start, int length); |
81 static int SDL_SYS_CDPause(SDL_CD *cdrom); | 81 static int SDL_SYS_CDPause (SDL_CD * cdrom); |
82 static int SDL_SYS_CDResume(SDL_CD *cdrom); | 82 static int SDL_SYS_CDResume (SDL_CD * cdrom); |
83 static int SDL_SYS_CDStop(SDL_CD *cdrom); | 83 static int SDL_SYS_CDStop (SDL_CD * cdrom); |
84 static int SDL_SYS_CDEject(SDL_CD *cdrom); | 84 static int SDL_SYS_CDEject (SDL_CD * cdrom); |
85 static void SDL_SYS_CDClose(SDL_CD *cdrom); | 85 static void SDL_SYS_CDClose (SDL_CD * cdrom); |
86 | 86 |
87 typedef struct scsi_cdb cdb_t; | 87 typedef struct scsi_cdb cdb_t; |
88 | 88 |
89 static int scsi_cmd(int fd, | 89 static int |
90 struct scsi_cdb *cdb, | 90 scsi_cmd (int fd, |
91 int cdblen, | 91 struct scsi_cdb *cdb, |
92 int rw, | 92 int cdblen, |
93 caddr_t data, | 93 int rw, caddr_t data, int datalen, struct scsi_user_cdb *sus) |
94 int datalen, | 94 { |
95 struct scsi_user_cdb *sus) | 95 int scsistatus; |
96 { | 96 unsigned char *cp; |
97 int scsistatus; | 97 struct scsi_user_cdb suc; |
98 unsigned char *cp; | |
99 struct scsi_user_cdb suc; | |
100 | 98 |
101 /* safety checks */ | 99 /* safety checks */ |
102 if (!cdb) return(-1); | 100 if (!cdb) |
103 if (rw != SUC_READ && rw != SUC_WRITE) return(-1); | 101 return (-1); |
104 | 102 if (rw != SUC_READ && rw != SUC_WRITE) |
105 suc.suc_flags = rw; | 103 return (-1); |
106 suc.suc_cdblen = cdblen; | 104 |
107 bcopy(cdb, suc.suc_cdb, cdblen); | 105 suc.suc_flags = rw; |
108 suc.suc_datalen = datalen; | 106 suc.suc_cdblen = cdblen; |
109 suc.suc_data = data; | 107 bcopy (cdb, suc.suc_cdb, cdblen); |
110 suc.suc_timeout = 10; /* 10 secs max for TUR or SENSE */ | 108 suc.suc_datalen = datalen; |
111 if (ioctl(fd, SCSIRAWCDB, &suc) == -1) | 109 suc.suc_data = data; |
112 return(-11); | 110 suc.suc_timeout = 10; /* 10 secs max for TUR or SENSE */ |
113 scsistatus = suc.suc_sus.sus_status; | 111 if (ioctl (fd, SCSIRAWCDB, &suc) == -1) |
114 cp = suc.suc_sus.sus_sense; | 112 return (-11); |
113 scsistatus = suc.suc_sus.sus_status; | |
114 cp = suc.suc_sus.sus_sense; | |
115 | 115 |
116 /* | 116 /* |
117 * If a place to copy the sense data back to has been provided then the | 117 * If a place to copy the sense data back to has been provided then the |
118 * caller is responsible for checking the errors and printing any information | 118 * caller is responsible for checking the errors and printing any information |
119 * out if the status was not successful. | 119 * out if the status was not successful. |
120 */ | 120 */ |
121 if (scsistatus != 0 && !sus) | 121 if (scsistatus != 0 && !sus) { |
122 { | 122 fprintf (stderr, "scsistatus = %x cmd = %x\n", scsistatus, cdb[0]); |
123 fprintf(stderr,"scsistatus = %x cmd = %x\n", | 123 fprintf (stderr, |
124 scsistatus, cdb[0]); | 124 "sense %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n", |
125 fprintf(stderr, "sense %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n", | 125 cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7], |
126 cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], | 126 cp[8], cp[9], cp[10], cp[11], cp[12], cp[13], cp[14], |
127 cp[6], cp[7], cp[8], cp[9], cp[10], cp[11], | 127 cp[15]); |
128 cp[12], cp[13], cp[14], cp[15]); | 128 return (1); |
129 return(1); | 129 } |
130 } | 130 if (sus) |
131 if (sus) | 131 bcopy (&suc, sus, sizeof (struct scsi_user_cdb)); |
132 bcopy(&suc, sus, sizeof (struct scsi_user_cdb)); | 132 if (scsistatus) |
133 if (scsistatus) | 133 return (1); /* Return non-zero for unsuccessful status */ |
134 return(1); /* Return non-zero for unsuccessful status */ | 134 return (0); |
135 return(0); | 135 } |
136 } | |
137 | 136 |
138 /* request vendor brand and model */ | 137 /* request vendor brand and model */ |
139 unsigned char *Inquiry(int fd) | 138 unsigned char * |
140 { | 139 Inquiry (int fd) |
141 static struct scsi_cdb6 cdb = | 140 { |
142 { | 141 static struct scsi_cdb6 cdb = { |
143 0x12, | 142 0x12, |
144 0, 0, 0, | 143 0, 0, 0, |
145 56, | 144 56, |
146 0 | 145 0 |
147 }; | 146 }; |
148 static unsigned char Inqbuffer[56]; | 147 static unsigned char Inqbuffer[56]; |
149 | 148 |
150 if (scsi_cmd(fd, (cdb_t *)&cdb, 6, SUC_READ, Inqbuffer, | 149 if (scsi_cmd (fd, (cdb_t *) & cdb, 6, SUC_READ, Inqbuffer, |
151 sizeof(Inqbuffer), 0)) | 150 sizeof (Inqbuffer), 0)) |
152 return("\377"); | 151 return ("\377"); |
153 return(Inqbuffer); | 152 return (Inqbuffer); |
154 } | 153 } |
155 | 154 |
156 #define ADD_SENSECODE 12 | 155 #define ADD_SENSECODE 12 |
157 #define ADD_SC_QUALIFIER 13 | 156 #define ADD_SC_QUALIFIER 13 |
158 | 157 |
159 int TestForMedium(int fd) | 158 int |
160 { | 159 TestForMedium (int fd) |
161 int sts, asc, ascq; | 160 { |
162 struct scsi_user_cdb sus; | 161 int sts, asc, ascq; |
163 static struct scsi_cdb6 cdb = | 162 struct scsi_user_cdb sus; |
164 { | 163 static struct scsi_cdb6 cdb = { |
165 CMD_TEST_UNIT_READY, /* command */ | 164 CMD_TEST_UNIT_READY, /* command */ |
166 0, /* reserved */ | 165 0, /* reserved */ |
167 0, /* reserved */ | 166 0, /* reserved */ |
168 0, /* reserved */ | 167 0, /* reserved */ |
169 0, /* reserved */ | 168 0, /* reserved */ |
170 0 /* reserved */ | 169 0 /* reserved */ |
171 }; | 170 }; |
172 | 171 |
173 again: sts = scsi_cmd(fd, (cdb_t *)&cdb, 6, SUC_READ, 0, 0, &sus); | 172 again:sts = scsi_cmd (fd, (cdb_t *) & cdb, 6, SUC_READ, 0, 0, &sus); |
174 asc = sus.suc_sus.sus_sense[ADD_SENSECODE]; | 173 asc = sus.suc_sus.sus_sense[ADD_SENSECODE]; |
175 ascq = sus.suc_sus.sus_sense[ADD_SC_QUALIFIER]; | 174 ascq = sus.suc_sus.sus_sense[ADD_SC_QUALIFIER]; |
176 if (asc == 0x3a && ascq == 0x0) /* no medium */ | 175 if (asc == 0x3a && ascq == 0x0) /* no medium */ |
177 return(0); | 176 return (0); |
178 if (asc == 0x28 && ascq == 0x0) /* medium changed */ | 177 if (asc == 0x28 && ascq == 0x0) /* medium changed */ |
179 goto again; | 178 goto again; |
180 if (asc == 0x4 && ascq == 0x1 ) /* coming ready */ | 179 if (asc == 0x4 && ascq == 0x1) { /* coming ready */ |
181 { | 180 sleep (2); |
182 sleep(2); | 181 goto again; |
183 goto again; | 182 } |
184 } | 183 return (1); |
185 return(1); | 184 } |
186 } | |
187 | 185 |
188 /* Check a drive to see if it is a CD-ROM */ | 186 /* Check a drive to see if it is a CD-ROM */ |
189 static int CheckDrive(char *drive, struct stat *stbuf) | 187 static int |
190 { | 188 CheckDrive (char *drive, struct stat *stbuf) |
191 int is_cd = 0, cdfd; | 189 { |
192 char *p; | 190 int is_cd = 0, cdfd; |
193 | 191 char *p; |
194 /* If it doesn't exist, return -1 */ | 192 |
195 if ( stat(drive, stbuf) < 0 ) { | 193 /* If it doesn't exist, return -1 */ |
196 return(-1); | 194 if (stat (drive, stbuf) < 0) { |
197 } | 195 return (-1); |
198 | 196 } |
199 /* If it does exist, verify that it's an available CD-ROM */ | 197 |
200 cdfd = open(drive, (O_RDONLY|O_EXCL|O_NONBLOCK), 0); | 198 /* If it does exist, verify that it's an available CD-ROM */ |
201 if ( cdfd >= 0 ) { | 199 cdfd = open (drive, (O_RDONLY | O_EXCL | O_NONBLOCK), 0); |
202 p = Inquiry(cdfd); | 200 if (cdfd >= 0) { |
203 if (*p == TYPE_ROM) | 201 p = Inquiry (cdfd); |
204 is_cd = 1; | 202 if (*p == TYPE_ROM) |
205 close(cdfd); | 203 is_cd = 1; |
206 } | 204 close (cdfd); |
207 return(is_cd); | 205 } |
206 return (is_cd); | |
208 } | 207 } |
209 | 208 |
210 /* Add a CD-ROM drive to our list of valid drives */ | 209 /* Add a CD-ROM drive to our list of valid drives */ |
211 static void AddDrive(char *drive, struct stat *stbuf) | 210 static void |
212 { | 211 AddDrive (char *drive, struct stat *stbuf) |
213 int i; | 212 { |
214 | 213 int i; |
215 if ( SDL_numcds < MAX_DRIVES ) { | 214 |
216 /* Check to make sure it's not already in our list. | 215 if (SDL_numcds < MAX_DRIVES) { |
217 This can happen when we see a drive via symbolic link. | 216 /* Check to make sure it's not already in our list. |
218 */ | 217 This can happen when we see a drive via symbolic link. |
219 for ( i=0; i<SDL_numcds; ++i ) { | 218 */ |
220 if ( stbuf->st_rdev == SDL_cdmode[i] ) { | 219 for (i = 0; i < SDL_numcds; ++i) { |
220 if (stbuf->st_rdev == SDL_cdmode[i]) { | |
221 #ifdef DEBUG_CDROM | 221 #ifdef DEBUG_CDROM |
222 fprintf(stderr, "Duplicate drive detected: %s == %s\n", drive, SDL_cdlist[i]); | 222 fprintf (stderr, "Duplicate drive detected: %s == %s\n", |
223 drive, SDL_cdlist[i]); | |
223 #endif | 224 #endif |
224 return; | 225 return; |
225 } | 226 } |
226 } | 227 } |
227 | 228 |
228 /* Add this drive to our list */ | 229 /* Add this drive to our list */ |
229 i = SDL_numcds; | 230 i = SDL_numcds; |
230 SDL_cdlist[i] = SDL_strdup(drive); | 231 SDL_cdlist[i] = SDL_strdup (drive); |
231 if ( SDL_cdlist[i] == NULL ) { | 232 if (SDL_cdlist[i] == NULL) { |
232 SDL_OutOfMemory(); | 233 SDL_OutOfMemory (); |
233 return; | 234 return; |
234 } | 235 } |
235 SDL_cdmode[i] = stbuf->st_rdev; | 236 SDL_cdmode[i] = stbuf->st_rdev; |
236 ++SDL_numcds; | 237 ++SDL_numcds; |
237 #ifdef DEBUG_CDROM | 238 #ifdef DEBUG_CDROM |
238 fprintf(stderr, "Added CD-ROM drive: %s\n", drive); | 239 fprintf (stderr, "Added CD-ROM drive: %s\n", drive); |
239 #endif | 240 #endif |
240 } | 241 } |
241 } | 242 } |
242 | 243 |
243 int SDL_SYS_CDInit(void) | 244 int |
244 { | 245 SDL_SYS_CDInit (void) |
245 /* checklist: /dev/rsr?c */ | 246 { |
246 static char *checklist[] = { | 247 /* checklist: /dev/rsr?c */ |
247 "?0 rsr?", NULL | 248 static char *checklist[] = { |
248 }; | 249 "?0 rsr?", NULL |
249 char *SDLcdrom; | 250 }; |
250 int i, j, exists; | 251 char *SDLcdrom; |
251 char drive[32]; | 252 int i, j, exists; |
252 struct stat stbuf; | 253 char drive[32]; |
253 | 254 struct stat stbuf; |
254 /* Fill in our driver capabilities */ | 255 |
255 SDL_CDcaps.Name = SDL_SYS_CDName; | 256 /* Fill in our driver capabilities */ |
256 SDL_CDcaps.Open = SDL_SYS_CDOpen; | 257 SDL_CDcaps.Name = SDL_SYS_CDName; |
257 SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; | 258 SDL_CDcaps.Open = SDL_SYS_CDOpen; |
258 SDL_CDcaps.Status = SDL_SYS_CDStatus; | 259 SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; |
259 SDL_CDcaps.Play = SDL_SYS_CDPlay; | 260 SDL_CDcaps.Status = SDL_SYS_CDStatus; |
260 SDL_CDcaps.Pause = SDL_SYS_CDPause; | 261 SDL_CDcaps.Play = SDL_SYS_CDPlay; |
261 SDL_CDcaps.Resume = SDL_SYS_CDResume; | 262 SDL_CDcaps.Pause = SDL_SYS_CDPause; |
262 SDL_CDcaps.Stop = SDL_SYS_CDStop; | 263 SDL_CDcaps.Resume = SDL_SYS_CDResume; |
263 SDL_CDcaps.Eject = SDL_SYS_CDEject; | 264 SDL_CDcaps.Stop = SDL_SYS_CDStop; |
264 SDL_CDcaps.Close = SDL_SYS_CDClose; | 265 SDL_CDcaps.Eject = SDL_SYS_CDEject; |
265 | 266 SDL_CDcaps.Close = SDL_SYS_CDClose; |
266 /* Look in the environment for our CD-ROM drive list */ | 267 |
267 SDLcdrom = SDL_getenv("SDL_CDROM"); /* ':' separated list of devices */ | 268 /* Look in the environment for our CD-ROM drive list */ |
268 if ( SDLcdrom != NULL ) { | 269 SDLcdrom = SDL_getenv ("SDL_CDROM"); /* ':' separated list of devices */ |
269 char *cdpath, *delim; | 270 if (SDLcdrom != NULL) { |
270 size_t len = SDL_strlen(SDLcdrom)+1; | 271 char *cdpath, *delim; |
271 cdpath = SDL_stack_alloc(char, len); | 272 size_t len = SDL_strlen (SDLcdrom) + 1; |
272 if ( cdpath != NULL ) { | 273 cdpath = SDL_stack_alloc (char, len); |
273 SDL_strlcpy(cdpath, SDLcdrom, len); | 274 if (cdpath != NULL) { |
274 SDLcdrom = cdpath; | 275 SDL_strlcpy (cdpath, SDLcdrom, len); |
275 do { | 276 SDLcdrom = cdpath; |
276 delim = SDL_strchr(SDLcdrom, ':'); | 277 do { |
277 if ( delim ) { | 278 delim = SDL_strchr (SDLcdrom, ':'); |
278 *delim++ = '\0'; | 279 if (delim) { |
279 } | 280 *delim++ = '\0'; |
280 if ( CheckDrive(SDLcdrom, &stbuf) > 0 ) { | 281 } |
281 AddDrive(SDLcdrom, &stbuf); | 282 if (CheckDrive (SDLcdrom, &stbuf) > 0) { |
282 } | 283 AddDrive (SDLcdrom, &stbuf); |
283 if ( delim ) { | 284 } |
284 SDLcdrom = delim; | 285 if (delim) { |
285 } else { | 286 SDLcdrom = delim; |
286 SDLcdrom = NULL; | 287 } else { |
287 } | 288 SDLcdrom = NULL; |
288 } while ( SDLcdrom ); | 289 } |
289 SDL_stack_free(cdpath); | 290 } |
290 } | 291 while (SDLcdrom); |
291 | 292 SDL_stack_free (cdpath); |
292 /* If we found our drives, there's nothing left to do */ | 293 } |
293 if ( SDL_numcds > 0 ) { | 294 |
294 return(0); | 295 /* If we found our drives, there's nothing left to do */ |
295 } | 296 if (SDL_numcds > 0) { |
296 } | 297 return (0); |
297 | 298 } |
298 /* Scan the system for CD-ROM drives */ | 299 } |
299 for ( i=0; checklist[i]; ++i ) { | 300 |
300 if ( checklist[i][0] == '?' ) { | 301 /* Scan the system for CD-ROM drives */ |
301 char *insert; | 302 for (i = 0; checklist[i]; ++i) { |
302 exists = 1; | 303 if (checklist[i][0] == '?') { |
303 for ( j=checklist[i][1]; exists; ++j ) { | 304 char *insert; |
304 SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%sc", &checklist[i][3]); | 305 exists = 1; |
305 insert = SDL_strchr(drive, '?'); | 306 for (j = checklist[i][1]; exists; ++j) { |
306 if ( insert != NULL ) { | 307 SDL_snprintf (drive, SDL_arraysize (drive), "/dev/%sc", |
307 *insert = j; | 308 &checklist[i][3]); |
308 } | 309 insert = SDL_strchr (drive, '?'); |
309 switch (CheckDrive(drive, &stbuf)) { | 310 if (insert != NULL) { |
310 /* Drive exists and is a CD-ROM */ | 311 *insert = j; |
311 case 1: | 312 } |
312 AddDrive(drive, &stbuf); | 313 switch (CheckDrive (drive, &stbuf)) { |
313 break; | 314 /* Drive exists and is a CD-ROM */ |
314 /* Drive exists, but isn't a CD-ROM */ | 315 case 1: |
315 case 0: | 316 AddDrive (drive, &stbuf); |
316 break; | 317 break; |
317 /* Drive doesn't exist */ | 318 /* Drive exists, but isn't a CD-ROM */ |
318 case -1: | 319 case 0: |
319 exists = 0; | 320 break; |
320 break; | 321 /* Drive doesn't exist */ |
321 } | 322 case -1: |
322 } | 323 exists = 0; |
323 } else { | 324 break; |
324 SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%s", checklist[i]); | 325 } |
325 if ( CheckDrive(drive, &stbuf) > 0 ) { | 326 } |
326 AddDrive(drive, &stbuf); | 327 } else { |
327 } | 328 SDL_snprintf (drive, SDL_arraysize (drive), "/dev/%s", |
328 } | 329 checklist[i]); |
329 } | 330 if (CheckDrive (drive, &stbuf) > 0) { |
330 return(0); | 331 AddDrive (drive, &stbuf); |
331 } | 332 } |
332 | 333 } |
333 static const char *SDL_SYS_CDName(int drive) | 334 } |
334 { | 335 return (0); |
335 return(SDL_cdlist[drive]); | 336 } |
336 } | 337 |
337 | 338 static const char * |
338 static int SDL_SYS_CDOpen(int drive) | 339 SDL_SYS_CDName (int drive) |
339 { | 340 { |
340 return(open(SDL_cdlist[drive], O_RDONLY | O_NONBLOCK | O_EXCL, 0)); | 341 return (SDL_cdlist[drive]); |
341 } | 342 } |
342 | 343 |
343 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom) | 344 static int |
344 { | 345 SDL_SYS_CDOpen (int drive) |
345 u_char cdb[10], buf[4], *p, *toc; | 346 { |
346 struct scsi_user_cdb sus; | 347 return (open (SDL_cdlist[drive], O_RDONLY | O_NONBLOCK | O_EXCL, 0)); |
347 int i, sts, first_track, last_track, ntracks, toc_size; | 348 } |
348 | 349 |
349 bzero(cdb, sizeof (cdb)); | 350 static int |
350 cdb[0] = 0x43; /* Read TOC */ | 351 SDL_SYS_CDGetTOC (SDL_CD * cdrom) |
351 cdb[1] = 0x2; /* MSF */ | 352 { |
352 cdb[8] = 4; /* size TOC header */ | 353 u_char cdb[10], buf[4], *p, *toc; |
353 sts = scsi_cmd(cdrom->id, (cdb_t *)cdb, 10, SUC_READ, buf, 4, &sus); | 354 struct scsi_user_cdb sus; |
354 if (sts < 0) | 355 int i, sts, first_track, last_track, ntracks, toc_size; |
355 return(-1); | 356 |
356 first_track = buf[2]; | 357 bzero (cdb, sizeof (cdb)); |
357 last_track = buf[3]; | 358 cdb[0] = 0x43; /* Read TOC */ |
358 ntracks = last_track - first_track + 1; | 359 cdb[1] = 0x2; /* MSF */ |
359 cdrom->numtracks = ntracks; | 360 cdb[8] = 4; /* size TOC header */ |
360 toc_size = 4 + (ntracks + 1) * 8; | 361 sts = scsi_cmd (cdrom->id, (cdb_t *) cdb, 10, SUC_READ, buf, 4, &sus); |
361 toc = (u_char *)SDL_malloc(toc_size); | 362 if (sts < 0) |
362 if (toc == NULL) | 363 return (-1); |
363 return(-1); | 364 first_track = buf[2]; |
364 bzero(cdb, sizeof (cdb)); | 365 last_track = buf[3]; |
365 cdb[0] = 0x43; | 366 ntracks = last_track - first_track + 1; |
366 cdb[1] = 0x2; | 367 cdrom->numtracks = ntracks; |
367 cdb[6] = first_track; | 368 toc_size = 4 + (ntracks + 1) * 8; |
368 cdb[7] = toc_size >> 8; | 369 toc = (u_char *) SDL_malloc (toc_size); |
369 cdb[8] = toc_size & 0xff; | 370 if (toc == NULL) |
370 sts = scsi_cmd(cdrom->id, (cdb_t *)cdb, 10, SUC_READ, toc, toc_size, | 371 return (-1); |
371 &sus); | 372 bzero (cdb, sizeof (cdb)); |
372 if (sts < 0) | 373 cdb[0] = 0x43; |
373 { | 374 cdb[1] = 0x2; |
374 SDL_free(toc); | 375 cdb[6] = first_track; |
375 return(-1); | 376 cdb[7] = toc_size >> 8; |
376 } | 377 cdb[8] = toc_size & 0xff; |
377 | 378 sts = scsi_cmd (cdrom->id, (cdb_t *) cdb, 10, SUC_READ, toc, toc_size, |
378 for (i = 0, p = toc+4; i <= ntracks; i++, p+= 8) | 379 &sus); |
379 { | 380 if (sts < 0) { |
380 if (i == ntracks) | 381 SDL_free (toc); |
381 cdrom->track[i].id = 0xAA; /* Leadout */ | 382 return (-1); |
382 else | 383 } |
383 cdrom->track[i].id = first_track + i; | 384 |
384 if (p[1] & 0x20) | 385 for (i = 0, p = toc + 4; i <= ntracks; i++, p += 8) { |
385 cdrom->track[i].type = SDL_DATA_TRACK; | 386 if (i == ntracks) |
386 else | 387 cdrom->track[i].id = 0xAA; /* Leadout */ |
387 cdrom->track[i].type = SDL_AUDIO_TRACK; | 388 else |
388 cdrom->track[i].offset = msf_to_frame(p[5], p[6], p[7]); | 389 cdrom->track[i].id = first_track + i; |
389 cdrom->track[i].length = 0; | 390 if (p[1] & 0x20) |
390 if (i > 0) | 391 cdrom->track[i].type = SDL_DATA_TRACK; |
391 cdrom->track[i-1].length = cdrom->track[i].offset - | 392 else |
392 cdrom->track[i-1].offset; | 393 cdrom->track[i].type = SDL_AUDIO_TRACK; |
393 } | 394 cdrom->track[i].offset = msf_to_frame (p[5], p[6], p[7]); |
394 SDL_free(toc); | 395 cdrom->track[i].length = 0; |
395 return(0); | 396 if (i > 0) |
396 } | 397 cdrom->track[i - 1].length = cdrom->track[i].offset - |
398 cdrom->track[i - 1].offset; | |
399 } | |
400 SDL_free (toc); | |
401 return (0); | |
402 } | |
397 | 403 |
398 /* Get CD-ROM status */ | 404 /* Get CD-ROM status */ |
399 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) | 405 static CDstatus |
400 { | 406 SDL_SYS_CDStatus (SDL_CD * cdrom, int *position) |
401 CDstatus status; | 407 { |
402 u_char cdb[10], buf[16]; | 408 CDstatus status; |
403 int sts; | 409 u_char cdb[10], buf[16]; |
404 struct scsi_user_cdb sus; | 410 int sts; |
405 | 411 struct scsi_user_cdb sus; |
406 bzero(cdb, sizeof (cdb)); | 412 |
407 cdb[0] = 0x42; /* read subq */ | 413 bzero (cdb, sizeof (cdb)); |
408 cdb[1] = 0x2; /* MSF */ | 414 cdb[0] = 0x42; /* read subq */ |
409 cdb[2] = 0x40; /* q channel */ | 415 cdb[1] = 0x2; /* MSF */ |
410 cdb[3] = 1; /* current pos */ | 416 cdb[2] = 0x40; /* q channel */ |
411 cdb[7] = sizeof (buf) >> 8; | 417 cdb[3] = 1; /* current pos */ |
412 cdb[8] = sizeof (buf) & 0xff; | 418 cdb[7] = sizeof (buf) >> 8; |
413 sts = scsi_cmd(cdrom->id, (cdb_t *)cdb, 10, SUC_READ, buf, sizeof (buf), | 419 cdb[8] = sizeof (buf) & 0xff; |
414 &sus); | 420 sts = scsi_cmd (cdrom->id, (cdb_t *) cdb, 10, SUC_READ, buf, sizeof (buf), |
415 if (sts < 0) | 421 &sus); |
416 return(-1); | 422 if (sts < 0) |
417 if (sts) | 423 return (-1); |
418 { | 424 if (sts) { |
419 if (TestForMedium(cdrom->id) == 0) | 425 if (TestForMedium (cdrom->id) == 0) |
420 status = CD_TRAYEMPTY; | 426 status = CD_TRAYEMPTY; |
421 else | 427 else |
422 status = CD_ERROR; | 428 status = CD_ERROR; |
423 } | 429 } else { |
424 else | 430 switch (buf[1]) { |
425 { | 431 case 0x11: |
426 switch (buf[1]) | 432 status = CD_PLAYING; |
427 { | 433 break; |
428 case 0x11: | 434 case 0x12: |
429 status = CD_PLAYING; | 435 status = CD_PAUSED; |
430 break; | 436 break; |
431 case 0x12: | 437 case 0x13: |
432 status = CD_PAUSED; | 438 case 0x14: |
433 break; | 439 case 0x15: |
434 case 0x13: | 440 status = CD_STOPPED; |
435 case 0x14: | 441 break; |
436 case 0x15: | 442 default: |
437 status = CD_STOPPED; | 443 status = CD_ERROR; |
438 break; | 444 break; |
439 default: | 445 } |
440 status = CD_ERROR; | 446 } |
441 break; | 447 if (position) { |
442 } | 448 if (status == CD_PLAYING || (status == CD_PAUSED)) |
443 } | 449 *position = msf_to_frame (buf[9], buf[10], buf[11]); |
444 if (position) | 450 else |
445 { | 451 *position = 0; |
446 if ( status == CD_PLAYING || (status == CD_PAUSED) ) | 452 } |
447 *position = msf_to_frame(buf[9], buf[10], buf[11]); | 453 return (status); |
448 else | 454 } |
449 *position = 0; | |
450 } | |
451 return(status); | |
452 } | |
453 | 455 |
454 /* Start play */ | 456 /* Start play */ |
455 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) | 457 static int |
456 { | 458 SDL_SYS_CDPlay (SDL_CD * cdrom, int start, int length) |
457 u_char cdb[10]; | 459 { |
458 int sts, minute, second, frame, eminute, esecond, eframe; | 460 u_char cdb[10]; |
459 struct scsi_user_cdb sus; | 461 int sts, minute, second, frame, eminute, esecond, eframe; |
460 | 462 struct scsi_user_cdb sus; |
461 bzero(cdb, sizeof(cdb)); | 463 |
462 cdb[0] = 0x47; /* Play */ | 464 bzero (cdb, sizeof (cdb)); |
463 frame_to_msf(start, &minute, &second, &frame); | 465 cdb[0] = 0x47; /* Play */ |
464 frame_to_msf(start + length, &eminute, &esecond, &eframe); | 466 frame_to_msf (start, &minute, &second, &frame); |
465 cdb[3] = minute; | 467 frame_to_msf (start + length, &eminute, &esecond, &eframe); |
466 cdb[4] = second; | 468 cdb[3] = minute; |
467 cdb[5] = frame; | 469 cdb[4] = second; |
468 cdb[6] = eminute; | 470 cdb[5] = frame; |
469 cdb[7] = esecond; | 471 cdb[6] = eminute; |
470 cdb[8] = eframe; | 472 cdb[7] = esecond; |
471 sts = scsi_cmd(cdrom->id, (cdb_t *)cdb, 10, SUC_READ, 0, 0, &sus); | 473 cdb[8] = eframe; |
472 return(sts); | 474 sts = scsi_cmd (cdrom->id, (cdb_t *) cdb, 10, SUC_READ, 0, 0, &sus); |
473 } | 475 return (sts); |
474 | 476 } |
475 static int | 477 |
476 pauseresume(SDL_CD *cdrom, int flag) | 478 static int |
477 { | 479 pauseresume (SDL_CD * cdrom, int flag) |
478 u_char cdb[10]; | 480 { |
479 struct scsi_user_cdb sus; | 481 u_char cdb[10]; |
480 | 482 struct scsi_user_cdb sus; |
481 bzero(cdb, sizeof (cdb)); | 483 |
482 cdb[0] = 0x4b; | 484 bzero (cdb, sizeof (cdb)); |
483 cdb[8] = flag & 0x1; | 485 cdb[0] = 0x4b; |
484 return(scsi_cmd(cdrom->id, (cdb_t *)cdb, 10, SUC_READ, 0, 0, &sus)); | 486 cdb[8] = flag & 0x1; |
485 } | 487 return (scsi_cmd (cdrom->id, (cdb_t *) cdb, 10, SUC_READ, 0, 0, &sus)); |
488 } | |
486 | 489 |
487 /* Pause play */ | 490 /* Pause play */ |
488 static int SDL_SYS_CDPause(SDL_CD *cdrom) | 491 static int |
489 { | 492 SDL_SYS_CDPause (SDL_CD * cdrom) |
490 return(pauseresume(cdrom, 0)); | 493 { |
494 return (pauseresume (cdrom, 0)); | |
491 } | 495 } |
492 | 496 |
493 /* Resume play */ | 497 /* Resume play */ |
494 static int SDL_SYS_CDResume(SDL_CD *cdrom) | 498 static int |
495 { | 499 SDL_SYS_CDResume (SDL_CD * cdrom) |
496 return(pauseresume(cdrom, 1)); | 500 { |
501 return (pauseresume (cdrom, 1)); | |
497 } | 502 } |
498 | 503 |
499 /* Stop play */ | 504 /* Stop play */ |
500 static int SDL_SYS_CDStop(SDL_CD *cdrom) | 505 static int |
501 { | 506 SDL_SYS_CDStop (SDL_CD * cdrom) |
502 u_char cdb[6]; | 507 { |
503 struct scsi_user_cdb sus; | 508 u_char cdb[6]; |
504 | 509 struct scsi_user_cdb sus; |
505 bzero(cdb, sizeof (cdb)); | 510 |
506 cdb[0] = 0x1b; /* stop */ | 511 bzero (cdb, sizeof (cdb)); |
507 cdb[1] = 1; /* immediate */ | 512 cdb[0] = 0x1b; /* stop */ |
508 return(scsi_cmd(cdrom->id, (cdb_t *)cdb, 6, SUC_READ, 0, 0, &sus)); | 513 cdb[1] = 1; /* immediate */ |
514 return (scsi_cmd (cdrom->id, (cdb_t *) cdb, 6, SUC_READ, 0, 0, &sus)); | |
509 } | 515 } |
510 | 516 |
511 /* Eject the CD-ROM */ | 517 /* Eject the CD-ROM */ |
512 static int SDL_SYS_CDEject(SDL_CD *cdrom) | 518 static int |
513 { | 519 SDL_SYS_CDEject (SDL_CD * cdrom) |
514 u_char cdb[6]; | 520 { |
515 struct scsi_user_cdb sus; | 521 u_char cdb[6]; |
516 | 522 struct scsi_user_cdb sus; |
517 bzero(cdb, sizeof (cdb)); | 523 |
518 cdb[0] = 0x1b; /* stop */ | 524 bzero (cdb, sizeof (cdb)); |
519 cdb[1] = 1; /* immediate */ | 525 cdb[0] = 0x1b; /* stop */ |
520 cdb[4] = 2; /* eject */ | 526 cdb[1] = 1; /* immediate */ |
521 return(scsi_cmd(cdrom->id, (cdb_t *)cdb, 6, SUC_READ, 0, 0, &sus)); | 527 cdb[4] = 2; /* eject */ |
528 return (scsi_cmd (cdrom->id, (cdb_t *) cdb, 6, SUC_READ, 0, 0, &sus)); | |
522 } | 529 } |
523 | 530 |
524 /* Close the CD-ROM handle */ | 531 /* Close the CD-ROM handle */ |
525 static void SDL_SYS_CDClose(SDL_CD *cdrom) | 532 static void |
526 { | 533 SDL_SYS_CDClose (SDL_CD * cdrom) |
527 close(cdrom->id); | 534 { |
528 } | 535 close (cdrom->id); |
529 | 536 } |
530 void SDL_SYS_CDQuit(void) | 537 |
531 { | 538 void |
532 int i; | 539 SDL_SYS_CDQuit (void) |
533 | 540 { |
534 if ( SDL_numcds > 0 ) { | 541 int i; |
535 for ( i=0; i<SDL_numcds; ++i ) { | 542 |
536 SDL_free(SDL_cdlist[i]); | 543 if (SDL_numcds > 0) { |
537 } | 544 for (i = 0; i < SDL_numcds; ++i) { |
538 } | 545 SDL_free (SDL_cdlist[i]); |
539 SDL_numcds = 0; | 546 } |
547 } | |
548 SDL_numcds = 0; | |
540 } | 549 } |
541 | 550 |
542 #endif /* SDL_CDROM_BSDI */ | 551 #endif /* SDL_CDROM_BSDI */ |
552 /* vi: set ts=4 sw=4 expandtab: */ |