aboutsummaryrefslogtreecommitdiff
path: root/plugins/dfcdrom/cdr-libcdio.c
diff options
context:
space:
mode:
authorPCSX* teams2010-11-16 14:15:22 +0200
committerGrazvydas Ignotas2010-11-16 14:15:22 +0200
commitef79bbde537d6b9c745a7d86cb9df1d04c35590d (patch)
treeef8d2520dbb9e1e345b41b12c9959f300ca8fd10 /plugins/dfcdrom/cdr-libcdio.c
downloadpcsx_rearmed-ef79bbde537d6b9c745a7d86cb9df1d04c35590d.tar.gz
pcsx_rearmed-ef79bbde537d6b9c745a7d86cb9df1d04c35590d.tar.bz2
pcsx_rearmed-ef79bbde537d6b9c745a7d86cb9df1d04c35590d.zip
pcsxr-1.9.92
Diffstat (limited to 'plugins/dfcdrom/cdr-libcdio.c')
-rw-r--r--plugins/dfcdrom/cdr-libcdio.c257
1 files changed, 257 insertions, 0 deletions
diff --git a/plugins/dfcdrom/cdr-libcdio.c b/plugins/dfcdrom/cdr-libcdio.c
new file mode 100644
index 0000000..738d203
--- /dev/null
+++ b/plugins/dfcdrom/cdr-libcdio.c
@@ -0,0 +1,257 @@
+/*
+ * 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>.
+ */
+
+#ifdef USE_LIBCDIO
+
+#include <cdio/cdio.h>
+#include <cdio/mmc.h>
+
+#include "cdr.h"
+
+static CdIo_t *cdHandle = NULL;
+
+static void SetSpeed(int speed) {
+ speed *= 176;
+ if (speed == 0) speed = 0xFFFF;
+
+ cdio_set_speed(cdHandle, speed);
+}
+
+static void SetSpinDown(unsigned char spindown) {
+ mmc_cdb_t cdb;
+ char buf[16];
+
+ memset(&cdb, 0, sizeof(cdb));
+
+ cdb.field[0] = 0x5A;
+ cdb.field[2] = 0x0D;
+ cdb.field[8] = sizeof(buf);
+
+ if (mmc_run_cmd(cdHandle, 10000, &cdb, SCSI_MMC_DATA_READ, sizeof(buf), buf) != DRIVER_OP_SUCCESS)
+ return;
+
+ buf[11] = (buf[11] & 0xF0) | (spindown & 0x0F);
+
+ memset(&cdb, 0, sizeof(cdb));
+ memset(buf, 0, 2);
+
+ cdb.field[0] = 0x55;
+ cdb.field[1] = 0x10;
+ cdb.field[8] = sizeof(buf);
+
+ mmc_run_cmd(cdHandle, 10000, &cdb, SCSI_MMC_DATA_WRITE, sizeof(buf), buf);
+}
+
+static void UnlockDoor() {
+ mmc_cdb_t cdb;
+
+ memset(&cdb, 0, sizeof(cdb));
+
+ cdb.field[0] = 0x1E;
+ cdb.field[4] = 0;
+
+ mmc_run_cmd(cdHandle, 10000, &cdb, SCSI_MMC_DATA_WRITE, 0, NULL);
+}
+
+int OpenCdHandle(const char *dev) {
+ if (dev == NULL || dev[0] == '\0') {
+ if ((dev = cdio_get_default_device(NULL)) == NULL) {
+ return -1;
+ }
+ }
+
+#ifdef __FreeBSD__
+ cdHandle = cdio_open_am_cd(dev, "CAM");
+#else
+ cdHandle = cdio_open_cd(dev);
+#endif
+
+ if (cdHandle != NULL) {
+ SetSpeed(CdrSpeed);
+ SetSpinDown(SpinDown);
+ UnlockDoor();
+
+ return 0;
+ }
+
+ return -1;
+}
+
+void CloseCdHandle() {
+ if (cdHandle != NULL) {
+ cdio_set_speed(cdHandle, 0xFFFF);
+ SetSpinDown(SPINDOWN_VENDOR_SPECIFIC);
+
+ cdio_destroy(cdHandle);
+ }
+
+ cdHandle = NULL;
+}
+
+int IsCdHandleOpen() {
+ return (cdHandle != NULL);
+}
+
+long GetTN(unsigned char *buffer) {
+ buffer[0] = cdio_get_first_track_num(cdHandle);
+ buffer[1] = cdio_get_last_track_num(cdHandle);
+
+ return 0;
+}
+
+long GetTD(unsigned char track, unsigned char *buffer) {
+ msf_t msf;
+
+ if (track == 0) track = CDIO_CDROM_LEADOUT_TRACK;
+
+ if (!cdio_get_track_msf(cdHandle, track, &msf)) {
+ memset(buffer + 1, 0, 3);
+ return 0;
+ }
+
+ buffer[0] = btoi(msf.f);
+ buffer[1] = btoi(msf.s);
+ buffer[2] = btoi(msf.m);
+
+ return 0;
+}
+
+long GetTE(unsigned char track, unsigned char *m, unsigned char *s, unsigned char *f) {
+ unsigned char msf[3];
+
+ lba_to_msf(cdio_get_track_lba(cdHandle, track + 1) - CD_MSF_OFFSET, msf);
+
+ *m = msf[0];
+ *s = msf[1];
+ *f = msf[2];
+
+ return 0;
+}
+
+long ReadSector(crdata *cr) {
+ int lba;
+ MMC_READ_CD cdb;
+
+ lba = msf_to_lba(cr->msf.cdmsf_min0, cr->msf.cdmsf_sec0, cr->msf.cdmsf_frame0);
+ memset(&cdb, 0, sizeof(cdb));
+
+ cdb.Code = 0xBE;
+ cdb.IncludeEDC = 1;
+ cdb.IncludeUserData = 1;
+ cdb.HeaderCode = 3;
+ cdb.IncludeSyncData = 1;
+ cdb.SubChannelSelection = 0;
+ cdb.StartingLBA[1] = lba >> 16;
+ cdb.StartingLBA[2] = lba >> 8;
+ cdb.StartingLBA[3] = lba;
+ cdb.TransferBlocks[2] = 1;
+
+ if (mmc_run_cmd(cdHandle, 10000, (mmc_cdb_t *)&cdb, SCSI_MMC_DATA_READ, sizeof(*cr), cr) != DRIVER_OP_SUCCESS)
+ return -1;
+
+ return 0;
+}
+
+long PlayCDDA(unsigned char *sector) {
+ msf_t start, end;
+
+ if (!cdio_get_track_msf(cdHandle, CDIO_CDROM_LEADOUT_TRACK, &end))
+ return -1;
+
+ start.m = itob(sector[0]);
+ start.s = itob(sector[1]);
+ start.f = itob(sector[2]);
+
+ if (cdio_audio_play_msf(cdHandle, &start, &end) != DRIVER_OP_SUCCESS)
+ return -1;
+
+ return 0;
+}
+
+long StopCDDA() {
+ cdio_subchannel_t subchnl;
+
+ if (cdio_audio_read_subchannel(cdHandle, &subchnl) != DRIVER_OP_SUCCESS)
+ return -1;
+
+ switch (subchnl.audio_status) {
+ case CDIO_MMC_READ_SUB_ST_PLAY:
+ case CDIO_MMC_READ_SUB_ST_PAUSED:
+ cdio_audio_stop(cdHandle);
+ }
+
+ return 0;
+}
+
+long GetStatus(int playing, struct CdrStat *stat) {
+ cdio_subchannel_t subchnl;
+
+ memset(stat, 0, sizeof(struct CdrStat));
+
+ if (playing) {
+ if (cdio_audio_read_subchannel(cdHandle, &subchnl) == DRIVER_OP_SUCCESS) {
+ stat->Time[0] = btoi(subchnl.abs_addr.m);
+ stat->Time[1] = btoi(subchnl.abs_addr.s);
+ stat->Time[2] = btoi(subchnl.abs_addr.f);
+ }
+ }
+
+ stat->Type = 0x01;
+
+ if (mmc_get_tray_status(cdHandle)) {
+ stat->Type = 0xff;
+ stat->Status |= 0x10;
+ } else {
+ SetSpeed(CdrSpeed);
+ SetSpinDown(SpinDown);
+ UnlockDoor();
+ }
+
+ return 0;
+}
+
+unsigned char *ReadSub(const unsigned char *time) {
+ int lba = msf_to_lba(btoi(time[0]), btoi(time[1]), btoi(time[2]));
+ static unsigned char buf[CD_FRAMESIZE_RAW + 96];
+
+ MMC_READ_CD cdb;
+
+ memset(&cdb, 0, sizeof(cdb));
+
+ cdb.Code = 0xBE;
+ cdb.IncludeEDC = 1;
+ cdb.IncludeUserData = 1;
+ cdb.HeaderCode = 3;
+ cdb.IncludeSyncData = 1;
+ cdb.StartingLBA[1] = lba >> 16;
+ cdb.StartingLBA[2] = lba >> 8;
+ cdb.StartingLBA[3] = lba;
+ cdb.TransferBlocks[2] = 1;
+ cdb.SubChannelSelection = 1;
+
+ if (mmc_run_cmd(cdHandle, 10000, (mmc_cdb_t *)&cdb, SCSI_MMC_DATA_READ, sizeof(buf), buf) != DRIVER_OP_SUCCESS)
+ return NULL;
+
+ DecodeRawSubData(buf + CD_FRAMESIZE_RAW);
+ return buf + CD_FRAMESIZE_RAW;
+}
+
+#endif