146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* 246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL - Simple DirectMedia Layer 346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Copyright (C) 1997-2006 Sam Lantinga 446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner This library is free software; you can redistribute it and/or 646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner modify it under the terms of the GNU Lesser General Public 746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner License as published by the Free Software Foundation; either 846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner version 2.1 of the License, or (at your option) any later version. 946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner This library is distributed in the hope that it will be useful, 1146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner but WITHOUT ANY WARRANTY; without even the implied warranty of 1246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Lesser General Public License for more details. 1446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner You should have received a copy of the GNU Lesser General Public 1646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner License along with this library; if not, write to the Free Software 1746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 1846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Sam Lantinga 2046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner slouken@libsdl.org 2146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner*/ 2246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_config.h" 2346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 2446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef SDL_CDROM_BSDI 2546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 2646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* 2746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * Functions for system-level CD-ROM audio control for BSD/OS 4.x 2846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * This started life out as a copy of the freebsd/SDL_cdrom.c file but was 2946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * heavily modified. Works for standard (MMC) SCSI and ATAPI CDrom drives. 3046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * 3146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * Steven Schultz - sms@to.gd-es.com 3246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner*/ 3346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 3446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <sys/types.h> 3546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <sys/stat.h> 3646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <fcntl.h> 3746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <err.h> 3846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <unistd.h> 3946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <sys/ioctl.h> 4046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include </sys/dev/scsi/scsi.h> 4146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include </sys/dev/scsi/scsi_ioctl.h> 4246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 4346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_cdrom.h" 4446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "../SDL_syscdrom.h" 4546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 4646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* 4746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * The msf_to_frame and frame_to_msf were yanked from libcdrom and inlined 4846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * here so that -lcdrom doesn't have to be dragged in for something so simple. 4946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner*/ 5046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 5146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define FRAMES_PER_SECOND 75 5246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define FRAMES_PER_MINUTE (FRAMES_PER_SECOND * 60) 5346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 5446be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint 5546be48730333120a7b939116cef075e61c12c703David 'Digit' Turnermsf_to_frame(int minute, int second, int frame) 5646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { 5746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(minute * FRAMES_PER_MINUTE + second * FRAMES_PER_SECOND + frame); 5846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 5946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 6046be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid 6146be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerframe_to_msf(int frame, int *minp, int *secp, int *framep) 6246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { 6346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner *minp = frame / FRAMES_PER_MINUTE; 6446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner *secp = (frame % FRAMES_PER_MINUTE) / FRAMES_PER_SECOND; 6546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner *framep = frame % FRAMES_PER_SECOND; 6646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 6746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 6846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* The maximum number of CD-ROM drives we'll detect */ 6946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define MAX_DRIVES 16 7046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 7146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* A list of available CD-ROM drives */ 7246be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic char *SDL_cdlist[MAX_DRIVES]; 7346be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic dev_t SDL_cdmode[MAX_DRIVES]; 7446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 7546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* The system-dependent CD control functions */ 7646be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic const char *SDL_SYS_CDName(int drive); 7746be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDOpen(int drive); 7846be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDGetTOC(SDL_CD *cdrom); 7946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position); 8046be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length); 8146be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDPause(SDL_CD *cdrom); 8246be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDResume(SDL_CD *cdrom); 8346be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDStop(SDL_CD *cdrom); 8446be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDEject(SDL_CD *cdrom); 8546be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void SDL_SYS_CDClose(SDL_CD *cdrom); 8646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 8746be48730333120a7b939116cef075e61c12c703David 'Digit' Turnertypedef struct scsi_cdb cdb_t; 8846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 8946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int scsi_cmd(int fd, 9046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct scsi_cdb *cdb, 9146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int cdblen, 9246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int rw, 9346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner caddr_t data, 9446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int datalen, 9546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct scsi_user_cdb *sus) 9646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { 9746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int scsistatus; 9846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner unsigned char *cp; 9946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct scsi_user_cdb suc; 10046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 10146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* safety checks */ 10246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (!cdb) return(-1); 10346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (rw != SUC_READ && rw != SUC_WRITE) return(-1); 10446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 10546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner suc.suc_flags = rw; 10646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner suc.suc_cdblen = cdblen; 10746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner bcopy(cdb, suc.suc_cdb, cdblen); 10846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner suc.suc_datalen = datalen; 10946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner suc.suc_data = data; 11046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner suc.suc_timeout = 10; /* 10 secs max for TUR or SENSE */ 11146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (ioctl(fd, SCSIRAWCDB, &suc) == -1) 11246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(-11); 11346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner scsistatus = suc.suc_sus.sus_status; 11446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cp = suc.suc_sus.sus_sense; 11546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 11646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* 11746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * If a place to copy the sense data back to has been provided then the 11846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * caller is responsible for checking the errors and printing any information 11946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * out if the status was not successful. 12046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner*/ 12146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (scsistatus != 0 && !sus) 12246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { 12346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr,"scsistatus = %x cmd = %x\n", 12446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner scsistatus, cdb[0]); 12546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr, "sense %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n", 12646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], 12746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cp[6], cp[7], cp[8], cp[9], cp[10], cp[11], 12846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cp[12], cp[13], cp[14], cp[15]); 12946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(1); 13046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 13146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (sus) 13246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner bcopy(&suc, sus, sizeof (struct scsi_user_cdb)); 13346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (scsistatus) 13446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(1); /* Return non-zero for unsuccessful status */ 13546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(0); 13646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 13746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 13846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* request vendor brand and model */ 13946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerunsigned char *Inquiry(int fd) 14046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { 14146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner static struct scsi_cdb6 cdb = 14246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { 14346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 0x12, 14446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 0, 0, 0, 14546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 56, 14646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 0 14746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner }; 14846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner static unsigned char Inqbuffer[56]; 14946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 15046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (scsi_cmd(fd, (cdb_t *)&cdb, 6, SUC_READ, Inqbuffer, 15146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner sizeof(Inqbuffer), 0)) 15246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return("\377"); 15346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(Inqbuffer); 15446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 15546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 15646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define ADD_SENSECODE 12 15746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define ADD_SC_QUALIFIER 13 15846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 15946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint TestForMedium(int fd) 16046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { 16146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int sts, asc, ascq; 16246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct scsi_user_cdb sus; 16346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner static struct scsi_cdb6 cdb = 16446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { 16546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner CMD_TEST_UNIT_READY, /* command */ 16646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 0, /* reserved */ 16746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 0, /* reserved */ 16846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 0, /* reserved */ 16946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 0, /* reserved */ 17046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 0 /* reserved */ 17146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner }; 17246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 17346be48730333120a7b939116cef075e61c12c703David 'Digit' Turneragain: sts = scsi_cmd(fd, (cdb_t *)&cdb, 6, SUC_READ, 0, 0, &sus); 17446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner asc = sus.suc_sus.sus_sense[ADD_SENSECODE]; 17546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner ascq = sus.suc_sus.sus_sense[ADD_SC_QUALIFIER]; 17646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (asc == 0x3a && ascq == 0x0) /* no medium */ 17746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(0); 17846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (asc == 0x28 && ascq == 0x0) /* medium changed */ 17946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner goto again; 18046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (asc == 0x4 && ascq == 0x1 ) /* coming ready */ 18146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { 18246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner sleep(2); 18346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner goto again; 18446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 18546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(1); 18646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 18746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 18846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Check a drive to see if it is a CD-ROM */ 18946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int CheckDrive(char *drive, struct stat *stbuf) 19046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 19146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int is_cd = 0, cdfd; 19246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner char *p; 19346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 19446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* If it doesn't exist, return -1 */ 19546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( stat(drive, stbuf) < 0 ) { 19646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(-1); 19746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 19846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 19946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* If it does exist, verify that it's an available CD-ROM */ 20046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdfd = open(drive, (O_RDONLY|O_EXCL|O_NONBLOCK), 0); 20146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( cdfd >= 0 ) { 20246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner p = Inquiry(cdfd); 20346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (*p == TYPE_ROM) 20446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner is_cd = 1; 20546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner close(cdfd); 20646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 20746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(is_cd); 20846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 20946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 21046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Add a CD-ROM drive to our list of valid drives */ 21146be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void AddDrive(char *drive, struct stat *stbuf) 21246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 21346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int i; 21446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 21546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_numcds < MAX_DRIVES ) { 21646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Check to make sure it's not already in our list. 21746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner This can happen when we see a drive via symbolic link. 21846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner */ 21946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for ( i=0; i<SDL_numcds; ++i ) { 22046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( stbuf->st_rdev == SDL_cdmode[i] ) { 22146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef DEBUG_CDROM 22246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr, "Duplicate drive detected: %s == %s\n", drive, SDL_cdlist[i]); 22346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 22446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return; 22546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 22646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 22746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 22846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Add this drive to our list */ 22946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner i = SDL_numcds; 23046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_cdlist[i] = SDL_strdup(drive); 23146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_cdlist[i] == NULL ) { 23246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_OutOfMemory(); 23346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return; 23446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 23546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_cdmode[i] = stbuf->st_rdev; 23646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner ++SDL_numcds; 23746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef DEBUG_CDROM 23846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr, "Added CD-ROM drive: %s\n", drive); 23946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 24046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 24146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 24246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 24346be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint SDL_SYS_CDInit(void) 24446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 24546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* checklist: /dev/rsr?c */ 24646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner static char *checklist[] = { 24746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner "?0 rsr?", NULL 24846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner }; 24946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner char *SDLcdrom; 25046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int i, j, exists; 25146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner char drive[32]; 25246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct stat stbuf; 25346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 25446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Fill in our driver capabilities */ 25546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Name = SDL_SYS_CDName; 25646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Open = SDL_SYS_CDOpen; 25746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; 25846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Status = SDL_SYS_CDStatus; 25946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Play = SDL_SYS_CDPlay; 26046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Pause = SDL_SYS_CDPause; 26146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Resume = SDL_SYS_CDResume; 26246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Stop = SDL_SYS_CDStop; 26346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Eject = SDL_SYS_CDEject; 26446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Close = SDL_SYS_CDClose; 26546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 26646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Look in the environment for our CD-ROM drive list */ 26746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDLcdrom = SDL_getenv("SDL_CDROM"); /* ':' separated list of devices */ 26846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDLcdrom != NULL ) { 26946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner char *cdpath, *delim; 27046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner size_t len = SDL_strlen(SDLcdrom)+1; 27146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdpath = SDL_stack_alloc(char, len); 27246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( cdpath != NULL ) { 27346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_strlcpy(cdpath, SDLcdrom, len); 27446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDLcdrom = cdpath; 27546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner do { 27646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner delim = SDL_strchr(SDLcdrom, ':'); 27746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( delim ) { 27846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner *delim++ = '\0'; 27946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 28046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( CheckDrive(SDLcdrom, &stbuf) > 0 ) { 28146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner AddDrive(SDLcdrom, &stbuf); 28246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 28346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( delim ) { 28446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDLcdrom = delim; 28546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else { 28646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDLcdrom = NULL; 28746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 28846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } while ( SDLcdrom ); 28946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_stack_free(cdpath); 29046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 29146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 29246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* If we found our drives, there's nothing left to do */ 29346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_numcds > 0 ) { 29446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(0); 29546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 29646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 29746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 29846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Scan the system for CD-ROM drives */ 29946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for ( i=0; checklist[i]; ++i ) { 30046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( checklist[i][0] == '?' ) { 30146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner char *insert; 30246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner exists = 1; 30346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for ( j=checklist[i][1]; exists; ++j ) { 30446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%sc", &checklist[i][3]); 30546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner insert = SDL_strchr(drive, '?'); 30646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( insert != NULL ) { 30746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner *insert = j; 30846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 30946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner switch (CheckDrive(drive, &stbuf)) { 31046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Drive exists and is a CD-ROM */ 31146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case 1: 31246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner AddDrive(drive, &stbuf); 31346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 31446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Drive exists, but isn't a CD-ROM */ 31546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case 0: 31646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 31746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Drive doesn't exist */ 31846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case -1: 31946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner exists = 0; 32046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 32146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 32246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 32346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else { 32446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%s", checklist[i]); 32546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( CheckDrive(drive, &stbuf) > 0 ) { 32646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner AddDrive(drive, &stbuf); 32746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 32846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 32946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 33046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(0); 33146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 33246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 33346be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic const char *SDL_SYS_CDName(int drive) 33446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 33546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(SDL_cdlist[drive]); 33646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 33746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 33846be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDOpen(int drive) 33946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 34046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(open(SDL_cdlist[drive], O_RDONLY | O_NONBLOCK | O_EXCL, 0)); 34146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 34246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 34346be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDGetTOC(SDL_CD *cdrom) 34446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { 34546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner u_char cdb[10], buf[4], *p, *toc; 34646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct scsi_user_cdb sus; 34746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int i, sts, first_track, last_track, ntracks, toc_size; 34846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 34946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner bzero(cdb, sizeof (cdb)); 35046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[0] = 0x43; /* Read TOC */ 35146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[1] = 0x2; /* MSF */ 35246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[8] = 4; /* size TOC header */ 35346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner sts = scsi_cmd(cdrom->id, (cdb_t *)cdb, 10, SUC_READ, buf, 4, &sus); 35446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (sts < 0) 35546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(-1); 35646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner first_track = buf[2]; 35746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner last_track = buf[3]; 35846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner ntracks = last_track - first_track + 1; 35946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->numtracks = ntracks; 36046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner toc_size = 4 + (ntracks + 1) * 8; 36146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner toc = (u_char *)SDL_malloc(toc_size); 36246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (toc == NULL) 36346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(-1); 36446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner bzero(cdb, sizeof (cdb)); 36546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[0] = 0x43; 36646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[1] = 0x2; 36746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[6] = first_track; 36846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[7] = toc_size >> 8; 36946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[8] = toc_size & 0xff; 37046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner sts = scsi_cmd(cdrom->id, (cdb_t *)cdb, 10, SUC_READ, toc, toc_size, 37146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner &sus); 37246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (sts < 0) 37346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { 37446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_free(toc); 37546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(-1); 37646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 37746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 37846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for (i = 0, p = toc+4; i <= ntracks; i++, p+= 8) 37946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { 38046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (i == ntracks) 38146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i].id = 0xAA; /* Leadout */ 38246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner else 38346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i].id = first_track + i; 38446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (p[1] & 0x20) 38546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i].type = SDL_DATA_TRACK; 38646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner else 38746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i].type = SDL_AUDIO_TRACK; 38846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i].offset = msf_to_frame(p[5], p[6], p[7]); 38946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i].length = 0; 39046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (i > 0) 39146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i-1].length = cdrom->track[i].offset - 39246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i-1].offset; 39346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 39446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_free(toc); 39546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(0); 39646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 39746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 39846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Get CD-ROM status */ 39946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) 40046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { 40146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner CDstatus status; 40246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner u_char cdb[10], buf[16]; 40346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int sts; 40446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct scsi_user_cdb sus; 40546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 40646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner bzero(cdb, sizeof (cdb)); 40746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[0] = 0x42; /* read subq */ 40846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[1] = 0x2; /* MSF */ 40946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[2] = 0x40; /* q channel */ 41046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[3] = 1; /* current pos */ 41146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[7] = sizeof (buf) >> 8; 41246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[8] = sizeof (buf) & 0xff; 41346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner sts = scsi_cmd(cdrom->id, (cdb_t *)cdb, 10, SUC_READ, buf, sizeof (buf), 41446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner &sus); 41546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (sts < 0) 41646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(-1); 41746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (sts) 41846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { 41946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (TestForMedium(cdrom->id) == 0) 42046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner status = CD_TRAYEMPTY; 42146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner else 42246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner status = CD_ERROR; 42346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 42446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner else 42546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { 42646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner switch (buf[1]) 42746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { 42846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case 0x11: 42946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner status = CD_PLAYING; 43046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 43146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case 0x12: 43246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner status = CD_PAUSED; 43346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 43446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case 0x13: 43546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case 0x14: 43646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case 0x15: 43746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner status = CD_STOPPED; 43846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 43946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner default: 44046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner status = CD_ERROR; 44146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 44246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 44346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 44446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (position) 44546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { 44646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( status == CD_PLAYING || (status == CD_PAUSED) ) 44746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner *position = msf_to_frame(buf[9], buf[10], buf[11]); 44846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner else 44946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner *position = 0; 45046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 45146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(status); 45246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 45346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 45446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Start play */ 45546be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) 45646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { 45746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner u_char cdb[10]; 45846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int sts, minute, second, frame, eminute, esecond, eframe; 45946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct scsi_user_cdb sus; 46046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 46146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner bzero(cdb, sizeof(cdb)); 46246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[0] = 0x47; /* Play */ 46346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner frame_to_msf(start, &minute, &second, &frame); 46446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner frame_to_msf(start + length, &eminute, &esecond, &eframe); 46546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[3] = minute; 46646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[4] = second; 46746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[5] = frame; 46846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[6] = eminute; 46946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[7] = esecond; 47046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[8] = eframe; 47146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner sts = scsi_cmd(cdrom->id, (cdb_t *)cdb, 10, SUC_READ, 0, 0, &sus); 47246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(sts); 47346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 47446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 47546be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int 47646be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerpauseresume(SDL_CD *cdrom, int flag) 47746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { 47846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner u_char cdb[10]; 47946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct scsi_user_cdb sus; 48046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 48146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner bzero(cdb, sizeof (cdb)); 48246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[0] = 0x4b; 48346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[8] = flag & 0x1; 48446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(scsi_cmd(cdrom->id, (cdb_t *)cdb, 10, SUC_READ, 0, 0, &sus)); 48546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 48646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 48746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Pause play */ 48846be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDPause(SDL_CD *cdrom) 48946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 49046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(pauseresume(cdrom, 0)); 49146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 49246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 49346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Resume play */ 49446be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDResume(SDL_CD *cdrom) 49546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 49646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(pauseresume(cdrom, 1)); 49746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 49846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 49946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Stop play */ 50046be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDStop(SDL_CD *cdrom) 50146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 50246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner u_char cdb[6]; 50346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct scsi_user_cdb sus; 50446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 50546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner bzero(cdb, sizeof (cdb)); 50646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[0] = 0x1b; /* stop */ 50746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[1] = 1; /* immediate */ 50846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(scsi_cmd(cdrom->id, (cdb_t *)cdb, 6, SUC_READ, 0, 0, &sus)); 50946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 51046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 51146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Eject the CD-ROM */ 51246be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDEject(SDL_CD *cdrom) 51346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 51446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner u_char cdb[6]; 51546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct scsi_user_cdb sus; 51646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 51746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner bzero(cdb, sizeof (cdb)); 51846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[0] = 0x1b; /* stop */ 51946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[1] = 1; /* immediate */ 52046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdb[4] = 2; /* eject */ 52146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(scsi_cmd(cdrom->id, (cdb_t *)cdb, 6, SUC_READ, 0, 0, &sus)); 52246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 52346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 52446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Close the CD-ROM handle */ 52546be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void SDL_SYS_CDClose(SDL_CD *cdrom) 52646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { 52746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner close(cdrom->id); 52846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 52946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 53046be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid SDL_SYS_CDQuit(void) 53146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 53246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int i; 53346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 53446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_numcds > 0 ) { 53546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for ( i=0; i<SDL_numcds; ++i ) { 53646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_free(SDL_cdlist[i]); 53746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 53846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 53946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_numcds = 0; 54046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 54146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 54246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif /* SDL_CDROM_BSDI */ 543