Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/yabause/src/cd-macosx.c
2 views
1
/* Copyright 2004-2005 Lucas Newman
2
Copyright 2004-2005 Theo Berkau
3
Copyright 2005 Weston Yager
4
Copyright 2006-2008 Guillaume Duhamel
5
Copyright 2010 Lawrence Sebald
6
7
This file is part of Yabause.
8
9
Yabause is free software; you can redistribute it and/or modify
10
it under the terms of the GNU General Public License as published by
11
the Free Software Foundation; either version 2 of the License, or
12
(at your option) any later version.
13
14
Yabause is distributed in the hope that it will be useful,
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
GNU General Public License for more details.
18
19
You should have received a copy of the GNU General Public License
20
along with Yabause; if not, write to the Free Software
21
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
*/
23
24
#include <stdio.h>
25
#include <string.h>
26
#include <unistd.h>
27
#include <fcntl.h>
28
#include <sys/ioctl.h>
29
#include <paths.h>
30
#include <sys/param.h>
31
#include <IOKit/IOKitLib.h>
32
#include <IOKit/IOBSD.h>
33
#include <IOKit/storage/IOMediaBSDClient.h>
34
#include <IOKit/storage/IOMedia.h>
35
#include <IOKit/storage/IOCDTypes.h>
36
#include <IOKit/storage/IOCDMedia.h>
37
#include <CoreFoundation/CoreFoundation.h>
38
#include <util.h>
39
40
#include "cdbase.h"
41
42
static int MacOSXCDInit(const char *);
43
static void MacOSXCDDeInit(void);
44
static int MacOSXCDGetStatus(void);
45
static s32 MacOSXCDReadTOC(u32 *);
46
static int MacOSXCDReadSectorFAD(u32, void *);
47
static void MacOSXCDReadAheadFAD(u32);
48
49
CDInterface ArchCD = {
50
CDCORE_ARCH,
51
"MacOSX CD Drive",
52
MacOSXCDInit,
53
MacOSXCDDeInit,
54
MacOSXCDGetStatus,
55
MacOSXCDReadTOC,
56
MacOSXCDReadSectorFAD,
57
MacOSXCDReadAheadFAD,
58
};
59
60
static int hCDROM;
61
62
static int MacOSXCDInit(const char * useless_for_now)
63
{
64
CFMutableDictionaryRef classesToMatch;
65
io_iterator_t mediaIterator;
66
io_object_t media;
67
char cdrom_name[ MAXPATHLEN ];
68
69
classesToMatch = IOServiceMatching(kIOCDMediaClass);
70
CFDictionarySetValue(classesToMatch, CFSTR(kIOMediaEjectableKey),
71
kCFBooleanTrue);
72
IOServiceGetMatchingServices(kIOMasterPortDefault,
73
classesToMatch, &mediaIterator);
74
75
media = IOIteratorNext(mediaIterator);
76
77
if(media)
78
{
79
CFTypeRef path;
80
81
path = IORegistryEntryCreateCFProperty(media,
82
CFSTR(kIOBSDNameKey),
83
kCFAllocatorDefault, 0);
84
85
if (path)
86
{
87
size_t length;
88
89
strcpy(cdrom_name, _PATH_DEV);
90
strcat(cdrom_name, "r");
91
length = strlen(cdrom_name);
92
93
CFStringGetCString(path, cdrom_name + length,
94
MAXPATHLEN - length, kCFStringEncodingUTF8);
95
96
CFRelease(path);
97
}
98
IOObjectRelease(media);
99
}
100
101
if ((hCDROM = open(cdrom_name, O_RDONLY)) == -1)
102
{
103
return -1;
104
}
105
106
return 0;
107
}
108
109
static void MacOSXCDDeInit(void)
110
{
111
if (hCDROM != -1)
112
{
113
close(hCDROM);
114
}
115
}
116
117
static CDTOC * GetTOCFromCDPath(void)
118
{
119
CFMutableDictionaryRef classesToMatch;
120
io_iterator_t mediaIterator;
121
io_object_t media;
122
CDTOC * TOC;
123
124
classesToMatch = IOServiceMatching(kIOCDMediaClass);
125
CFDictionarySetValue(classesToMatch, CFSTR(kIOMediaEjectableKey),
126
kCFBooleanTrue);
127
IOServiceGetMatchingServices(kIOMasterPortDefault,
128
classesToMatch, &mediaIterator);
129
130
media = IOIteratorNext(mediaIterator);
131
132
if(media)
133
{
134
CFDataRef TOCData = IORegistryEntryCreateCFProperty(media, CFSTR(kIOCDMediaTOCKey), kCFAllocatorDefault, 0);
135
TOC = malloc(CFDataGetLength(TOCData));
136
CFDataGetBytes(TOCData,CFRangeMake(0,CFDataGetLength(TOCData)),(UInt8 *)TOC);
137
CFRelease(TOCData);
138
IOObjectRelease(media);
139
}
140
141
return TOC;
142
}
143
144
static s32 MacOSXCDReadTOC(u32 *TOC)
145
{
146
int add150 = 150, tracks = 0;
147
u_char track;
148
int i, fad = 0;
149
CDTOC *cdTOC = GetTOCFromCDPath();
150
CDTOCDescriptor *pTrackDescriptors;
151
pTrackDescriptors = cdTOC->descriptors;
152
153
memset(TOC, 0xFF, 0xCC * 2);
154
155
/* Convert TOC to Saturn format */
156
for( i = 3; i < CDTOCGetDescriptorCount(cdTOC); i++ ) {
157
track = pTrackDescriptors[i].point;
158
fad = CDConvertMSFToLBA(pTrackDescriptors[i].p) + add150;
159
if ((track > 99) || (track < 1))
160
continue;
161
TOC[i-3] = (pTrackDescriptors[i].control << 28 | pTrackDescriptors[i].adr << 24 | fad);
162
tracks++;
163
}
164
165
/* First */
166
TOC[99] = pTrackDescriptors[0].control << 28 | pTrackDescriptors[0].adr << 24 | 1 << 16;
167
/* Last */
168
TOC[100] = pTrackDescriptors[1].control << 28 | pTrackDescriptors[1].adr << 24 | tracks << 16;
169
/* Leadout */
170
TOC[101] = pTrackDescriptors[2].control << 28 | pTrackDescriptors[2].adr << 24 | CDConvertMSFToLBA(pTrackDescriptors[2].p) + add150;
171
172
//free(cdTOC); Looks like this is not need, will look into that.
173
return (0xCC * 2);
174
}
175
176
static int MacOSXCDGetStatus(void)
177
{
178
// 0 - CD Present, disc spinning
179
// 1 - CD Present, disc not spinning
180
// 2 - CD not present
181
// 3 - Tray open
182
// see ../windows/cd.cc for more info
183
184
//Return that disc is present and spinning. 2 and 3 can't happen in the mac port, i don't understand what "not spinning" is supposed to say
185
return 0;
186
}
187
188
static int MacOSXCDReadSectorFAD(u32 FAD, void *buffer)
189
{
190
const int blockSize = 2352;
191
#ifdef CRAB_REWRITE
192
const int cacheBlocks = 32;
193
static u8 cache[blockSize * cacheBlocks];
194
static u32 cacheFAD = 0xFFFFFF00;
195
#endif
196
197
if (hCDROM != -1)
198
{
199
#ifdef CRAB_REWRITE
200
/* See if the block we are looking for is in the cache already... */
201
if(FAD < cacheFAD || FAD >= cacheFAD + cacheBlocks) {
202
/* Cache miss, read some blocks from the cd, then we'll hit the
203
cache below. */
204
if(!pread(hCDROM, cache, blockSize * cacheBlocks,
205
(FAD - 150) * blockSize)) {
206
return 0;
207
}
208
209
cacheFAD = FAD;
210
}
211
212
/* Cache hit, copy the block out. */
213
memcpy(buffer, cache + (blockSize * (FAD - cacheFAD)), blockSize);
214
return 1;
215
#else
216
if (pread(hCDROM, buffer, blockSize, (FAD - 150) * blockSize))
217
return true;
218
#endif
219
}
220
221
return false;
222
}
223
224
static void MacOSXCDReadAheadFAD(UNUSED u32 FAD)
225
{
226
// No-op
227
}
228
229