--- interface.c.orig	Fri Nov 14 17:10:53 1997
+++ interface.c	Wed Dec  3 14:32:03 1997
@@ -317,8 +317,13 @@
       break;
   }
 }
+#else
+void dump_extra_info(void)
+{
+}
 #endif
 
+
 #if !defined(SIM_CD)
 static int FixupTOC(unsigned long tracks)
 {
@@ -541,6 +546,82 @@
 static unsigned char orgmode4 = 0xff;
 static unsigned char orgmode10, orgmode11;
 
+/* get CD capabilities page and determine whether drive supports MMC cmd set */
+/* returns 0 if not an MMC drive */
+/* returns 1 if an MMC drive which does not have the "CD-DA stream is accurate" bit set */
+/* returns 2 if an MMC drive which has the "CD-DA stream is accurate" bit set */
+
+static unsigned int 
+get_mmc(void)
+{
+      /* MODE_SENSE */
+      static unsigned char cmdblk0 [6] = { 
+	  0x1A, /* MODE_SENSE */
+	  0x00, /* return block descriptor */
+	  0x2A, /* CD capabilities and mechanical status page */
+	  0, /* reserved */
+	  22, /* sizeof(modesense - OFF) */
+	  0}; /* reserved */
+   
+      static unsigned char modesense[sizeof(struct sg_header) + 22]
+          __attribute__ ((aligned (__alignof__ (struct sg_header))));
+   
+      int base;
+
+      memcpy( cmd + OFF, cmdblk0, sizeof(cmdblk0) );
+      memset(modesense, 0, sizeof modesense);
+      /* do the scsi cmd */
+      if (handle_scsi_cmd (6, 0, cmd, sizeof modesense - OFF, modesense, 1)) {
+	  perror ("get_mmc mode sense failed\n");
+	  return 0;
+      }
+   
+      if ((modesense[OFF] & 0x3F) == 0x2A) {
+	 base = OFF;
+      } else if ((modesense[OFF+12] & 0x3F) == 0x2A) {
+	 base = OFF+12;
+      } else {
+#ifdef NOTDEF
+	 printf("Can't find mode sense data for page 2A\n");
+#endif
+	 return 0;
+      }
+#ifdef NOTDEF
+   printf("MMC data: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
+	  modesense[base + 0], 
+	  modesense[base + 1],
+	  modesense[base + 2], 
+	  modesense[base + 3], 
+	  modesense[base + 4], 
+	  modesense[base + 5], 
+	  modesense[base + 6], 
+	  modesense[base + 7], 
+	  modesense[base + 8], 
+	  modesense[base + 9], 
+	  modesense[base + 10], 
+	  modesense[base + 11], 
+	  modesense[base + 12],
+	  modesense[base + 13], 
+	  modesense[base + 14], 
+	  modesense[base + 15], 
+	  modesense[base + 16], 
+	  modesense[base + 17], 
+	  modesense[base + 18], 
+	  modesense[base + 19], 
+	  modesense[base + 20], 
+	  modesense[base + 21]);
+#endif
+      if ((modesense[base + 0] & 0x3F) == 0x2A &&
+	  modesense[base + 1] >= 5 &&
+	  (modesense[base + 5] & 0x01)) {
+	 if (modesense[base + 5] & 0x02) {
+	    return 2;
+	 }
+	 return 1;
+      }
+   return 0;
+}
+
 /* get current sector size from SCSI cdrom drive */
 static unsigned int 
 get_orig_sectorsize(unsigned char *m4, unsigned char *m10, 
@@ -871,6 +952,31 @@
     FatalError ("Read CD-ROM12MSF failed\n");
 }
 
+/* Read max. SectorBurst of cdda sectors to bufferCdda+OFF
+   via MMC standard READ CD command */
+static void ReadCddaMMC12 (unsigned char *p, long lSector, unsigned long SectorBurstVal )
+{
+  static unsigned char cmdblk [12] = {0xbe, 0x4, 0, 0, 0, 0, 0, 0, 0, 0xf0, 0, 0};
+
+  unsigned char *cmd0 = cmd + OFF;
+  int count = 3;
+
+  memcpy( cmd + OFF, cmdblk, sizeof(cmdblk) );
+
+  cmd0 [2] = (unsigned char)((lSector >> 24) & 0xFF);
+  cmd0 [3] = (unsigned char)((lSector >> 16) & 0xFF);
+  cmd0 [4] = (unsigned char)((lSector >> 8) & 0xFF);
+  cmd0 [5] = (unsigned char)(lSector & 0xFF);
+  cmd0 [8] = (unsigned char)SectorBurstVal;
+
+  while (handle_scsi_cmd(sizeof(cmdblk), 0, cmd, 
+			 SectorBurstVal * CD_FRAMESIZE_RAW, p - OFF, 0 )
+	 && count--)
+    ;
+  if (!count)
+    FatalError ("Read CD-ROMMMC12 failed\n");
+}
+
 /* Read the Sub-Q-Channel to SubQbuffer+OFF */
 static subq_chnl *ReadSubQSCSI ( unsigned char format, unsigned char track )
 {
@@ -1061,6 +1167,40 @@
         perror ("speed select Yamaha failed\n");
 }
 
+static void SpeedSelectSCSIMMC (unsigned speed)
+{
+   static unsigned char cmdblk [12] = {
+      0xBB, /* SET SPEED */
+	0, /* reserved */
+	0, /* read speed MSB */
+	0, /* read speed LSB */
+	0, /* write speed MSB */
+	0, /* write speed LSB */
+	0, /* reserved */
+	0, /* reserved */
+	0, /* reserved */
+	0, /* reserved */
+	0, /* reserved */
+	0}; /* reserved */
+
+  int spd;
+
+   memcpy( cmd + OFF, cmdblk, sizeof(cmdblk) );
+
+   if (speed == 0) {
+      spd = 0xFFFF;
+   } else {
+      spd = 176 * speed;
+   }
+   cmd[OFF + 2] = spd / 256;
+   cmd[OFF + 3] = spd & 0xFF;
+/*    printf ("Setting read speed to %d kB/sec\n", spd == 0xFFFF ? maxspd : spd); */
+   /* do the scsi cmd */
+   if (handle_scsi_cmd (12, 0, cmd, 0, NULL, 0)) {
+      perror ("speed select MMC failed\n");
+   }
+}
+
 /* request vendor brand and model */
 unsigned char *Inquiry ( void )
 {
@@ -1172,6 +1312,21 @@
 	     the value of global.littleendian.
 
      */
+    switch (get_mmc()) {
+     case 2:
+       if ( global.littleendian == -1 )
+	 global.littleendian = 1;
+       overlap = 0;
+       ReadCdRom = ReadCddaMMC12;
+       SelectSpeed = SpeedSelectSCSIMMC;
+       break;
+     case 1:
+       if ( global.littleendian == -1 )
+	 global.littleendian = 1;
+       ReadCdRom = ReadCddaMMC12;
+       SelectSpeed = SpeedSelectSCSIMMC;
+       break;
+     case 0:
     if (!memcmp(p+8,"TOSHIBA", 7) ||
         !memcmp(p+8,"IBM", 3) ||
         !memcmp(p+8,"DEC", 3)) {
@@ -1212,6 +1367,9 @@
 /*	overlap = 0; */
 	if ( global.littleendian == -1 )
 		global.littleendian = 1;
+        if (!memcmp(p+16, "CD-ROM CDU55E",13)) {
+	   ReadCdRom = ReadCddaMMC12;
+	}
     } else if (!memcmp(p+8,"NEC",3)) {
 	ReadCdRom = ReadCdda10;
         SelectSpeed = SpeedSelectSCSINEC;
@@ -1219,6 +1377,7 @@
 		global.littleendian = 1;
         if (!memcmp(p+29,"5022.0r",3)) /* I assume all versions of the 502 require this? */
                overlap = 0;           /* no overlap reading for NEC CD-ROM 502 */
+    }
     }
 
     ReadToc = (!memcmp(p+8, "IMS", 3)) ? ReadTocCdrSCSI : ReadTocSCSI;
