static void GenSubQFromSubPW(void)
{
 uint8 SubQBuf[0xC];

 subq_deinterleave(cd.SubPWBuf, SubQBuf);

 //printf("Real %d/ SubQ %d - ", read_sec, BCD_to_U8(SubQBuf[7]) * 75 * 60 + BCD_to_U8(SubQBuf[8]) * 75 + BCD_to_U8(SubQBuf[9]) - 150);
 // Debug code, remove me.
 //for(int i = 0; i < 0xC; i++)
 // printf("%02x ", SubQBuf[i]);
 //printf("\n");

 if(!subq_check_checksum(SubQBuf))
 {
  SCSIDBG("SubQ checksum error!");
 }
 else
 {
  memcpy(cd.SubQBuf_Last, SubQBuf, 0xC);

  uint8 adr = SubQBuf[0] & 0xF;

  if(adr <= 0x3)
   memcpy(cd.SubQBuf[adr], SubQBuf, 0xC);

  //if(adr == 0x02)
  //for(int i = 0; i < 12; i++)
  // printf("%02x\n", cd.SubQBuf[0x2][i]);
 }
}
//
// Checks for Q subchannel mode 1(current time) data that has a correct checksum, but the data is nonsensical or corrupted nonetheless; this is the
// case for some bad rips floating around on the Internet.  Allowing these bad rips to be used will cause all sorts of problems during emulation, so we
// error out here if a bad rip is detected.
//
// This check is not as aggressive or exhaustive as it could be, and will not detect all potential Q subchannel rip errors; as such, it should definitely NOT be
// used in an effort to "repair" a broken rip.
//
void CDAccess_CCD::CheckSubQSanity(void)
{
 size_t checksum_pass_counter = 0;
 int prev_lba = INT_MAX;
 uint8 prev_track = 0;

 for(size_t s = 0; s < img_numsectors; s++)
 {
  union
  {
   uint8 full[96];
   struct
   {
    uint8 pbuf[12];
    uint8 qbuf[12];
   };
  } buf;

  sub_stream->seek(s * 96, SEEK_SET);
  sub_stream->read(buf.full, 96);

  if(subq_check_checksum(buf.qbuf))
  {
   uint8 adr = buf.qbuf[0] & 0xF;

   if(adr == 0x01)
   {
    uint8 track_bcd = buf.qbuf[1];
    uint8 index_bcd = buf.qbuf[2];
    uint8 rm_bcd = buf.qbuf[3];
    uint8 rs_bcd = buf.qbuf[4];
    uint8 rf_bcd = buf.qbuf[5];
    uint8 am_bcd = buf.qbuf[7];
    uint8 as_bcd = buf.qbuf[8];
    uint8 af_bcd = buf.qbuf[9];

    //printf("%2x %2x %2x\n", am_bcd, as_bcd, af_bcd);

    if(!BCD_is_valid(track_bcd) || !BCD_is_valid(index_bcd) || !BCD_is_valid(rm_bcd) || !BCD_is_valid(rs_bcd) || !BCD_is_valid(rf_bcd) ||
	!BCD_is_valid(am_bcd) || !BCD_is_valid(as_bcd) || !BCD_is_valid(af_bcd) ||
	rs_bcd > 0x59 || rf_bcd > 0x74 || as_bcd > 0x59 || af_bcd > 0x74)
    {
     throw MDFN_Error(0, _("Garbage subchannel Q data detected(bad BCD/out of range): %02x:%02x:%02x %02x:%02x:%02x"), rm_bcd, rs_bcd, rf_bcd, am_bcd, as_bcd, af_bcd);
    }
    else
    {
     int lba = ((BCD_to_U8(am_bcd) * 60 + BCD_to_U8(as_bcd)) * 75 + BCD_to_U8(af_bcd)) - 150;
     uint8 track = BCD_to_U8(track_bcd);

     prev_lba = lba;

     if(track < prev_track)
      throw MDFN_Error(0, _("Garbage subchannel Q data detected(bad track number)"));
     //else if(prev_track && track - pre

     prev_track = track;
    }
    checksum_pass_counter++;
   }
  }
 }

 //printf("%u/%u\n", checksum_pass_counter, img_numsectors);
}