pandora: fix readme and pxml version
[picodrive.git] / pico / cd / cdd.c
CommitLineData
274fcc35 1/***************************************************************************************
2 * Genesis Plus
3 * CD drive processor & CD-DA fader
4 *
5 * Copyright (C) 2012-2013 Eke-Eke (Genesis Plus GX)
6 *
7 * Redistribution and use of this code or any derivative works are permitted
8 * provided that the following conditions are met:
9 *
10 * - Redistributions may not be sold, nor may they be used in a commercial
11 * product or activity.
12 *
13 * - Redistributions that are modified from the original source must include the
14 * complete source code, including the source code for all components used by a
15 * binary built from the modified sources. However, as a special exception, the
16 * source code distributed need not include anything that is normally distributed
17 * (in either source or binary form) with the major components (compiler, kernel,
18 * and so on) of the operating system on which the executable runs, unless that
19 * component itself accompanies the executable.
20 *
21 * - Redistributions must reproduce the above copyright notice, this list of
22 * conditions and the following disclaimer in the documentation and/or other
23 * materials provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 *
37 ****************************************************************************************/
38
39#include "../pico_int.h"
40#include "genplus_macros.h"
15ca7152 41#include "cd_parse.h"
274fcc35 42#include "cdd.h"
43
44#ifdef USE_LIBTREMOR
45#define SUPPORTED_EXT 20
46#else
47#define SUPPORTED_EXT 10
48#endif
49
50cdd_t cdd;
51
02ff0254 52#define is_audio(index) \
53 (cdd.toc.tracks[index].type & CT_AUDIO)
54
274fcc35 55/* BCD conversion lookup tables */
56static const uint8 lut_BCD_8[100] =
57{
58 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
59 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
60 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
61 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
62 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
63 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
64 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
65 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
66 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
67 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
68};
69
70static const uint16 lut_BCD_16[100] =
71{
72 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009,
73 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107, 0x0108, 0x0109,
74 0x0200, 0x0201, 0x0202, 0x0203, 0x0204, 0x0205, 0x0206, 0x0207, 0x0208, 0x0209,
75 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0305, 0x0306, 0x0307, 0x0308, 0x0309,
76 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, 0x0409,
77 0x0500, 0x0501, 0x0502, 0x0503, 0x0504, 0x0505, 0x0506, 0x0507, 0x0508, 0x0509,
78 0x0600, 0x0601, 0x0602, 0x0603, 0x0604, 0x0605, 0x0606, 0x0607, 0x0608, 0x0609,
79 0x0700, 0x0701, 0x0702, 0x0703, 0x0704, 0x0705, 0x0706, 0x0707, 0x0708, 0x0709,
80 0x0800, 0x0801, 0x0802, 0x0803, 0x0804, 0x0805, 0x0806, 0x0807, 0x0808, 0x0809,
81 0x0900, 0x0901, 0x0902, 0x0903, 0x0904, 0x0905, 0x0906, 0x0907, 0x0908, 0x0909,
82};
83
84/* pre-build TOC */
85static const uint16 toc_snatcher[21] =
86{
87 56014, 495, 10120, 20555, 1580, 5417, 12502, 16090, 6553, 9681,
88 8148, 20228, 8622, 6142, 5858, 1287, 7424, 3535, 31697, 2485,
89 31380
90};
91
92static const uint16 toc_lunar[52] =
93{
94 5422, 1057, 7932, 5401, 6380, 6592, 5862, 5937, 5478, 5870,
95 6673, 6613, 6429, 4996, 4977, 5657, 3720, 5892, 3140, 3263,
96 6351, 5187, 3249, 1464, 1596, 1750, 1751, 6599, 4578, 5205,
97 1550, 1827, 2328, 1346, 1569, 1613, 7199, 4928, 1656, 2549,
98 1875, 3901, 1850, 2399, 2028, 1724, 4889, 14551, 1184, 2132,
99 685, 3167
100};
101
102static const uint32 toc_shadow[15] =
103{
104 10226, 70054, 11100, 12532, 12444, 11923, 10059, 10167, 10138, 13792,
105 11637, 2547, 2521, 3856, 900
106};
107
108static const uint32 toc_dungeon[13] =
109{
110 2250, 22950, 16350, 24900, 13875, 19950, 13800, 15375, 17400, 17100,
111 3325, 6825, 25275
112};
113
114static const uint32 toc_ffight[26] =
115{
116 11994, 9742, 10136, 9685, 9553, 14588, 9430, 8721, 9975, 9764,
117 9704, 12796, 585, 754, 951, 624, 9047, 1068, 817, 9191, 1024,
118 14562, 10320, 8627, 3795, 3047
119};
120
121static const uint32 toc_ffightj[29] =
122{
123 11994, 9752, 10119, 9690, 9567, 14575, 9431, 8731, 9965, 9763,
124 9716, 12791, 579, 751, 958, 630, 9050, 1052, 825, 9193, 1026,
125 14553, 9834, 10542, 1699, 1792, 1781, 3783, 3052
126};
127
ba11a481 128#if 0
274fcc35 129/* supported WAVE file header (16-bit stereo samples @44.1kHz) */
130static const unsigned char waveHeader[32] =
131{
132 0x57,0x41,0x56,0x45,0x66,0x6d,0x74,0x20,0x10,0x00,0x00,0x00,0x01,0x00,0x02,0x00,
133 0x44,0xac,0x00,0x00,0x10,0xb1,0x02,0x00,0x04,0x00,0x10,0x00,0x64,0x61,0x74,0x61
134};
ba11a481 135#endif
274fcc35 136
137#ifdef USE_LIBTREMOR
138#ifdef DISABLE_MANY_OGG_OPEN_FILES
139static void ogg_free(int i)
140{
141 /* clear OGG file descriptor to prevent file from being closed */
142 cdd.toc.tracks[i].vf.datasource = NULL;
143
144 /* close VORBIS file structure */
145 ov_clear(&cdd.toc.tracks[i].vf);
146
147 /* indicates that the track is a seekable VORBIS file */
148 cdd.toc.tracks[i].vf.seekable = 1;
149
150 /* reset file reading position */
151 fseek(cdd.toc.tracks[i].fd, 0, SEEK_SET);
152}
153#endif
154#endif
155
f56ffef0 156static off_t read_pos = -1;
157
274fcc35 158void cdd_reset(void)
159{
de5da52e 160 /* stop audio streaming */
161 Pico_mcd->cdda_stream = NULL;
162
274fcc35 163 /* reset cycle counter */
164 cdd.cycles = 0;
165
166 /* reset drive access latency */
167 cdd.latency = 0;
168
169 /* reset track index */
549dd407 170 cdd.index = 0;
274fcc35 171
172 /* reset logical block address */
173 cdd.lba = 0;
174
175 /* reset status */
7b3ddc11 176 cdd.status = NO_DISC;
177
274fcc35 178 /* reset CD-DA fader (full volume) */
179 cdd.volume = 0x400;
180
181 /* clear CD-DA output */
182 cdd.audio[0] = cdd.audio[1] = 0;
f56ffef0 183
a85010ba 184 /* no audio track playing */
185 Pico_mcd->s68k_regs[0x36+0] = 0x01;
f56ffef0 186 /* reset file read position */
187 read_pos = -1;
274fcc35 188}
189
190/* FIXME: use cdd_read_audio() instead */
b0be121b 191void cdd_play_audio(int index, int lba)
274fcc35 192{
193 int i, base, lba_offset, lb_len;
194
4aaedc89 195 for (i = index; i >= 0; i--)
274fcc35 196 if (cdd.toc.tracks[i].fd != NULL)
197 break;
4e18e219 198 // prevent playing from file with binary track if MD+ (Doom Fusion)
78673090 199 // TODO: this doesn't cover all tracks being in a single bin file properly:
200 // in that case, fd should be duplicated to work properly with this MD+ shit.
4e18e219 201 if (! is_audio(index) || (read_pos >= 0 && cdd.index == i && ! is_audio(i)))
202 return;
274fcc35 203
204 Pico_mcd->cdda_stream = cdd.toc.tracks[i].fd;
78673090 205 Pico_mcd->cdda_type = cdd.toc.tracks[i].type;
274fcc35 206 base = cdd.toc.tracks[index].offset;
207 lba_offset = lba - cdd.toc.tracks[index].start;
208 lb_len = cdd.toc.tracks[index].end - cdd.toc.tracks[index].start;
209
210 elprintf(EL_CD, "play #%d lba %d base %d", index, lba, base);
211
212 cdda_start_play(base, lba_offset, lb_len);
213}
214
4e18e219 215static void cdd_seek(int index, int lba)
274fcc35 216{
274fcc35 217#ifdef USE_LIBTREMOR
218#ifdef DISABLE_MANY_OGG_OPEN_FILES
4e18e219 219 /* close previous track VORBIS file structure to save memory */
220 if (is_audio(cdd.index) && cdd.toc.tracks[cdd.index].vf.datasource)
274fcc35 221 {
4e18e219 222 ogg_free(cdd.index);
223 }
44479027 224
4e18e219 225 /* open current track VORBIS file */
226 if (is_audio(index) && cdd.toc.tracks[index].vf.seekable)
227 {
228 ov_open(cdd.toc.tracks[index].fd,&cdd.toc.tracks[index].vf,0,0);
274fcc35 229 }
230#endif
231#endif
232
44479027 233 /* update current track index and LBA */
4e18e219 234 cdd.index = (index < 0 ? 0 : index);
44479027 235 cdd.lba = lba;
4e18e219 236 if (index < 0) return;
274fcc35 237
44479027 238 /* stay within track limits when seeking files */
274fcc35 239 if (lba < cdd.toc.tracks[cdd.index].start)
240 {
241 lba = cdd.toc.tracks[cdd.index].start;
242 }
243
44479027 244 /* seek to current block */
02ff0254 245 if (!is_audio(cdd.index))
274fcc35 246 {
247 /* DATA track */
44479027 248 read_pos = lba * cdd.sectorSize;
249 pm_seek(cdd.toc.tracks[cdd.index].fd, read_pos, SEEK_SET);
274fcc35 250 }
251#ifdef USE_LIBTREMOR
252 else if (cdd.toc.tracks[cdd.index].vf.seekable)
253 {
274fcc35 254 /* VORBIS AUDIO track */
255 ov_pcm_seek(&cdd.toc.tracks[cdd.index].vf, (lba - cdd.toc.tracks[cdd.index].start) * 588 - cdd.toc.tracks[cdd.index].offset);
256 }
257#endif
258#if 0
259 else if (cdd.toc.tracks[cdd.index].fd)
260 {
261 /* PCM AUDIO track */
262 fseek(cdd.toc.tracks[cdd.index].fd, (lba * 2352) - cdd.toc.tracks[cdd.index].offset, SEEK_SET);
263 }
264#else
265 else
266 {
b0be121b 267 cdd_play_audio(cdd.index, lba);
274fcc35 268 }
269#endif
44479027 270}
271
272int cdd_context_save(uint8 *state)
273{
274 int bufferptr = 0;
275
276 save_param(&cdd.cycles, sizeof(cdd.cycles));
277 save_param(&cdd.latency, sizeof(cdd.latency));
278 save_param(&cdd.index, sizeof(cdd.index));
279 save_param(&cdd.lba, sizeof(cdd.lba));
280 save_param(&cdd.scanOffset, sizeof(cdd.scanOffset));
281 save_param(&cdd.volume, sizeof(cdd.volume));
282 save_param(&cdd.status, sizeof(cdd.status));
283
284 return bufferptr;
285}
286
287int cdd_context_load(uint8 *state)
288{
289 int bufferptr = 0;
290
291 load_param(&cdd.cycles, sizeof(cdd.cycles));
292 load_param(&cdd.latency, sizeof(cdd.latency));
293 load_param(&cdd.index, sizeof(cdd.index));
294 load_param(&cdd.lba, sizeof(cdd.lba));
295 load_param(&cdd.scanOffset, sizeof(cdd.scanOffset));
296 load_param(&cdd.volume, sizeof(cdd.volume));
297 load_param(&cdd.status, sizeof(cdd.status));
298
299 /* seek to current track position */
4e18e219 300 cdd_seek(cdd.index, cdd.lba);
274fcc35 301
302 return bufferptr;
303}
304
305int cdd_context_load_old(uint8 *state)
306{
307 memcpy(&cdd.lba, state + 8, sizeof(cdd.lba));
4e18e219 308 cdd_seek(cdd.index, cdd.lba);
44479027 309
274fcc35 310 return 12 * 4;
311}
312
313int cdd_load(const char *filename, int type)
314{
315 char header[0x210];
316 int ret;
317
318 /* first unmount any loaded disc */
319 cdd_unload();
320
321 /* genplus parses cue here, in PD we use our own parser */
322 ret = load_cd_image(filename, &type);
323 if (ret != 0)
324 return ret;
325
f6043d93 326 if (type == CT_ISO) {
327 /* ISO format (2048 bytes data blocks) */
328 cdd.sectorSize = 2048;
329 } else {
330 /* audio or BIN format (2352 bytes data blocks) */
331 cdd.sectorSize = 2352;
332 }
333
274fcc35 334 /* read first 16 bytes */
335 pm_read(header, 0x10, cdd.toc.tracks[0].fd);
336
337 /* look for valid CD image ID string */
f6043d93 338 if (!Pico.romsize && memcmp("SEGADISCSYSTEM", header, 14))
339 {
274fcc35 340 /* if not found, read next 16 bytes */
341 pm_read(header, 0x10, cdd.toc.tracks[0].fd);
342
343 /* look again for valid CD image ID string */
344 if (memcmp("SEGADISCSYSTEM", header, 14))
345 {
346 elprintf(EL_STATUS|EL_ANOMALY, "cd: bad cd image?");
347 /* assume bin without security code */
348 }
274fcc35 349 }
350
15ca7152 351 pm_sectorsize(cdd.sectorSize, cdd.toc.tracks[0].fd);
274fcc35 352
274fcc35 353 /* Simulate audio tracks if none found */
f6043d93 354 if (!Pico.romsize && cdd.toc.last == 1)
274fcc35 355 {
f6043d93 356 /* read CD image header + security code */
357 pm_read(header + 0x10, 0x200, cdd.toc.tracks[0].fd);
358
274fcc35 359 /* Some games require exact TOC infos */
360 if (strstr(header + 0x180,"T-95035") != NULL)
361 {
362 /* Snatcher */
363 cdd.toc.last = cdd.toc.end = 0;
364 do
365 {
366 cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end;
367 cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + toc_snatcher[cdd.toc.last];
368 cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end;
369 cdd.toc.last++;
370 }
371 while (cdd.toc.last < 21);
372 }
373 else if (strstr(header + 0x180,"T-127015") != NULL)
374 {
375 /* Lunar - The Silver Star */
376 cdd.toc.last = cdd.toc.end = 0;
377 do
378 {
379 cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end;
380 cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + toc_lunar[cdd.toc.last];
381 cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end;
382 cdd.toc.last++;
383 }
384 while (cdd.toc.last < 52);
385 }
386 else if (strstr(header + 0x180,"T-113045") != NULL)
387 {
388 /* Shadow of the Beast II */
389 cdd.toc.last = cdd.toc.end = 0;
390 do
391 {
392 cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end;
393 cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + toc_shadow[cdd.toc.last];
394 cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end;
395 cdd.toc.last++;
396 }
397 while (cdd.toc.last < 15);
398 }
399 else if (strstr(header + 0x180,"T-143025") != NULL)
400 {
401 /* Dungeon Explorer */
402 cdd.toc.last = cdd.toc.end = 0;
403 do
404 {
405 cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end;
406 cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + toc_dungeon[cdd.toc.last];
407 cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end;
408 cdd.toc.last++;
409 }
410 while (cdd.toc.last < 13);
411 }
412 else if (strstr(header + 0x180,"MK-4410") != NULL)
413 {
414 /* Final Fight CD (USA, Europe) */
415 cdd.toc.last = cdd.toc.end = 0;
416 do
417 {
418 cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end;
419 cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + toc_ffight[cdd.toc.last];
420 cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end;
421 cdd.toc.last++;
422 }
423 while (cdd.toc.last < 26);
424 }
425 else if (strstr(header + 0x180,"G-6013") != NULL)
426 {
427 /* Final Fight CD (Japan) */
428 cdd.toc.last = cdd.toc.end = 0;
429 do
430 {
431 cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end;
432 cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + toc_ffightj[cdd.toc.last];
433 cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end;
434 cdd.toc.last++;
435 }
436 while (cdd.toc.last < 29);
437 }
438#if 0
439 else
440 {
441 /* default TOC (99 tracks & 2s per audio tracks) */
442 do
443 {
444 cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end + 2*75;
445 cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + 2*75;
446 cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end;
447 cdd.toc.last++;
448 }
449 while ((cdd.toc.last < 99) && (cdd.toc.end < 56*60*75));
450 }
451#endif
452 }
453
454 /* Lead-out */
455 cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end;
456
457 /* CD loaded */
458 cdd.loaded = 1;
7b3ddc11 459
460 /* disc not scanned yet */
461 cdd.status = NO_DISC;
462
274fcc35 463 return 0;
464}
465
466int cdd_unload(void)
467{
468 int was_loaded = cdd.loaded;
469
470 if (cdd.loaded)
471 {
472 int i;
473
7e77080f 474 /* stop audio streaming */
78673090 475 if (Pico_mcd) Pico_mcd->cdda_stream = NULL;
7e77080f 476
274fcc35 477 /* close CD tracks */
478 if (cdd.toc.tracks[0].fd)
479 {
480 pm_close(cdd.toc.tracks[0].fd);
481 cdd.toc.tracks[0].fd = NULL;
15ca7152 482 if (cdd.toc.tracks[0].fname)
ef3241d2 483 free(cdd.toc.tracks[0].fname);
15ca7152 484 cdd.toc.tracks[0].fname = NULL;
274fcc35 485 }
486
487 for (i = 1; i < cdd.toc.last; i++)
488 {
489#ifdef USE_LIBTREMOR
490 if (cdd.toc.tracks[i].vf.datasource)
491 {
492 /* close VORBIS file (if still opened) */
493 ov_clear(&cdd.toc.tracks[i].vf);
494 }
495 else
496#endif
497 if (cdd.toc.tracks[i].fd)
498 {
499 /* close file */
78673090 500 if (cdd.toc.tracks[i].type == CT_MP3)
274fcc35 501 fclose(cdd.toc.tracks[i].fd);
502 else
15ca7152 503 pm_close(cdd.toc.tracks[i].fd);
504 cdd.toc.tracks[i].fd = NULL;
505 if (cdd.toc.tracks[i].fname)
ef3241d2 506 free(cdd.toc.tracks[i].fname);
15ca7152 507 cdd.toc.tracks[i].fname = NULL;
274fcc35 508
509 /* detect single file images */
510 if (cdd.toc.tracks[i+1].fd == cdd.toc.tracks[i].fd)
511 {
512 /* exit loop */
513 i = cdd.toc.last;
514 }
515 }
516 }
517
518 /* CD unloaded */
519 cdd.loaded = 0;
7b3ddc11 520
521 if (cdd.status != CD_OPEN)
522 cdd.status = NO_DISC;
274fcc35 523 }
524
525 /* reset TOC */
526 memset(&cdd.toc, 0x00, sizeof(cdd.toc));
527
528 /* unknown CD image file format */
529 cdd.sectorSize = 0;
530
531 return was_loaded;
532}
533
534void cdd_read_data(uint8 *dst)
535{
536 /* only read DATA track sectors */
44479027 537 if (!is_audio(cdd.index) && (cdd.lba >= cdd.toc.tracks[cdd.index].start) &&
538 (cdd.lba < cdd.toc.tracks[cdd.index].end))
274fcc35 539 {
44479027 540 off_t pos;
541
274fcc35 542 /* BIN format ? */
543 if (cdd.sectorSize == 2352)
544 {
545 /* skip 16-byte header */
44479027 546 pos = cdd.lba * 2352 + 16;
547 }
548 else
549 {
550 pos = cdd.lba * cdd.sectorSize;
551 }
552
553 if (pos != read_pos) {
554 pm_seek(cdd.toc.tracks[cdd.index].fd, pos, SEEK_SET);
555 read_pos = pos;
274fcc35 556 }
557
558 /* read sector data (Mode 1 = 2048 bytes) */
44479027 559 read_pos += pm_read(dst, 2048, cdd.toc.tracks[cdd.index].fd);
274fcc35 560 }
561}
562
563#if 0
564void cdd_read_audio(unsigned int samples)
565{
566 /* previous audio outputs */
567 int16 l = cdd.audio[0];
568 int16 r = cdd.audio[1];
569
570 /* get number of internal clocks (samples) needed */
571 samples = blip_clocks_needed(blip[0], samples);
572
573 /* audio track playing ? */
f47d0a28 574 if (!Pico_mcd->s68k_regs[0x36+0] && cdd.toc.tracks[cdd.index].fd)
274fcc35 575 {
576 int i, mul, delta;
577
578 /* current CD-DA fader volume */
579 int curVol = cdd.volume;
580
581 /* CD-DA fader volume setup (0-1024) */
582 int endVol = Pico_mcd->regs[0x34>>1].w >> 4;
583
584 /* read samples from current block */
585#ifdef USE_LIBTREMOR
586 if (cdd.toc.tracks[cdd.index].vf.datasource)
587 {
588 int len, done = 0;
589 int16 *ptr = (int16 *) (cdc.ram);
590 samples = samples * 4;
591 while (done < samples)
592 {
593 len = ov_read(&cdd.toc.tracks[cdd.index].vf, (char *)(cdc.ram + done), samples - done, 0);
594 if (len <= 0)
595 {
596 done = samples;
597 break;
598 }
599 done += len;
600 }
601 samples = done / 4;
602
603 /* process 16-bit (host-endian) stereo samples */
604 for (i=0; i<samples; i++)
605 {
606 /* CD-DA fader multiplier (cf. LC7883 datasheet) */
607 /* (MIN) 0,1,2,3,4,8,12,16,20...,1020,1024 (MAX) */
608 mul = (curVol & 0x7fc) ? (curVol & 0x7fc) : (curVol & 0x03);
609
610 /* left channel */
611 delta = ((ptr[0] * mul) / 1024) - l;
612 ptr++;
613 l += delta;
614 blip_add_delta_fast(blip[0], i, delta);
615
616 /* right channel */
617 delta = ((ptr[0] * mul) / 1024) - r;
618 ptr++;
619 r += delta;
620 blip_add_delta_fast(blip[1], i, delta);
621
622 /* update CD-DA fader volume (one step/sample) */
623 if (curVol < endVol)
624 {
625 /* fade-in */
626 curVol++;
627 }
628 else if (curVol > endVol)
629 {
630 /* fade-out */
631 curVol--;
632 }
633 else if (!curVol)
634 {
635 /* audio will remain muted until next setup */
636 break;
637 }
638 }
639 }
640 else
641#endif
642 {
643#ifdef LSB_FIRST
644 int16 *ptr = (int16 *) (cdc.ram);
645#else
646 uint8 *ptr = cdc.ram;
647#endif
648 fread(cdc.ram, 1, samples * 4, cdd.toc.tracks[cdd.index].fd);
649
650 /* process 16-bit (little-endian) stereo samples */
651 for (i=0; i<samples; i++)
652 {
653 /* CD-DA fader multiplier (cf. LC7883 datasheet) */
654 /* (MIN) 0,1,2,3,4,8,12,16,20...,1020,1024 (MAX) */
655 mul = (curVol & 0x7fc) ? (curVol & 0x7fc) : (curVol & 0x03);
656
657 /* left channel */
658 #ifdef LSB_FIRST
659 delta = ((ptr[0] * mul) / 1024) - l;
660 ptr++;
661 #else
662 delta = (((int16)((ptr[0] + ptr[1]*256)) * mul) / 1024) - l;
663 ptr += 2;
664 #endif
665 l += delta;
666 blip_add_delta_fast(blip[0], i, delta);
667
668 /* right channel */
669 #ifdef LSB_FIRST
670 delta = ((ptr[0] * mul) / 1024) - r;
671 ptr++;
672 #else
673 delta = (((int16)((ptr[0] + ptr[1]*256)) * mul) / 1024) - r;
674 ptr += 2;
675 #endif
676 r += delta;
677 blip_add_delta_fast(blip[1], i, delta);
678
679 /* update CD-DA fader volume (one step/sample) */
680 if (curVol < endVol)
681 {
682 /* fade-in */
683 curVol++;
684 }
685 else if (curVol > endVol)
686 {
687 /* fade-out */
688 curVol--;
689 }
690 else if (!curVol)
691 {
692 /* audio will remain muted until next setup */
693 break;
694 }
695 }
696 }
697
698 /* save current CD-DA fader volume */
699 cdd.volume = curVol;
700
701 /* save last audio output for next frame */
702 cdd.audio[0] = l;
703 cdd.audio[1] = r;
704 }
705 else
706 {
707 /* no audio output */
708 if (l) blip_add_delta_fast(blip[0], 0, -l);
709 if (r) blip_add_delta_fast(blip[1], 0, -r);
710
711 /* save audio output for next frame */
712 cdd.audio[0] = 0;
713 cdd.audio[1] = 0;
714 }
715
716 /* end of Blip Buffer timeframe */
717 blip_end_frame(blip[0], samples);
718 blip_end_frame(blip[1], samples);
719}
720#endif
721
722
723void cdd_update(void)
de5da52e 724{
274fcc35 725#ifdef LOG_CDD
726