pcsxr-1.9.92
[pcsx_rearmed.git] / macosx / plugins / DFCdrom / macsrc / cdr-macosx.c
CommitLineData
ef79bbde
P
1/*
2 * Copyright (c) 2010, Wei Mingzhi <whistler@openoffice.org>.
3 * All Rights Reserved.
4 *
5 * Based on: Cdrom for Psemu Pro like Emulators
6 * By: linuzappz <linuzappz@hotmail.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see <http://www.gnu.org/licenses>.
20 */
21
22#include "cdr.h"
23
24#ifdef _MACOSX
25
26#include <IOKit/IOKitLib.h>
27#include <IOKit/IOBSD.h>
28#include <IOKit/storage/IOCDMedia.h>
29#include <IOKit/storage/IODVDMedia.h>
30#include <IOKit/storage/IOMedia.h>
31#include <IOKit/storage/IOCDMediaBSDClient.h>
32#include <CoreFoundation/CoreFoundation.h>
33
34int cdHandle = -1;
35char cdDevice[4096] = "";
36
37static int IsPsxDisc(const char *dev) {
38 int fd;
39 char buf[CD_FRAMESIZE_RAW];
40 dk_cd_read_t r;
41
42 fd = open(dev, O_RDONLY, 0);
43 if (fd < 0) return 0;
44
45 memset(&r, 0, sizeof(r));
46
47 r.offset = msf_to_lba(0, 2, 4) * CD_FRAMESIZE_RAW;
48 r.sectorArea = 0xF8;
49 r.sectorType = kCDSectorTypeUnknown;
50 r.bufferLength = CD_FRAMESIZE_RAW;
51 r.buffer = buf;
52
53 if (ioctl(fd, DKIOCCDREAD, &r) != kIOReturnSuccess) {
54 close(fd);
55 return 0;
56 }
57
58 close(fd);
59
60 if (strncmp(buf + 56, "Sony Computer Entertainment", 27) == 0) {
61 return 1;
62 }
63
64 return 0;
65}
66
67static void FindCdDevice(char *dev) {
68 io_object_t next_media;
69 kern_return_t kern_result;
70 io_iterator_t media_iterator;
71 CFMutableDictionaryRef classes_to_match;
72 const char *name, *cd = kIOCDMediaClass, *dvd = kIODVDMediaClass;
73
74 dev[0] = '\0';
75 name = cd;
76
77start:
78 classes_to_match = IOServiceMatching(name);
79 if (classes_to_match == NULL) goto end;
80
81 CFDictionarySetValue(classes_to_match, CFSTR(kIOMediaEjectableKey),
82 kCFBooleanTrue);
83
84 kern_result = IOServiceGetMatchingServices(kIOMasterPortDefault,
85 classes_to_match, &media_iterator);
86
87 if (kern_result != KERN_SUCCESS) goto end;
88
89 next_media = IOIteratorNext(media_iterator);
90 if (next_media != 0) {
91 char psz_buf[0x32];
92 size_t dev_path_length;
93 CFTypeRef str_bsd_path;
94
95 do {
96 str_bsd_path = IORegistryEntryCreateCFProperty(next_media,
97 CFSTR(kIOBSDNameKey), kCFAllocatorDefault, 0);
98
99 if (str_bsd_path == NULL) {
100 IOObjectRelease(next_media);
101 continue;
102 }
103
104 strcpy(psz_buf, "/dev/r");
105 dev_path_length = strlen(psz_buf);
106
107 if (CFStringGetCString(str_bsd_path, (char *)&psz_buf + dev_path_length,
108 sizeof(psz_buf) - dev_path_length, kCFStringEncodingASCII))
109 {
110 strcpy(dev, psz_buf);
111
112 if (IsPsxDisc(dev)) {
113 CFRelease(str_bsd_path);
114 IOObjectRelease(next_media);
115 IOObjectRelease(media_iterator);
116 return;
117 }
118 }
119
120 CFRelease(str_bsd_path);
121 IOObjectRelease(next_media);
122 } while ((next_media = IOIteratorNext(media_iterator)) != 0);
123 }
124
125 IOObjectRelease(media_iterator);
126
127end:
128 if (dev[0] == '\0') {
129 if (name == cd) {
130 name = dvd; // Is this really necessary or correct? Dunno...
131 goto start;
132 }
133 }
134}
135
136int OpenCdHandle(const char *dev) {
137 if (dev != NULL && dev[0] != '\0') strcpy(cdDevice, dev);
138 else if (cdDevice[0] == '\0') FindCdDevice(cdDevice);
139
140 cdHandle = open(cdDevice, O_RDONLY, 0);
141 if (cdHandle < 0) return -1;
142
143 if (CdrSpeed > 0) {
144 u_int16_t speed = kCDSpeedMin * CdrSpeed;
145 ioctl(cdHandle, DKIOCCDSETSPEED, &speed);
146 }
147
148 return 0;
149}
150
151void CloseCdHandle() {
152 if (cdHandle != -1) close(cdHandle);
153 cdHandle = -1;
154}
155
156int IsCdHandleOpen() {
157 return 1;
158}
159
160long GetTN(unsigned char *buffer) {
161 if (cdHandle < 0) return -1;
162
163 // TODO
164 buffer[0] = 1;
165 buffer[1] = 1;
166
167 return 0;
168}
169
170long GetTD(unsigned char track, unsigned char *buffer) {
171 if (cdHandle < 0) return -1;
172
173 // TODO
174 memset(buffer + 1, 0, 3);
175 return 0;
176}
177
178long GetTE(unsigned char track, unsigned char *m, unsigned char *s, unsigned char *f) {
179 return -1; // TODO
180}
181
182long ReadSector(crdata *cr) {
183 int lba;
184 dk_cd_read_t r;
185
186 if (cdHandle < 0) return -1;
187
188 lba = msf_to_lba(cr->msf.cdmsf_min0, cr->msf.cdmsf_sec0, cr->msf.cdmsf_frame0);
189
190 memset(&r, 0, sizeof(r));
191
192 r.offset = lba * CD_FRAMESIZE_RAW;
193 r.sectorArea = 0xF8;
194 r.sectorType = kCDSectorTypeUnknown;
195 r.bufferLength = CD_FRAMESIZE_RAW;
196 r.buffer = cr->buf;
197
198 if (ioctl(cdHandle, DKIOCCDREAD, &r) != kIOReturnSuccess) {
199 return -1;
200 }
201
202 return 0;
203}
204
205long PlayCDDA(unsigned char *sector) {
206 return 0; // TODO
207}
208
209long StopCDDA() {
210 return 0; // TODO
211}
212
213long GetStatus(int playing, struct CdrStat *stat) {
214 memset(stat, 0, sizeof(struct CdrStat));
215 stat->Type = 0x01;
216
217 // Close and reopen the CD handle. If opening failed,
218 // then there is no CD in drive.
219 // Note that this WILL be screwed if user inserted another
220 // removable device such as USB stick when tray is open.
221 // There may be a better way, but this should do the job.
222 if (cdHandle >= 0) {
223 close(cdHandle);
224 cdHandle = -1;
225 }
226
227 cdHandle = open(cdDevice, O_RDONLY, 0);
228 if (cdHandle < 0) {
229 // No CD in drive
230 stat->Type = 0xff;
231 stat->Status |= 0x10;
232 } else {
233 if (CdrSpeed > 0) {
234 u_int16_t speed = kCDSpeedMin * CdrSpeed;
235 ioctl(cdHandle, DKIOCCDSETSPEED, &speed);
236 }
237 }
238
239 return 0;
240}
241
242unsigned char *ReadSub(const unsigned char *time) {
243 return NULL; // TODO
244}
245
246char *CDRgetDriveLetter(void) {
247 return cdDevice;
248}
249
250#endif