146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* 246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Tru64 audio module for SDL (Simple DirectMedia Layer) 346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Copyright (C) 2003 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 Library General Public 746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner License as published by the Free Software Foundation; either 846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner version 2 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 Library General Public License for more details. 1446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner You should have received a copy of the GNU Library General Public 1646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner License along with this library; if not, write to the Free 1746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 1846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 2046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner*/ 2146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_config.h" 2246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 2346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef SDL_CDROM_OSF 2446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 2546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Functions for system-level CD-ROM audio control */ 2646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 2746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* #define DEBUG_CDROM 1 */ 2846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 2946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <sys/types.h> 3046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <dirent.h> 3146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <sys/stat.h> 3246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <fcntl.h> 3346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <io/cam/cdrom.h> 3446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <io/cam/rzdisk.h> 3546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <io/common/devgetinfo.h> 3646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 3746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_cdrom.h" 3846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "../SDL_syscdrom.h" 3946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 4046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* The maximum number of CD-ROM drives we'll detect */ 4146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define MAX_DRIVES 16 4246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 4346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* A list of available CD-ROM drives */ 4446be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic char *SDL_cdlist[MAX_DRIVES]; 4546be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic dev_t SDL_cdmode[MAX_DRIVES]; 4646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 4746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* The system-dependent CD control functions */ 4846be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic const char *SDL_SYS_CDName(int drive); 4946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDOpen(int drive); 5046be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDGetTOC(SDL_CD *cdrom); 5146be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position); 5246be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length); 5346be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDPause(SDL_CD *cdrom); 5446be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDResume(SDL_CD *cdrom); 5546be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDStop(SDL_CD *cdrom); 5646be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDEject(SDL_CD *cdrom); 5746be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void SDL_SYS_CDClose(SDL_CD *cdrom); 5846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 5946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Check a drive to see if it is a CD-ROM */ 6046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Caution!! Not tested. */ 6146be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int CheckDrive(char *drive, struct stat *stbuf) 6246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 6346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int cdfd, is_cd = 0; 6446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct mode_sel_sns_params msp; 6546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct inquiry_info inq; 6646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 6746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef DEBUG_CDROM 6846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner char *devtype[] = {"Disk", "Tape", "Printer", "Processor", "WORM", 6946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner "CD-ROM", "Scanner", "Optical", "Changer", "Comm", "Unknown"}; 7046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 7146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 7246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner bzero(&msp, sizeof(msp)); 7346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner bzero(&inq, sizeof(inq)); 7446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 7546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* If it doesn't exist, return -1 */ 7646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( stat(drive, stbuf) < 0 ) { 7746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(-1); 7846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 7946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 8046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( (cdfd = open(drive, (O_RDWR|O_NDELAY), 0)) >= 0 ) { 8146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner msp.msp_addr = (caddr_t) &inq; 8246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner msp.msp_pgcode = 0; 8346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner msp.msp_pgctrl = 0; 8446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner msp.msp_length = sizeof(inq); 8546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner msp.msp_setps = 0; 8646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 8746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( ioctl(cdfd, SCSI_GET_INQUIRY_DATA, &msp) ) 8846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return (0); 8946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 9046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef DEBUG_CDROM 9146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr, "Device Type: %s\n", devtype[inq.perfdt]); 9246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr, "Vendor: %.8s\n", inq.vndrid); 9346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr, "Product: %.8s\n", inq.prodid); 9446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr, "Revision: %.8s\n", inq.revlvl); 9546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 9646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( inq.perfdt == DTYPE_RODIRECT ) 9746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner is_cd = 1; 9846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 9946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 10046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(is_cd); 10146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 10246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 10346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Add a CD-ROM drive to our list of valid drives */ 10446be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void AddDrive(char *drive, struct stat *stbuf) 10546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 10646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int i; 10746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 10846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_numcds < MAX_DRIVES ) { 10946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Check to make sure it's not already in our list. 11046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * This can happen when we see a drive via symbolic link. 11146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * 11246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner */ 11346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for ( i=0; i<SDL_numcds; ++i ) { 11446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( stbuf->st_rdev == SDL_cdmode[i] ) { 11546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef DEBUG_CDROM 11646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr, "Duplicate drive detected: %s == %s\n", drive, SDL_cdlist[i]); 11746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 11846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return; 11946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 12046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 12146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 12246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Add this drive to our list */ 12346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner i = SDL_numcds; 12446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_cdlist[i] = SDL_strdup(drive); 12546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_cdlist[i] == NULL ) { 12646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_OutOfMemory(); 12746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return; 12846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 12946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_cdmode[i] = stbuf->st_rdev; 13046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner ++SDL_numcds; 13146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef DEBUG_CDROM 13246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr, "Added CD-ROM drive: %s\n", drive); 13346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 13446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 13546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 13646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 13746be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint SDL_SYS_CDInit(void) 13846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 13946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* checklist: 14046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * 14146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * Tru64 5.X (/dev/rdisk/cdrom?c) 14246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * dir: /dev/rdisk, name: cdrom 14346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * 14446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * Digital UNIX 4.0X (/dev/rrz?c) 14546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * dir: /dev, name: rrz 14646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * 14746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner */ 14846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct { 14946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner char *dir; 15046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner char *name; 15146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } checklist[] = { 15246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner {"/dev/rdisk", "cdrom"}, 15346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner {"/dev", "rrz"}, 15446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner {NULL, NULL}}; 15546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner char drive[32]; 15646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner char *SDLcdrom; 15746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int i, j, exists; 15846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct stat stbuf; 15946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 16046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Fill in our driver capabilities */ 16146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Name = SDL_SYS_CDName; 16246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Open = SDL_SYS_CDOpen; 16346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; 16446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Status = SDL_SYS_CDStatus; 16546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Play = SDL_SYS_CDPlay; 16646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Pause = SDL_SYS_CDPause; 16746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Resume = SDL_SYS_CDResume; 16846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Stop = SDL_SYS_CDStop; 16946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Eject = SDL_SYS_CDEject; 17046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Close = SDL_SYS_CDClose; 17146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 17246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 17346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Look in the environment for our CD-ROM drive list */ 17446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDLcdrom = SDL_getenv("SDL_CDROM"); /* ':' separated list of devices */ 17546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDLcdrom != NULL ) { 17646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner char *cdpath, *delim; 17746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner size_t len = SDL_strlen(SDLcdrom)+1; 17846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdpath = SDL_stack_alloc(char, len); 17946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( cdpath != NULL ) { 18046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_strlcpy(cdpath, SDLcdrom, len); 18146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDLcdrom = cdpath; 18246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner do { 18346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner delim = SDL_strchr(SDLcdrom, ':'); 18446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( delim ) { 18546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner *delim++ = '\0'; 18646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 18746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( CheckDrive(SDLcdrom, &stbuf) > 0 ) { 18846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner AddDrive(SDLcdrom, &stbuf); 18946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 19046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( delim ) { 19146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDLcdrom = delim; 19246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else { 19346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDLcdrom = NULL; 19446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 19546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } while ( SDLcdrom ); 19646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_stack_free(cdpath); 19746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 19846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 19946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* If we found our drives, there's nothing left to do */ 20046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_numcds > 0 ) { 20146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(0); 20246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 20346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 20446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Scan the system for CD-ROM drives */ 20546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for ( i = 0; checklist[i].dir; ++i) { 20646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DIR *devdir; 20746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct dirent *devent; 20846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int name_len; 20946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 21046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner devdir = opendir(checklist[i].dir); 21146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (devdir) { 21246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner name_len = SDL_strlen(checklist[i].name); 21346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner while (devent = readdir(devdir)) 21446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (SDL_memcmp(checklist[i].name, devent->d_name, name_len) == 0) 21546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (devent->d_name[devent->d_namlen-1] == 'c') { 21646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_snprintf(drive, SDL_arraysize(drive), "%s/%s", checklist[i].dir, devent->d_name); 21746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef DEBUG_CDROM 21846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr, "Try to add drive: %s\n", drive); 21946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 22046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( CheckDrive(drive, &stbuf) > 0 ) 22146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner AddDrive(drive, &stbuf); 22246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 22346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner closedir(devdir); 22446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else { 22546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef DEBUG_CDROM 22646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr, "cannot open dir: %s\n", checklist[i].dir); 22746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 22846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 22946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 23046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return (0); 23146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 23246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 23346be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic const char *SDL_SYS_CDName(int drive) 23446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 23546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(SDL_cdlist[drive]); 23646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 23746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 23846be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDOpen(int drive) 23946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 24046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* O_RDWR: To use ioctl(fd, SCSI_STOP_UNIT) */ 24146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(open(SDL_cdlist[drive], (O_RDWR|O_NDELAY), 0)); 24246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 24346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 24446be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDGetTOC(SDL_CD *cdrom) 24546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 24646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct cd_toc toc; 24746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct cd_toc_header hdr; 24846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct cd_toc_entry *cdte; 24946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int i; 25046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int okay = 0; 25146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( ioctl(cdrom->id, CDROM_TOC_HEADER, &hdr) ) { 25246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr,"ioctl error CDROM_TOC_HEADER\n"); 25346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return -1; 25446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 25546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->numtracks = hdr.th_ending_track - hdr.th_starting_track + 1; 25646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( cdrom->numtracks > SDL_MAX_TRACKS ) { 25746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->numtracks = SDL_MAX_TRACKS; 25846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 25946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef DEBUG_CDROM 26046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr,"hdr.th_data_len1 = %d\n", hdr.th_data_len1); 26146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr,"hdr.th_data_len0 = %d\n", hdr.th_data_len0); 26246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr,"hdr.th_starting_track = %d\n", hdr.th_starting_track); 26346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr,"hdr.th_ending_track = %d\n", hdr.th_ending_track); 26446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr,"cdrom->numtracks = %d\n", cdrom->numtracks); 26546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 26646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner toc.toc_address_format = CDROM_LBA_FORMAT; 26746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner toc.toc_starting_track = 0; 26846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner toc.toc_alloc_length = (hdr.th_data_len1 << 8) + 26946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner hdr.th_data_len0 + sizeof(hdr); 27046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( (toc.toc_buffer = alloca(toc.toc_alloc_length)) == NULL) { 27146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr,"cannot allocate toc.toc_buffer\n"); 27246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return -1; 27346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 27446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 27546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner bzero (toc.toc_buffer, toc.toc_alloc_length); 27646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (ioctl(cdrom->id, CDROM_TOC_ENTRYS, &toc)) { 27746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr,"ioctl error CDROM_TOC_ENTRYS\n"); 27846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return -1; 27946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 28046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 28146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdte =(struct cd_toc_entry *) ((char *) toc.toc_buffer + sizeof(hdr)); 28246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for (i=0; i <= cdrom->numtracks; ++i) { 28346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (i == cdrom->numtracks ) { 28446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i].id = 0xAA;; 28546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else { 28646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i].id = hdr.th_starting_track + i; 28746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 28846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 28946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i].type = 29046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdte[i].te_control & CDROM_DATA_TRACK; 29146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i].offset = 29246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdte[i].te_absaddr.lba.addr3 << 24 | 29346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdte[i].te_absaddr.lba.addr2 << 16 | 29446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdte[i].te_absaddr.lba.addr1 << 8 | 29546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdte[i].te_absaddr.lba.addr0; 29646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i].length = 0; 29746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( i > 0 ) { 29846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i - 1].length = 29946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i].offset - 30046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i - 1].offset; 30146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 30246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 30346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef DEBUG_CDROM 30446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for (i = 0; i <= cdrom->numtracks; i++) { 30546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr,"toc_entry[%d].te_track_number = %d\n", 30646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner i,cdte[i].te_track_number); 30746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr,"cdrom->track[%d].id = %d\n", i,cdrom->track[i].id); 30846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr,"cdrom->track[%d].type = %x\n", i,cdrom->track[i].type); 30946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr,"cdrom->track[%d].offset = %d\n", i,cdrom->track[i].offset); 31046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr,"cdrom->track[%d].length = %d\n", i,cdrom->track[i].length); 31146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 31246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 31346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( i == (cdrom->numtracks+1) ) { 31446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner okay = 1; 31546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 31646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 31746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(okay ? 0 : -1); 31846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 31946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 32046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Get CD-ROM status */ 32146be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) 32246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 32346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner CDstatus status; 32446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct cd_sub_channel sc; 32546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct cd_subc_channel_data scd; 32646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 32746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner sc.sch_address_format = CDROM_LBA_FORMAT; 32846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner sc.sch_data_format = CDROM_CURRENT_POSITION; 32946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner sc.sch_track_number = 0; 33046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner sc.sch_alloc_length = sizeof(scd); 33146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner sc.sch_buffer = (caddr_t)&scd; 33246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( ioctl(cdrom->id, CDROM_READ_SUBCHANNEL, &sc) ) { 33346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner status = CD_ERROR; 33446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr,"ioctl error CDROM_READ_SUBCHANNEL \n"); 33546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else { 33646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner switch (scd.scd_header.sh_audio_status) { 33746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case AS_AUDIO_INVALID: 33846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner status = CD_STOPPED; 33946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 34046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case AS_PLAY_IN_PROGRESS: 34146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner status = CD_PLAYING; 34246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 34346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case AS_PLAY_PAUSED: 34446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner status = CD_PAUSED; 34546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 34646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case AS_PLAY_COMPLETED: 34746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner status = CD_STOPPED; 34846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 34946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case AS_PLAY_ERROR: 35046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner status = CD_ERROR; 35146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 35246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case AS_NO_STATUS: 35346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner status = CD_STOPPED; 35446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 35546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner default: 35646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner status = CD_ERROR; 35746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 35846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 35946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef DEBUG_CDROM 36046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr,"scd.scd_header.sh_audio_status = %x\n", 36146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner scd.scd_header.sh_audio_status); 36246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 36346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 36446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (position) { 36546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (status == CD_PLAYING || (status == CD_PAUSED) ) { 36646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner *position = 36746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner scd.scd_position_data.scp_absaddr.lba.addr3 << 24 | 36846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner scd.scd_position_data.scp_absaddr.lba.addr2 << 16 | 36946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner scd.scd_position_data.scp_absaddr.lba.addr1 << 8 | 37046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner scd.scd_position_data.scp_absaddr.lba.addr0; 37146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else { 37246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner *position = 0; 37346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 37446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 37546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 37646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return status; 37746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 37846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 37946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Start play */ 38046be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) 38146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 38246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* 38346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * Play MSF 38446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner */ 38546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct cd_play_audio_msf msf; 38646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int end; 38746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 38846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner bzero(&msf, sizeof(msf)); 38946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner end = start +length; 39046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner FRAMES_TO_MSF(start + 150, /* LBA = 4500*M + 75*S + F - 150 */ 39146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner &msf.msf_starting_M_unit, 39246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner &msf.msf_starting_S_unit, 39346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner &msf.msf_starting_F_unit); 39446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner FRAMES_TO_MSF(end + 150, /* LBA = 4500*M + 75*S + F - 150 */ 39546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner &msf.msf_ending_M_unit, 39646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner &msf.msf_ending_S_unit, 39746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner &msf.msf_ending_F_unit); 39846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 39946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(ioctl(cdrom->id, CDROM_PLAY_AUDIO_MSF, &msf)); 40046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 40146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 40246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Pause play */ 40346be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDPause(SDL_CD *cdrom) 40446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 40546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(ioctl(cdrom->id, CDROM_PAUSE_PLAY)); 40646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 40746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 40846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Resume play */ 40946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDResume(SDL_CD *cdrom) 41046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 41146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(ioctl(cdrom->id, CDROM_RESUME_PLAY)); 41246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 41346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 41446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Stop play */ 41546be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDStop(SDL_CD *cdrom) 41646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 41746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(ioctl(cdrom->id, SCSI_STOP_UNIT)); 41846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 41946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 42046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Eject the CD-ROM */ 42146be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDEject(SDL_CD *cdrom) 42246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 42346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(ioctl(cdrom->id, CDROM_EJECT_CADDY)); 42446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 42546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 42646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Close the CD-ROM handle */ 42746be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void SDL_SYS_CDClose(SDL_CD *cdrom) 42846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 42946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner close(cdrom->id); 43046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 43146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 43246be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid SDL_SYS_CDQuit(void) 43346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 43446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int i; 43546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 43646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_numcds > 0 ) { 43746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for ( i=0; i<SDL_numcds; ++i ) { 43846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_free(SDL_cdlist[i]); 43946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 44046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_numcds = 0; 44146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 44246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 44346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 44446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif /* SDL_CDROM_OSF */ 445