cdda_start_play(base, lba_offset, lb_len);
}
-int cdd_context_save(uint8 *state)
-{
- int bufferptr = 0;
-
- save_param(&cdd.cycles, sizeof(cdd.cycles));
- save_param(&cdd.latency, sizeof(cdd.latency));
- save_param(&cdd.index, sizeof(cdd.index));
- save_param(&cdd.lba, sizeof(cdd.lba));
- save_param(&cdd.scanOffset, sizeof(cdd.scanOffset));
- save_param(&cdd.volume, sizeof(cdd.volume));
- save_param(&cdd.status, sizeof(cdd.status));
-
- return bufferptr;
-}
+static off_t read_pos = -1;
-int cdd_context_load(uint8 *state)
+void cdd_seek(int index, int lba)
{
- int lba;
- int bufferptr = 0;
+ int aindex = (index < 0 ? -index : index);
#ifdef USE_LIBTREMOR
#ifdef DISABLE_MANY_OGG_OPEN_FILES
- /* close previous track VORBIS file structure to save memory */
- if (cdd.toc.tracks[cdd.index].vf.datasource)
+ /* check if track index has changed */
+ if (index != cdd.index)
{
- ogg_free(cdd.index);
+ /* close previous track VORBIS file structure to save memory */
+ if (cdd.index >= 0 && cdd.toc.tracks[cdd.index].vf.datasource)
+ {
+ ogg_free(cdd.index);
+ }
+
+ /* open current track VORBIS file */
+ if (cdd.toc.tracks[aindex].vf.seekable)
+ {
+ ov_open(cdd.toc.tracks[aindex].fd,&cdd.toc.tracks[aindex].vf,0,0);
+ }
}
#endif
#endif
- load_param(&cdd.cycles, sizeof(cdd.cycles));
- load_param(&cdd.latency, sizeof(cdd.latency));
- load_param(&cdd.index, sizeof(cdd.index));
- load_param(&cdd.lba, sizeof(cdd.lba));
- load_param(&cdd.scanOffset, sizeof(cdd.scanOffset));
- load_param(&cdd.volume, sizeof(cdd.volume));
- load_param(&cdd.status, sizeof(cdd.status));
+ /* update current track index and LBA */
+ cdd.index = aindex;
+ cdd.lba = lba;
- /* adjust current LBA within track limit */
- lba = cdd.lba;
+ /* stay within track limits when seeking files */
if (lba < cdd.toc.tracks[cdd.index].start)
{
lba = cdd.toc.tracks[cdd.index].start;
}
- /* seek to current track position */
+ /* seek to current block */
if (!is_audio(cdd.index))
{
/* DATA track */
- if (cdd.toc.tracks[cdd.index].fd)
- {
- pm_seek(cdd.toc.tracks[cdd.index].fd, lba * cdd.sectorSize, SEEK_SET);
- }
+ read_pos = lba * cdd.sectorSize;
+ pm_seek(cdd.toc.tracks[cdd.index].fd, read_pos, SEEK_SET);
}
#ifdef USE_LIBTREMOR
else if (cdd.toc.tracks[cdd.index].vf.seekable)
{
-#ifdef DISABLE_MANY_OGG_OPEN_FILES
- /* VORBIS file need to be opened first */
- ov_open(cdd.toc.tracks[cdd.index].fd,&cdd.toc.tracks[cdd.index].vf,0,0);
-#endif
/* VORBIS AUDIO track */
ov_pcm_seek(&cdd.toc.tracks[cdd.index].vf, (lba - cdd.toc.tracks[cdd.index].start) * 588 - cdd.toc.tracks[cdd.index].offset);
}
cdd_change_track(cdd.index, lba);
}
#endif
+}
+
+int cdd_context_save(uint8 *state)
+{
+ int bufferptr = 0;
+
+ save_param(&cdd.cycles, sizeof(cdd.cycles));
+ save_param(&cdd.latency, sizeof(cdd.latency));
+ save_param(&cdd.index, sizeof(cdd.index));
+ save_param(&cdd.lba, sizeof(cdd.lba));
+ save_param(&cdd.scanOffset, sizeof(cdd.scanOffset));
+ save_param(&cdd.volume, sizeof(cdd.volume));
+ save_param(&cdd.status, sizeof(cdd.status));
+
+ return bufferptr;
+}
+
+int cdd_context_load(uint8 *state)
+{
+ int bufferptr = 0;
+
+ load_param(&cdd.cycles, sizeof(cdd.cycles));
+ load_param(&cdd.latency, sizeof(cdd.latency));
+ load_param(&cdd.index, sizeof(cdd.index));
+ load_param(&cdd.lba, sizeof(cdd.lba));
+ load_param(&cdd.scanOffset, sizeof(cdd.scanOffset));
+ load_param(&cdd.volume, sizeof(cdd.volume));
+ load_param(&cdd.status, sizeof(cdd.status));
+
+ /* seek to current track position */
+ cdd_seek(-cdd.index, cdd.lba);
return bufferptr;
}
int cdd_context_load_old(uint8 *state)
{
memcpy(&cdd.lba, state + 8, sizeof(cdd.lba));
+ cdd_seek(-cdd.index, cdd.lba);
+
return 12 * 4;
}
void cdd_read_data(uint8 *dst)
{
/* only read DATA track sectors */
- if (!is_audio(cdd.index) && (cdd.lba >= 0) && (cdd.lba < cdd.toc.tracks[cdd.index].end))
+ if (!is_audio(cdd.index) && (cdd.lba >= cdd.toc.tracks[cdd.index].start) &&
+ (cdd.lba < cdd.toc.tracks[cdd.index].end))
{
+ off_t pos;
+
/* BIN format ? */
if (cdd.sectorSize == 2352)
{
/* skip 16-byte header */
- pm_seek(cdd.toc.tracks[cdd.index].fd, cdd.lba * 2352 + 16, SEEK_SET);
+ pos = cdd.lba * 2352 + 16;
+ }
+ else
+ {
+ pos = cdd.lba * cdd.sectorSize;
+ }
+
+ if (pos != read_pos) {
+ pm_seek(cdd.toc.tracks[cdd.index].fd, pos, SEEK_SET);
+ read_pos = pos;
}
/* read sector data (Mode 1 = 2048 bytes) */
- pm_read(dst, 2048, cdd.toc.tracks[cdd.index].fd);
+ read_pos += pm_read(dst, 2048, cdd.toc.tracks[cdd.index].fd);
}
}
header[3] = 0x01;
/* data track sector read is controlled by CDC */
- cdd.lba += cdc_decoder_update(header);
+ cdc_decoder_update(header);
}
else
{
/* audio blocks are still sent to CDC as well as CD DAC/Fader */
cdc_decoder_update(header);
-
- /* next audio block is automatically read */
- cdd.lba++;
}
+
+ /* next block is automatically read */
+ cdd.lba++;
/* check end of current track */
if (cdd.lba >= cdd.toc.tracks[cdd.index].end)
{
-#ifdef USE_LIBTREMOR
-#ifdef DISABLE_MANY_OGG_OPEN_FILES
- /* close previous track VORBIS file structure to save memory */
- if (cdd.toc.tracks[cdd.index].vf.datasource)
- {
- ogg_free(cdd.index);
- }
-#endif
-#endif
- /* play next track */
- cdd.index++;
-
/* PAUSE between tracks */
Pico_mcd->s68k_regs[0x36+0] = 0x01;
/* seek to next audio track start */
-#ifdef USE_LIBTREMOR
- if (cdd.toc.tracks[cdd.index].vf.seekable)
- {
-#ifdef DISABLE_MANY_OGG_OPEN_FILES
- /* VORBIS file need to be opened first */
- ov_open(cdd.toc.tracks[cdd.index].fd,&cdd.toc.tracks[cdd.index].vf,0,0);
-#endif
- ov_pcm_seek(&cdd.toc.tracks[cdd.index].vf, -cdd.toc.tracks[cdd.index].offset);
- }
- else
-#endif
-#if 0
- if (cdd.toc.tracks[cdd.index].fd)
- {
- fseek(cdd.toc.tracks[cdd.index].fd, (cdd.toc.tracks[cdd.index].start * 2352) - cdd.toc.tracks[cdd.index].offset, SEEK_SET);
- }
-#else
- {
- cdd_change_track(cdd.index, cdd.lba);
- }
-#endif
+ cdd_seek(cdd.index + 1, cdd.lba);
}
}
/* check current track limits */
if (cdd.lba >= cdd.toc.tracks[cdd.index].end)
{
-#ifdef USE_LIBTREMOR
-#ifdef DISABLE_MANY_OGG_OPEN_FILES
- /* close previous track VORBIS file structure to save memory */
- if (cdd.toc.tracks[cdd.index].vf.datasource)
- {
- ogg_free(cdd.index);
- }
-#endif
-#endif
/* next track */
- cdd.index++;
+ if (cdd.index >= cdd.toc.last)
+ {
+ /* no AUDIO track playing */
+ Pico_mcd->s68k_regs[0x36+0] = 0x01;
- /* skip directly to track start position */
- cdd.lba = cdd.toc.tracks[cdd.index].start;
-
- /* AUDIO track playing ? */
- if (cdd.status == CD_PLAY)
+ /* end of disc */
+ cdd.lba = cdd.toc.end;
+ cdd.status = CD_END;
+ }
+ else
{
- Pico_mcd->s68k_regs[0x36+0] = 0x00;
+ cdd_seek(cdd.index + 1, cdd.toc.tracks[cdd.index+1].start);
+
+ /* AUDIO track playing ? */
+ if (cdd.status == CD_PLAY && is_audio(cdd.index))
+ {
+ Pico_mcd->s68k_regs[0x36+0] = 0x00;
+ }
}
}
else if (cdd.lba < cdd.toc.tracks[cdd.index].start)
{
-#ifdef USE_LIBTREMOR
-#ifdef DISABLE_MANY_OGG_OPEN_FILES
- /* close previous track VORBIS file structure to save memory */
- if (cdd.toc.tracks[cdd.index].vf.datasource)
+ /* previous track */
+ if (cdd.index <= 0)
{
- ogg_free(cdd.index);
+ cdd_seek(0, 0);
+ }
+ else
+ {
+ cdd_seek(cdd.index - 1, cdd.toc.tracks[cdd.index-1].end);
}
-#endif
-#endif
-
- /* previous track */
- cdd.index--;
-
- /* skip directly to track end position */
- cdd.lba = cdd.toc.tracks[cdd.index].end;
- }
-
- /* check disc limits */
- if (cdd.index < 0)
- {
- cdd.index = 0;
- cdd.lba = 0;
- }
- else if (cdd.index >= cdd.toc.last)
- {
- /* no AUDIO track playing */
- Pico_mcd->s68k_regs[0x36+0] = 0x01;
-
- /* end of disc */
- cdd.index = cdd.toc.last;
- cdd.lba = cdd.toc.end;
- cdd.status = CD_END;
- return;
}
- /* seek to current block */
if (!is_audio(cdd.index))
{
/* no AUDIO track playing */
Pico_mcd->s68k_regs[0x36+0] = 0x01;
-
- /* DATA track */
- pm_seek(cdd.toc.tracks[cdd.index].fd, cdd.lba * cdd.sectorSize, SEEK_SET);
}
-#ifdef USE_LIBTREMOR
- else if (cdd.toc.tracks[cdd.index].vf.seekable)
- {
-#ifdef DISABLE_MANY_OGG_OPEN_FILES
- /* check if a new track is being played */
- if (!cdd.toc.tracks[cdd.index].vf.datasource)
- {
- /* VORBIS file need to be opened first */
- ov_open(cdd.toc.tracks[cdd.index].fd,&cdd.toc.tracks[cdd.index].vf,0,0);
- }
-#endif
- /* VORBIS AUDIO track */
- ov_pcm_seek(&cdd.toc.tracks[cdd.index].vf, (cdd.lba - cdd.toc.tracks[cdd.index].start) * 588 - cdd.toc.tracks[cdd.index].offset);
- }
-#endif
-#if 0
- else if (cdd.toc.tracks[cdd.index].fd)
- {
- /* PCM AUDIO track */
- fseek(cdd.toc.tracks[cdd.index].fd, (cdd.lba * 2352) - cdd.toc.tracks[cdd.index].offset, SEEK_SET);
- }
-#else
- else
- {
- cdd_change_track(cdd.index, cdd.lba);
- }
-#endif
}
}
Pico_mcd->s68k_regs[0x38+1] == 0x00 ||
Pico_mcd->s68k_regs[0x38+1] == 0x01)
{
- int lba = cdd.lba + 150;
+ int lba = cdd.lba + 150 - cdd.latency;
if (Pico_mcd->s68k_regs[0x38+1] == 0x01)
lba = abs(cdd.lba - cdd.toc.tracks[cdd.index].start);
if (Pico_mcd->s68k_regs[0x38+1] == 0x0f)
cdd.latency += (((cdd.lba - lba) * 120) / 270000);
}
- /* update current LBA */
- cdd.lba = lba;
-
/* get track index */
while ((cdd.toc.tracks[index].end <= lba) && (index < cdd.toc.last)) index++;
-#ifdef USE_LIBTREMOR
-#ifdef DISABLE_MANY_OGG_OPEN_FILES
- /* check if track index has changed */
- if (index != cdd.index)
- {
- /* close previous track VORBIS file structure to save memory */
- if (cdd.toc.tracks[cdd.index].vf.datasource)
- {
- ogg_free(cdd.index);
- }
-
- /* open current track VORBIS file */
- if (cdd.toc.tracks[index].vf.seekable)
- {
- ov_open(cdd.toc.tracks[index].fd,&cdd.toc.tracks[index].vf,0,0);
- }
- }
-#endif
-#endif
-
- /* update current track index */
- cdd.index = index;
-
- /* stay within track limits when seeking files */
- if (lba < cdd.toc.tracks[index].start)
- {
- lba = cdd.toc.tracks[index].start;
- }
-
- /* seek to current block */
- if (!is_audio(cdd.index))
- {
- /* DATA track */
- pm_seek(cdd.toc.tracks[cdd.index].fd, lba * cdd.sectorSize, SEEK_SET);
- }
-#ifdef USE_LIBTREMOR
- else if (cdd.toc.tracks[index].vf.seekable)
- {
- /* VORBIS AUDIO track */
- ov_pcm_seek(&cdd.toc.tracks[index].vf, (lba - cdd.toc.tracks[index].start) * 588 - cdd.toc.tracks[index].offset);
- }
-#endif
-#if 0
- else if (cdd.toc.tracks[index].fd)
- {
- /* PCM AUDIO track */
- fseek(cdd.toc.tracks[index].fd, (lba * 2352) - cdd.toc.tracks[index].offset, SEEK_SET);
- }
-#else
- else
- {
- cdd_change_track(index, lba);
- }
-#endif
+ cdd_seek(index, lba);
/* no audio track playing (yet) */
Pico_mcd->s68k_regs[0x36+0] = 0x01;
cdd.latency = ((cdd.lba - lba) * 120) / 270000;
}
- /* update current LBA */
- cdd.lba = lba;
-
/* get current track index */
while ((cdd.toc.tracks[index].end <= lba) && (index < cdd.toc.last)) index++;
-#ifdef USE_LIBTREMOR
-#ifdef DISABLE_MANY_OGG_OPEN_FILES
- /* check if track index has changed */
- if (index != cdd.index)
- {
- /* close previous track VORBIS file structure to save memory */
- if (cdd.toc.tracks[cdd.index].vf.datasource)
- {
- ogg_free(cdd.index);
- }
-
- /* open current track VORBIS file */
- if (cdd.toc.tracks[index].vf.seekable)
- {
- ov_open(cdd.toc.tracks[index].fd,&cdd.toc.tracks[index].vf,0,0);
- }
- }
-#endif
-#endif
-
- /* update current track index */
- cdd.index = index;
-
- /* stay within track limits */
- if (lba < cdd.toc.tracks[index].start)
- {
- lba = cdd.toc.tracks[index].start;
- }
-
/* seek to current block */
- if (!is_audio(cdd.index))
- {
- /* DATA track */
- pm_seek(cdd.toc.tracks[cdd.index].fd, lba * cdd.sectorSize, SEEK_SET);
- }
-#ifdef USE_LIBTREMOR
- else if (cdd.toc.tracks[index].vf.seekable)
- {
- /* VORBIS AUDIO track */
- ov_pcm_seek(&cdd.toc.tracks[index].vf, (lba - cdd.toc.tracks[index].start) * 588 - cdd.toc.tracks[index].offset);
- }
-#endif
-#if 0
- else if (cdd.toc.tracks[index].fd)
- {
- /* PCM AUDIO track */
- fseek(cdd.toc.tracks[index].fd, (lba * 2352) - cdd.toc.tracks[index].offset, SEEK_SET);
- }
-#else
- else
- {
- cdd_change_track(index, lba);
- }
-#endif
+ cdd_seek(index, lba);
/* no audio track playing */
Pico_mcd->s68k_regs[0x36+0] = 0x01;