Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/yabause/src/cd-linux.c
2 views
1
/* Copyright 2004-2005 Theo Berkau
2
Copyright 2004-2006 Guillaume Duhamel
3
Copyright 2005 Joost Peters
4
5
This file is part of Yabause.
6
7
Yabause is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or
10
(at your option) any later version.
11
12
Yabause is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
16
17
You should have received a copy of the GNU General Public License
18
along with Yabause; if not, write to the Free Software
19
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
*/
21
22
#include <sys/types.h>
23
#include <sys/ioctl.h>
24
#include <fcntl.h>
25
#include <linux/cdrom.h>
26
#include <unistd.h>
27
#include <string.h>
28
#include <stdio.h>
29
#ifdef LINUX_CDROM_H_IS_BROKEN
30
#include <limits.h>
31
#endif
32
33
#include "cdbase.h"
34
#include "debug.h"
35
36
static int LinuxCDInit(const char *);
37
static void LinuxCDDeInit(void);
38
static s32 LinuxCDReadTOC(u32 *);
39
static int LinuxCDGetStatus(void);
40
static int LinuxCDReadSectorFAD(u32, void *);
41
static void LinuxCDReadAheadFAD(u32);
42
43
CDInterface ArchCD = {
44
CDCORE_ARCH,
45
"Linux CD Drive",
46
LinuxCDInit,
47
LinuxCDDeInit,
48
LinuxCDGetStatus,
49
LinuxCDReadTOC,
50
LinuxCDReadSectorFAD,
51
LinuxCDReadAheadFAD,
52
};
53
54
static int hCDROM;
55
56
static int LinuxCDInit(const char * cdrom_name) {
57
if ((hCDROM = open(cdrom_name, O_RDONLY | O_NONBLOCK)) == -1) {
58
return -1;
59
}
60
LOG("CDInit (%s) OK\n", cdrom_name);
61
return 0;
62
}
63
64
static void LinuxCDDeInit(void) {
65
if (hCDROM != -1) {
66
close(hCDROM);
67
}
68
69
LOG("CDDeInit OK\n");
70
}
71
72
73
static s32 LinuxCDReadTOC(u32 * TOC)
74
{
75
struct cdrom_tochdr ctTOC;
76
struct cdrom_tocentry ctTOCent;
77
int i;
78
int add150 = 0;
79
80
ctTOCent.cdte_format = CDROM_LBA;
81
82
if (hCDROM != -1)
83
{
84
memset(TOC, 0xFF, 0xCC * 2);
85
memset(&ctTOC, 0xFF, sizeof(struct cdrom_tochdr));
86
87
if (ioctl(hCDROM, CDROMREADTOCHDR, &ctTOC) == -1) {
88
return 0;
89
}
90
91
ctTOCent.cdte_track = ctTOC.cdth_trk0;
92
ioctl(hCDROM, CDROMREADTOCENTRY, &ctTOCent);
93
if (ctTOCent.cdte_addr.lba == 0) add150 = 150;
94
TOC[0] = ((ctTOCent.cdte_ctrl << 28) |
95
(ctTOCent.cdte_adr << 24) |
96
(ctTOCent.cdte_addr.lba + add150));
97
98
// convert TOC to saturn format
99
for (i = ctTOC.cdth_trk0 + 1; i <= ctTOC.cdth_trk1; i++)
100
{
101
ctTOCent.cdte_track = i;
102
ioctl(hCDROM, CDROMREADTOCENTRY, &ctTOCent);
103
TOC[i - 1] = (ctTOCent.cdte_ctrl << 28) |
104
(ctTOCent.cdte_adr << 24) |
105
(ctTOCent.cdte_addr.lba + add150);
106
}
107
108
// Do First, Last, and Lead out sections here
109
110
ctTOCent.cdte_track = ctTOC.cdth_trk0;
111
ioctl(hCDROM, CDROMREADTOCENTRY, &ctTOCent);
112
TOC[99] = (ctTOCent.cdte_ctrl << 28) |
113
(ctTOCent.cdte_adr << 24) |
114
(ctTOC.cdth_trk0 << 16);
115
116
ctTOCent.cdte_track = ctTOC.cdth_trk1;
117
ioctl(hCDROM, CDROMREADTOCENTRY, &ctTOCent);
118
TOC[100] = (ctTOCent.cdte_ctrl << 28) |
119
(ctTOCent.cdte_adr << 24) |
120
(ctTOC.cdth_trk1 << 16);
121
122
ctTOCent.cdte_track = CDROM_LEADOUT;
123
ioctl(hCDROM, CDROMREADTOCENTRY, &ctTOCent);
124
TOC[101] = (ctTOCent.cdte_ctrl << 28) |
125
(ctTOCent.cdte_adr << 24) |
126
(ctTOCent.cdte_addr.lba + add150);
127
128
return (0xCC * 2);
129
}
130
131
return 0;
132
}
133
134
static int LinuxCDGetStatus(void) {
135
// 0 - CD Present, disc spinning
136
// 1 - CD Present, disc not spinning
137
// 2 - CD not present
138
// 3 - Tray open
139
// see ../windows/cd.cc for more info
140
141
int ret = ioctl(hCDROM, CDROM_DRIVE_STATUS, CDSL_CURRENT);
142
switch(ret) {
143
case CDS_DISC_OK:
144
return 0;
145
case CDS_NO_DISC:
146
return 2;
147
case CDS_TRAY_OPEN:
148
return 3;
149
}
150
151
// guess it's ok to say there's no disc here...
152
return 2;
153
}
154
155
static int LinuxCDReadSectorFAD(u32 FAD, void *buffer) {
156
union {
157
struct cdrom_msf msf;
158
char bigbuf[2352];
159
} position;
160
161
if (hCDROM != -1)
162
{
163
position.msf.cdmsf_min0 = FAD / 4500;
164
position.msf.cdmsf_sec0 = (FAD % 4500) / 75;
165
position.msf.cdmsf_frame0 = FAD % 75;
166
167
if (ioctl(hCDROM, CDROMREADRAW, &position) == -1) {
168
return 0;
169
}
170
171
memcpy(buffer, position.bigbuf, 2352);
172
173
return 1;
174
}
175
176
return 0;
177
}
178
179
static void LinuxCDReadAheadFAD(UNUSED u32 FAD)
180
{
181
// No-op
182
}
183
184