146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/*
246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    SDL - Simple DirectMedia Layer
346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    Copyright (C) 1997-2004 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 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    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_MINT
2546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
2646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/*
2746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	Atari MetaDOS CD-ROM functions
2846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
2946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	Patrice Mandin
3046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner*/
3146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
3246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <errno.h>
3346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
3446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <cdromio.h>
3546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <metados.h>
3646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
3746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_cdrom.h"
3846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "../SDL_syscdrom.h"
3946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
4046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Some ioctl() errno values which occur when the tray is empty */
4146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifndef ENOMEDIUM
4246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define ENOMEDIUM ENOENT
4346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif
4446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define ERRNO_TRAYEMPTY(errno)	\
4546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	((errno == EIO)    || (errno == ENOENT) || \
4646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	 (errno == EINVAL) || (errno == ENOMEDIUM))
4746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
4846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* The maximum number of CD-ROM drives we'll detect */
4946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define MAX_DRIVES	32
5046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
5146be48730333120a7b939116cef075e61c12c703David 'Digit' Turnertypedef struct {
5246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	unsigned char device[3];	/* Physical device letter + ':' + '\0' */
5346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	metaopen_t	metaopen;		/* Infos on opened drive */
5446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} metados_drive_t;
5546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
5646be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic metados_drive_t metados_drives[MAX_DRIVES];
5746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
5846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* The system-dependent CD control functions */
5946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic const char *SDL_SYS_CDName(int drive);
6046be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDOpen(int drive);
6146be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void SDL_SYS_CDClose(SDL_CD *cdrom);
6246be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDioctl(int id, int command, void *arg);
6346be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDGetTOC(SDL_CD *cdrom);
6446be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position);
6546be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length);
6646be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDPause(SDL_CD *cdrom);
6746be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDResume(SDL_CD *cdrom);
6846be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDStop(SDL_CD *cdrom);
6946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDEject(SDL_CD *cdrom);
7046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
7146be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint SDL_SYS_CDInit(void)
7246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{
7346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	metainit_t	metainit={0,0,0,0};
7446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	metaopen_t	metaopen;
7546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	int i, handle;
7646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	struct cdrom_subchnl info;
7746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
7846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	Metainit(&metainit);
7946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	if (metainit.version == NULL) {
8046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef DEBUG_CDROM
8146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		fprintf(stderr, "MetaDOS not installed\n");
8246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif
8346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		return -1;
8446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	}
8546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
8646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	if (metainit.drives_map == 0) {
8746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef DEBUG_CDROM
8846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		fprintf(stderr, "No MetaDOS devices present\n");
8946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif
9046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		return -1;
9146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	}
9246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
9346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	SDL_numcds = 0;
9446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
9546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	for (i='A'; i<='Z'; i++) {
9646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		metados_drives[SDL_numcds].device[0] = 0;
9746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		metados_drives[SDL_numcds].device[1] = ':';
9846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		metados_drives[SDL_numcds].device[2] = 0;
9946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
10046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		if (metainit.drives_map & (1<<(i-'A'))) {
10146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			handle = Metaopen(i, &metaopen);
10246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			if (handle == 0) {
10346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
10446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				info.cdsc_format = CDROM_MSF;
10546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				if ( (Metaioctl(i, METADOS_IOCTL_MAGIC, CDROMSUBCHNL, &info) == 0) || ERRNO_TRAYEMPTY(errno) ) {
10646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner					metados_drives[SDL_numcds].device[0] = i;
10746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner					++SDL_numcds;
10846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				}
10946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
11046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				Metaclose(i);
11146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			}
11246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		}
11346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	}
11446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
11546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	/* Fill in our driver capabilities */
11646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	SDL_CDcaps.Name = SDL_SYS_CDName;
11746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	SDL_CDcaps.Open = SDL_SYS_CDOpen;
11846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	SDL_CDcaps.Close = SDL_SYS_CDClose;
11946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
12046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC;
12146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	SDL_CDcaps.Status = SDL_SYS_CDStatus;
12246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	SDL_CDcaps.Play = SDL_SYS_CDPlay;
12346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	SDL_CDcaps.Pause = SDL_SYS_CDPause;
12446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	SDL_CDcaps.Resume = SDL_SYS_CDResume;
12546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	SDL_CDcaps.Stop = SDL_SYS_CDStop;
12646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	SDL_CDcaps.Eject = SDL_SYS_CDEject;
12746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
12846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	return 0;
12946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner}
13046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
13146be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid SDL_SYS_CDQuit(void)
13246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{
13346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	SDL_numcds = 0;
13446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner}
13546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
13646be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic const char *SDL_SYS_CDName(int drive)
13746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{
13846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	return(metados_drives[drive].device);
13946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner}
14046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
14146be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDOpen(int drive)
14246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{
14346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	int handle;
14446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
14546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	handle = Metaopen(metados_drives[drive].device[0], &(metados_drives[drive].metaopen));
14646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	if (handle == 0) {
14746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		return drive;
14846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	}
14946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
15046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	return -1;
15146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner}
15246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
15346be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void SDL_SYS_CDClose(SDL_CD *cdrom)
15446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{
15546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	Metaclose(metados_drives[cdrom->id].device[0]);
15646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner}
15746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
15846be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDioctl(int id, int command, void *arg)
15946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{
16046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	int retval;
16146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
16246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	retval = Metaioctl(metados_drives[id].device[0], METADOS_IOCTL_MAGIC, command, arg);
16346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	if ( retval < 0 ) {
16446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		SDL_SetError("ioctl() error: %s", strerror(errno));
16546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	}
16646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	return(retval);
16746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner}
16846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
16946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDGetTOC(SDL_CD *cdrom)
17046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{
17146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	int i,okay;
17246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	struct cdrom_tochdr toc;
17346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	struct cdrom_tocentry entry;
17446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
17546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	/* Use standard ioctl() */
17646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	if (SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCHDR, &toc)<0) {
17746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		return -1;
17846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	}
17946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
18046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	cdrom->numtracks = toc.cdth_trk1-toc.cdth_trk0+1;
18146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	if ( cdrom->numtracks > SDL_MAX_TRACKS ) {
18246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		cdrom->numtracks = SDL_MAX_TRACKS;
18346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	}
18446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
18546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	/* Read all the track TOC entries */
18646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	okay=1;
18746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	for ( i=0; i<=cdrom->numtracks; ++i ) {
18846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		if ( i == cdrom->numtracks ) {
18946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			cdrom->track[i].id = CDROM_LEADOUT;
19046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		} else {
19146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			cdrom->track[i].id = toc.cdth_trk0+i;
19246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		}
19346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		entry.cdte_track = cdrom->track[i].id;
19446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		entry.cdte_format = CDROM_MSF;
19546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		if ( SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCENTRY, &entry) < 0 ) {
19646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			okay=0;
19746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			break;
19846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		} else {
19946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			if ( entry.cdte_ctrl & CDROM_DATA_TRACK ) {
20046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				cdrom->track[i].type = SDL_DATA_TRACK;
20146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			} else {
20246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				cdrom->track[i].type = SDL_AUDIO_TRACK;
20346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			}
20446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			cdrom->track[i].offset = MSF_TO_FRAMES(
20546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				entry.cdte_addr.msf.minute,
20646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				entry.cdte_addr.msf.second,
20746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				entry.cdte_addr.msf.frame);
20846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				cdrom->track[i].length = 0;
20946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			if ( i > 0 ) {
21046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				cdrom->track[i-1].length = cdrom->track[i].offset-cdrom->track[i-1].offset;
21146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			}
21246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		}
21346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	}
21446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
21546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	return(okay ? 0 : -1);
21646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner}
21746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
21846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Get CD-ROM status */
21946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position)
22046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{
22146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	CDstatus status;
22246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	struct cdrom_tochdr toc;
22346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	struct cdrom_subchnl info;
22446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
22546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	info.cdsc_format = CDROM_MSF;
22646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	if ( SDL_SYS_CDioctl(cdrom->id, CDROMSUBCHNL, &info) < 0 ) {
22746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		if ( ERRNO_TRAYEMPTY(errno) ) {
22846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			status = CD_TRAYEMPTY;
22946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		} else {
23046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			status = CD_ERROR;
23146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		}
23246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	} else {
23346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		switch (info.cdsc_audiostatus) {
23446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			case CDROM_AUDIO_INVALID:
23546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			case CDROM_AUDIO_NO_STATUS:
23646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				/* Try to determine if there's a CD available */
23746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				if (SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCHDR, &toc)==0) {
23846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner					status = CD_STOPPED;
23946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				} else {
24046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner					status = CD_TRAYEMPTY;
24146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				}
24246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				break;
24346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			case CDROM_AUDIO_COMPLETED:
24446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				status = CD_STOPPED;
24546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				break;
24646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			case CDROM_AUDIO_PLAY:
24746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				status = CD_PLAYING;
24846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				break;
24946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			case CDROM_AUDIO_PAUSED:
25046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				/* Workaround buggy CD-ROM drive */
25146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				if ( info.cdsc_trk == CDROM_LEADOUT ) {
25246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner					status = CD_STOPPED;
25346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				} else {
25446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner					status = CD_PAUSED;
25546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				}
25646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				break;
25746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			default:
25846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				status = CD_ERROR;
25946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				break;
26046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		}
26146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	}
26246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	if ( position ) {
26346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		if ( status == CD_PLAYING || (status == CD_PAUSED) ) {
26446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			*position = MSF_TO_FRAMES(
26546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner					info.cdsc_absaddr.msf.minute,
26646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner					info.cdsc_absaddr.msf.second,
26746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner					info.cdsc_absaddr.msf.frame);
26846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		} else {
26946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			*position = 0;
27046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		}
27146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	}
27246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	return(status);
27346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner}
27446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
27546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Start play */
27646be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length)
27746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{
27846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	struct cdrom_msf playtime;
27946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
28046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	FRAMES_TO_MSF(start,
28146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	   &playtime.cdmsf_min0, &playtime.cdmsf_sec0, &playtime.cdmsf_frame0);
28246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	FRAMES_TO_MSF(start+length,
28346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	   &playtime.cdmsf_min1, &playtime.cdmsf_sec1, &playtime.cdmsf_frame1);
28446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef DEBUG_CDROM
28546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner  fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n",
28646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	playtime.cdmsf_min0, playtime.cdmsf_sec0, playtime.cdmsf_frame0,
28746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	playtime.cdmsf_min1, playtime.cdmsf_sec1, playtime.cdmsf_frame1);
28846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif
28946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
29046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	return SDL_SYS_CDioctl(cdrom->id, CDROMPLAYMSF, &playtime);
29146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner}
29246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
29346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Pause play */
29446be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDPause(SDL_CD *cdrom)
29546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{
29646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	return SDL_SYS_CDioctl(cdrom->id, CDROMPAUSE, 0);
29746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner}
29846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
29946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Resume play */
30046be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDResume(SDL_CD *cdrom)
30146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{
30246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	return SDL_SYS_CDioctl(cdrom->id, CDROMRESUME, 0);
30346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner}
30446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
30546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Stop play */
30646be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDStop(SDL_CD *cdrom)
30746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{
30846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	return SDL_SYS_CDioctl(cdrom->id, CDROMSTOP, 0);
30946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner}
31046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
31146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Eject the CD-ROM */
31246be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDEject(SDL_CD *cdrom)
31346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{
31446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	return SDL_SYS_CDioctl(cdrom->id, CDROMEJECT, 0);
31546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner}
31646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
31746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif /* SDL_CDROM_MINT */
318