diff options
| author | SND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2010-07-08 00:23:38 +0000 |
|---|---|---|
| committer | SND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2010-07-08 00:23:38 +0000 |
| commit | e69ea176d835fa98912c99636a1a5cea8cbab105 (patch) | |
| tree | 350c3f53ccdda0a0603ac88a77037b15d8e71e5b /plugins/dfcdrom/cdr-linux.c | |
| parent | 337765356b5fd420d3cab3349caa34eec2f98e65 (diff) | |
| download | pcsxr-e69ea176d835fa98912c99636a1a5cea8cbab105.tar.gz | |
dfcdrom: refactored for better portability.
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@54325 e17a0e51-4ae3-4d35-97c3-1a29b211df97
Diffstat (limited to 'plugins/dfcdrom/cdr-linux.c')
| -rw-r--r-- | plugins/dfcdrom/cdr-linux.c | 562 |
1 files changed, 71 insertions, 491 deletions
diff --git a/plugins/dfcdrom/cdr-linux.c b/plugins/dfcdrom/cdr-linux.c index 8b4a928f..d0e520b2 100644 --- a/plugins/dfcdrom/cdr-linux.c +++ b/plugins/dfcdrom/cdr-linux.c @@ -1,186 +1,59 @@ /* - * Cdrom for Psemu Pro like Emulators + * Copyright (c) 2010, Wei Mingzhi <whistler@openoffice.org>. + * All Rights Reserved. * + * Based on: Cdrom for Psemu Pro like Emulators * By: linuzappz <linuzappz@hotmail.com> * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses>. */ -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <sys/stat.h> -#include <unistd.h> -#include <pthread.h> -#include <time.h> -#include <string.h> - #include "cdr.h" -#ifndef CDROMSETSPINDOWN -#define CDROMSETSPINDOWN 0x531e -#endif - -static inline unsigned int msf_to_lba(char m, char s, char f) { - return (((m * CD_SECS) + s) * CD_FRAMES + f) - CD_MSF_OFFSET; -} - -static inline void lba_to_msf(unsigned int s, char *msf) { - s += CD_MSF_OFFSET; - - msf[0] = s / CD_FRAMES / CD_SECS; - s = s - msf[0] * CD_FRAMES * CD_SECS; - msf[1] = s / CD_FRAMES; - s = s - msf[1] * CD_FRAMES; - msf[2] = s; -} - -int initial_time = 0; - -pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; -pthread_cond_t cond = PTHREAD_COND_INITIALIZER; - -CacheData *cdcache; -unsigned char *cdbuffer; -int cacheaddr; - -crdata cr; - -unsigned char lastTime[3]; -int cdHandle; -pthread_t thread; -int subqread; -volatile int stopth, found, locked, playing; - -long (*ReadTrackT[])() = { - ReadNormal, - ReadThreaded, -}; - -unsigned char* (*GetBufferT[])() = { - GetBNormal, - GetBThreaded, -}; - -long (*fReadTrack)(); -unsigned char* (*fGetBuffer)(); - -void *CdrThread(void *arg); +#ifdef __linux__ char *LibName = N_("CD-ROM Drive Reader"); -long CDRinit(void) { - cdHandle = -1; - thread = -1; - - return 0; -} - -long CDRshutdown(void) { - return 0; -} - -long CDRopen(void) { +int OpenCdHandle(const char *dev) { + int h; char spindown; - LoadConf(); + h = open(dev, O_RDONLY); - if (cdHandle > 0) - return 0; /* it's already open */ - cdHandle = open(CdromDev, O_RDONLY); - if (cdHandle != -1) { // if we can't open the cdrom we'll works as a null plugin - ioctl(cdHandle, CDROM_LOCKDOOR, 0); -// ioctl(cdHandle, CDROMSTART, NULL); + if (h != -1) { + ioctl(h, CDROM_LOCKDOOR, 0); +// ioctl(h, CDROMSTART, NULL); spindown = (char)SpinDown; - ioctl(cdHandle, CDROMSETSPINDOWN, &spindown); - - ioctl(cdHandle, CDROM_SELECT_SPEED, CdrSpeed); - } else { - fprintf(stderr, "CDR: Could not open %s\n", CdromDev); - } - - fReadTrack = ReadTrackT[ReadMode]; - fGetBuffer = GetBufferT[ReadMode]; - - if (ReadMode == THREADED) { - cdcache = (CacheData *)malloc(CacheSize * sizeof(CacheData)); - if (cdcache == NULL) return -1; - memset(cdcache, 0, CacheSize * sizeof(CacheData)); + ioctl(h, CDROMSETSPINDOWN, &spindown); - found = 0; - } else { - cdbuffer = cr.buf + 12; /* skip sync data */ + ioctl(h, CDROM_SELECT_SPEED, CdrSpeed); } - if (ReadMode == THREADED) { - pthread_attr_t attr; - - pthread_mutex_init(&mut, NULL); - pthread_cond_init(&cond, NULL); - locked = 0; - - pthread_attr_init(&attr); - pthread_create(&thread, &attr, CdrThread, NULL); - - cacheaddr = -1; - } else thread = -1; - - playing = 0; - stopth = 0; - initial_time = 0; - - return 0; + return h; } -long CDRclose(void) { - char spindown; - - if (cdHandle < 1) return 0; - - if (playing) CDRstop(); - spindown = SPINDOWN_VENDOR_SPECIFIC; - ioctl(cdHandle, CDROMSETSPINDOWN, &spindown); - close(cdHandle); - cdHandle = -1; - - if (thread != -1) { - if (locked == 0) { - stopth = 1; - while (locked == 0) usleep(5000); - } - - stopth = 2; - pthread_mutex_lock(&mut); - pthread_cond_signal(&cond); - pthread_mutex_unlock(&mut); - - pthread_join(thread, NULL); - pthread_mutex_destroy(&mut); - pthread_cond_destroy(&cond); - } - - if (ReadMode == THREADED) { - free(cdcache); - } - - return 0; +void CloseCdHandle(int handle) { + char spindown = SPINDOWN_VENDOR_SPECIFIC; + ioctl(handle, CDROMSETSPINDOWN, &spindown); + close(handle); } -// return Starting and Ending Track -// buffer: -// byte 0 - start track -// byte 1 - end track -long CDRgetTN(unsigned char *buffer) { +long GetTN(int handle, unsigned char *buffer) { struct cdrom_tochdr toc; - if (cdHandle < 1) { - buffer[0] = 1; - buffer[1] = 1; - return 0; - } - - if (ioctl(cdHandle, CDROMREADTOCHDR, &toc) == -1) + if (ioctl(handle, CDROMREADTOCHDR, &toc) == -1) return -1; buffer[0] = toc.cdth_trk0; // start track @@ -189,25 +62,15 @@ long CDRgetTN(unsigned char *buffer) { return 0; } -// return Track Time -// buffer: -// byte 0 - frame -// byte 1 - second -// byte 2 - minute -long CDRgetTD(unsigned char track, unsigned char *buffer) { +long GetTD(int handle, unsigned char track, unsigned char *buffer) { struct cdrom_tocentry entry; - if (cdHandle < 1) { - memset(buffer + 1, 0, 3); - return 0; - } - if (track == 0) track = 0xaa; // total time entry.cdte_track = track; entry.cdte_format = CDROM_MSF; - if (ioctl(cdHandle, CDROMREADTOCENTRY, &entry) == -1) + if (ioctl(handle, CDROMREADTOCENTRY, &entry) == -1) return -1; buffer[0] = entry.cdte_addr.msf.frame; /* frame */ @@ -217,174 +80,40 @@ long CDRgetTD(unsigned char track, unsigned char *buffer) { return 0; } -// normal reading -long ReadNormal() { - if (ioctl(cdHandle, CDROMREADRAW, &cr) == -1) - return -1; - - return 0; -} - -unsigned char* GetBNormal() { - return cdbuffer; -} +long GetTE(int handle, unsigned char track, unsigned char *m, unsigned char *s, unsigned char *f) { + struct cdrom_tocentry entry; + char msf[3]; -// threaded reading (with cache) -long ReadThreaded() { - int addr = msf_to_lba(cr.msf.cdmsf_min0, cr.msf.cdmsf_sec0, cr.msf.cdmsf_frame0); - int i; - - if (addr >= cacheaddr && addr < (cacheaddr + CacheSize) && cacheaddr != -1) { - i = addr - cacheaddr; - PRINTF("found %d\n", (addr - cacheaddr)); - cdbuffer = cdcache[i].cr.buf + 12; - while (btoi(cdbuffer[0]) != cr.msf.cdmsf_min0 || - btoi(cdbuffer[1]) != cr.msf.cdmsf_sec0 || - btoi(cdbuffer[2]) != cr.msf.cdmsf_frame0) { - if (locked == 1) { - if (cdcache[i].ret == 0) break; - return -1; - } - usleep(5000); - } - PRINTF("%x:%x:%x, %p, %p\n", cdbuffer[0], cdbuffer[1], cdbuffer[2], cdbuffer, cdcache); - found = 1; + entry.cdte_track = track + 1; + entry.cdte_format = CDROM_MSF; - return 0; - } else found = 0; + if (ioctl(handle, CDROMREADTOCENTRY, &entry) == -1) + return -1; - if (locked == 0) { - stopth = 1; - while (locked == 0) { usleep(5000); } - stopth = 0; - } + lba_to_msf(msf_to_lba(entry.cdte_addr.msf.minute, entry.cdte_addr.msf.second, entry.cdte_addr.msf.frame) - CD_MSF_OFFSET, msf); - // not found in cache - locked = 0; - pthread_mutex_lock(&mut); - pthread_cond_signal(&cond); - pthread_mutex_unlock(&mut); + *m = msf[0]; + *s = msf[1]; + *f = msf[2]; return 0; } -unsigned char* GetBThreaded() { - PRINTF("threadc %d\n", found); - - if (found == 1) return cdbuffer; - cdbuffer = cdcache[0].cr.buf + 12; - while (btoi(cdbuffer[0]) != cr.msf.cdmsf_min0 || - btoi(cdbuffer[1]) != cr.msf.cdmsf_sec0 || - btoi(cdbuffer[2]) != cr.msf.cdmsf_frame0) { - if (locked == 1) return NULL; - usleep(5000); - } - if (cdcache[0].ret == -1) return NULL; - - return cdbuffer; -} - -void *CdrThread(void *arg) { - unsigned char curTime[3]; - int i; - - for (;;) { - locked = 1; - pthread_mutex_lock(&mut); - pthread_cond_wait(&cond, &mut); - - if (stopth == 2) pthread_exit(NULL); - // refill the buffer - cacheaddr = msf_to_lba(cr.msf.cdmsf_min0, cr.msf.cdmsf_sec0, cr.msf.cdmsf_frame0); - - memcpy(curTime, &cr.msf, 3); - - PRINTF("start thc %d:%d:%d\n", curTime[0], curTime[1], curTime[2]); - - for (i = 0; i < CacheSize; i++) { - memcpy(&cdcache[i].cr.msf, curTime, 3); - PRINTF("reading %d:%d:%d\n", curTime[0], curTime[1], curTime[2]); - cdcache[i].ret = ioctl(cdHandle, CDROMREADRAW, &cdcache[i].cr); - - PRINTF("readed %x:%x:%x\n", cdcache[i].cr.buf[12], cdcache[i].cr.buf[13], cdcache[i].cr.buf[14]); - if (cdcache[i].ret == -1) break; - - curTime[2]++; - if (curTime[2] == 75) { - curTime[2] = 0; - curTime[1]++; - if (curTime[1] == 60) { - curTime[1] = 0; - curTime[0]++; - } - } - - if (stopth) break; - } - - pthread_mutex_unlock(&mut); - } - - return NULL; -} - -// read track -// time: -// byte 0 - minute -// byte 1 - second -// byte 2 - frame -// uses bcd format -long CDRreadTrack(unsigned char *time) { - if (cdHandle < 1) { - memset(cr.buf, 0, DATA_SIZE); - return 0; - } - - PRINTF("CDRreadTrack %d:%d:%d\n", btoi(time[0]), btoi(time[1]), btoi(time[2])); - - if (UseSubQ) memcpy(lastTime, time, 3); - subqread = 0; - - cr.msf.cdmsf_min0 = btoi(time[0]); - cr.msf.cdmsf_sec0 = btoi(time[1]); - cr.msf.cdmsf_frame0 = btoi(time[2]); - - return fReadTrack(); -} +long ReadSector(int handle, crdata *cr) { + if (ioctl(handle, CDROMREADRAW, cr) == -1) + return -1; -// return readed track -unsigned char *CDRgetBuffer(void) { - return fGetBuffer(); + return 0; } -// plays cdda audio -// sector: -// byte 0 - minute -// byte 1 - second -// byte 2 - frame -// does NOT uses bcd format -long CDRplay(unsigned char *sector) { +long PlayCDDA(int handle, unsigned char *sector) { struct cdrom_msf addr; unsigned char ptmp[4]; - if (cdHandle < 1) - return 0; - - // If play was called with the same time as the previous call, - // don't restart it. Of course, if play is called with a different - // track, stop playing the current stream. - if (playing) - { - if (msf_to_lba(sector[0], sector[1], sector[2]) == initial_time) - return 0; - else - CDRstop(); - } - initial_time = msf_to_lba(sector[0], sector[1], sector[2]); - // 0 is the last track of every cdrom, so play up to there - if (CDRgetTD(0, ptmp) == -1) + if (GetTD(handle, 0, ptmp) == -1) return -1; + addr.cdmsf_min0 = sector[0]; addr.cdmsf_sec0 = sector[1]; addr.cdmsf_frame0 = sector[2]; @@ -392,92 +121,43 @@ long CDRplay(unsigned char *sector) { addr.cdmsf_sec1 = ptmp[1]; addr.cdmsf_frame1 = ptmp[0]; - if (ioctl(cdHandle, CDROMPLAYMSF, &addr) == -1) + if (ioctl(handle, CDROMPLAYMSF, &addr) == -1) return -1; - playing = 1; - return 0; } -// stops cdda audio -long CDRstop(void) { +long StopCDDA(int handle) { struct cdrom_subchnl sc; - if (cdHandle < 1) - return 0; - sc.cdsc_format = CDROM_MSF; - if (ioctl(cdHandle, CDROMSUBCHNL, &sc) == -1) + if (ioctl(handle, CDROMSUBCHNL, &sc) == -1) return -1; switch (sc.cdsc_audiostatus) { case CDROM_AUDIO_PAUSED: case CDROM_AUDIO_PLAY: - ioctl(cdHandle, CDROMSTOP); + ioctl(handle, CDROMSTOP); break; } - playing = 0; - initial_time = 0; - return 0; } -struct CdrStat { - unsigned long Type; - unsigned long Status; - unsigned char Time[3]; // current playing time -}; - -struct CdrStat ostat; - -// reads cdr status -// type: -// 0x00 - unknown -// 0x01 - data -// 0x02 - audio -// 0xff - no cdrom -// status: (only shell open supported) -// 0x00 - unknown -// 0x01 - error -// 0x04 - seek error -// 0x10 - shell open -// 0x20 - reading -// 0x40 - seeking -// 0x80 - playing -// time: -// byte 0 - minute -// byte 1 - second -// byte 2 - frame - -long CDRgetStatus(struct CdrStat *stat) { +long GetStatus(int handle, int playing, struct CdrStat *stat) { struct cdrom_subchnl sc; int ret; - static time_t to; char spindown; - if (cdHandle < 1) - return -1; - - if (!playing) { // if not playing update stat only once in a second - if (to < time(NULL)) { - to = time(NULL); - } else { - memcpy(stat, &ostat, sizeof(struct CdrStat)); - return 0; - } - } - memset(stat, 0, sizeof(struct CdrStat)); if (playing) { // return Time only if playing sc.cdsc_format = CDROM_MSF; - if (ioctl(cdHandle, CDROMSUBCHNL, &sc) != -1) + if (ioctl(handle, CDROMSUBCHNL, &sc) != -1) memcpy(stat->Time, &sc.cdsc_absaddr.msf, 3); } - ret = ioctl(cdHandle, CDROM_DISC_STATUS); + ret = ioctl(handle, CDROM_DISC_STATUS); switch (ret) { case CDS_AUDIO: stat->Type = 0x02; @@ -489,7 +169,7 @@ long CDRgetStatus(struct CdrStat *stat) { stat->Type = 0x01; break; } - ret = ioctl(cdHandle, CDROM_DRIVE_STATUS); + ret = ioctl(handle, CDROM_DRIVE_STATUS); switch (ret) { case CDS_NO_DISC: case CDS_TRAY_OPEN: @@ -498,8 +178,8 @@ long CDRgetStatus(struct CdrStat *stat) { break; default: spindown = (char)SpinDown; - ioctl(cdHandle, CDROMSETSPINDOWN, &spindown); - ioctl(cdHandle, CDROM_LOCKDOOR, 0); + ioctl(handle, CDROMSETSPINDOWN, &spindown); + ioctl(handle, CDROM_LOCKDOOR, 0); break; } @@ -509,54 +189,31 @@ long CDRgetStatus(struct CdrStat *stat) { break; } - memcpy(&ostat, stat, sizeof(struct CdrStat)); - return 0; } -struct SubQ { - char res0[12]; - unsigned char ControlAndADR; - unsigned char TrackNumber; - unsigned char IndexNumber; - unsigned char TrackRelativeAddress[3]; - unsigned char Filler; - unsigned char AbsoluteAddress[3]; - char res1[72]; -}; - -struct SubQ subq; - -unsigned char *CDRgetBufferSub(void) { +unsigned char *ReadSub(int handle, const unsigned char *time) { + static struct SubQ subq; struct cdrom_subchnl subchnl; int ret; + crdata cr; - if (!UseSubQ) return NULL; - if (subqread) return (unsigned char *)&subq; - - cr.msf.cdmsf_min0 = btoi(lastTime[0]); - cr.msf.cdmsf_sec0 = btoi(lastTime[1]); - cr.msf.cdmsf_frame0 = btoi(lastTime[2]); - - if (ReadMode == THREADED) pthread_mutex_lock(&mut); + cr.msf.cdmsf_min0 = btoi(time[0]); + cr.msf.cdmsf_sec0 = btoi(time[1]); + cr.msf.cdmsf_frame0 = btoi(time[2]); - if (ioctl(cdHandle, CDROMSEEK, &cr.msf) == -1) { + if (ioctl(handle, CDROMSEEK, &cr.msf) == -1) { // will be slower, but there's no other way to make it accurate - if (ioctl(cdHandle, CDROMREADRAW, &cr) == -1) { - if (ReadMode == THREADED) pthread_mutex_unlock(&mut); + if (ioctl(handle, CDROMREADRAW, &cr) == -1) { return NULL; } } subchnl.cdsc_format = CDROM_MSF; - ret = ioctl(cdHandle, CDROMSUBCHNL, &subchnl); - - if (ReadMode == THREADED) pthread_mutex_unlock(&mut); + ret = ioctl(handle, CDROMSUBCHNL, &subchnl); if (ret == -1) return NULL; - subqread = 1; - subq.TrackNumber = subchnl.cdsc_trk; subq.IndexNumber = subchnl.cdsc_ind; subq.TrackRelativeAddress[0] = itob(subchnl.cdsc_reladdr.msf.minute); @@ -574,81 +231,4 @@ unsigned char *CDRgetBufferSub(void) { return (unsigned char *)&subq; } -// read CDDA sector into buffer -long CDRreadCDDA(unsigned char m, unsigned char s, unsigned char f, unsigned char *buffer) { - unsigned char msf[3] = {m, s, f}; - unsigned char *p; - - if (CDRreadTrack(msf) != 0) return -1; - - p = CDRgetBuffer(); - if (p == NULL) return -1; - - memcpy(buffer, p - 12, CD_FRAMESIZE_RAW); // copy from the beginning of the sector - return 0; -} - -// get Track End Time -long CDRgetTE(unsigned char track, unsigned char *m, unsigned char *s, unsigned char *f) { - struct cdrom_tocentry entry; - char msf[3]; - - if (cdHandle < 1) return -1; - - entry.cdte_track = track + 1; - entry.cdte_format = CDROM_MSF; - - if (ioctl(cdHandle, CDROMREADTOCENTRY, &entry) == -1) - return -1; - - lba_to_msf(msf_to_lba(entry.cdte_addr.msf.minute, entry.cdte_addr.msf.second, entry.cdte_addr.msf.frame) - CD_MSF_OFFSET, msf); - - *m = msf[0]; - *s = msf[1]; - *f = msf[2]; - - return 0; -} - -void ExecCfg(char *arg) { - char cfg[256]; - struct stat buf; - - strcpy(cfg, "./cfgDFCdrom"); - if (stat(cfg, &buf) != -1) { - if (fork() == 0) { - execl(cfg, "cfgDFCdrom", arg, NULL); - exit(0); - } - return; - } - - strcpy(cfg, "./cfg/DFCdrom"); - if (stat(cfg, &buf) != -1) { - if (fork() == 0) { - execl(cfg, "cfgDFCdrom", arg, NULL); - exit(0); - } - return; - } - - fprintf(stderr, "cfgDFCdrom file not found!\n"); -} - -long CDRconfigure() { - ExecCfg("configure"); - return 0; -} - -void CDRabout() { - ExecCfg("about"); -} - -long CDRtest(void) { - cdHandle = open(CdromDev, O_RDONLY); - if (cdHandle == -1) - return -1; - close(cdHandle); - cdHandle = -1; - return 0; -} +#endif |
