core, add md+ cue file extensions
authorkub <derkub@gmail.com>
Tue, 24 Sep 2024 20:02:54 +0000 (22:02 +0200)
committerkub <derkub@gmail.com>
Tue, 24 Sep 2024 20:23:12 +0000 (22:23 +0200)
pico/cd/cd_image.c
pico/cd/cd_parse.c
pico/cd/cdd.h
pico/cd/megasd.c
pico/cd/memory.c
pico/pico.h

index 9bd29ce..afe9dff 100644 (file)
@@ -193,6 +193,10 @@ int load_cd_image(const char *cd_img_name, int *type)
       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 ",
index eeb3e88..9ca0e04 100644 (file)
@@ -416,6 +416,19 @@ file_ok:
                        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
index d896e25..7174fcf 100644 (file)
@@ -69,6 +69,7 @@ typedef struct
   int offset;
   int start;
   int end;
+  int loop, loop_lba; /* for MEGASD */
 } track_t; 
 
 /* CD TOC */
index c34669c..ffc5aea 100644 (file)
@@ -2,7 +2,14 @@
  * 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"
@@ -24,7 +31,7 @@ static s32 msd_startlba, msd_endlba, msd_looplba;
 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 };
 
@@ -76,12 +83,27 @@ static void cdd_stop(void)
 // 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);
@@ -90,6 +112,11 @@ static void msd_playtrack(int idx, s32 offs, int loop)
 // 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;
@@ -104,8 +131,13 @@ static void msd_playsectors(s32 startlba, s32 endlba, s32 looplba, int loop)
 // 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);
 }
@@ -169,7 +201,7 @@ void msd_process(u16 d)
   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;
index 4ccf238..f6d64e5 100644 (file)
@@ -791,7 +791,7 @@ void PicoWrite8_mcd_io(u32 a, u32 d)
     return;\r
   }\r
 \r
-  if (carthw_ssf2_active && (a & ~0x0e) == 0xa130f1 && a != 0xa130f1)\r
+  if (carthw_ssf2_active)\r
     carthw_ssf2_write8(a, d); // for MSU/MD+\r
   else\r
     PicoWrite8_io(a, d);\r
@@ -809,7 +809,7 @@ void PicoWrite16_mcd_io(u32 a, u32 d)
     return;\r
   }\r
 \r
-  if (carthw_ssf2_active && (a & ~0x0f) == 0xa130f0 && a != 0xa130f0)\r
+  if (carthw_ssf2_active)\r
     carthw_ssf2_write16(a, d); // for MSU/MD+\r
   else\r
     PicoWrite16_io(a, d);\r
index 6759f73..a48310f 100644 (file)
@@ -303,6 +303,7 @@ typedef struct
        int pregap;             /* pregap for current track */\r
        int sector_offset;      /* in current file */\r
        int sector_xlength;\r
+       int loop, loop_lba;     /* MEGASD extensions */\r
        enum cd_track_type type;\r
 } cd_track_t;\r
 \r