lba += length;
tracks[index].end = lba;
+ // weird MEGASD cue file extensions
+ tracks[index].loop = cue_data->tracks[n].loop;
+ tracks[index].loop_lba = cue_data->tracks[n].loop_lba;
+
sprintf_lba(tmp_ext, sizeof(tmp_ext), tracks[index].start);
elprintf(EL_STATUS, "Track %2i: %s %9i %s %s", n, tmp_ext, length,
tracks[index].type ? "AUDIO" : "DATA ",
if (ret != 3) continue;
data->tracks[count].sector_xlength = m*60*75 + s*75 + f;
}
+ else if (BEGINS(buff, "REM NOLOOP")) // MEGASD "extension"
+ {
+ data->tracks[count].loop = -1;
+ }
+ else if (BEGINS(buff, "REM LOOP")) // MEGASD "extension"
+ {
+ int lba;
+ get_token(buff+8, buff2, sizeof(buff2));
+ ret = sscanf(buff2, "%d", &lba);
+ if (ret != 1) lba = 0;
+ data->tracks[count].loop_lba = lba;
+ data->tracks[count].loop = 1;
+ }
else if (BEGINS(buff, "REM"))
continue;
else
* PicoDrive
* (C) irixxxx, 2024
*
- * MEGASD enhancement support
+ * MEGASD enhancement support as "documented" in "MegaSD DEV Manual Rev.2"
+ *
+ * Emulates parts of the MEGASD API for "CD enhanced Megadrive games". Missing:
+ * - Fader and volume control
+ * - enhanced SSF2 mapper
+ * - PCM access
+ * The missing features are AFAIK not used by any currently available patch.
+ * I'm not going to look into these until I see it used somewhere.
*/
#include "../pico_int.h"
static s32 msd_readlba = -1; // >= 0 if sector read is running
static int msd_loop, msd_index = -1; // >= 0 if audio track is playing
-static u16 verser[] = // mimick version 1.04 R7, serial 0x01234567
+static u16 verser[] = // mimick version 1.04 R7, serial 0x12345678
{ 0x4d45, 0x4741, 0x5344, 0x0104, 0x0700, 0xffff, 0x1234, 0x5678 };
// { 0x4d45, 0x4741, 0x5344, 0x9999, 0x9900, 0xffff, 0x1234, 0x5678 };
// play a track, looping from offset if enabled
static void msd_playtrack(int idx, s32 offs, int loop)
{
+ track_t *track;
+
+ if (idx < 1 || idx > cdd.toc.last) {
+ msd_result = msd_command = 0;
+ return;
+ }
msd_index = idx-1;
+
+ track = &cdd.toc.tracks[msd_index];
+ if (track->loop) {
+ // overridden by some bizarre proprietary extensions in the cue file
+ // NB using these extensions definitely prevents using CHD files with MD+!
+ loop = track->loop > 0;
+ offs = track->loop_lba;
+ }
+
msd_loop = loop;
msd_readlba = -1;
- msd_startlba = cdd.toc.tracks[msd_index].start + 150;
- msd_endlba = cdd.toc.tracks[msd_index].end + 150;
+ msd_startlba = track->start + 150;
+ msd_endlba = track->end + 150;
msd_looplba = msd_startlba + offs;
cdd_play(msd_startlba);
// play a range of sectors, with looping if enabled
static void msd_playsectors(s32 startlba, s32 endlba, s32 looplba, int loop)
{
+ if (startlba < 0 || startlba >= cdd.toc.tracks[cdd.toc.last].start) {
+ msd_result = msd_command = 0;
+ return;
+ }
+
msd_index = 99;
msd_loop = loop;
msd_readlba = -1;
// read a block of data
static void msd_readdata(s32 lba)
{
+ if (lba < 0 || lba >= cdd.toc.tracks[cdd.toc.last].start) {
+ msd_result = msd_command = 0;
+ return;
+ }
+
msd_index = -1;
- msd_readlba = lba;
+ msd_readlba = lba + 150;
cdd_play(msd_readlba);
}
case 0x17: msd_readdata(get32(0)); break;
case 0x18: msd_transfer();
msd_command = 0; break;
- case 0x19: msd_readdata(++msd_readlba); break;
+ case 0x19: msd_readdata(msd_readlba-150 + 1); break;
case 0x27: msd_result = cdd.toc.last << 8;
msd_command = 0; break;