1 /*
2  * Copyright (c) 2010, Wei Mingzhi <whistler_wmz@users.sf.net>.
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 #ifndef __CDR_H__
23 #define __CDR_H__
24 
25 //#define DEBUG 1
26 
27 #include "config.h"
28 
29 #ifdef ENABLE_NLS
30 #include <libintl.h>
31 #include <locale.h>
32 #define _(x)  gettext(x)
33 #define N_(x) (x)
34 #elif defined(_MACOSX)
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38 #ifdef PCSXRCORE
39 __private_extern char* Pcsxr_locale_text(char* toloc);
40 #define _(String) Pcsxr_locale_text(String)
41 #define N_(String) String
42 #else
43 #ifndef PCSXRPLUG
44 #warning please define the plug being built to use Mac OS X localization!
45 #define _(msgid) msgid
46 #define N_(msgid) msgid
47 #else
48 //Kludge to get the preprocessor to accept PCSXRPLUG as a variable.
49 #define PLUGLOC_x(x,y) x ## y
50 #define PLUGLOC_y(x,y) PLUGLOC_x(x,y)
51 #define PLUGLOC PLUGLOC_y(PCSXRPLUG,_locale_text)
52 __private_extern char* PLUGLOC(char* toloc);
53 #define _(String) PLUGLOC(String)
54 #define N_(String) String
55 #endif
56 #ifdef __cplusplus
57 }
58 #endif
59 #endif
60 #else
61 #define _(x)  (x)
62 #define N_(x) (x)
63 #endif
64 
65 #include <stdio.h>
66 #include <stdlib.h>
67 #include <stdint.h>
68 #include <fcntl.h>
69 #include <sys/ioctl.h>
70 #include <sys/stat.h>
71 #include <unistd.h>
72 #include <pthread.h>
73 #include <time.h>
74 #include <string.h>
75 
76 #include "psemu_plugin_defs.h"
77 
78 #if defined (__linux__)
79 
80 #include <linux/cdrom.h>
81 #include <scsi/scsi.h>
82 #include <scsi/sg.h>
83 
84 #ifndef CDROMSETSPINDOWN
85 #define CDROMSETSPINDOWN 0x531e
86 #endif
87 
88 #define DEV_DEF		"/dev/cdrom"
89 
90 #else
91 
92 struct cdrom_msf {
93 	unsigned char cdmsf_min0;     /* start minute */
94 	unsigned char cdmsf_sec0;     /* start second */
95 	unsigned char cdmsf_frame0;   /* start frame */
96 	unsigned char cdmsf_min1;     /* end minute */
97 	unsigned char cdmsf_sec1;     /* end second */
98 	unsigned char cdmsf_frame1;   /* end frame */
99 };
100 
101 #define CD_SECS				60
102 #define CD_FRAMES			75
103 #define CD_MSF_OFFSET		150
104 #define CD_FRAMESIZE_SUB	96
105 
106 #if defined (__FreeBSD__)
107 #define DEV_DEF		"/dev/cd0"
108 #else
109 #define DEV_DEF		""
110 #endif
111 
112 #if !defined (USE_LIBCDIO) && !defined (_MACOSX)
113 #define USE_NULL	1
114 #endif
115 
116 #endif
117 
118 extern char CdromDev[256];
119 extern long ReadMode;
120 extern long UseSubQ;
121 extern long CacheSize;
122 extern long CdrSpeed;
123 extern long SpinDown;
124 
125 #define NORMAL		0
126 #define THREADED	1
127 #define READ_MODES	2
128 
129 #ifndef CD_FRAMESIZE_RAW
130 #define CD_FRAMESIZE_RAW 2352
131 #endif
132 
133 #define DATA_SIZE	(CD_FRAMESIZE_RAW - 12)
134 
135 // spindown codes
136 #define SPINDOWN_VENDOR_SPECIFIC	0x00
137 #define SPINDOWN_125MS				0x01
138 #define SPINDOWN_250MS				0x02
139 #define SPINDOWN_500MS				0x03
140 #define SPINDOWN_1S					0x04
141 #define SPINDOWN_2S					0x05
142 #define SPINDOWN_4S					0x06
143 #define SPINDOWN_8S					0x07
144 #define SPINDOWN_16S				0x08
145 #define SPINDOWN_32S				0x09
146 #define SPINDOWN_1MIN				0x0A
147 #define SPINDOWN_2MIN				0x0B
148 #define SPINDOWN_4MIN				0x0C
149 #define SPINDOWN_8MIN				0x0D
150 #define SPINDOWN_16MIN				0x0E
151 #define SPINDOWN_32MIN				0x0F
152 
153 typedef struct _MMC_READ_CD {
154 	unsigned char Code; // 0xBE
155 
156 	unsigned char RelativeAddress : 1;
157 	unsigned char : 1;
158 	unsigned char ExpectedSectorType : 3;
159 	unsigned char Lun : 3;
160 
161 	unsigned char StartingLBA[4];
162 	unsigned char TransferBlocks[3];
163 
164 	unsigned char : 1;
165 	unsigned char ErrorFlags : 2;
166 	unsigned char IncludeEDC : 1;
167 	unsigned char IncludeUserData : 1;
168 	unsigned char HeaderCode : 2;
169 	unsigned char IncludeSyncData : 1;
170 
171 	unsigned char SubChannelSelection : 3;
172 	unsigned char : 5;
173 
174 	unsigned char Ctrl;
175 } MMC_READ_CD;
176 
177 #define itob(i)		((i)/10*16 + (i)%10)	/* u_char to BCD */
178 #define btoi(b)		((b)/16*10 + (b)%16)	/* BCD to u_char */
179 
180 struct CdrStat {
181 	unsigned long Type;
182 	unsigned long Status;
183 	unsigned char Time[3];		// current playing time
184 };
185 
186 struct SubQ {
187 	char res0[12];
188 	unsigned char ControlAndADR;
189 	unsigned char TrackNumber;
190 	unsigned char IndexNumber;
191 	unsigned char TrackRelativeAddress[3];
192 	unsigned char Filler;
193 	unsigned char AbsoluteAddress[3];
194 	unsigned char CRC[2];
195 	char res1[72];
196 };
197 
198 typedef union {
199 	struct cdrom_msf msf;
200 	unsigned char buf[CD_FRAMESIZE_RAW];
201 } crdata;
202 
203 typedef struct {
204 	unsigned char msf[3];
205 	crdata cr;
206 	int ret;
207 } CacheData;
208 
209 long ReadNormal();
210 long ReadThreaded();
211 unsigned char* GetBNormal();
212 unsigned char* GetBThreaded();
213 
214 long CDRstop(void);
215 
216 void LoadConf();
217 void SaveConf();
218 
219 #ifdef DEBUG
220 #define PRINTF printf
221 #else
222 #define PRINTF(...) /* */
223 #endif
224 
225 unsigned int msf_to_lba(char m, char s, char f);
226 void lba_to_msf(unsigned int s, unsigned char *msf);
227 void DecodeRawSubData(unsigned char *subbuffer);
228 unsigned short calcCrc(unsigned char *d, int len);
229 
230 int OpenCdHandle();
231 void CloseCdHandle();
232 int IsCdHandleOpen();
233 long GetTN(unsigned char *buffer);
234 long GetTD(unsigned char track, unsigned char *buffer);
235 long GetTE(unsigned char track, unsigned char *m, unsigned char *s, unsigned char *f);
236 long ReadSector(crdata *cr);
237 long PlayCDDA(unsigned char *sector);
238 long StopCDDA();
239 long GetStatus(int playing, struct CdrStat *stat);
240 unsigned char *ReadSub(const unsigned char *time);
241 
242 #endif
243